Re: [PATCH] usb: gadget: dummy_hcd: prevent unbind via sysfs

Alan Stern <[email protected]>
Newsgroups org.kernel.vger.linux-usb,dev.linux.lists.syzbot,org.kernel.vger.linux-kernel
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].
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.