CVE-2026-19575 in Zephyrinfo

Summary

by MITRE • 10/09/2026

The user-mode verification handler for the device_deinit() system call, z_vrfy_device_deinit() in kernel/device.c, validated its dev argument with K_SYSCALL_OBJ_INIT(dev, K_OBJ_ANY). k_object_validate() short-circuits its type comparison when the requested type is K_OBJ_ANY, so the check reduced to "this pointer is the base address of some kernel object the calling thread has been granted" — the object's actual type was never compared, and K_SYSCALL_OBJ_INIT also skips the initialization-state check. The sibling handlers z_vrfy_device_init() and z_vrfy_device_is_ready() already used K_OBJ_DRIVER_ANY and were unaffected.

A thread running in user mode can therefore pass any kernel object it holds permission on — most usefully a thread stack object obtained from the k_thread_stack_alloc() syscall or a statically defined K_THREAD_STACK it was granted in order to spawn a child user thread — whose backing memory is writable from user mode. z_impl_device_deinit() then interprets those attacker-written bytes as a struct device: it dereferences the state pointer read out of the object, calls the function pointer read out of ops.deinit, and on success writes through state again. The result is an indirect call to an arbitrary address executed in supervisor mode, plus an arbitrary kernel read and a single-byte kernel write.

Exploitation gives a local unprivileged thread full kernel code execution, defeating the CONFIG_USERSPACE isolation boundary entirely; a less precise attempt yields a supervisor-mode fault and a system crash. The defect is only reachable in builds that enable both CONFIG_USERSPACE and CONFIG_DEVICE_DEINIT_SUPPORT — with de-initialization support disabled, z_impl_device_deinit() returns -ENOTSUP without ever dereferencing the pointer. In v4.2.x and v4.3.x, CONFIG_DEVICE_DEINIT_SUPPORT defaulted to y, so every CONFIG_USERSPACE build of those releases is exposed unless the option was explicitly turned off. From v4.4.0 the option is opt-in (no default, and not selected by any in-tree subsystem), so a v4.4.x build is exposed only if it enables the option explicitly. The v4.2 line is no longer maintained and receives no backport.

The fix changes the object check to K_OBJ_DRIVER_ANY, which constrains the argument to the build-generated driver object type range (K_OBJ_DRIVER_FIRST..K_OBJ_DRIVER_LAST) — the real struct device instances placed by the linker — so the state and ops.deinit fields are once again kernel-controlled.

Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.

Analysis

by VulDB Data Team • 10/09/2026

The vulnerability resides in the user-mode verification handler for the device_deinit system call, specifically within the z_vrfy_device_deinit function located in the Zephyr RTOS kernel/device.c file. This flaw stems from an incorrect validation mechanism that fails to enforce strict type checking on the input argument provided by unprivileged threads. The original implementation utilized K_SYSCALL_OBJ_INIT with a parameter of K_OBJ_ANY, which instructs the underlying k_object_validate routine to short-circuit its type comparison logic. Consequently, the security check was reduced to verifying only whether the pointer corresponds to the base address of some kernel object for which the calling thread has been granted access rights. This approach critically overlooked two essential aspects: it did not verify that the object is actually a device driver instance, and it bypassed initialization state checks entirely due to the nature of K_OBJ_ANY validation rules. In contrast, sibling handlers such as z_vrfy_device_init and z_vrfy_device_is_ready correctly employed K_OBJ_DRIVER_ANY, thereby restricting access to legitimate driver objects and remaining unaffected by this specific defect.

The operational impact of this vulnerability is severe, allowing a local unprivileged thread in user mode to achieve arbitrary code execution within supervisor mode, effectively breaking the CONFIG_USERSPACE isolation boundary that is fundamental to secure embedded systems design. An attacker can exploit this flaw by passing any kernel object they hold permission over, most notably a thread stack object obtained via k_thread_stack_alloc or a statically defined K_THREAD_STACK granted for spawning child user threads. Since these objects have backing memory writable from user mode, the malicious thread can craft arbitrary data structures that mimic the layout of struct device. When z_impl_device_deinit processes this forged input, it interprets the attacker-controlled bytes as valid kernel structures. It dereferences a state pointer read from the object and subsequently calls a function pointer located in the ops.deinit field, both of which are under the control of the unprivileged user thread.

This exploitation path results in an indirect call to an arbitrary memory address executed with supervisor privileges, granting full kernel code execution capabilities. Beyond remote or local privilege escalation, the vulnerability also facilitates information disclosure and limited integrity violations through a single-byte kernel write operation performed after the deinit function returns successfully. If the exploit is less precise or fails during the dereference phase, it typically results in a supervisor-mode fault leading to a system crash, representing a denial of service vector. The severity is compounded by the fact that this defect directly undermines the security model intended for multi-threaded environments where user and kernel modes are strictly separated.

The vulnerability is only reachable in Zephyr RTOS builds that explicitly enable both CONFIG_USERSPACE and CONFIG_DEVICE_DEINIT_SUPPORT configuration options. When de-initialization support is disabled, the implementation returns -ENOTSUP without attempting to dereference any pointers, thereby neutralizing the attack surface. In versions 4.2.x and 4.3.x of Zephyr RTOS, CONFIG_DEVICE_DEINIT_SUPPORT was enabled by default, meaning that every build utilizing user space isolation in these releases is inherently vulnerable unless the option was manually disabled during compilation. Starting from version 4.4.0, this configuration became opt-in with no default value and is not selected by any subsystem within the main tree, significantly reducing the attack surface for newer deployments. However, systems running on the v4.2 line remain exposed as that branch has reached end-of-life and does not receive backported security patches.

The remediation strategy involves correcting the object validation logic to enforce strict type constraints. The fix modifies the verification handler to use K_OBJ_DRIVER_ANY instead of K_OBJ_ANY for the device_deinit system call argument check. This change ensures that only objects falling within the build-generated driver object range, specifically between K_OBJ_DRIVER_FIRST and K_OBJ_DRIVER_LAST, are accepted as valid inputs. These ranges correspond to real struct device instances placed by the linker during the build process, ensuring that their internal state and operation pointers remain kernel-controlled rather than user-controllable. This alignment with proper access control principles restores the integrity of the isolation boundary between user mode applications and core kernel services.

From a classification perspective, this vulnerability aligns with CWE-20 Improper Input Validation, as the system fails to adequately verify that input data meets expected specifications before processing it in a privileged context. It also relates to CWE-94 Improper Control of Generation of Code (Code Injection), since user-controlled data is interpreted and executed as code within supervisor mode. In terms of offensive security frameworks like MITRE ATT&CK, this flaw facilitates Privilege Escalation via Local Exploitation, allowing an unprivileged actor to gain higher-level permissions by abusing a system call interface that lacks rigorous type checking. The incident underscores the critical importance of strict object type validation in operating systems enforcing user-kernel separation models.

Responsible

Zephyr

Reservation

08/11/2026

Disclosure

10/09/2026

Moderation

accepted

EPSS

0.00000

KEV

no

Activities

low

Sources

Want to know what is going to be exploited?

We predict KEV entries!