On Sun Jan 11 00:17:53 2026 +0900, Jeongjun Park wrote:
> In as102_usb driver, the following race condition occurs:
> ```
> CPU0 CPU1
> as102_usb_probe()
> kzalloc(); // alloc as102_dev_t
> ....
> usb_register_dev();
> fd =
> sys_open("/path/to/dev"); // open as102 fd
> ....
> usb_deregister_dev();
> ....
> kfree(); // free as102_dev_t
> ....
> sys_close(fd);
> as102_release() // UAF!!
> as102_usb_release()
> kfree(); // DFB!!
> ```
>
> When a USB character device registered with usb_register_dev() is later
> unregistered (via usb_deregister_dev() or disconnect), the device node is
> removed so new open() calls fail. However, file descriptors that are
> already open do not go away immediately: they remain valid until the last
> reference is dropped and the driver's .release() is invoked.
>
> In as102, as102_usb_probe() calls usb_register_dev() and then, on an
> error path, does usb_deregister_dev() and frees as102_dev_t right away.
> If userspace raced a successful open() before the deregistration, that
> open FD will later hit as102_release() --> as102_usb_release() and access
> or free as102_dev_t again, occur a race to use-after-free and
> double-free vuln.
>
> The fix is to never kfree(as102_dev_t) directly once usb_register_dev()
> has succeeded. After deregistration, defer freeing memory to .release().
>
> In other words, let release() perform the last kfree when the final open
> FD is closed.
>
> Cc: <[email protected]>
> Reported-by: [email protected]
> Closes: https://syzkaller.appspot.com/bug?extid=47321e8fd5a4c84088db
> Fixes: cd19f7d3e39b ("[media] as102: fix leaks at failure paths in
> as102_usb_probe()")
> Signed-off-by: Jeongjun Park <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>
Patch committed.
Thanks,
Hans Verkuil
drivers/media/usb/as102/as102_usb_drv.c | 2 ++
1 file changed, 2 insertions(+)
---
diff --git a/drivers/media/usb/as102/as102_usb_drv.c
b/drivers/media/usb/as102/as102_usb_drv.c
index 8e480ab78f9b..a11024451ceb 100644
--- a/drivers/media/usb/as102/as102_usb_drv.c
+++ b/drivers/media/usb/as102/as102_usb_drv.c
@@ -403,7 +403,9 @@ static int as102_usb_probe(struct usb_interface *intf,
failed_dvb:
as102_free_usb_stream_buffer(as102_dev);
failed_stream:
+ usb_set_intfdata(intf, NULL);
usb_deregister_dev(intf, &as102_usb_class_driver);
+ return ret;
failed:
usb_put_dev(as102_dev->bus_adap.usb_dev);
usb_set_intfdata(intf, NULL);
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]