PT-2026-128334
CVE-2026-82961
·
Published
2026-10-28
·
Updated
2026-10-28
Description by
CVSS 3.1
7.8
HighMetricsAV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
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.
Found an issue in the description? Have something to add? Feel free to write us 👾