Re: [PATCH usb-next v2] USB: gadgetfs: Fix use-after-free in gadgetfs_kill_sb
From: Alan Stern
Date: Tue Sep 01 2026 - 11:09:59 EST
On Mon, Aug 31, 2026 at 10:06:23PM -0700, Rafael Alejandro Díaz Cruz wrote:
> After spending a couple hours staring at the code and
> asking claude for things I might have missed, I did come
> up with a better explanation of how the error happens,
> but not why it happens.
>
> I began by removing the get_dev(dev) line I previously
> added and keeping a mental score of all the times
> that refcount is incremented and decremented and found
> that in most cases, they are even. Except in one case
> inside gadgetfs_bind():
>
> static int gadgetfs_bind(struct usb_gadget *gadget, struct
> usb_gadget_driver *driver) {
> struct dev_data *dev = the_device;
> // ........
> + get_dev(dev) // HERE
> if (!dev->req);
> goto enomem;
>
> if (activate_ep_files (dev) < 0)
> goto enomem;
> // ......
> - get_dev (dev); // Move this up
> return 0;
>
> enomem:
> gadgetfs_unbind (gadget);
> return -ENOMEM;
> }
> Somehow the reproducer is triggering one of those two
> if conditions and sending the execution down the error
> path directly to the gadgetfs_unbind(gadget) and skipping
> the get_dev(dev) right before it.
That definitely looks like a bug. The get_dev() call should be moved up
before the set_gadget_data() call.
> Inside gadgetfs_unbind() we call put_dev(dev) which
> would be an uneven decrement. I can confirm this was
> the problem by first making the change above and
> then triggering the reproducer on my local QEMU which
> does not trigger the UAF.
>
> Yet, I don't understand why this is being triggered since
> from what I can see, none of the syscalls coming from
> the reproducer are directly related to this. And these
> .._bind(), ..._unbind() functions are not part of the UAF
> stack trace but rather, something that happens in between
> the reproducer triggered by the usb protocol.
>
> Not sure if this is good enough. I don't know what else to
> look into.
You can make debugging easier by adding dev_info() or pr_info() calls at
various strategic places in the code. Then the kernel log should tell
you exactly what is happening.
However, no matter how you decide to attack the problem, you shouldn't
submit a patch until you truly understand what is going wrong and how
the patch will fix it. This means thinking for yourself, not relying on
an AI to do all the thinking for you.
Alan Stern