IT SBIT Services
Schneeberger
DEEN
CVE tracker

Zephyr RTOS: Missing pin validation in GPIO syscalls allows out-of-bounds kernel writes

CVE-2026-82961High 7.8

← All vulnerabilities

Summary

Zephyr's GPIO syscall handlers do not validate the pin argument from user-mode callers. A user-mode thread that holds a grant on a GPIO device object can trigger out-of-bounds writes and reads in supervisor mode, which can escape the user-mode sandbox and lead to kernel memory corruption, code execution or a crash. The issue only applies to builds with CONFIG_USERSPACE enabled, and an attacker must first run code as such a thread on the device.

Affected

  • Zephyr from 2.2.0 up to and including 4.4.2 (CNA data; NVD analysis pending)
  • Only builds with CONFIG_USERSPACE=y and user-mode threads with GPIO object access

Fixed in

  • Zephyr 4.3.2 lists this CVE as fixed
  • Status of 4.4.x and LTS branches: Unknown. Check the GHSA advisory and your Zephyr branch for the backport

Workaround

  • No vendor-published workaround. Upgrading is the documented remedy.
  • Interim measure: review which threads receive GPIO object permissions and whether user mode is required

Exploitation

  • No known exploitation in the wild
  • No public proof of concept found
  • EPSS about 0.13 % (percentile 3)

Our recommendation

  • Identify Zephyr-based devices and firmware in your inventory and ask device vendors for their Zephyr version
  • Ask vendors for firmware updates that include the Zephyr 4.3.2 fix or a later backport
  • Until patched, limit GPIO object grants to user-mode threads and disable user mode where it is not needed
  • Note the CVSS disagreement: CNA 7.8, VulDB 8.8, CIRCL 5.8

Public exploits

PoC-in-GitHub, Metasploit and Exploit-DB list nothing for this CVE.

Research sources

Researched and written up in English and German by an AI (Claude by Anthropic) based on NVD, CISA, EPSS and the sources listed. The vendor information is authoritative. Researched on 1 Nov 2026, 21:45.

Original description (NVD)

The GPIO syscall handlers in drivers/gpio/gpio_handlers.c did not validate the pin argument supplied by a user-mode caller. z_vrfy_gpio_pin_configure(), z_vrfy_gpio_pin_get_config() and z_vrfy_gpio_pin_interrupt_configure() verified only the device object (K_SYSCALL_DRIVER_GPIO() / K_SYSCALL_OBJ()) and then passed the caller-supplied gpio_pin_t straight through to z_impl_gpio_pin_*() and on to the driver. The only pin check in include/zephyr/drivers/gpio.h was __ASSERT(gpio_port_pin_is_supported(cfg->port_pin_mask, pin), ...), which compiles to nothing unless CONFIG_ASSERT is enabled, so in a production build no check existed at all. GPIO drivers use pin as a shift count and as an array index on the documented assumption that it is a pin the controller supports. On STM32, for example, gpio_stm32_pin_interrupt_configure() turns pin into an EXTI line and stm32_gpio_intc_set_irq_callback() writes data->cb[line_num].cb and data->cb[line_num].data into a NUM_EXTI_LINES-entry array (default 16) in drivers/interrupt_controller/intc_gpio_stm32.c, guarded only by a compiled-out __ASSERT_NO_MSG(); the same function then reads exti_irq_table[line_num] and calls irq_enable() on the result. Other controllers index fixed-size per-pin configuration tables the same way — drivers/gpio/gpio_ite_it8xxx2_v2.c reads an MMIO base pointer out of wuc_base[8] with the caller's pin and performs a read-modify-write through it. The issue is reachable only in builds with CONFIG_USERSPACE=y (the file is compiled under that symbol), by a user-mode thread that has been granted access to a GPIO device object. Such a grant is intended to authorize control of that port's pins; the missing validation instead lets the thread drive a supervisor-mode out-of-bounds write of a function pointer and an associated void * past a kernel .bss array, and out-of-bounds reads that feed irq_enable() and MMIO accesses — an escape from the user-mode sandbox that can lead to kernel memory corruption, arbitrary code execution, or a crash. The fix validates pin against the controller's gpio_driver_config.port_pin_mask with gpio_port_pin_is_supported() in every pin-taking z_vrfy_ handler and returns -EINVAL otherwise, complemented by an unconditional pin >= GPIO_MAX_PINS_PER_PORT range check added to the shared z_impl_gpio_pin_*() inlines.

NVD references (5)

Sources

The tracker combines official, freely usable data sources – updated continuously:

This product uses data from the NVD API but is not endorsed or certified by the NVD. EPSS data © FIRST.org.

Affected? We can help.

We check whether your systems are affected, install updates and close the gap – continuously with the System Health Checker if you wish.