CVE-2026-5071
Description
The SocketCAN implementation validates the length of a user-provided buffer containing a socketcan_frame object using only a NET_ASSERT statement in zcan_sendto_ctx() before dereferencing it in socketcan_to_can_frame(). In production builds where assertions are disabled, a userspace application that controls the length passed to a sendto syscall can supply an incomplete or truncated frame, causing socketcan_to_can_frame() to dereference fields beyond the end of the buffer. This results in an out-of-bounds read that can cause denial-of-service crashes or, because the parsed frame contents are transmitted on the network, leak adjacent memory.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Out-of-bounds read in Zephyr's SocketCAN when NET_ASSERT is disabled allows local DoS and potential memory leak via crafted sendto syscall.
Vulnerability
The Zephyr SocketCAN implementation in zcan_sendto_ctx() validates the length of a user-provided buffer containing a socketcan_frame object using only a NET_ASSERT (sockets_can.c:L259). In production builds where assertions are disabled, a userspace application that controls the length passed to a sendto syscall can supply an incomplete or truncated frame. This causes socketcan_to_can_frame() (socketcan_utils.h:L40-L45) to dereference fields beyond the end of the buffer, leading to an out-of-bounds read. The issue affects Zephyr versions prior to patches applied in v3.7 (#104677), v4.2 (#104678), v4.3 (#104679), and main (#104654) [1].
Exploitation
An attacker needs the ability to invoke a sendto syscall on a SocketCAN socket with a controlled buffer length smaller than sizeof(struct socketcan_frame). No special authentication or network position is required; a local unprivileged userspace application can trigger the path by crafting a sendto call with an undersized buffer. The zcan_sendto_ctx() function processes the data and only validates the length with an assert, which is eliminated in production builds, so the execution reaches socketcan_to_can_frame() without additional checks, directly reading out-of-bounds memory [1].
Impact
Successful exploitation results in an out-of-bounds read that can cause denial-of-service crashes due to access of invalid memory. Because the parsed frame contents are transmitted on the network via the SocketCAN interface, the out-of-bounds data can be exfiltrated to adjacent network nodes, potentially leaking sensitive memory contents. The attacker does not gain code execution but can poison internal memory structures or cause system instability [1].
Mitigation
Patches are available in the Zephyr repository at v3.7 (#104677), v4.2 (#104678), v4.3 (#104679), and main (#104654). The recommended fix replaces the NET_ASSERT with an explicit runtime check: if (len != sizeof(struct socketcan_frame)) return -EINVAL; to ensure safety in production builds [1]. Users should update to patched versions; there is no known workaround. The vulnerability is not listed in CISA KEV as of publication date.
AI Insight generated on May 30, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
2(expand)+ 1 more
- (no CPE)
- (no CPE)
Patches
61e595d5864d1doc: vuln: Add CVE under embargo
1 file changed · +5 −0
doc/security/vulnerabilities.rst+5 −0 modified@@ -2247,3 +2247,8 @@ Under embargo until 2026-05-23 ---------------- Under embargo until 2026-05-21 + +:cve:`2026-5071` +---------------- + +Under embargo until 2026-05-18
4b92d9cc339edoc: release/4.4: Add CVE under embargo
1 file changed · +2 −0
doc/releases/release-notes-4.4.rst+2 −0 modified@@ -66,6 +66,8 @@ The following CVEs are addressed by this release: * :cve:`2026-5067` Under embargo until 2026-05-23 +* :cve:`2026-5071` Under embargo until 2026-05-18 + API Changes ***********
dc33bc95a87cnet: lib: sockets: can: always verify length in zcan_sendto_ctx()
1 file changed · +3 −1
subsys/net/lib/sockets/sockets_can.c+3 −1 modified@@ -257,7 +257,9 @@ ssize_t zcan_sendto_ctx(struct net_context *ctx, const void *buf, size_t len, dest_addr = (struct sockaddr *)&can_addr; } - NET_ASSERT(len == sizeof(struct socketcan_frame)); + if (len != sizeof(struct socketcan_frame)) { + return -EINVAL; + } socketcan_to_can_frame((struct socketcan_frame *)buf, &zframe);
ba00f963494cnet: lib: sockets: can: always verify length in zcan_sendto_ctx()
1 file changed · +3 −1
subsys/net/lib/sockets/sockets_can.c+3 −1 modified@@ -257,7 +257,9 @@ ssize_t zcan_sendto_ctx(struct net_context *ctx, const void *buf, size_t len, dest_addr = (struct sockaddr *)&can_addr; } - NET_ASSERT(len == sizeof(struct socketcan_frame)); + if (len != sizeof(struct socketcan_frame)) { + return -EINVAL; + } socketcan_to_can_frame((struct socketcan_frame *)buf, &zframe);
eb20a1037737net: lib: sockets: can: always verify length in zcan_sendto_ctx()
1 file changed · +3 −1
subsys/net/lib/sockets/sockets_can.c+3 −1 modified@@ -257,7 +257,9 @@ ssize_t zcan_sendto_ctx(struct net_context *ctx, const void *buf, size_t len, dest_addr = (struct sockaddr *)&can_addr; } - NET_ASSERT(len == sizeof(struct socketcan_frame)); + if (len != sizeof(struct socketcan_frame)) { + return -EINVAL; + } socketcan_to_can_frame((struct socketcan_frame *)buf, &zframe);
b43902929638net: lib: sockets: can: always verify length in zcan_sendto_ctx()
1 file changed · +3 −1
subsys/net/lib/sockets/sockets_can.c+3 −1 modified@@ -256,7 +256,9 @@ ssize_t zcan_sendto_ctx(struct net_context *ctx, const void *buf, size_t len, dest_addr = (struct net_sockaddr *)&can_addr; } - NET_ASSERT(len == sizeof(struct socketcan_frame)); + if (len != sizeof(struct socketcan_frame)) { + return -EINVAL; + } socketcan_to_can_frame((struct socketcan_frame *)buf, &zframe);
Vulnerability mechanics
Root cause
"Missing input validation: the length of a user-supplied buffer is only checked via a debug-only NET_ASSERT, which is compiled away in production builds, allowing an undersized buffer to be passed to socketcan_to_can_frame() where fields beyond the buffer boundary are read."
Attack vector
A local attacker with the ability to invoke the sendto syscall on a SocketCAN socket can supply a buffer whose length is smaller than sizeof(struct socketcan_frame). In production builds, NET_ASSERT is a no-op, so the truncated buffer reaches socketcan_to_can_frame(), which reads fields beyond the end of the buffer. This out-of-bounds read can cause a denial-of-service crash, and because the parsed frame contents are transmitted on the network, adjacent kernel memory may be leaked.
Affected code
The vulnerable code is in zcan_sendto_ctx() in subsys/net/lib/sockets/sockets_can.c. The function validates the user-provided buffer length only via NET_ASSERT(len == sizeof(struct socketcan_frame)), which is compiled away when assertions are disabled. The buffer is then cast to struct socketcan_frame * and passed to socketcan_to_can_frame(), which dereferences fields without any further length check.
What the fix does
The patch replaces the debug-only NET_ASSERT(len == sizeof(struct socketcan_frame)) with a runtime check that returns -EINVAL when the length does not match [patch_id=3165185][patch_id=3165186][patch_id=3165187]. This ensures the length validation is always enforced, even in production builds where assertions are disabled. No other changes are needed because the existing socketcan_to_can_frame() logic is correct when given a properly sized buffer.
Preconditions
- authAttacker must have local access and the ability to invoke sendto on a SocketCAN socket.
- inputAttacker supplies a buffer with length less than sizeof(struct socketcan_frame).
- configThe build must have assertions disabled (production configuration), making NET_ASSERT a no-op.
Generated on May 30, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
1News mentions
0No linked articles in our index yet.