CVE-2026-19185 Overview
CVE-2026-19185 is a kernel privilege escalation vulnerability in the Zephyr Real-Time Operating System (RTOS). The flaw resides in the system call verifier for i3c_do_ccc() located in drivers/i3c/i3c_handlers.c. The verifier validates the outer struct i3c_ccc_payload, the broadcast ccc.data buffer, and the targets.payloads[] array. It does not validate the per-target data buffers that those array elements reference. The defect only exists in CONFIG_USERSPACE builds. An unprivileged user-mode thread with access to the Improved Inter-Integrated Circuit (I3C) controller device object can issue a direct Common Command Code (CCC) that references arbitrary kernel memory [CWE-822].
Critical Impact
An unprivileged user thread can read from or write to arbitrary kernel memory through the I3C controller driver, defeating the isolation that CONFIG_USERSPACE is designed to provide.
Affected Products
- Zephyr RTOS builds compiled with CONFIG_USERSPACE enabled
- I3C controller drivers including drivers/i3c/i3c_mcux.c, drivers/i3c/i3c_cdns.c, drivers/i3c/i3c_stm32.c, and drivers/i3c/i3c_npcx.c
- Applications that grant user threads access to an I3C controller device object
Discovery Timeline
- 2026-10-05 - CVE-2026-19185 published to NVD
- 2026-10-06 - Last updated in NVD database
Technical Details for CVE-2026-19185
Vulnerability Analysis
The vulnerability lies in the Zephyr system call handler z_vrfy_i3c_do_ccc() in drivers/i3c/i3c_handlers.c. The verifier validated the outer payload structure, the broadcast ccc.data buffer, and the targets.payloads[] array. It did not pass each struct i3c_ccc_target_payload's own data pointer and data_len through K_SYSCALL_MEMORY() before forwarding the payload to z_impl_i3c_do_ccc() and the controller driver.
Controller drivers dereference the per-target data pointer directly and use the read-not-write (rnw) flag to determine transfer direction. A read CCC causes the kernel-mode driver to write bus-received bytes to an attacker-chosen kernel address. A write CCC transmits kernel memory out onto the I3C bus. The outcome is an out-of-bounds kernel write combined with kernel memory disclosure, enabling escalation from a user thread to supervisor privilege.
Root Cause
Two defects compound the issue. First, nested buffers inside the targets.payloads[] array were never validated with K_SYSCALL_MEMORY(). Second, the verifier operated on the caller's live structure rather than a snapshot. A second user thread could modify the validated fields between the check and the driver's use, producing a time-of-check to time-of-use (TOCTOU) race. The sibling z_vrfy_i3c_transfer() handler already copied its message array first, but z_vrfy_i3c_do_ccc() did not.
Attack Vector
Exploitation requires local access and low privileges. An unprivileged user-mode thread must hold a kernel object permission on the I3C controller device, which is the standard way an application lets a user thread communicate with I3C peripherals. The attacker crafts an i3c_ccc_payload whose per-target data pointer names an arbitrary kernel address, then invokes the i3c_do_ccc syscall.
// Security patch excerpt - drivers/i3c/i3c_handlers.c
// Introduces copy_ccc_and_do() to snapshot and validate nested buffers
static int copy_ccc_and_do(const struct device *dev,
struct i3c_ccc_payload *payload)
{
struct i3c_ccc_payload copy;
struct i3c_ccc_target_payload *user_payloads;
struct i3c_ccc_target_payload *kernel_payloads = NULL;
size_t i;
int ret;
/* Work from a local copy rather than the caller's live structure. */
memcpy(©, payload, sizeof(copy));
if (copy.ccc.data != NULL) {
K_OOPS(K_SYSCALL_MEMORY_ARRAY_WRITE(copy.ccc.data,
copy.ccc.data_len,
sizeof(*copy.ccc.data)));
}
user_payloads = copy.targets.payloads;
if (user_payloads != NULL) {
K_OOPS(K_SYSCALL_VERIFY(copy.targets.num_targets >= 1 &&
copy.targets.num_targets < 32));
K_OOPS(K_SYSCALL_MEMORY_ARRAY_WRITE(user_payloads,
copy.targets.num_targets,
sizeof(*user_payloads)));
Source: Zephyr Project patch commit 35562f22
Detection Methods for CVE-2026-19185
Indicators of Compromise
- Kernel oops, panic, or unexpected faults originating from I3C controller driver code paths such as i3c_mcux, i3c_cdns, i3c_stm32, or i3c_npcx
- Unexpected device reboots or crashes correlated with user-mode applications that hold permissions on an I3C controller device object
- I3C bus traffic that does not match expected peripheral protocol patterns, suggesting kernel memory is being transmitted
Detection Strategies
- Audit Zephyr firmware builds to identify images compiled with CONFIG_USERSPACE=y that also enable the I3C subsystem
- Review application code and device policies for user-mode threads granted access to I3C controller device objects via k_object_access_grant()
- Compare the deployed drivers/i3c/i3c_handlers.c against upstream commit 35562f22 to confirm the copy_ccc_and_do() helper is present
Monitoring Recommendations
- Enable kernel fault logging and forward crash telemetry from embedded devices to a central collector for analysis
- Monitor firmware update pipelines to ensure new Zephyr builds include the patch before deployment
- Track I3C transaction patterns on sensitive devices to flag anomalous CCC usage
How to Mitigate CVE-2026-19185
Immediate Actions Required
- Rebuild and redeploy Zephyr firmware with the upstream patch applied to drivers/i3c/i3c_handlers.c
- Inventory all devices running CONFIG_USERSPACE builds that include the I3C subsystem and prioritize them for update
- Review application designs that expose the I3C controller to user-mode threads and remove unnecessary permissions
Patch Information
The fix is published in Zephyr commit 35562f22f40c6d2f31969a31f0a4902e5b067f27. It introduces copy_ccc_and_do(), which snapshots the payload, copies the target array into kernel memory with k_usermode_alloc_from_copy(), bounds num_targets to fewer than 32, validates each per-target buffer with K_SYSCALL_MEMORY() according to the rnw flag, and copies the driver-written num_xfer and err fields back to the caller. See the Zephyr Security Advisory GHSA-pcrr-29j7-8w57 and the patch commit for details.
Workarounds
- Disable CONFIG_USERSPACE in Zephyr builds where user-mode isolation is not required, which removes the vulnerable handler from the image
- Revoke user-mode thread access to I3C controller device objects, keeping I3C operations in supervisor mode only
- Restrict physical and network access to affected devices until firmware is patched to reduce opportunity for local exploitation
# Rebuild Zephyr with the patched tree
git fetch origin
git cherry-pick 35562f22f40c6d2f31969a31f0a4902e5b067f27
west build -b <board> -p always <application>
west flash
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.