CVE-2026-17050
MediumCVSS 5.7Exploitation Probability (EPSS)
Low risk5th percentile - higher than 5% of all known CVEs
Summary
The experimental USB host stack in Zephyr contains a double-free vulnerability in the configuration descriptor buffer. On three error paths, the buffer is freed but the pointer is left dangling, leading to a second free during cleanup. The vulnerability can be triggered by a malicious or malformed USB device.
Risk Assessment
The risk includes deterministic denial of service (panic) on systems with heap hardening, or heap corruption on systems without it, potentially leading to unpredictable behavior. The attack requires physical connection of a malicious USB device but no user interaction.
Recommendation
Apply the fix that sets udev->cfg_desc = NULL after every k_heap_free(). If possible, disable the experimental USB host stack (CONFIG_USB_HOST_STACK) in production environments until the patch is deployed.
Other vulnerabilities in Zephyr
See all- CVE-2026-10772Unknown
This CVE has been rejected as a duplicate. The described vulnerability involved incorrect permission checking in the Bluetooth GATT notify/indicate paths in the Zephyr stack, but was already reported as CVE-2026-2411.
- CVE-2026-10676Unknown
CVE-2026-10676 has been withdrawn as analysis determined that the reported defect is not reachable in any released version of Zephyr. In every supported release, the affected value is corrected before use.
- CVE-2026-5067Critical
Zephyr OS has a memory corruption vulnerability in the HTTP server WebSocket upgrade path. An unauthenticated remote attacker can trigger it by sending a crafted Sec-WebSocket-Key header. The bounded copy does not guarantee NUL termination, leading to out-of-bounds read/write on stack.
- CVE-2026-15890Medium
A vulnerability in the PSA Internal Trusted Storage module in Zephyr involves a lack of synchronization in nonce generation for AEAD encryption. The function secure_storage_its_transform_aead_get_nonce() uses unsynchronized function-local static variables, and concurrent writes to the same UID can lead to nonce reuse with the same key. This causes a catastrophic AEAD failure, enabling data leakage and forgery of stored entries.
- CVE-2026-16515Medium
The net_icmpv6_send_error() function in the Zephyr network stack implemented only one of the three RFC 4443 section 2.4 suppression rules, so it did not check whether the packet's source address identifies a single node or whether the packet was sent to a multicast destination. An unauthenticated attacker on the same link can send a single IPv6 packet to ff02::1 with a spoofed victim source, causing every Zephyr node to emit ICMPv6 Parameter Problem messages to that victim (reflection with amplification), or send a unicast packet with a multicast source address, turning it into a link-flooding multicast frame.
- CVE-2026-15924Medium
Zephyr's TLS socket layer (subsys/net/lib/sockets/sockets_tls.c) keeps a process-global client_cache array of cached client session buffers shared by every TLS socket, with access serialized only by the per-socket ctx->lock mutex. Because CONFIG_NET_SOCKETS_TLS_MAX_CLIENT_SESSION_COUNT defaults to 1, two concurrent client sockets contend for the same slot, causing a use-after-free read and a double-free when two saves evict the same entry. This corrupts the mbedTLS heap; the fix adds a dedicated session_cache_lock mutex taken across every accessor of client_cache.
- CVE-2026-15923Medium
The Zephyr SDIO subsystem has a vulnerability in sdio_io_rw_extended_helper() where func->cis.max_blk_size is decoded from the SDIO card without validation. If a card reports a maximum block size of zero, the transfer loop never terminates, causing a thread hang and permanent mutex lock, leading to denial of service for the SDIO peripheral.
- CVE-2026-15460Medium
A vulnerability in the Bluetooth Classic (BR/EDR) stack in Zephyr RTOS affects the L2CAP receive handler, which dispatches inbound data PDUs based only on the destination channel ID without verifying that the channel has reached the BT_L2CAP_CONNECTED state. An attacker within radio range can send data to a channel during connection setup, before configuration and authentication complete. This can lead to delivery of attacker data to upper-layer protocols on a half-open channel and to use of stale or partially initialized channel state, causing denial of service or a potential dangling-pointer condition.
- CVE-2026-14697Medium
In the IPv6 subsystem of the Zephyr stack (subsys/net/ip/ipv6_nbr.c), the net_ipv6_send_ns() function allocates a transmit net_pkt for a Neighbor Solicitation. When called with a data packet pending on an unresolved neighbor and the neighbor's pending_queue is already non-empty, the function appends the data packet and returns early without sending the NS via net_send_data() or releasing it with net_pkt_unref(). The freshly allocated NS net_pkt and its attached TX buffers are held only by a local variable and are leaked permanently, never returning to CONFIG_NET_PKT_TX_COUNT / CONFIG_NET_BUF_TX_COUNT.
- CVE-2026-13735Low
Zephyr's WireGuard implementation mishandled keepalive packets. A type-4 message with a 16-byte payload (empty plaintext plus Poly1305 tag) was accepted without tag verification because wg_process_data_message() returned early before calling wg_decrypt_packet(). An attacker could send a forged keepalive without knowing the session key.
Original NVD description (English source)
The experimental USB host stack allocates a per-device configuration-descriptor buffer, udev->cfg_desc, from the dedicated usb_device_heap in usbh_device_set_configuration() (subsys/usb/host/usbh_device.c). On three failure paths — a failed full-length GET_DESCRIPTOR(CONFIGURATION) read, a mismatch between the short and full descriptor reads, and a rejected descriptor in parse_configuration_descriptor() — the buffer was released with k_heap_free() but the pointer was left dangling. The cleanup in usbh_device_free() is guarded only by if (udev->cfg_desc != NULL), so it frees the same block a second time. The path is driven entirely by the attached peripheral: usbh_device_connect() calls usbh_device_init(), which ends in usbh_device_set_configuration(), and on failure usbh_device_connect() calls usbh_device_free(). On v4.4.x this happens during the same enumeration, with no unplug required; on v4.1.0–v4.3.x the second free instead arrives via dev_removed_handler()/dev_connected_handler() in subsys/usb/host/usbh_core.c, so it requires a removal or duplicate-connect event after the failed enumeration — a sequence the attached device fully controls. A malicious or malformed USB device only has to answer the first 9-byte configuration-descriptor request with a well-formed header and then fail any of the three checks, for example by returning a full descriptor whose interface count disagrees with bNumInterfaces, or by answering the second read with different bytes. The result is a double free on usb_device_heap. On builds where lib/heap hardening is active (the current default CONFIG_SYS_HEAP_HARDENING_BASIC), sys_heap_free() detects the already-free chunk and calls k_panic(), giving a deterministic, peripheral-triggered denial of service of the USB host. On builds without that detection — earlier releases, or CONFIG_SYS_HEAP_HARDENING_NONE — the second free manipulates a chunk already on the free list, corrupting the heap's free list so that later allocations can return overlapping or invalid blocks. Exploitation beyond denial of service is bounded by the fact that usb_device_heap is a small dedicated heap (CONFIG_USBH_USB_DEVICE_HEAP, default 1024 bytes) whose only client is this descriptor buffer, and by CONFIG_USB_HOST_STACK being marked experimental and disabled by default. The fix sets udev->cfg_desc = NULL after every k_heap_free(), making the cleanup guard sound.
Vulnerability data from NVD (NIST) · CISA KEV · EPSS

