Description
The native BSD-socket layer recorded a pending asynchronous socket error by type-punning it into struct net_context's void user_data field (ctx->user_data = INT_TO_POINTER(-status) in zsock_accepted_cb(), zsock_received_cb(), zsock_connected_cb() and zsock_close_ctx() in subsys/net/lib/sockets/sockets_inet.c), reading it back with POINTER_TO_INT(). That same field is owned by the network stack for listening TCP contexts: net_tcp_accept() stores the parent context pointer there and the TCP core passes it back to the registered accept callback. A failed accept therefore left a small integer (an errno value) where the stack expected a struct net_context .

When the network interface carrying a listening TCP socket goes down, close_tcp_conn() in subsys/net/ip/tcp.c invokes the accept callback with -ENETDOWN and the context's user_data. In v4.3.0 the callback was not disarmed afterwards, so a second interface-down event forwarded the previously stored errno to zsock_accepted_cb(), which dereferenced it as the parent context and performed several stores through it (sock_set_error()'s read-modify-write of socket_data, k_fifo_cancel_wait(&parent->recv_q)) — the crash described in the fix's commit message. v4.3.1 and v4.4.x carry a later change clearing conn->accept_cb after the error callback (269cb8823d3 on the v4.3 branch, 913fae5169425550f2364655298fceb79b320066 on main), which closes that repeat path; on those releases the poisoned cookie remains reachable only by a narrower race, a handshake completing alongside the interface-down still passing the stale cookie to k_fifo_put(&parent->accept_q, ...), and by getsockopt(SO_ERROR), which reads the field back unconditionally.

On v4.3.0 an application that keeps a listening TCP socket open across repeated link-down events is sufficient to reach the defect; the triggering condition is a network-interface state change, not attacker-supplied packet data, so the practical attacker is one able to force the link down repeatedly (for example an adjacent attacker disrupting a wireless link) or one with local/physical access. Because both the faulting address and the stored data are fixed small constants derived from the errno value, the outcome is a wild-pointer access leading to a kernel fatal error — a denial of service (device crash or reset) rather than an attacker-directed memory corruption.

The fix stores the pending error in a dedicated net_context.sock_error field and converts every producer and consumer to sock_set_error()/sock_get_error(), leaving user_data untouched. As a side effect it also stops getsockopt(SO_ERROR) — which is evaluated unconditionally — from returning the kernel address held in user_data to a userspace application.
Published: 2026-09-28
Score: 6.5 Medium
EPSS: n/a
KEV: No
Impact: Denial of Service
Action: Patch Now
AI Analysis

Impact

The bug involves a wild pointer dereference in Zephyr's BSD socket implementation. During asynchronous error handling, an integer error value is mistakenly stored in the user_data field of a listening TCP context, which the TCP core later reinterprets as a pointer to the parent context. If a network interface with a listening socket goes down repeatedly, this corrupted pointer is dereferenced during a second interface‑down event, causing the kernel to write through an invalid address and crash. The flaw results in a device reset and is classified as a denial‑of‑service condition, with the associated weakness identified as CWE‑843 (Type Confusion). Because the stored data are fixed errno values, the crash cannot be used to leak or alter memory beyond causing a reset, so the impact is limited to a service interruption.

Affected Systems

Affected systems are devices running Zephyr Project version 4.3.0. The problem is present only in that release; versions 4.3.1 and later include a patch that clears the accept callback after an error and redirects error storage to a dedicated sock_error field. Vendors using the Zephyr 4.3.0 kernel for embedded applications that maintain long‑lived listening TCP sockets across link changes are vulnerable.

Risk and Exploitability

The CVSS score of 6.5 indicates moderate severity, while the EPSS score is not available, leaving the likelihood of exploitation uncertain. The vulnerability appears in the CISA KEV list as not listed, and no public exploitation has been reported. The attack vector requires an attacker to force the network interface down repeatedly, which could be achieved by disrupting a wireless link or by local or physical access. Therefore, devices that expose persistent listening sockets and rely on network reliability are at moderate risk of a device crash that could be triggered in the field or by a nearby attacker. Prompt remediation is recommended.

Generated by OpenCVE AI on September 29, 2026 at 00:26 UTC.

Remediation

No vendor fix or workaround currently provided.

