CVE-2026-82961 in Zephyrinfo

Summary

by MITRE • 10/28/2026

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.

Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.

Analysis

by VulDB Data Team • 10/28/2026

The vulnerability identified involves a critical lack of input validation within the General Purpose Input/Output syscall handlers located in drivers/gpio/gpio_handlers.c for Zephyr-based systems. Specifically, functions such as z_vrfy_gpio_pin_configure(), z_vrfy_gpio_pin_get_config(), and z_vrfy_gpio_interrupt_configure() were designed to verify only that the caller possessed a valid reference to a GPIO device object via K_SYSCALL_DRIVER_GPIO or K_SYSCALL_OBJ macros. However, these handlers failed to validate the gpio_pin_t argument provided by user-mode callers before passing it directly to the underlying implementation functions like z_impl_gpio_pin_*. The existing validation mechanism relied on an __ASSERT macro within include/zephyr/drivers/gpio.h which checks if the pin is supported using gpio_port_pin_is_supported. This assertion compiles out in production builds where CONFIG_ASSERT is disabled, effectively leaving no runtime boundary check for invalid pin numbers supplied by untrusted user-space applications.

This architectural flaw allows a malicious or compromised user-mode thread with access to a GPIO device object to supply arbitrary integer values as pin identifiers. These values are subsequently used directly by various GPIO drivers without bounds checking. For instance, on STM32 microcontrollers, the gpio_stm32_pin_interrupt_configure function utilizes the pin value as an index into fixed-size arrays such as data->cb[line_num] and exti_irq_table[]. The array size is typically small, defaulting to sixteen entries representing NUM_EXTI_LINES. When a user supplies a pin number exceeding this limit, it results in out-of-bounds writes to kernel memory structures containing function pointers and associated void pointer data. Similarly, other controllers like the ITE IT8xxx2 v2 use the pin value as an index into wuc_base arrays for MMIO base pointer retrieval, leading to read-modify-write operations on unintended hardware registers or memory locations.

The operational impact of this vulnerability is severe, constituting a privilege escalation from user mode to supervisor mode. By exploiting the missing validation, an attacker can trigger out-of-bounds writes that corrupt kernel .bss arrays containing callback function pointers and data structures. This corruption enables arbitrary code execution by redirecting interrupt handlers or other critical system functions to malicious payloads placed in user-controlled memory regions. Additionally, improper pin values passed to irq_enable() via the exti_irq_table array can cause undefined behavior, potentially leading to system crashes or denial of service conditions. The vulnerability is specifically reachable only in configurations where CONFIG_USERSPACE is enabled, as this symbol gates the compilation of the affected syscall handlers and establishes the user-mode sandbox context that the exploit bypasses.

From a security classification perspective, this flaw aligns with CWE-20 Improper Input Validation and CWE-125 Out-of-bounds Read, as well as CWE-787 Out-of-bounds Write depending on the specific driver implementation triggered. In terms of MITRE ATT&CK mapping for embedded systems, this represents a technique akin to T1068 Exploitation for Privilege Escalation, where an attacker leverages software vulnerabilities to gain higher-level access than originally permitted. The attack vector involves user-space interaction with kernel interfaces, highlighting the risks associated with insufficient boundary checks in operating system kernels that manage hardware resources.

The remediation strategy implemented addresses these deficiencies by introducing rigorous validation at both the syscall verification layer and the implementation layer. In every pin-taking z_vrfy_ handler, the code now explicitly validates the pin against the controller's gpio_driver_config.port_pin_mask using the gpio_port_pin_is_supported function. If the pin is not supported by the specific hardware instance, the system returns an -EINVAL error code, preventing further processing of invalid inputs. Furthermore, a complementary unconditional range check ensuring that the pin value is less than GPIO_MAX_PINS_PER_PORT has been added to the shared z_impl_gpio_pin_* inline functions. This defense-in-depth approach ensures that even if validation fails at one layer, the implementation layer provides an additional safeguard against out-of-bounds access, thereby closing the privilege escalation vector and protecting kernel memory integrity from user-mode exploitation attempts.

Responsible

Zephyr

Reservation

08/31/2026

Disclosure

10/28/2026

Moderation

accepted

EPSS

0.00000

KEV

no

Activities

low

Sources

Want to stay up to date on a daily basis?

Enable the mail alert feature now!