]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
gpio: mockup: reject invalid gpio_mockup_ranges widths
authorSamuel Moelius <sam.moelius@trailofbits.com>
Tue, 9 Jun 2026 00:45:38 +0000 (00:45 +0000)
committerBartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Tue, 9 Jun 2026 11:19:56 +0000 (13:19 +0200)
gpio-mockup validates only that each second gpio_mockup_ranges value is
non-negative before creating the mock chips.  The fixed-base form uses
the second value as the first GPIO number after the range, while the
dynamic-base form uses it as the number of GPIOs.

gpio_mockup_register_chip() stores the resulting number of GPIOs in a
u16 and passes it through a PROPERTY_ENTRY_U16("nr-gpios", ...).  Values
greater than U16_MAX therefore truncate silently.  For example,
gpio_mockup_ranges=-1,65537 creates a one-line mock GPIO chip instead of
rejecting the invalid request.

Reject zero-width, reversed, and over-U16 ranges before registering any
mock chip.

Assisted-by: Codex:gpt-5.5-cyber-preview
Signed-off-by: Samuel Moelius <sam.moelius@trailofbits.com>
Link: https://patch.msgid.link/20260609004538.1240091.3fba33a20b88.gpio-mockup-ngpio-u16-truncation@trailofbits.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
drivers/gpio/gpio-mockup.c

index a7d69f3835c1e4015de09116ed6a30232478fa23..91ff789c4fa62fc7c9c76f91011f96c168cea06e 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/irq.h>
 #include <linux/irq_sim.h>
 #include <linux/irqdomain.h>
+#include <linux/limits.h>
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -578,7 +579,7 @@ static int __init gpio_mockup_register_chip(int idx)
 
 static int __init gpio_mockup_init(void)
 {
-       int i, num_chips, err;
+       int i, num_chips, err, base, ngpio;
 
        if ((gpio_mockup_num_ranges % 2) ||
            (gpio_mockup_num_ranges > GPIO_MOCKUP_MAX_RANGES))
@@ -592,8 +593,19 @@ static int __init gpio_mockup_init(void)
         * always be greater than 0.
         */
        for (i = 0; i < num_chips; i++) {
-               if (gpio_mockup_range_ngpio(i) < 0)
+               base = gpio_mockup_range_base(i);
+               ngpio = gpio_mockup_range_ngpio(i);
+
+               if (ngpio <= 0)
                        return -EINVAL;
+
+               if (base < 0) {
+                       if (ngpio > U16_MAX)
+                               return -EINVAL;
+               } else {
+                       if (ngpio <= base || ngpio - base > U16_MAX)
+                               return -EINVAL;
+               }
        }
 
        gpio_mockup_dbg_dir = debugfs_create_dir("gpio-mockup", NULL);