Re: [PATCH 4/9] MIPS: TXX9: rbtx4927: Use GPIO lookup table for TXx9 LEDs
From: Geert Uytterhoeven
Date: Mon Jun 29 2026 - 04:39:28 EST
Hi Xiao,
On Sun, 28 Jun 2026 at 21:23, XIAO WU <xiaowu.417@xxxxxx> wrote:
> I came across the Sashiko AI review of this series and reproduced the
> use-after-free that it flagged in rbtx4927_gpioled_init() — a KASAN
> slab-use-after-free triggers when platform_device_add() fails on the
> error path.
>
> The Sashiko review is at:
> https://sashiko.dev/#/patchset/cover.1782389357.git.geert@xxxxxxxxxxxxxx
>
> In rbtx4927_gpioled_init() (arch/mips/txx9/rbtx4927/setup.c), this
> patch introduces a GPIO lookup table that references the platform
> device name. The error path looks like:
>
> ```c
> pdev = platform_device_alloc("leds-gpio", 0);
> if (!pdev)
> return;
> pdev->dev.platform_data = &pdata;
> if (platform_device_add(pdev))
> platform_device_put(pdev); // frees pdev on error!
> rbtx4927_gpioled_table.dev_id = dev_name(&pdev->dev); // UAF!
> ```
>
> If platform_device_add() fails (e.g., because a device with the same
> name already exists in the platform bus), platform_device_put() drops
> the last reference and frees the struct platform_device. The code then
> unconditionally calls dev_name(&pdev->dev) on the freed pointer, and
> assigns the dangling pointer into the global GPIO lookup table.
>
> This is a classic use-after-free: the freed memory can be reallocated
> and overwritten, and the GPIO lookup table will later dereference a
> dangling or corrupted dev_id pointer.
Thanks, I will fix that in v2.
>
> For comparison, the iocled equivalent introduced in patch 6 handles
> this correctly with a goto:
>
> ```c
> if (platform_device_add(pdev))
> goto out_pdev; // skips dev_name()
> txx9_iocled_table.dev_id = dev_name(&pdev->dev);
> ...
> out_pdev:
> platform_device_put(pdev);
> ```
>
> === Reproduction ===
>
> Kernel: 7.1.0-next-20260623-gaca8efd71d03-dirty #3 PREEMPT(full)
> Arch: x86_64 (QEMU Standard PC Q35 + ICH9, 2009)
> Config: CONFIG_KASAN=y
>
> The UAF pattern is reproduced via a kernel module that mirrors the
> same platform_device_add / dev_name error path sequence. The module
> loads at boot via late_initcall.
[...]
> Build: insert into kernel tree and build with CONFIG_POC_UAF=m
> Run: insmod poc_uaf.ko (twice, so the second load hits -EEXIST)
Thanks for verifying! But TBH, I think writing a PoC for this is a
bit over the top...
And if the platform_device_add() in rbtx4927_gpioled_init() would
ever fail, that would be due to out-of-memory, and the system would
be dead anyway.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@xxxxxxxxxxxxxx
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds