{"id":"CVE-2026-85032","kind":"vulnerability","aliases":["CVE-2026-85032"],"related":[],"title":"Zephyr MCTP USB: race between RX worker and disable frees live buffer","description":"The MCTP over USB device class in subsys/pmci/mctp/mctp_usb.c splits RX handling across two threads: the system workqueue runs mctp_usb_class_out_work(), which parses host OUT data byte by byte and fills a packet buffer at usb->rx_pkt, while the USB device stack thread runs mctp_usb_class_disable(). The disable handler used k_work_cancel(), which removes a queued work item but returns immediately without waiting for a handler that is already running, and then called mctp_usb_reset_rx_state() to mctp_pktbuf_free() the packet buffer the worker may still be using.\n\nBoth entry points into mctp_usb_class_disable() are driven by the attached USB host: a SET_CONFIGURATION request and a USB bus reset both reach it via usbd_config_reset() in subsys/usb/device_next/usbd_config.c. A host that streams partial MCTP frames on the bulk OUT endpoint and repeatedly forces a configuration change or bus reset therefore controls both the data being parsed and the moment the teardown runs, and can retry the race indefinitely without credentials or user interaction.\n\nIf the free lands while the worker holds the pointer, the worker writes host-supplied bytes into freed memory of the dedicated MCTP heap (CONFIG_MCTP_HEAP_SIZE in subsys/pmci/mctp/mctp_memory.c), corrupting recycled buffers or sys_heap free-block metadata; this window requires genuine parallelism, i.e. CONFIG_SMP or a preemptible CONFIG_SYSTEM_WORKQUEUE_PRIORITY. With the default cooperative workqueue the worker can still yield inside mctp_bus_rx() (application callback or a control-message reply blocking in mctp_usb_tx()), after which it resumes and calls mctp_pktbuf_free(usb->rx_pkt) on a pointer the teardown has NULLed, dereferencing NULL and faulting on targets with null-pointer detection.\n\nThe fix replaces the cancel with k_work_cancel_sync() plus a new struct k_work_sync out_work_sync, so disable waits for the RX worker to finish before draining the FIFO and freeing the packet buffer. The affected code is the MCTP subsystem, which is marked experimental, built only with CONFIG_MCTP_USB.","summary":"The MCTP over USB driver in Zephyr can free a packet buffer while its receive worker is still writing to it when the USB host changes configuration or resets the bus. A USB host that repeatedly triggers these events can corrupt the MCTP heap or fault the device.","severity":"medium","cvss":4.8,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["embedded","mctp","runtime","usb","zephyr"],"not_affected_if":["mctp-usb-disabled","no-untrusted-usb-host"],"how_to_check":"- Check whether the build enables `CONFIG_MCTP_USB`, since only builds with that option are affected.\n- Check whether the Zephyr tree includes `subsys/pmci/mctp/mctp_usb.c` using `k_work_cancel()` without the `k_work_cancel_sync()` fix.\n- Check whether `CONFIG_SMP` or a preemptible `CONFIG_SYSTEM_WORKQUEUE_PRIORITY` is set; the heap-corruption path needs it, while the default cooperative workqueue can still fault on a NULL dereference.","fix":null,"status":"open","published_at":"2026-11-03T14:17:38+00:00","first_seen_at":"2026-11-03T14:21:08+00:00","triaged_at":"2026-11-03T14:22:06+00:00","updated_at":"2026-11-03T14:22:06+00:00","category":"runtime","confidence":0.6,"triage":{"at":"2026-11-03T14:22:06Z","model":"claude-haiku-5-5","output":{"fix":"unknown","reach":"local","title":"Zephyr MCTP USB: race between RX worker and disable frees live buffer","impact":"high","summary":"The MCTP over USB driver in Zephyr can free a packet buffer while its receive worker is still writing to it when the USB host changes configuration or resets the bus. A USB host that repeatedly triggers these events can corrupt the MCTP heap or fault the device.","audience":"developers","category":"runtime","nicknames":[],"who_cares":["zephyr","embedded","usb","mctp"],"confidence":0.6,"fix_status":"unknown","needs_auth":"no","worst_case":"Attacker-controlled USB host corrupts heap memory or crashes the device","analyst_note":"Confirm the fixed Zephyr version from the linked patch and vendor advisory on github.com; the sources here do not name one.","how_to_check":"- Check whether the build enables `CONFIG_MCTP_USB`, since only builds with that option are affected.\n- Check whether the Zephyr tree includes `subsys/pmci/mctp/mctp_usb.c` using `k_work_cancel()` without the `k_work_cancel_sync()` fix.\n- Check whether `CONFIG_SMP` or a preemptible `CONFIG_SYSTEM_WORKQUEUE_PRIORITY` is set; the heap-corruption path needs it, while the default cooperative workqueue can still fault on a NULL dereference.","plain_action":"","needs_analyst":true,"not_affected_if":["mctp-usb-disabled","no-untrusted-usb-host"],"who_is_affected":"Only Zephyr builds that enable experimental MCTP over USB (`CONFIG_MCTP_USB`) are exposed, and the attack comes from the USB host connected to the device. Devices that do not use MCTP over USB, or that do not expose USB to untrusted hosts, can skip it. The sources do not state a fixed version.","user_interaction":"no","needs_special_setup":"yes","severity_if_unknown":"medium"},"cost_usd":0.00084,"input_tokens":4855,"output_tokens":709,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-2026':14A,17A '-85032':15A,18A 'across':83C 'affect':399C 'alreadi':146C 'applic':317C 'attach':181C 'block':286C,325C 'buffer':12A,35B,107C,162C,280C,397C 'built':409C 'bulk':211C 'bus':54B,191C,221C,315C 'byte':100C,102C,263C 'call':150C,335C 'callback':318C 'cancel':129C,364C,368C 'chang':49B,219C 'class':77C,92C,121C,175C 'code':400C 'config':198C,272C,294C,299C,412C 'configur':50B,186C,218C 'control':224C,322C 'control-messag':321C 'cooper':306C 'corrupt':64B,278C 'credenti':243C 'cve':13A,16A 'data':99C,227C 'dedic':269C 'default':305C 'dereferenc':349C 'detect':359C 'devic':71B,76C,115C 'disabl':9A,122C,124C,176C,381C 'drain':390C 'driven':178C 'driver':28B 'embed':19B 'endpoint':213C 'entri':170C 'event':62B 'experiment':408C 'fault':69B,352C 'fifo':392C 'fill':104C 'finish':388C 'fix':361C 'forc':216C 'frame':208C 'free':10A,32B,159C,249C,285C,338C,394C 'free-block':284C 'freed':265C 'genuin':291C 'handl':82C 'handler':125C,143C 'heap':67B,271C,274C,283C 'hold':254C 'host':48B,57B,97C,183C,203C,261C 'host-suppli':260C 'i.e':293C 'immedi':138C 'indefinit':241C 'insid':313C 'interact':246C 'item':135C 'k':127C,366C,374C 'land':250C 'live':11A 'mark':407C 'may':165C 'mctp':2A,20B,25B,66B,73C,90C,119C,151C,157C,173C,207C,270C,273C,314C,327C,336C,403C,413C 'memori':266C 'messag':323C 'metadata':287C 'moment':232C 'new':372C 'null':348C,350C,357C 'null-point':356C 'packet':34B,106C,161C,396C 'parallel':292C 'pars':96C,229C 'partial':206C 'pkt':111C,341C 'pktbuf':158C,337C 'plus':370C 'point':171C 'pointer':256C,344C,358C 'preemptibl':298C 'prioriti':302C 'queu':133C 'race':4A,240C 'reach':194C 'receiv':38B 'recycl':279C 'remov':131C 'repeat':59B,215C 'replac':362C 'repli':324C 'request':187C 'requir':290C 'reset':52B,153C,192C,199C,222C 'resum':333C 'retri':238C 'return':137C 'run':89C,118C,147C,235C 'runtim':21B 'rx':6A,81C,110C,154C,316C,340C,385C 'set':185C 'size':275C 'smp':295C 'split':80C 'stack':116C 'state':155C 'still':41B,166C,311C 'stream':205C 'struct':373C 'subsys/pmci/mctp/mctp_memory.c':277C 'subsys/pmci/mctp/mctp_usb.c':79C 'subsys/usb/device_next/usbd_config.c':201C 'subsystem':404C 'suppli':262C 'sync':369C,376C,379C 'sys':282C 'system':87C,300C 'target':354C 'teardown':234C,346C 'therefor':223C 'thread':85C,117C 'trigger':60B 'two':84C 'tx':329C 'usb':3A,22B,27B,47B,56B,75C,91C,109C,114C,120C,152C,174C,182C,190C,328C,339C,414C 'usbd':197C 'use':126C,168C 'user':245C 'via':196C 'wait':140C,382C 'window':289C 'without':139C,242C 'work':94C,128C,134C,367C,375C,378C 'worker':7A,39B,164C,253C,258C,309C,386C 'workqueu':88C,301C,307C 'write':42B,259C 'yield':312C 'zephyr':1A,23B,30B","nicknames":[],"mitigations":[],"who_affected":"Only Zephyr builds that enable experimental MCTP over USB (`CONFIG_MCTP_USB`) are exposed, and the attack comes from the USB host connected to the device. Devices that do not use MCTP over USB, or that do not expose USB to untrusted hosts, can skip it. The sources do not state a fixed version.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"unknown","audience":"developers","plain_action":null,"pkeys":[],"ptokens":[],"labels":["embedded","mctp","medium","runtime","usb","zephyr"],"first_public_at":"2026-11-02T21:30:41+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:P/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:H","cvss_by":"vulnerabilities@zephyrproject.org","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-85032","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-85032","severity":null,"published_at":"2026-11-03T14:17:38+00:00","modified_at":"2026-11-03T14:17:38+00:00","first_seen_at":"2026-11-03T14:21:08+00:00","fetched_at":"2026-11-03T14:21:08+00:00","note":null}],"documents":[{"id":58016,"url":"https://github.com/zephyrproject-rtos/zephyr/commit/277424084e740da5d61a17f40bea3457fa593acc","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":58017,"url":"https://github.com/zephyrproject-rtos/zephyr/security/advisories/GHSA-pp5m-jr2h-qp3f","title":"Vendor advisory: github.com","kind":"vendor","source":"nvd","publisher":"vendor","text":null,"published_at":"2026-11-02T21:30:41+00:00","relation":"advisory","confidence":null,"note":"Vendor advisory: github.com"}],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}