Re: [PATCH] usb: gadget: udc: Fix NULL pointer dereference in gadget_match_driver
From: Alan Stern
Date: Tue Jun 02 2026 - 10:44:58 EST
On Tue, Jun 02, 2026 at 01:34:07PM +0800, Jimmy Hu (xWF) wrote:
> On Wed, May 27, 2026 at 2:00 AM Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote:
> >
> > On Tue, May 26, 2026 at 03:06:35PM +0800, Jimmy Hu wrote:
> > > A NULL pointer dereference occurs in gadget_match_driver() because a
> > > race condition exists between the DRD mode-switch work and the
> > > configfs UDC write path:
> > >
> > > 1. The DRD mode-switch work invokes __dwc3_set_mode(), which calls
> > > dwc3_gadget_exit() and subsequently frees the UDC device name via
> > > device_unregister(&udc->dev).
> > > 2. The configfs UDC write path invokes gadget_dev_desc_UDC_store(),
> > > which calls usb_gadget_register_driver() and subsequently
> > > compares the UDC device name via gadget_match_driver().
> > >
> > > If gadget_match_driver() runs concurrently during UDC unregistration, it
> > > may access the freed UDC device name. Once the freed memory is zeroed,
> > > dev_name(&udc->dev) returns NULL, causing a panic in strcmp().
> >
> > I don't see how this can happen. gadget_match_driver() runs during
> > probing of a gadget, which takes place only while the gadget is
> > registered in the device core. But usb_del_gadget() calls
> > device_del(&gadget->dev) before it calls device_unregister(&udc->dev).
> > This means that at any time when gadget_match_driver() can run, the UDC
> > device name must still be allocated.
> >
> > You should run more tests. Add debugging printk() calls just before and
> > just after the device_del(&gadget->dev) and device_unregister(&udc->dev)
> > lines, and inside gadget_match_driver(), so the tests will show
> > unambiguously when these things happen with respect to each other.
> >
> > > Fix this by checking dev_name(&udc->dev) before calling strcmp().
> >
> > Adding a check like this will not fix a race; it will only make the race
> > less likely to occur. It won't prevent the name from being deallocated
> > between the check and the strcmp() call.
> >
> > Alan Stern
>
> Hi Alan,
>
> Thank you for the review. You are absolutely right about the TOCTOU risk;
> the simple NULL check does not prevent the name from being deallocated
> after the check but before the strcmp() call.
>
> I will submit a v2 patch that uses get_device(&udc->dev) and put_device()
> to increment the UDC reference count during the matching phase. This will
> guarantee that the UDC device name remains allocated and valid throughout
> the entire duration of strcmp(), eliminating the race condition structurally.
>
> Does this approach sound reasonable to you?
No, because you haven't addressed the issue I raised at the start of my
email, namely, how can this problem actually occur? And you didn't run
additional tests with the extra debugging information that I asked for.
Alan Stern