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

Aleksandr Nogikh <[email protected]> Wed, 29 Jul 2026 14:21:39 +0200
Newsgroups dev.linux.lists.syzbot
Message-ID <CANp29Y7+G=-sVb1d1iU72KTvZ5K=ad6fG8ZtCucEgv1jpo14Kw@mail.gmail.com>
#syz upstream


On Wed, Jul 29, 2026 at 1:47=E2=80=AFPM 'syzbot' via
syzkaller-upstream-moderation
<[email protected]> wrote:
>
> The dummy_hcd (Host Controller) and dummy_udc (Device Controller) are
> implemented as two separate platform drivers that share the same underlyi=
ng
> 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 =3D NULL). However, the dummy_udc driver is
> still bound to its device, meaning the USB gadget is still registered wit=
h
> 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() callbac=
k.
> 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 H=
CD
> were unbound concurrently.
>
> Fix this by setting .suppress_bind_attrs =3D true in both driver definiti=
ons.
> This prevents userspace from unbinding these drivers dynamically, ensurin=
g
> their lifecycles remain strictly synchronized with the module's load/unlo=
ad
> process.
>
> Fixes: d9b762510c18 ("[PATCH] USB dummy_hcd: Use separate pdevs for HC an=
d 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=3Dd270af829aca04e783fc
> Link: https://syzkaller.appspot.com/ai_job?id=3D7a763ada-c07c-458f-9fea-f=
7e913dc1f2f
> To: "Greg Kroah-Hartman" <[email protected]>
> To: <[email protected]>
> To: "Alan Stern" <[email protected]>
> Cc: <[email protected]>
> Cc: "Jinchao Wang" <[email protected]>
>
> ---
> 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 =3D =
{
>         .resume         =3D dummy_udc_resume,
>         .driver         =3D {
>                 .name   =3D gadget_name,
> +               .suppress_bind_attrs =3D true,
>         },
>  };
>
> @@ -2802,6 +2803,7 @@ static struct platform_driver dummy_hcd_driver =3D =
{
>         .resume         =3D dummy_hcd_resume,
>         .driver         =3D {
>                 .name   =3D driver_name,
> +               .suppress_bind_attrs =3D true,
>         },
>  };
>
>
>
> base-commit: f5098b6bae761e346ebcd9da7f95622c04733cff
> --
> This is an AI-generated patch subject to moderation.
> Reply with '#syz upstream' to Sign-off the patch as a human author
> and send it to the upstream kernel mailing lists.
> Reply with '#syz reject' to reject it ('#syz unreject' to undo).
>
> 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].
>
> --
> You received this message because you are subscribed to the Google Groups=
 "syzkaller-upstream-moderation" group.
> To unsubscribe from this group and stop receiving emails from it, send an=
 email to [email protected].
> To view this discussion visit https://groups.google.com/d/msgid/syzkaller=
-upstream-moderation/ba57a566-316f-4ab3-9a6d-6d0f02a2480a%40mail.kernel.org=
.