* [PATCH v3] usb: raw_gadget: fix use-after-free when UDC is removed
@ 2026-08-04 15:02 Anuj Bolewar via B4 Relay
2026-08-04 15:32 ` Greg Kroah-Hartman
0 siblings, 1 reply; 2+ messages in thread
From: Anuj Bolewar via B4 Relay @ 2026-08-04 15:02 UTC (permalink / raw)
To: Andrey Konovalov, Greg Kroah-Hartman
Cc: linux-usb, linux-kernel, syzbot+9aacea11bc70c3ddaff2,
Anuj Bolewar
From: Anuj Bolewar <bolewara@gmail.com>
When the UDC is removed (e.g. dummy_hcd unbind via sysfs) while the raw
gadget fd is still open, usb_del_gadget() destroys the gadget device
and its name. raw_gadget keeps a dangling pointer in dev->gadget, and
ioctls dereference it after releasing dev->lock, leading to a
use-after-free in dev_err() when usb_ep_queue() fails.
Take a gadget reference in gadget_bind() and drop it in dev_free() so
the gadget device and its name stay alive for as long as the fd is open
and an ioctl may still dereference dev->gadget. gadget_unbind() only
marks the device as failed under dev->lock; the reference is dropped in
dev_free(), which runs only after the fd is closed and no ioctl can be
in flight.
Reported-by: syzbot+9aacea11bc70c3ddaff2@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=9aacea11bc70c3ddaff2
Fixes: f2c2e717642c ("usb: gadget: add raw-gadget interface")
Assisted-by: deepseek:v4-pro
Signed-off-by: Anuj Bolewar <bolewara@gmail.com>
---
The gadget device embedded in the UDC is destroyed when the UDC is
removed while the raw gadget fd is still open (e.g. unbinding dummy_hcd
via sysfs). raw_gadget keeps a dangling pointer in dev->gadget and
ioctls dereference it after dropping dev->lock, which KASAN reports as a
slab use-after-free in raw_process_ep0_io() (dev_err with a freed device
name).
Fix it by holding a gadget reference for the raw device lifetime:
gadget_bind() takes it, gadget_unbind() only marks the device as failed
under dev->lock, and the reference is dropped in dev_free() once the fd
is closed and no ioctl can still be in flight.
---
Changes in v3:
- Use scoped_guard() for the spinlock in gadget_unbind() per review.
- Add Assisted-by trailer per Documentation/process/coding-assistants.rst.
- Link to v2: https://patch.msgid.link/20260804-raw-gadget-ep0-uaf-v2-1-3a5ded46ab50@gmail.com
Changes in v2:
- Reworked per review: the gadget reference is now held for the raw
device lifetime (bind until dev_free()) instead of the bind/unbind
window, since ioctls dereference dev->gadget after releasing dev->lock
and the UDC core owns the gadget's lifetime during bind/unbind.
- gadget_unbind() now only marks the device as failed under dev->lock;
the reference is dropped in dev_free() after the fd is closed.
- Dropped the now-unneeded comment and switched the spinlock to guard().
- Link to v1: https://patch.msgid.link/20260804-raw-gadget-ep0-uaf-v1-1-07878773da15@gmail.com
---
drivers/usb/gadget/legacy/raw_gadget.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/gadget/legacy/raw_gadget.c b/drivers/usb/gadget/legacy/raw_gadget.c
index 4febf8dac7c..fb15ab6fc73 100644
--- a/drivers/usb/gadget/legacy/raw_gadget.c
+++ b/drivers/usb/gadget/legacy/raw_gadget.c
@@ -226,6 +226,7 @@ static void dev_free(struct kref *kref)
kfree(dev->eps[i].ep->desc);
dev->eps[i].state = STATE_EP_DISABLED;
}
+ usb_put_gadget(dev->gadget);
kfree(dev);
}
@@ -302,7 +303,7 @@ static int gadget_bind(struct usb_gadget *gadget,
dev->req = req;
dev->req->context = dev;
dev->req->complete = gadget_ep0_complete;
- dev->gadget = gadget;
+ dev->gadget = usb_get_gadget(gadget);
gadget_for_each_ep(ep, dev->gadget) {
dev->eps[i].ep = ep;
dev->eps[i].addr = get_ep_addr(ep->name);
@@ -329,6 +330,8 @@ static void gadget_unbind(struct usb_gadget *gadget)
{
struct raw_dev *dev = get_gadget_data(gadget);
+ scoped_guard(spinlock_irqsave, &dev->lock)
+ dev->state = STATE_DEV_FAILED;
set_gadget_data(gadget, NULL);
/* Matches kref_get() in gadget_bind(). */
kref_put(&dev->count, dev_free);
---
base-commit: 075b74841bd0065a3bda3440873c747938e69b68
change-id: 20260804-raw-gadget-ep0-uaf-10a82bdda5bc
Best regards,
--
Anuj Bolewar <bolewara@gmail.com>
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH v3] usb: raw_gadget: fix use-after-free when UDC is removed
2026-08-04 15:02 [PATCH v3] usb: raw_gadget: fix use-after-free when UDC is removed Anuj Bolewar via B4 Relay
@ 2026-08-04 15:32 ` Greg Kroah-Hartman
0 siblings, 0 replies; 2+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-04 15:32 UTC (permalink / raw)
To: bolewara
Cc: Andrey Konovalov, linux-usb, linux-kernel,
syzbot+9aacea11bc70c3ddaff2
On Tue, Aug 04, 2026 at 08:32:50PM +0530, Anuj Bolewar via B4 Relay wrote:
> From: Anuj Bolewar <bolewara@gmail.com>
>
> When the UDC is removed (e.g. dummy_hcd unbind via sysfs) while the raw
> gadget fd is still open, usb_del_gadget() destroys the gadget device
> and its name. raw_gadget keeps a dangling pointer in dev->gadget, and
> ioctls dereference it after releasing dev->lock, leading to a
> use-after-free in dev_err() when usb_ep_queue() fails.
>
> Take a gadget reference in gadget_bind() and drop it in dev_free() so
> the gadget device and its name stay alive for as long as the fd is open
> and an ioctl may still dereference dev->gadget.
But bind/unbind have nothing to do with open/close. bind/unbind track
the lifetime of a driver being bound to a device. After unbind happens,
the driver CAN NOT touch the device at all. That's not what you are
fixing here, you are attempting to keep a reference alive that you are
NOT allowed to keep alive, as it is gone.
> gadget_unbind() only
> marks the device as failed under dev->lock; the reference is dropped in
> dev_free(), which runs only after the fd is closed and no ioctl can be
> in flight.
Again, bind/unbind have nothing to do with open/close/ioctl. This is
the "traditional" issue with char devices having their "backing device"
go away. There are many different ways to solve this, none of which is
this patch at all.
So please, go back and rethink the lifetime rules here and do NOT rely
on a LLM to attempt to work it out as obviously it is totally getting it
incorrect.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-08-04 15:32 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-04 15:02 [PATCH v3] usb: raw_gadget: fix use-after-free when UDC is removed Anuj Bolewar via B4 Relay
2026-08-04 15:32 ` Greg Kroah-Hartman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox