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.
// 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()
# 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.

