Zephyr RTOS
CVE-2026-19595
MEDIUM
Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessObtain user-mode thread with RTIO access grant
-
DeliveryCraft CQE with RTIO_CQE_FLAG_MEMPOOL_BUFFER and block index/count
-
ExploitInvoke rtio_cqe_get_mempool_buffer with read-only buff/buff_len pointers
-
ExecutionKernel performs supervisor-mode stores through pointers
-
ImpactFault halts/reboots device or corrupts P_RW_U_RO partition
Vulnerability Assessment
| Weakness |
CWE
ASVS 5.0
V15 - Secure Coding and Architecture Bounds checking, write limits
MITRE ATT&CK
2 techniques across 2 tactics: Execution, Privilege Escalation The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | Exploitation requires the device to be built with BOTH CONFIG_USERSPACE and CONFIG_RTIO_SYS_MEM_BLOCKS (the configuration behind RTIO_DEFINE_WITH_MEMPOOL); without CONFIG_RTIO_SYS_MEM_BLOCKS the implementation returns -ENOTSUP and writes nothing, so the flaw is unreachable. The attacker must already be an unprivileged user-mode thread that has been granted access to the RTIO context via rtio_access_grant(). The thread must supply a completion-queue entry with RTIO_CQE_FLAG_MEMPOOL_BUFFER set in flags[7:0] (block index in flags[19:8], count in flags[31:20]) and buff/buff_len pointers to memory it can read but not write. Limiting factors: no remote vector (local user-mode thread only), the RTIO access grant must have been issued beforehand, and the retained read-permission check prevents targeting kernel-private memory or disclosing data - the realistic worst case is a reliable device halt/reboot (DoS) or a partly-controlled write into a user-read-only (P_RW_U_RO) memory-domain partition. |
| Impact | All signals converge on this being a genuine but moderate, locally-scoped issue rather than an internet-facing emergency. The CVSS vector (AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:H, 6.1) correctly reflects that exploitation requires an already-running unprivileged user-mode thread on the device that has been explicitly granted the RTIO context via rtio_access_grant() - this is local access with some pre-existing privilege, not a remote network attack. The dominant impact is Availability (A:H): any such thread can aim the out-parameters at globally-readable-but-unwritable flash (.text/.rodata), causing a supervisor-mode store fault that reaches z_fatal_error() and reliably halts or reboots the device (DoS). Integrity impact is limited (I:L): the attacker can deposit only partly-controlled values (a pointer-sized store and a 4-byte length) into memory a memory-domain partition marked K_MEM_PARTITION_P_RW_U_RO, bypassing that partition's user-level write protection. Confidentiality is correctly N - the retained read-permission check means kernel-private memory cannot be targeted and no data is disclosed. No EPSS score, no CISA KEV listing, and no public exploit were provided; absence of KEV/EPSS is expected for an embedded-RTOS flaw and is not itself a red flag. The practical priority is high for the specific population of devices running CONFIG_USERSPACE + CONFIG_RTIO_SYS_MEM_BLOCKS that expose RTIO to untrusted user threads, and low for everyone else, since the vulnerable code path is entirely absent without that configuration. |
| Exploit ScenarioDerived | On a Zephyr device built with CONFIG_USERSPACE and CONFIG_RTIO_SYS_MEM_BLOCKS, a low-trust application thread that holds an RTIO access grant calls rtio_cqe_get_mempool_buffer() passing a completion-queue entry whose flags it fully controls and buff/buff_len pointers aimed at read-only memory (e.g. flash .rodata). The kernel verifier only checks read permission, so it proceeds and performs supervisor-mode stores through those pointers, faulting and triggering the default fatal-error handler to halt or reboot the device for a reliable denial of service; alternatively the thread targets a P_RW_U_RO partition to write past its own write protection. No public proof-of-concept was identified at time of analysis, but the attack is deterministic and requires no special timing. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Oct 19, 2026
A permission-check flaw in Zephyr's RTIO syscall layer lets an unprivileged user-mode thread write into memory it is only permitted to read. In z_vrfy_rtio_cqe_get_mempool_buffer(), the two output parameters buff and buff_len are validated with K_SYSCALL_MEMORY_READ() instead of K_SYSCALL_MEMORY_WRITE(), so when CONFIG_USERSPACE and CONFIG_RTIO_SYS_MEM_BLOCKS are both enabled and the thread already holds an RTIO context grant, the kernel performs a pointer-sized and a 4-byte supervisor-mode store (a CWE-787 out-of-bounds write through mis-validated output pointers). Pointing those pointers at global read-only flash (.text/.rodata) causes a kernel fault handled by z_fatal_error() and the default fatal handler halts or reboots the device - a reliable denial of service - while targeting a K_MEM_PARTITION_P_RW_U_RO partition yields a partly attacker-controlled write that bypasses user-read-only protection; no data disclosure is possible because the read check still applies, and there is no public exploit identified at time of analysis, with exploitation strictly local (CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:H, 6.1).
RemediationAI
Vendor-released patch: apply upstream commit bea93400138362691403b7f81de1e9048681547d (referenced in advisory https://github.com/zephyrproject-rtos/zephyr/security/advisories/GHSA-7337-mc44-5wjm), which replaces the two K_SYSCALL_MEMORY_READ() checks on buff and buff_len in z_vrfy_rtio_cqe_get_mempool_buffer() with K_SYSCALL_MEMORY_WRITE() and then rebuild and reflash affected devices; backporting this two-line change to a downstream tree is feasible if upgrading is not immediately possible. Where patching must be deferred, the most effective compensating control is to disable CONFIG_RTIO_SYS_MEM_BLOCKS (and therefore RTIO_DEFINE_WITH_MEMPOOL), which makes the implementation return -ENOTSUP and writes nothing - the trade-off is loss of mempool-backed RTIO block-based I/O; failing that, avoid calling rtio_access_grant() on RTIO contexts so no userspace thread can reach the syscall, accepting that those threads lose RTIO access. Treat any combination of CONFIG_USERSPACE with a granted RTIO context as exposed until the fix lands, and note that disabling CONFIG_USERSPACE removes the attack path but forfeits the entire memory-protection model, while auditing log output for unexpected z_fatal_error()/k_sys_fatal_error_handler() halts can reveal attempted DoS exploitation.
Affects your stack
Find out whether the stacks and servers you run are on an affected version.
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
Zephyr's user-mode syscall verification layer uses K_SYSCALL_MEMORY_READ()/K_SYSCALL_MEMORY_WRITE() inside K_OOPS() to confirm, before dispatching to the z_impl_ function, that a userspace-supplied pointer is accessible with the required direction. Those macros ultimately call the architecture validator arch_buffer_validate(); on RISC-V PMP the global __rom_region/__rodata_region is accepted for reads only, and the ARM MPU validators accept P_RO_U_RO and P_RW_U_RO region attributes for reads only. rtio_cqe_get_mempool_buffer() has no input buffers at all: buff (pointer-sized) and buff_len (4 bytes) are pure out-parameters that z_impl_rtio_cqe_get_mempool_buffer() writes the mempool buffer address and length into, so read-validation of a writable output is the wrong direction entirely. The attacker controls the completion-queue entry's flags: flags[7:0] must contain RTIO_CQE_FLAG_MEMPOOL_BUFFER, flags[19:8] supply the block index and flags[31:20] the count, giving partial influence over the values deposited. Reachability is gated on CONFIG_USERSPACE plus CONFIG_RTIO_SYS_MEM_BLOCKS (the config behind RTIO_DEFINE_WITH_MEMPOOL); with that config absent the implementation returns -ENOTSUP and performs no store. The retained read check is what bounds severity: only memory the thread may read can be targeted, so kernel-private memory is out of reach and C:I remains none - the outcome is either resource-protection bypass inside a K_MEM_PARTITION_P_RW_U_RO domain or, against flash-resident .text/.rodata, a supervisor-mode fault escalated to z_fatal_error(). The upstream fix (commit bea93400138362691403b7f81de1e9048681547d) simply swaps both checks to K_SYSCALL_MEMORY_WRITE(), so a thread lacking write permission is killed by K_OOPS before the implementation runs, while the cqe argument correctly stays read-validated.
Know when Zephyr gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:H
Local user-mode thread with a prior RTIO access grant gives AV:L/PR:L; deterministic path is AC:L; read-check blocks disclosure (C:N); only partly-controlled writes (I:L) but reliable device halt (A:H).
Primary rating from Vendor (zephyr).
CVSS VectorVendor: zephyr
DescriptionCVE.org
The user-mode syscall verifier z_vrfy_rtio_cqe_get_mempool_buffer() in subsys/rtio/rtio_syscalls.c validated its two output parameters, buff and buff_len, with K_SYSCALL_MEMORY_READ() rather than K_SYSCALL_MEMORY_WRITE(). Both are pure out-parameters: z_impl_rtio_cqe_get_mempool_buffer() stores the mempool buffer address and its length through them. The distinction is enforced by every architecture validator - arch_buffer_validate() on RISC-V PMP explicitly accepts the global __rom_region/__rodata_region for reads only, and the ARM MPU validators accept P_RO_U_RO and P_RW_U_RO regions for reads only - so a read-validated pointer is not necessarily writable by the calling thread.
An unprivileged user-mode thread that has been granted access to an RTIO context (rtio_access_grant()) can invoke the rtio_cqe_get_mempool_buffer() syscall with buff/buff_len pointing at memory it may read but not write, and with a completion-queue entry whose flags field it fully controls (only RTIO_CQE_FLAG_MEMPOOL_BUFFER in flags[7:0] is required; flags[19:8] and flags[31:20] supply the block index and count). The kernel then performs a pointer-sized and a 4-byte store through those addresses while running in supervisor mode. Reaching the store requires CONFIG_USERSPACE together with CONFIG_RTIO_SYS_MEM_BLOCKS, the configuration behind RTIO_DEFINE_WITH_MEMPOOL; without the latter the implementation returns -ENOTSUP and writes nothing.
Two outcomes follow. If the target lies in a memory-domain partition declared K_MEM_PARTITION_P_RW_U_RO (privileged read-write, user read-only), the kernel-mode store succeeds and deposits partly attacker-chosen values into memory the memory domain had marked read-only for that thread, bypassing the partition's write protection. If the target lies in globally readable but unwritable memory such as .text/.rodata in flash, the store faults in kernel mode; the fault is delivered to z_fatal_error() and the default k_sys_fatal_error_handler() halts or reboots the device, giving an unprivileged thread a reliable full denial of service.
The read-permission check does bound the damage: the address must still be readable by the calling thread, so kernel-private memory cannot be targeted and no confidential data is disclosed. The fix replaces both checks with K_SYSCALL_MEMORY_WRITE(), so a thread lacking write permission is terminated by K_OOPS before the implementation runs; the cqe argument correctly remains read-validated.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
A buffer overflow occurs when a program writes more data to a memory buffer than it was allocated to hold, causing the excess data to spill into adjacent memory regions.
Memory corruption occurs when a program writes data beyond the boundaries of allocated memory regions or accesses memory in unintended ways, violating the integrity of the process's address space.
Denial of Service attacks render applications or systems unavailable by overwhelming resources or triggering failure conditions.
Affected Products (CPE)CVE.org
Potential off-by-one buffer overflow vulnerability in the Zephyr fuse file system. Rated critical severity (CVSS 10.0),
An out-of-bounds write in the Zephyr RTOS DNS resolver (dns_unpack_name()) lets a crafted DNS response corrupt memory on
Possible variant of CVE-2021-3434 in function le_ecred_reconf_req. Rated critical severity (CVSS 9.8), this vulnerabilit
Unchecked user input length in /subsys/net/l2/wifi/wifi_shell.c can cause buffer overflows. Rated critical severity (CVS
Potential buffer overflow vulnerability in the Zephyr CAN bus subsystem. Rated critical severity (CVSS 9.8), this vulner
Integer Underflow in 6LoWPAN IPHC Header Uncompression in Zephyr. Rated critical severity (CVSS 9.8), this vulnerability
Buffer overflow in Zephyr USB DFU DNLOAD. Rated critical severity (CVSS 9.8), this vulnerability is remotely exploitable
DOS: Incorrect 802154 Frame Validation for Omitted Source / Dest Addresses. Rated critical severity (CVSS 9.8), this vul
zephyr-rtos version 1.12.0 contains a NULL base pointer reference vulnerability in sys_ring_buf_put(), sys_ring_buf_get(
Potential buffer overflow vulnerabilities n the Zephyr Bluetooth subsystem. Rated critical severity (CVSS 9.6), this vul
The documentation specifies that the BT_GATT_PERM_READ_LESC and BT_GATT_PERM_WRITE_LESC defines for a Bluetooth characte
Potential buffer overflows in the Bluetooth subsystem due to asserts being disabled in /subsys/bluetooth/host/hci_core.c
NVD
CVE.org
EPSS
Vulnrichment
GitHub
Exploit-DB