Re: [PATCH] usb: gadget: dummy_hcd: prevent unbind via sysfs
Alan Stern <[email protected]> Wed, 29 Jul 2026 09:54:50 -0400
| Newsgroups | dev.linux.lists.syzbot,org.kernel.vger.linux-kernel,org.kernel.vger.linux-usb |
|---|---|
| Message-ID | <[email protected]> |
On Wed, Jul 29, 2026 at 12:25:27PM +0000, syzbot wrote: > From: Aleksandr Nogikh <[email protected]> > > The dummy_hcd (Host Controller) and dummy_udc (Device Controller) are > implemented as two separate platform drivers that share the same underlying > state (struct dummy). They are designed to be created and destroyed > together during the module's init and exit phases. > > If userspace forces the dummy_hcd driver to unbind from the device via > sysfs, dummy_hcd_remove() cleans up the host controllers and sets the > pointers to NULL (dum->hs_hcd = NULL). However, the dummy_udc driver is > still bound to its device, meaning the USB gadget is still registered with > the udc-core subsystem. > > If a new gadget driver is subsequently registered, it binds to the > still-registered dummy_udc gadget, invoking the dummy_udc_start() callback. > This callback attempts to retrieve the HCD state using > gadget_to_dummy_hcd(), which returns NULL because of the unbind. This > results in a null-pointer dereference: > > Oops: general protection fault, probably for non-canonical address > 0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI > KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] > ... > RIP: 0010:dummy_udc_start+0xd0/0x1f0 > drivers/usb/gadget/udc/dummy_hcd.c:1022 > ... > Call Trace: > <TASK> > usb_gadget_udc_start_locked drivers/usb/gadget/udc/core.c:1237 [inline] > gadget_bind_driver+0x3a8/0x9e0 drivers/usb/gadget/udc/core.c:1667 > call_driver_probe drivers/base/dd.c:-1 [inline] > really_probe+0x254/0xae0 drivers/base/dd.c:706 > __driver_probe_device+0x1e8/0x360 drivers/base/dd.c:868 > driver_probe_device+0x4f/0x240 drivers/base/dd.c:898 > __driver_attach+0x339/0x600 drivers/base/dd.c:1292 > bus_for_each_dev+0x23b/0x2c0 drivers/base/bus.c:383 > bus_add_driver+0x345/0x670 drivers/base/bus.c:763 > driver_register+0x23a/0x320 drivers/base/driver.c:174 > usb_gadget_register_driver_owner+0xf9/0x270 > drivers/usb/gadget/udc/core.c:1752 > raw_ioctl_run drivers/usb/gadget/legacy/raw_gadget.c:596 [inline] > raw_ioctl+0x1541/0x41c0 drivers/usb/gadget/legacy/raw_gadget.c:1307 > > Adding NULL checks to the UDC callbacks is not a robust solution because > there is no synchronization between dummy_hcd_remove() and the UDC > callbacks, which would result in a use-after-free race condition if the HCD > were unbound concurrently. > > Fix this by setting .suppress_bind_attrs = true in both driver definitions. > This prevents userspace from unbinding these drivers dynamically, ensuring > their lifecycles remain strictly synchronized with the module's load/unload > process. > > Fixes: d9b762510c18 ("[PATCH] USB dummy_hcd: Use separate pdevs for HC and UDC") > Assisted-by: Gemini:gemini-3.5-flash Gemini:gemini-3.1-pro-preview syzbot > Reported-by: [email protected] > Closes: https://syzkaller.appspot.com/bug?extid=d270af829aca04e783fc > Link: https://syzkaller.appspot.com/ai_job?id=7a763ada-c07c-458f-9fea-f7e913dc1f2f > Signed-off-by: Aleksandr Nogikh <[email protected]> > > --- In theory the driver could be rewritten to allow independent unbinding and rebinding of the HCD and UDC. But that would be a much more intrusive change, whereas as this is a small and reasonable fix for a real problem. Acked-by: Alan Stern <[email protected]> Alan Stern > diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c > index c0e40fa6d..415096835 100644 > --- a/drivers/usb/gadget/udc/dummy_hcd.c > +++ b/drivers/usb/gadget/udc/dummy_hcd.c > @@ -1180,6 +1180,7 @@ static struct platform_driver dummy_udc_driver = { > .resume = dummy_udc_resume, > .driver = { > .name = gadget_name, > + .suppress_bind_attrs = true, > }, > }; > > @@ -2802,6 +2803,7 @@ static struct platform_driver dummy_hcd_driver = { > .resume = dummy_hcd_resume, > .driver = { > .name = driver_name, > + .suppress_bind_attrs = true, > }, > }; > > > > base-commit: f5098b6bae761e346ebcd9da7f95622c04733cff > -- > See https://goo.gle/syzbot-ai-patches for information about AI-generated patches. > You can comment on the patch as usual, syzbot will try to address > the comments and send a new version of the patch if necessary. > syzbot engineers can be reached at [email protected].