CVE-2026-16513: Missing write validation of user-supplied handle pointer in the RTIO syscall verifier allows arbitrary kernel write

Published Sep 28, 2026
·
Updated

The userspace verifier zvrfyrtiosqecopyingethandles() in subsys/rtio/rtiosyscalls.c (subsys/rtio/rtiohandlers.c before v4.3.0) validated the RTIO object handle and the sqes input array, but not the handle out-parameter. On the first loop iteration it executed handle = sqe, storing the kernel address of the newly acquired submission-queue entry through a pointer taken verbatim from user mode, with no KSYSCALLMEMORYWRITE check in front of it.

Any user-mode thread that has been granted a struct rtio kernel object can invoke the syscall with an arbitrary address in handle. That is the ordinary way an unprivileged thread uses the RTIO API, for example via sensorreadasyncmempool() or the async ADC helpers, which call rtiosqecopyingethandles() internally. The store happens in supervisor mode before any submission-entry validation, so it fires regardless of whether the SQE contents are subsequently rejected. Only builds with CONFIGUSERSPACE and CONFIGRTIO are affected; without CONFIGUSERSPACE the verifier is not compiled and the caller is already privileged.

The write address is fully attacker-chosen and the written value is a pointer into the caller's own RTIO ring, whose contents the caller controls (the following sqe = sqes[i] copies an attacker-supplied struct rtiosqe into that slot). This yields a write-what-where primitive placing a pointer to attacker-controlled data at any kernel address, sufficient to corrupt kernel function pointers, thread structures, or memory-domain partition tables, and thus to escalate from user mode to kernel mode, defeating the isolation boundary CONFIGUSERSPACE is meant to enforce. At minimum it is a reliable kernel memory-corruption and crash primitive. The reporter reproduced the write on qemux86: a KUSER thread changed a supervisor global from NULL to a live kernel SQE pointer.

The fix adds KSYSCALLMEMORYWRITE(handle, sizeof(handle)) (guarded by the existing optional-NULL semantics) before the loop, so the destination must lie in the calling thread's writable memory domain or the thread is terminated by KOOPS. The neighbouring verifier zvrfyrtiocqegetmempoolbuffer(), which checked its buff/bufflen out-parameters only for read although the implementation writes through them, was hardened separately by bea93400138 ("rtio: syscalls: validate output params as writable"); that residual was materially weaker, since a read check still confines the target to the caller's own memory domain.

Affected Software

1 affected component
Zephyr Project Zephyr RTOS<4.3.0

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade to a fixed release to a version that resolves this vulnerability.

    Patch bea93400138
  2. Configuration

    Add K_SYSCALL_MEMORY_WRITE(handle, sizeof(*handle)) before the loop, preserving the existing optional-NULL semantics, so the handle destination must be in the calling thread's writable memory domain and invalid pointers terminate the thread with K_OOPS.

    Zephyr RTIO syscall verifier (z_vrfy_rtio_sqe_copy_in_get_handles) K_SYSCALL_MEMORY_WRITE(handle, sizeof(*handle)) = enabled

Event History

Sep 28, 2026
CVE Published
via MITRE·07:59 PM
Data Sourced
via MITRE·07:59 PM
DescriptionSeverityWeakness
Data Sourced
via NVD·09:17 PM
DescriptionSeverityWeakness

Frequently Asked Questions

1

Which deployments are exposed?

Only Zephyr builds that enable both CONFIG_USERSPACE and CONFIG_RTIO are affected. A user-mode thread must also have been granted a struct rtio kernel object; builds without CONFIG_USERSPACE do not compile the verifier, and callers are already privileged.

2

What does an attacker need to exploit this?

An attacker needs code execution as a user-mode thread with access to an RTIO object. They can supply an arbitrary address as the handle output parameter; no user interaction is required.

3

Can invalid submission-queue entries prevent exploitation?

No. The unvalidated write occurs in supervisor mode on the first loop iteration before submission-entry contents are validated, so it occurs even if the supplied SQE is later rejected.

4

How can I identify potentially affected application paths?

Review userspace-enabled RTIO use, especially code that grants RTIO objects to unprivileged threads. The affected syscall may be reached indirectly through sensor_read_async_mempool() or the asynchronous ADC helper APIs.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203