OpenCVE Recommended Actions

  • Upgrade Zephyr to version 4.3.1 or later, where the bug is fully resolved.
  • If immediate upgrade is not possible, modify the application to close any listening TCP sockets before the network interface may go down, or ensure they are re‑created after the interface is restored.
  • As an interim measure, disable or suppress the accept callback during interface state changes until the system can be updated, or monitor for link‑down events and programmatically reset the socket to avoid the stale cookie.

Generated by OpenCVE AI on September 29, 2026 at 00:26 UTC.

Tracking

Sign in to view the affected projects.

Advisories

No advisories yet.

History

Tue, 29 Sep 2026 01:00:00 +0000

Type Values Removed Values Added
First Time appeared Zephyrproject
Zephyrproject zephyr
Vendors & Products Zephyrproject
Zephyrproject zephyr

Mon, 28 Sep 2026 23:45:00 +0000

Type Values Removed Values Added
Description The native BSD-socket layer recorded a pending asynchronous socket error by type-punning it into struct net_context's void user_data field (ctx->user_data = INT_TO_POINTER(-status) in zsock_accepted_cb(), zsock_received_cb(), zsock_connected_cb() and zsock_close_ctx() in subsys/net/lib/sockets/sockets_inet.c), reading it back with POINTER_TO_INT(). That same field is owned by the network stack for listening TCP contexts: net_tcp_accept() stores the parent context pointer there and the TCP core passes it back to the registered accept callback. A failed accept therefore left a small integer (an errno value) where the stack expected a struct net_context . When the network interface carrying a listening TCP socket goes down, close_tcp_conn() in subsys/net/ip/tcp.c invokes the accept callback with -ENETDOWN and the context's user_data. In v4.3.0 the callback was not disarmed afterwards, so a second interface-down event forwarded the previously stored errno to zsock_accepted_cb(), which dereferenced it as the parent context and performed several stores through it (sock_set_error()'s read-modify-write of socket_data, k_fifo_cancel_wait(&parent->recv_q)) — the crash described in the fix's commit message. v4.3.1 and v4.4.x carry a later change clearing conn->accept_cb after the error callback (269cb8823d3 on the v4.3 branch, 913fae5169425550f2364655298fceb79b320066 on main), which closes that repeat path; on those releases the poisoned cookie remains reachable only by a narrower race, a handshake completing alongside the interface-down still passing the stale cookie to k_fifo_put(&parent->accept_q, ...), and by getsockopt(SO_ERROR), which reads the field back unconditionally. On v4.3.0 an application that keeps a listening TCP socket open across repeated link-down events is sufficient to reach the defect; the triggering condition is a network-interface state change, not attacker-supplied packet data, so the practical attacker is one able to force the link down repeatedly (for example an adjacent attacker disrupting a wireless link) or one with local/physical access. Because both the faulting address and the stored data are fixed small constants derived from the errno value, the outcome is a wild-pointer access leading to a kernel fatal error — a denial of service (device crash or reset) rather than an attacker-directed memory corruption. The fix stores the pending error in a dedicated net_context.sock_error field and converts every producer and consumer to sock_set_error()/sock_get_error(), leaving user_data untouched. As a side effect it also stops getsockopt(SO_ERROR) — which is evaluated unconditionally — from returning the kernel address held in user_data to a userspace application.
Title Wild pointer dereference in Zephyr BSD sockets when a TCP listening socket reports an asynchronous error
Weaknesses CWE-843
References
Metrics cvssV3_1

{'score': 6.5, 'vector': 'CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H'}


Subscriptions

Zephyrproject Zephyr
cve-icon MITRE

Status: PUBLISHED

Assigner: zephyr

Published:

Updated: 2026-09-28T23:25:23.903Z

Reserved: 2026-07-30T17:54:13.939Z

Link: CVE-2026-18417

cve-icon Vulnrichment

No data.

cve-icon NVD

Status : Received

Published: 2026-09-29T00:17:04.207

Modified: 2026-09-29T00:17:04.207

Link: CVE-2026-18417

cve-icon Redhat

No data.

cve-icon OpenCVE Enrichment

Updated: 2026-09-29T00:45:07Z

Weaknesses
  • CWE-843

    Access of Resource Using Incompatible Type ('Type Confusion')