Skip to main content
Vulnerability Database/CVE-2026-19185

CVE-2026-19185: Zephyr I3C Driver Privilege Escalation

CVE-2026-19185 is a privilege escalation flaw in Zephyr RTOS I3C driver allowing unprivileged threads to gain supervisor access through improper validation. This post covers technical details, impact, and fixes.

Published:

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.

c
// 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
bash
# 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.

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.