virtio_gpio_get_names() walks the line names that the device returns in
a block of gpio_names_size bytes, which the driver ends with a NUL, and
checks each name only after stepping past it. If the block holds fewer
than ngpio names, the walk reaches the end of the block after the last
name, and the next iteration starts strlen() at the byte after the
allocation. With a block that holds one name for four lines, KASAN
reports:
BUG: KASAN: slab-out-of-bounds in strlen+0x57/0x70
Read of size 1 at addr ffff8880026687c0 by task swapper/0/1
Call Trace:
strlen+0x57/0x70
virtio_gpio_probe+0xcb4/0xfc0
virtio_dev_probe+0xa7a/0xc50
Allocated by task 1:
devm_kmalloc+0x6e/0x280
virtio_gpio_probe+0xc06/0xfc0
The buggy address is located 0 bytes to the right of
allocated 64-byte region [ffff888002668780, ffff8880026687c0)
Check that a name starts inside the block before reading it.
This patch is assisted by Claude Opus 5.5.
Fixes: 3a29355a22c0 ("gpio: Add virtio-gpio driver")
Cc: [email protected]
Signed-off-by: Lianjie Wang <[email protected]>
---
drivers/gpio/gpio-virtio.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpio/gpio-virtio.c b/drivers/gpio/gpio-virtio.c
index ed6e0e90fa8aa..32326d91f33d6 100644
--- a/drivers/gpio/gpio-virtio.c
+++ b/drivers/gpio/gpio-virtio.c
@@ -520,13 +520,13 @@ static const char **virtio_gpio_get_names(struct
virtio_gpio *vgpio,
gpio_names[gpio_names_size - 1] = '\0';
for (i = 0, str = gpio_names; i < ngpio; i++) {
- names[i] = str;
- str += strlen(str) + 1; /* zero-length strings are allowed */
-
- if (str > gpio_names + gpio_names_size) {
+ if (str >= gpio_names + gpio_names_size) {
dev_err(dev, "gpio_names block is too short (%d)\n", i);
return NULL;
}
+
+ names[i] = str;
+ str += strlen(str) + 1; /* zero-length strings are allowed */
}
return names;
base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
--
2.56.0