Description
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.
Published: 2026-09-21
Score: 5.7 Medium
EPSS: n/a
KEV: No
Impact: Denial of Service
Action: Immediate Patch
AI Analysis

Impact

This vulnerability arises when the Zephyr experimental USB host stack fails to correctly free the configuration‑descriptor buffer during device enumeration. A malformed USB device can trigger a double free on usb_device_heap, which causes a kernel panic on builds with heap hardening or corrupts the heap on builds without it. The outcome is a deterministic denial of service delivered directly by a peripheral, without requiring privileged access to the host or exploits beyond the USB interface.

Affected Systems

The issue affects Zephyr projects that enable the experimental USB host stack. It is present in zephyrproject:zephyr releases covering at least v4.1.0 through v4.4.x. The vulnerable code path is internal to the USB host stack and is not present when CONFIG_USB_HOST_STACK is disabled. Users only see the impact when a USB device triggers a failed enumeration.

Risk and Exploitability

The CVSS score of 5.7 indicates moderate severity. Because the attack vector requires a USB peripheral that can be physically attached, the risk is confined to systems that expose the USB host interface to untrusted devices. The exploit does not provide arbitrary code execution; it only causes a denial of service or heap corruption that could affect future allocations. While the EPSS score is not available and the vulnerability is not listed in CISA KEV, the deterministic nature of the failure makes it a credible threat in environments that use the experimental stack.

Generated by OpenCVE AI on September 21, 2026 at 18:26 UTC.

Remediation

No vendor fix or workaround currently provided.

OpenCVE Recommended Actions

  • Update the Zephyr source to a version that contains the commit restoring the cfg_desc pointer to NULL during free operations (e.g., any release after the patch commit d46a8c1f8fb65e1f80b44bd651a6dafea747602e).
  • Enable CONFIG_SYS_HEAP_HARDENING_BASIC so that a double free triggers a controlled kernel panic or diagnostic, preventing silent heap corruption on systems where an immediate upgrade is not feasible.
  • If the experimental USB host stack is not required, permanently disable CONFIG_USB_HOST_STACK or remove the driver to eliminate the attack surface.

Generated by OpenCVE AI on September 21, 2026 at 18:26 UTC.

Tracking

Sign in to view the affected projects.

Advisories

No advisories yet.

History

Mon, 21 Sep 2026 17:00:00 +0000

Type Values Removed Values Added
Description 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.
Title Double free of the USB host configuration descriptor when device enumeration fails
Weaknesses CWE-415
References
Metrics cvssV3_1

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


Subscriptions

No data.

cve-icon MITRE

Status: PUBLISHED

Assigner: zephyr

Published:

Updated: 2026-09-21T18:49:25.187Z

Reserved: 2026-07-24T13:31:03.256Z

Link: CVE-2026-17050

cve-icon Vulnrichment

No data.

cve-icon NVD

Status : Received

Published: 2026-09-21T17:17:34.020

Modified: 2026-09-21T17:17:34.020

Link: CVE-2026-17050

cve-icon Redhat

No data.

cve-icon OpenCVE Enrichment

Updated: 2026-09-21T18:30:17Z

Weaknesses