CVE-2026-87043
MediumCVSS 4.8Exploitation Probability (EPSS)
Low risk8th percentile - higher than 8% of all known CVEs
Summary
In the entropy-device random number generator (subsys/random/random_entropy_device.c), rand_get() returned early with -ENODEV when device_is_ready() failed, bypassing the non-cryptographic system-timer fallback. Because sys_rand_get() and sys_rand32_get() return void and cannot report failure, the caller's output buffer was left untouched and its previous (uninitialized) contents were returned as random data. The not-ready state is a normal runtime condition (e.g., early initialization) or a permanent result of an entropy driver init failure.
Risk Assessment
Every non-cryptographic random value in the system becomes constant or stale memory, leading to predictable CoAP tokens, incorrect TCP initial sequence numbers, DHCP transaction IDs, WebSocket masking keys, RTP SSRCs, and Pointer Authentication keys. Where bytes are transmitted directly (SSH padding, netmidi2 session nonce, DTLS connection ID), stale stack or heap contents may be disclosed on the wire.
Recommendation
Update to a version containing the fix that initializes ret to -ENODEV and only calls entropy_get_entropy() when the device is ready, ensuring the buffer is always written and the timer fallback is used. An attacker cannot induce the unready state, but the resulting non-random values can be exploited remotely, so patching is high priority.
Other vulnerabilities in Zephyr RTOS
See all- CVE-2026-90585Medium
The Renesas RA SCI UART driver in Zephyr does not acknowledge the receive-error condition in uart_ra_sci_eri_isr() when no callback is registered (data->user_cb is NULL). The SCI error flags remain set and the ICU interrupt flag is never cleared, causing the ISR to re-pend immediately and re-enter endlessly. This occurs with CONFIG_UART_INTERRUPT_DRIVEN=y and CONFIG_UART_ASYNC_API=n when the error interrupt is unmasked by uart_configure() or uart_irq_err_enable().
- CVE-2026-87041High
A vulnerability in the RTIO submission-queue verifier rtio_vrfy_sqe() in Zephyr RTOS stems from incorrectly combining K_SYSCALL_MEMORY() results with &=; since the macro returns nonzero on failure, buffer permission checks were inverted. Inaccessible buffers were accepted while legitimate thread-owned buffers caused a kernel oops. This allows user threads with an RTIO context to write to arbitrary kernel memory, disclose it, or fault the kernel, bypassing CONFIG_USERSPACE isolation.
- CVE-2026-87039High
A vulnerability in the Zephyr RTOS syscall verifier z_vrfy_i2s_configure() skips the K_SYSCALL_OBJ ownership/type check for config.mem_slab and the block_size sanity check when frame_clk_freq is 0. As a result, an unprivileged thread under CONFIG_USERSPACE can supply an arbitrary pointer that reaches driver code (e.g., i2s_litex) and is used in supervisor context by k_mem_slab_alloc()/k_mem_slab_free().
- CVE-2026-16511High
Two RTIO syscall verifiers in Zephyr RTOS failed to properly validate user-supplied pointers before the kernel wrote through them. z_vrfy_rtio_sqe_cancel() performed no validation at all, allowing a user-mode thread to set chosen bits in kernel memory, while z_vrfy_rtio_sqe_copy_in_get_handles() wrote a kernel pointer to an arbitrary address without a write-permission check. Only systems built with CONFIG_USERSPACE and CONFIG_RTIO are affected.
- CVE-2026-82962Medium
A vulnerability in ethernet_fill_header() in the Zephyr RTOS network stack prepends the Ethernet header in place via net_buf_push without verifying that the packet has sufficient headroom. Packets allocated by a different L2 (e.g., 802.15.4/OpenThread, PPP) and handed to Ethernet through routing or tunnelling have too little (usually zero) headroom, causing an out-of-bounds write. In builds without CONFIG_ASSERT and CONFIG_NET_BUF_HARDENING this results in memory corruption.
- CVE-2026-19595Medium
A vulnerability in the Zephyr RTOS syscall verifier: z_vrfy_rtio_cqe_get_mempool_buffer() validated its output parameters buff and buff_len with K_SYSCALL_MEMORY_READ() instead of K_SYSCALL_MEMORY_WRITE(). This allows an unprivileged user-mode thread to invoke the syscall with pointers to read-only memory, causing a supervisor-mode store outside the permitted region or a kernel fault that halts or reboots the device.
- CVE-2026-19940Medium
A vulnerability in the Bluetooth Classic Hands-Free Profile Audio Gateway (HFP AG) implementation in Zephyr RTOS causes corruption of the kernel timeout list. By sending AT+CIND? and quickly reconnecting, a remote attacker can trigger a system-wide fault or hang.
- CVE-2026-19736High
The NXP MCUX TRNG entropy driver in Zephyr (drivers/entropy/entropy_mcux_trng.c) passes the caller's byte count directly to the SDK routine TRNG_GetRandomData(), which on i.MX RT5xx/RT6xx parts always copies whole 32-bit words and rounds entropy draws up to a multiple of 128 bytes. A request length not a multiple of four causes an underflow in the SDK's buffer-full check, leading to an overflow of up to 127 bytes past the caller's buffer.
- CVE-2026-19575High
A vulnerability in Zephyr RTOS affects the user-mode verification handler z_vrfy_device_deinit() in kernel/device.c, which validated its dev argument with K_SYSCALL_OBJ_INIT(dev, K_OBJ_ANY). Because k_object_validate() short-circuits type comparison for K_OBJ_ANY, the check only verified that the pointer was the base address of some kernel object the calling thread was granted, without comparing the object's actual type. This allows a local user-mode thread to pass a thread stack object (e.g., from k_thread_stack_alloc()) and achieve supervisor-mode kernel code execution.
- CVE-2026-19574High
In the ARM64 MMU back-end of Zephyr RTOS, address space identifiers (ASIDs) are assigned by a bare round-robin counter, which after wrapping past 255 possible values can hand the same ASID to a new domain while a still-live domain holds it. Because domain-private mappings are installed as non-global (MT_NG), the ASID is the only tag separating cached translations in the TLB, and the context-switch path does not flush the TLB for a duplicate reached through a third domain. As a result, user-mode threads in one domain can read and write memory belonging to another domain, defeating memory-domain isolation.
Original NVD description (English source)
The entropy-device random number generator in subsys/random/random_entropy_device.c returned early with -ENODEV from rand_get() as soon as device_is_ready() failed, before reaching the non-cryptographic system-timer fallback further down the same function. Because z_impl_sys_rand_get() returns void and discards that error — and the public sys_rand_get() syscall is itself declared void, so it cannot report failure — the caller's output buffer was left untouched and its previous contents were handed back as random data. The thin wrappers make this a plain uninitialized read: sys_rand32_get() declares uint32_t ret;, calls sys_rand_get(&ret, sizeof(ret)) and returns ret. The "not ready" state is a normal runtime condition rather than a fault. Entropy drivers initialise at PRE_KERNEL_1 with CONFIG_ENTROPY_INIT_PRIORITY (default 50), so any earlier initialiser — kernel objects run at priority 30 — observes an unready device; the sibling generator subsys/random/random_xoshiro128.c and z_early_rand_get() in kernel/init.c both already carried an explicit timer fallback for exactly this case. The state is also permanent for the boot when an entropy driver's init hook fails, which several in-tree drivers can do on real hardware (entropy_stm32 on an RNG clock configuration error, entropy_psa_crypto when psa_crypto_init() fails, entropy_nrf_cracen, entropy_esp32, entropy_virtio). When this occurs, every non-cryptographic random value in the system is either a constant or stale memory. coap_next_token() in subsys/net/lib/coap/coap.c fills a static buffer, so every CoAP token becomes the same .bss constant; tcp_init_isn() in subsys/net/ip/tcp.c returns an uninitialized stack word as the TCP initial sequence number; DHCPv4/DHCPv6 transaction IDs, WebSocket masking keys and RTP SSRCs are similarly degraded, and arch/arm64/core/pac.c derives per-thread Pointer Authentication keys from the same source. Where the bytes are transmitted directly — SSH packet padding, the netmidi2 session nonce, a DTLS connection ID on builds without CONFIG_CSPRNG_ENABLED — stale caller stack or heap contents are disclosed on the wire. The fix initialises ret to -ENODEV and only calls entropy_get_entropy() when the device is ready, so the not-ready case now falls through to the timer fallback and the buffer is always written. The cryptographically secure path is unchanged: sys_csrand_get() still propagates the error to the caller and never silently degrades. An attacker cannot induce the unready state, but can observe and exploit the resulting non-random values remotely on an affected device.
Vulnerability data from NVD (NIST) · CISA KEV · EPSS

