Skip to main content
CVE Vulnerability Database

CVE-2026-9728: Zephyr RTOS Mailbox Race Condition Vulnerability

CVE-2026-9728 is a race condition vulnerability in Zephyr RTOS mailbox syscall verifier that enables privilege escalation and memory disclosure. This article covers the technical details, security impact, and available mitigations.

Published:

CVE-2026-9728 Overview

CVE-2026-9728 is a time-of-check/time-of-use (TOCTOU) race condition [CWE-367] in the Zephyr RTOS userspace syscall verifier z_vrfy_mbox_send() located in drivers/mbox/mbox_handlers.c. The verifier validated the nested msg->data and msg->size fields by reading them directly from live userspace memory, then forwarded the still-mutable userspace struct mbox_msg * pointer to z_impl_mbox_send(). A concurrent thread sharing the caller's address space can overwrite msg->data with a supervisor address after the bounds check succeeds but before the mailbox driver dereferences it. The result is a userspace-to-supervisor access-control bypass leading to kernel memory disclosure or a faulting kernel read.

Critical Impact

Unprivileged userspace threads on systems built with CONFIG_USERSPACE can race the syscall verifier to leak kernel memory contents through mailbox peer endpoints or trigger a kernel fault denial of service.

Affected Products

  • Zephyr RTOS builds with CONFIG_USERSPACE enabled
  • Systems using the mailbox (mbox) subsystem with userspace syscalls
  • Deployments using drivers such as the NXP mailbox driver that consume msg->data in supervisor context

Discovery Timeline

  • 2026-08-24 - CVE-2026-9728 published to the National Vulnerability Database
  • 2026-08-26 - Last updated in NVD database

Technical Details for CVE-2026-9728

Vulnerability Analysis

The flaw resides in the userspace-to-kernel boundary of the Zephyr mailbox subsystem. z_vrfy_mbox_send() is the verifier that runs before the kernel-side implementation z_impl_mbox_send(). Before the fix, the verifier performed two access checks: one on the outer struct mbox_msg pointer, and one on the nested msg->data buffer using the userspace-resident msg->size. It then passed the original userspace pointer to the driver.

Because the struct mbox_msg lives in shared userspace memory, another thread in the same address space can mutate its fields after validation completes. When the driver later dereferences msg->data, for example via memcpy(&data32, msg->data, msg->size) in the NXP mailbox driver, it reads from an attacker-chosen supervisor address. Those bytes are then emitted to the mailbox peer endpoint, disclosing kernel memory. An invalid target address instead triggers a supervisor-mode fault, causing denial of service.

Root Cause

The root cause is validation of mutable userspace memory without snapshotting. The verifier trusted that msg->data and msg->size observed at check time would remain unchanged at use time, violating the TOCTOU invariant required for any syscall crossing the userspace/supervisor boundary.

Attack Vector

Exploitation requires local code execution as an unprivileged userspace thread on a Zephyr build with CONFIG_USERSPACE. The attacker spawns two cooperating threads sharing an address space. Thread A repeatedly invokes mbox_send() with a valid struct mbox_msg. Thread B races to overwrite msg->data with a supervisor address between the verifier's K_SYSCALL_MEMORY_READ check and the driver's dereference. On success, the driver reads kernel memory and transmits it through the mailbox peer channel.

c
// Patch: drivers/mbox/mbox_handlers.c
// mbox: userspace: fix TOCTOU race in z_vrfy_mbox_send
                   mbox_channel_id_t channel_id,
                   const struct mbox_msg *msg)
 {
+       struct mbox_msg msg_copy;
+
        K_OOPS(K_SYSCALL_DRIVER_MBOX(dev, send));

        if (msg == NULL) {
                /* Signalling mode: NULL msg is valid per the API contract */
                return z_impl_mbox_send(dev, channel_id, NULL);
        }

-       K_OOPS(K_SYSCALL_MEMORY_READ(msg, sizeof(struct mbox_msg)));
-       K_OOPS(K_SYSCALL_MEMORY_READ(msg->data, msg->size));
+       /* Copy the userspace struct into a kernel-stack snapshot before
+        * validating the nested data pointer, preventing a TOCTOU race where
+        * a concurrent thread could replace msg->data with a supervisor address
+        * after the access check.
+        */
+       K_OOPS(k_usermode_from_copy(&msg_copy, msg, sizeof(msg_copy)));
+       K_OOPS(K_SYSCALL_MEMORY_READ(msg_copy.data, msg_copy.size));

-       return z_impl_mbox_send(dev, channel_id, msg);
+       return z_impl_mbox_send(dev, channel_id, &msg_copy);
 }

Source: Zephyr commit ab35eac

Detection Methods for CVE-2026-9728

Indicators of Compromise

  • Unexpected mailbox peer traffic containing byte patterns consistent with kernel data structures, pointers, or symbol addresses
  • Kernel panics or supervisor-mode faults originating from mailbox driver read paths such as the NXP mailbox memcpy from msg->data
  • Userspace processes spawning tightly-coupled thread pairs that repeatedly invoke mbox_send() at high frequency

Detection Strategies

  • Instrument the mailbox driver to log the source address range of msg->data on each transmit and alert when it falls outside expected userspace regions
  • Audit Zephyr builds for CONFIG_USERSPACE=y combined with vulnerable mailbox handlers and flag firmware images that predate the ab35eac commit
  • Correlate mailbox peer-side receivers for anomalous payload entropy or repeated fixed-length reads that could indicate kernel-memory scraping

Monitoring Recommendations

  • Enable Zephyr fault reporting and forward supervisor read faults to a centralized log for review
  • Track syscall invocation rates for mbox_send() per thread and alert on burst patterns paired with concurrent memory writes to the same struct mbox_msg
  • Include firmware version and patch-level attestation in device inventory to surface unpatched Zephyr endpoints

How to Mitigate CVE-2026-9728

Immediate Actions Required

  • Apply the upstream Zephyr fix from commit ab35eac that snapshots struct mbox_msg with k_usermode_from_copy() before validation
  • Rebuild and redeploy firmware for all devices running Zephyr with CONFIG_USERSPACE=y and the mailbox subsystem enabled
  • Inventory devices using mailbox drivers such as the NXP mailbox driver and prioritize them for patching

Patch Information

The fix replaces direct validation of the userspace struct mbox_msg with a kernel-stack copy created via k_usermode_from_copy(). The verifier then validates and forwards the immutable copy to z_impl_mbox_send(), closing the TOCTOU window. See the Zephyr GitHub Security Advisory GHSA-47q2-w832-7w67 and the upstream commit ab35eac.

Workarounds

  • Disable CONFIG_USERSPACE on devices that do not require userspace isolation, eliminating exposure of the vulnerable syscall path
  • Remove or restrict the mailbox driver from userspace-accessible device permissions until patched firmware is deployed
  • Constrain application threading models so untrusted code cannot spawn cooperating threads with shared writable buffers passed to mbox_send()
bash
# Verify Zephyr build configuration for exposure
grep -E 'CONFIG_USERSPACE|CONFIG_MBOX' build/zephyr/.config

# Confirm the patch is present in the source tree
git -C zephyr log --oneline ab35eaccec5976f05c196f176d0c32885754496f

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.