Description
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.
Published: 2026-10-09
Score: 7.8 High
EPSS: < 1% Very Low
KEV: No
Impact: Kernel code execution
Action: Apply patch
AI Analysis

Impact

The vulnerability arises from a type confusion bug in the device_deinit system call in Zephyr. The user‑mode verification handler validates the device argument using K_SYSCALL_OBJ_INIT with K_OBJ_ANY, which bypasses the actual object type check. Because the check only verifies that the pointer refers to a kernel object granted to the calling thread, an attacker can supply a writable kernel object, such as a thread stack, that resides in user‑accessible memory. The kernel then interprets the attacker‑controlled memory as a struct device, dereferences a function pointer in the ops.deinit field, and eventually performs a supervisor‑mode indirect call to an arbitrary address, together with arbitrary read and a one‑byte write. This results in full kernel code execution for the local unprivileged thread, completely subverting the CONFIG_USERSPACE isolation boundary.

Affected Systems

Vendor and Product: Zephyr Project's Zephyr real‑time operating system. Affected releases include Zephyr v4.2.x and v4.3.x, where CONFIG_DEVICE_DEINIT_SUPPORT was enabled by default, as well as any v4.4.0 or later build that explicitly enables CONFIG_DEVICE_DEINIT_SUPPORT. The older v4.2 line is no longer maintained and does not receive newer backports. Systems built with CONFIG_USERSPACE and with device de‑initialization support compiled in are vulnerable.

Risk and Exploitability

The CVSS score of 7.8 classifies the vulnerability as high severity. The EPSS score is not available, and the vulnerability is not listed in the CISA KEV catalog. The attack requires only a local unprivileged user thread with permission to hold a kernel object, which is a realistic scenario in many Zephyr deployments. As the vulnerability is limited to builds that enable both user‑space isolation and device de‑initialization support, the exploitability is focused but still quite concerning. Successful exploitation provides the attacker with complete kernel code execution, effectively granting full system compromise and bypassing all security hardening in the affected builds.

Generated by OpenCVE AI on October 9, 2026 at 08:21 UTC.

Remediation

No solution or workaround provided in the CVE record.

OpenCVE Recommended Actions

  • Upgrade Zephyr to a patched release that incorporates the fix (commit 1036694) or apply the patch directly.
  • If an upgrade is not possible, disable the CONFIG_DEVICE_DEINIT_SUPPORT option for all builds that enable CONFIG_USERSPACE.
  • Validate that configurations combining CONFIG_USERSPACE and CONFIG_DEVICE_DEINIT_SUPPORT are avoided, ensuring that user‑space threads cannot obtain control of kernel objects that could be misused.

Generated by OpenCVE AI on October 9, 2026 at 08:21 UTC.

Tracking

Sign in to view the affected projects.

Advisories

No advisories yet.

History

Fri, 09 Oct 2026 18:30:00 +0000

Type Values Removed Values Added
Metrics ssvc

{'options': {'Automatable': 'no', 'Exploitation': 'none', 'Technical Impact': 'total'}, 'version': '2.0.3'}


Fri, 09 Oct 2026 09:15:00 +0000

Type Values Removed Values Added
First Time appeared Zephyrproject
Zephyrproject zephyr
Vendors & Products Zephyrproject
Zephyrproject zephyr

Fri, 09 Oct 2026 07:45:00 +0000

Type Values Removed Values Added
Description 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.
Title Type confusion in the device_deinit system call allows user-mode threads to execute arbitrary kernel code
Weaknesses CWE-843
References
Metrics cvssV3_1

{'score': 7.8, 'vector': 'CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H'}


Subscriptions

Zephyrproject Zephyr
cve-icon MITRE

Status: PUBLISHED

Assigner: zephyr

Published:

Updated: 2026-10-09T17:54:02.591Z

Reserved: 2026-08-11T19:47:44.428Z

Link: CVE-2026-19575

cve-icon Vulnrichment

Updated: 2026-10-09T17:53:52.647Z

cve-icon NVD

Status : Awaiting Analysis

Published: 2026-10-09T08:16:55.057

Modified: 2026-10-09T18:17:08.263

Link: CVE-2026-19575

cve-icon Redhat

No data.

cve-icon OpenCVE Enrichment

Updated: 2026-10-09T09:00:03Z

Weaknesses
  • CWE-843

    Access of Resource Using Incompatible Type ('Type Confusion')