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

CVE-2026-10667: Zephyr RTOS Privilege Escalation Flaw

CVE-2026-10667 is a privilege escalation vulnerability in Zephyrproject Zephyr RTOS caused by a use-after-free race condition in kernel object tracking on SMP systems, allowing unprivileged threads to corrupt kernel memory.

Updated:

CVE-2026-10667 Overview

CVE-2026-10667 is a use-after-free vulnerability [CWE-416] in the Zephyr real-time operating system (RTOS) kernel. The flaw resides in the dynamic kernel-object tracking code in kernel/userspace/userspace.c. Iteration of the obj_list doubly-linked list occurred under lists_lock, while removal and freeing of nodes used disjoint spinlocks (objfree_lock and obj_lock). On symmetric multiprocessing (SMP) builds with userspace enabled, an unprivileged user thread can trigger concurrent removal of a node being traversed by another CPU. The result is a dangling list traversal that dereferences freed kernel memory, enabling kernel memory corruption or a kernel crash across the userspace security boundary.

Critical Impact

A local, deprivileged user-mode thread on a CONFIG_SMP + CONFIG_USERSPACE + CONFIG_DYNAMIC_OBJECTS build can corrupt kernel object-tracking structures, leading to potential privilege escalation or denial of service.

Affected Products

  • Zephyr RTOS v1.14.0 through v4.4.0
  • Builds with CONFIG_SMP + CONFIG_USERSPACE + CONFIG_DYNAMIC_OBJECTS enabled
  • Downstream distributions and firmware images based on affected Zephyr versions

Discovery Timeline

  • 2026-07-12 - CVE-2026-10667 published to NVD
  • 2026-07-16 - Last updated in NVD database

Technical Details for CVE-2026-10667

Vulnerability Analysis

Zephyr tracks dynamically allocated kernel objects in a doubly-linked list called obj_list. The function k_object_wordlist_foreach() iterates this list using the SAFE iterator variant, which caches the next node pointer before invoking the callback. That iteration is serialized by lists_lock.

Removal of nodes, however, was serialized by two different spinlocks. k_object_free() acquired objfree_lock, and unref_check() acquired obj_lock. Because the removal path and the iteration path never shared a lock, one CPU could unlink and k_free() the exact node that another CPU had cached as its next pointer. When the iterator advanced, it dereferenced freed memory.

All racing operations are reachable via system calls from unprivileged user threads. This crosses the userspace-to-kernel security boundary defined by CONFIG_USERSPACE.

Root Cause

The defect originated with the 2019 spinlockification refactor in commit 8a3d57b6cc6, first shipped in Zephyr v1.14.0. Splitting list mutation across objfree_lock and obj_lock while iteration held only lists_lock broke the invariant that traversal and removal must share a serializing primitive.

Attack Vector

An unprivileged user thread invokes k_object_alloc, k_object_alloc_size, or k_object_release to drive removals through unref_check(). Concurrently, k_thread_abort or thread creation drives iteration via k_thread_perms_all_clear() and k_thread_perms_inherit(). Racing these system calls across CPUs corrupts the obj_list state.

c
// Patch excerpt from kernel/userspace/userspace.c
#ifdef CONFIG_DYNAMIC_OBJECTS
 static struct k_spinlock lists_lock;       /* kobj dlist */
-static struct k_spinlock objfree_lock;     /* k_object_free */

Source: Zephyr commit fdc42fa256b8c2a7b27790f032d5385f8058c4a9. The patch removes objfree_lock and serializes every obj_list modification under lists_lock, including holding it across find-and-remove in k_object_free() and around unref_check() in k_thread_perms_clear().

Detection Methods for CVE-2026-10667

Indicators of Compromise

  • Unexpected kernel panics or hard faults during thread lifecycle events (k_thread_abort, thread creation) on SMP targets
  • Memory corruption warnings or slab allocator inconsistencies logged near k_object_free or k_object_wordlist_foreach
  • User threads issuing high-frequency, interleaved calls to k_object_alloc, k_object_release, and k_thread_abort

Detection Strategies

  • Audit build configurations for the vulnerable combination of CONFIG_SMP=y, CONFIG_USERSPACE=y, and CONFIG_DYNAMIC_OBJECTS=y on Zephyr versions v1.14.0 through v4.4.0
  • Enable kernel address sanitizer (KASAN) or equivalent memory checkers in development builds to catch use-after-free traversals during stress testing
  • Instrument obj_list operations with debug logging to detect concurrent modification under mismatched locks

Monitoring Recommendations

  • Collect kernel crash logs and coredumps from fleet devices and correlate faults to userspace boundary transitions
  • Track anomalous system call rates for object allocation and thread termination primitives on multi-core Zephyr devices
  • Baseline normal thread lifecycle behavior and alert on sustained bursts of k_object_alloc/k_object_release from a single user context

How to Mitigate CVE-2026-10667

Immediate Actions Required

  • Upgrade Zephyr to a release containing commit fdc42fa256b8c2a7b27790f032d5385f8058c4a9 (post-v4.4.0 fix)
  • Inventory all firmware images and downstream products built on Zephyr v1.14.0 through v4.4.0 and schedule rebuilds
  • Restrict which user-mode applications are permitted to run on affected devices until patched firmware is deployed

Patch Information

The fix is available in the Zephyr security advisory GHSA-9x5j-h3rh-x579 and the corresponding upstream commit fdc42fa. The patch removes objfree_lock entirely and serializes every obj_list modification under lists_lock, holding it across both the find-and-remove sequence in k_object_free() and the unref_check() call in k_thread_perms_clear().

Workarounds

  • Disable CONFIG_DYNAMIC_OBJECTS if the application does not require dynamic kernel object allocation
  • Build with CONFIG_SMP=n on single-core capable targets to eliminate the concurrent-CPU precondition
  • Disable CONFIG_USERSPACE where the deployment does not require the userspace security model, removing unprivileged system call access
bash
# Example Kconfig fragment to remove the vulnerable configuration surface
CONFIG_DYNAMIC_OBJECTS=n
# Or, where feasible for the target and application:
CONFIG_SMP=n

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.