From: Marco Scardovi Date: Wed, 10 Jun 2026 15:42:04 +0000 (+0200) Subject: gpiolib: acpi: Prevent out-of-bounds pin access in OperationRegion handler X-Git-Tag: v7.2-rc1~33^2~8 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ae9f812df3149729643d27d2af488c112f62af9a;p=thirdparty%2Flinux.git gpiolib: acpi: Prevent out-of-bounds pin access in OperationRegion handler The ACPI GPIO OperationRegion handler receives pin offsets as a 64-bit address. Previously, this value could be assigned to a pin index without validation, potentially causing out-of-bounds access if the ACPI table provides an invalid offset. This patch explicitly checks that the 64-bit address is less than agpio->pin_table_length before using it, returning AE_BAD_PARAMETER if the check fails. Additionally, it makes the length calculation overflow-safe and ensures proper unsigned types for loop counters. This corrects the commit message from v5 to accurately reflect the underlying issue, removing references to truncation or wrap-around, which do not occur in ACPICA. Assisted-by: Antigravity:gemini-3.5-flash Signed-off-by: Marco Scardovi Acked-by: Mika Westerberg Link: https://patch.msgid.link/20260610154204.110379-3-scardracs@disroot.org Signed-off-by: Bartosz Golaszewski --- diff --git a/drivers/gpio/gpiolib-acpi-core.c b/drivers/gpio/gpiolib-acpi-core.c index b09f89832890e..220f0ac4204ef 100644 --- a/drivers/gpio/gpiolib-acpi-core.c +++ b/drivers/gpio/gpiolib-acpi-core.c @@ -1098,10 +1098,10 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address, struct gpio_chip *chip = achip->chip; struct acpi_resource_gpio *agpio; struct acpi_resource *ares; - u16 pin_index = address; + unsigned int length; acpi_status status; - int length; - int i; + unsigned int i; + u16 pin_index; status = acpi_buffer_to_resource(achip->conn_info.connection, achip->conn_info.length, &ares); @@ -1121,7 +1121,14 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address, return AE_BAD_PARAMETER; } - length = min(agpio->pin_table_length, pin_index + bits); + /* address represents GPIO pin index in connection table */ + if (address >= agpio->pin_table_length) { + ACPI_FREE(ares); + return AE_BAD_PARAMETER; + } + + pin_index = address; + length = min_t(unsigned int, agpio->pin_table_length, pin_index + bits); for (i = pin_index; i < length; ++i) { unsigned int pin = agpio->pin_table[i]; struct acpi_gpio_connection *conn;