CVE-2026-82961: Unvalidated pin index in GPIO syscall handlers allows out-of-bounds kernel writes from user mode

Published Oct 28, 2026
·
Updated

The GPIO syscall handlers in drivers/gpio/gpiohandlers.c did not validate the pin argument supplied by a user-mode caller. zvrfygpiopinconfigure(), zvrfygpiopingetconfig() and zvrfygpiopininterruptconfigure() verified only the device object (KSYSCALLDRIVERGPIO() / KSYSCALLOBJ()) and then passed the caller-supplied gpiopint straight through to zimplgpiopin() and on to the driver. The only pin check in include/zephyr/drivers/gpio.h was ASSERT(gpioportpinissupported(cfg->portpinmask, pin), ...), which compiles to nothing unless CONFIGASSERT 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, gpiostm32pininterruptconfigure() turns pin into an EXTI line and stm32gpiointcsetirqcallback() writes data->cb[linenum].cb and data->cb[linenum].data into a NUMEXTILINES-entry array (default 16) in drivers/interruptcontroller/intcgpiostm32.c, guarded only by a compiled-out ASSERTNOMSG(); the same function then reads extiirqtable[linenum] and calls irqenable() on the result. Other controllers index fixed-size per-pin configuration tables the same way — drivers/gpio/gpioiteit8xxx2v2.c reads an MMIO base pointer out of wucbase[8] with the caller's pin and performs a read-modify-write through it.

The issue is reachable only in builds with CONFIGUSERSPACE=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 irqenable() 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 gpiodriverconfig.portpinmask with gpioportpinissupported() in every pin-taking zvrfy handler and returns -EINVAL otherwise, complemented by an unconditional pin >= GPIOMAXPINSPERPORT range check added to the shared zimplgpiopin() inlines.

Affected Software

1 affected component
Zephyr Project Zephyr

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Compensating control

    Validate the pin argument in every pin-taking z_vrfy_ GPIO handler using gpio_port_pin_is_supported() against the controller's gpio_driver_config.port_pin_mask, returning -EINVAL when unsupported; also add an unconditional pin >= GPIO_MAX_PINS_PER_PORT check to the shared z_impl_gpio_pin_*() inlines.

Event History

Oct 28, 2026
CVE Published
via MITRE·04:58 PM
Data Sourced
via MITRE·04:58 PM
DescriptionSeverityWeakness

Frequently Asked Questions

1

Who is exposed to this issue?

Systems that expose the affected GPIO syscalls to user-mode code are exposed, particularly production builds where CONFIG_ASSERT is not enabled. The caller must have permission to invoke the GPIO syscall on a valid GPIO device object.

2

What does an attacker need to exploit it?

An attacker needs local user-mode code execution with access to an affected GPIO device through the syscall object/driver permission checks. They can then supply an unsupported pin value to the affected GPIO configuration, configuration-query, or interrupt-configuration syscall handlers.

3

What is the impact on STM32-based systems?

On STM32, an invalid pin used for interrupt configuration can cause writes beyond the NUM_EXTI_LINES callback array, which defaults to 16 entries. The same path can also read an out-of-range interrupt table entry and pass it to irq_enable().

4

Does enabling assertions mitigate the issue?

CONFIG_ASSERT causes the GPIO pin-support assertion to be present, preventing the unchecked path described for production builds. Assertions are not enabled in the production-build scenario described, so this should not be treated as a substitute for applying the available fixes.

5

How can I identify potentially affected code paths?

Review whether untrusted user-mode code can call gpio_pin_configure, gpio_pin_get_config, or gpio_pin_interrupt_configure on GPIO devices it is authorized to use. GPIO interrupt configuration on STM32 is especially relevant because it uses the supplied pin as an EXTI line and callback-array index.

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