]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
gpiolib: acpi: Add robust bounds-checking for GPIO pin resources
authorMarco Scardovi <scardracs@disroot.org>
Wed, 10 Jun 2026 15:42:03 +0000 (17:42 +0200)
committerBartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Wed, 17 Jun 2026 06:14:30 +0000 (08:14 +0200)
Ensure that GPIO pin resource arrays are safely bounded before accessing
indices. Add explicit bounds checking in acpi_request_own_gpiod(),
acpi_gpio_irq_is_wake(), and acpi_gpiochip_alloc_event() to prevent
out-of-bounds array reads if the ACPI namespace provides malformed or empty
pin tables.

This change addresses potential safety issues arising from
inconsistent or invalid ACPI pin tables. It does not alter functional
behavior in well-formed tables.

Assisted-by: Antigravity:gemini-3.5-flash
Signed-off-by: Marco Scardovi <scardracs@disroot.org>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Link: https://patch.msgid.link/20260610154204.110379-2-scardracs@disroot.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
drivers/gpio/gpiolib-acpi-core.c

index 1a762a2988b7c270939c1e6b129a7762e16db40c..b09f89832890ef92477c4547d3aa49b5ddc7a787 100644 (file)
@@ -316,10 +316,17 @@ static struct gpio_desc *acpi_request_own_gpiod(struct gpio_chip *chip,
                                                unsigned int index,
                                                const char *label)
 {
-       int polarity = GPIO_ACTIVE_HIGH;
-       enum gpiod_flags flags = acpi_gpio_to_gpiod_flags(agpio, polarity);
-       unsigned int pin = agpio->pin_table[index];
+       enum gpiod_flags flags;
        struct gpio_desc *desc;
+       unsigned int pin;
+       int polarity;
+
+       if (index >= agpio->pin_table_length)
+               return ERR_PTR(-EINVAL);
+
+       pin = agpio->pin_table[index];
+       polarity = GPIO_ACTIVE_HIGH;
+       flags = acpi_gpio_to_gpiod_flags(agpio, polarity);
 
        desc = gpiochip_request_own_desc(chip, pin, label, polarity, flags);
        if (IS_ERR(desc))
@@ -333,7 +340,12 @@ static struct gpio_desc *acpi_request_own_gpiod(struct gpio_chip *chip,
 static bool acpi_gpio_irq_is_wake(struct device *parent,
                                  const struct acpi_resource_gpio *agpio)
 {
-       unsigned int pin = agpio->pin_table[0];
+       unsigned int pin;
+
+       if (agpio->pin_table_length == 0)
+               return false;
+
+       pin = agpio->pin_table[0];
 
        if (agpio->wake_capable != ACPI_WAKE_CAPABLE)
                return false;
@@ -363,6 +375,9 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares,
        if (!acpi_gpio_get_irq_resource(ares, &agpio))
                return AE_OK;
 
+       if (agpio->pin_table_length == 0)
+               return AE_OK;
+
        handle = ACPI_HANDLE(chip->parent);
        pin = agpio->pin_table[0];