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

CVE-2026-16513: Zephyr RTOS Privilege Escalation Vulnerability

CVE-2026-16513 is a privilege escalation flaw in Zephyr RTOS that allows unprivileged threads to write kernel memory and escalate to supervisor mode. This article covers the technical details, affected configurations, and patches.

Published:

CVE-2026-16513 Overview

CVE-2026-16513 is a kernel memory corruption vulnerability in the Zephyr Real-Time Operating System (RTOS) affecting the RTIO subsystem. The userspace verifier z_vrfy_rtio_sqe_copy_in_get_handles() in subsys/rtio/rtio_syscalls.c fails to validate the handle out-parameter before writing to it. An unprivileged user-mode thread holding a struct rtio kernel object can invoke the syscall with an arbitrary destination pointer. This yields a write-what-where primitive that stores a kernel pointer to attacker-controlled data at any kernel address. The flaw is classified as [CWE-787] Out-of-bounds Write and affects builds compiled with both CONFIG_USERSPACE and CONFIG_RTIO prior to Zephyr v4.3.0.

Critical Impact

Attackers with user-mode execution can escalate to kernel mode by corrupting function pointers, thread structures, or memory-domain partition tables, defeating the isolation boundary CONFIG_USERSPACE is designed to enforce.

Affected Products

  • Zephyr RTOS versions prior to v4.3.0
  • Builds compiled with CONFIG_USERSPACE=y and CONFIG_RTIO=y
  • Applications using sensor_read_async_mempool() or async ADC helpers that internally call rtio_sqe_copy_in_get_handles()

Discovery Timeline

  • 2026-09-28 - CVE-2026-16513 published to the National Vulnerability Database (NVD)
  • 2026-09-30 - Last updated in NVD database

Technical Details for CVE-2026-16513

Vulnerability Analysis

The defect lives in the RTIO syscall verifier that mediates user-to-kernel transitions for submission-queue entry (SQE) copy operations. The verifier correctly validates the r kernel object and the sqes input array using K_SYSCALL_OBJ and K_SYSCALL_MEMORY_ARRAY_READ respectively. However, it never checks the handle out-parameter before dereferencing it. On the first loop iteration, the verifier executes *handle = sqe, storing the kernel address of a newly acquired SQE through a pointer taken verbatim from user mode.

Because the store executes in supervisor mode and precedes any submission-entry content validation, it fires unconditionally when the syscall is invoked. The reporter demonstrated the primitive on qemu_x86, where a K_USER thread mutated a supervisor global from NULL to a live kernel SQE pointer.

Root Cause

The root cause is a missing K_SYSCALL_MEMORY_WRITE validation for a syscall out-parameter [CWE-787]. Zephyr's userspace threat model requires every writable pointer crossing the user-kernel boundary to be checked against the caller's memory domain. The verifier omitted this check for handle, treating it as trusted despite originating in user mode.

Attack Vector

Any user-mode thread already granted access to a struct rtio object can invoke the vulnerable syscall path. This is the ordinary calling pattern for the RTIO API in production Zephyr builds. The attacker supplies an arbitrary kernel address as handle; the kernel then writes a pointer to an SQE slot whose contents the attacker fully controls via the subsequent *sqe = sqes[i] copy. The resulting write-what-where primitive is sufficient to corrupt kernel function pointers, thread structures, or memory-domain partition tables, enabling privilege escalation from user to kernel mode.

c
 	K_OOPS(K_SYSCALL_OBJ(r, K_OBJ_RTIO));
 
 	K_OOPS(K_SYSCALL_MEMORY_ARRAY_READ(sqes, sqe_count, sizeof(struct rtio_sqe)));
+	if (handle != NULL) {
+		K_OOPS(K_SYSCALL_MEMORY_WRITE(handle, sizeof(*handle)));
+	}
 	struct rtio_sqe *sqe;
 	uint32_t acquirable = rtio_sqe_acquirable(r);

Source: Zephyr Security Patch Commit 95c355c. The patch adds a K_SYSCALL_MEMORY_WRITE check ahead of the loop, guarded by the existing optional-NULL semantics, so the destination must lie in the calling thread's writable memory domain or the thread is terminated by K_OOPS.

Detection Methods for CVE-2026-16513

Indicators of Compromise

  • Unexpected K_OOPS faults originating from user threads calling RTIO syscalls after applying the patch
  • Kernel crashes or panics traced to writes into supervisor-only memory regions during RTIO operations
  • Anomalous modifications to kernel globals, thread control blocks, or memory-domain partition tables on affected devices

Detection Strategies

  • Audit firmware images and build configurations for the combination CONFIG_USERSPACE=y and CONFIG_RTIO=y on Zephyr versions earlier than v4.3.0
  • Inspect application code for use of sensor_read_async_mempool(), async ADC helpers, or direct calls that reach rtio_sqe_copy_in_get_handles()
  • Enable Zephyr kernel fault logging and forward oops traces to a centralized log collector for review

Monitoring Recommendations

  • Correlate device telemetry for reboots, watchdog resets, and kernel oops events on IoT and embedded fleets running Zephyr
  • Ingest embedded-device logs into a centralized analytics platform to identify clusters of RTIO-related faults
  • Track supply-chain metadata to enumerate deployed Zephyr versions across the estate

How to Mitigate CVE-2026-16513

Immediate Actions Required

  • Upgrade Zephyr to v4.3.0 or later, which contains the K_SYSCALL_MEMORY_WRITE(handle, sizeof(*handle)) validation
  • Rebuild and reflash all affected firmware images that ship with CONFIG_USERSPACE and CONFIG_RTIO enabled
  • Audit downstream forks and vendor Zephyr distributions to confirm the fix is backported

Patch Information

The fix is committed upstream in Zephyr commit 95c355c and documented in GitHub Security Advisory GHSA-fwmc-q8qg-jcxq. The patch adds a K_SYSCALL_MEMORY_WRITE check before the copy loop, ensuring the handle destination lies within the calling thread's writable memory domain. A related hardening in commit bea93400138 addresses z_vrfy_rtio_cqe_get_mempool_buffer() out-parameter validation.

Workarounds

  • Disable CONFIG_RTIO in build configurations where the RTIO subsystem is not required
  • Disable CONFIG_USERSPACE where all threads can safely run as privileged, which removes the verifier from the build
  • Restrict grant of struct rtio kernel objects to trusted threads only until patching is complete
bash
# Kconfig fragment to disable RTIO where not needed
CONFIG_RTIO=n

# Verify installed Zephyr version meets or exceeds v4.3.0
west list -f "{name} {revision}" | grep zephyr

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.