Re: [PATCH v8 0/4] usb: gadget: gadgetfs: fix ep0 request lifetime and event counter

From: Alan Stern

Date: Tue Nov 10 2026 - 17:50:09 EST


On Tue, Nov 10, 2026 at 12:13:21PM +0800, Jing Lin via B4 Relay wrote:
> This series fixes the ep0 request lifetime and shared request buffer
> races in gadgetfs, and the pre-existing event counter underflow.
>
> The first patch covers request lifetime and buffer ownership, the second
> the ep0 setup abort and unbind state races, the third the event counter
> underflow, and the fourth removes the const cast in gadgetfs_setup().
>
> The setup() callback runs in interrupt context and may not sleep, so a
> mutex cannot be used to serialize it against ep0_read() and ep0_write().
> The shared request state remains protected by dev->lock and the control
> payloads are handed off through private buffers.
>
> The series was tested with the syzbot reproducer and with targeted
> lifecycle, request-reuse, abort, unbind, stale-setup, and event-counter
> tests on arm64 QEMU with dummy_hcd, KASAN, and lockdep. The syzbot
> reproducer still exits 137 on the fixed kernel without a BUG, WARNING,
> KASAN report, or lockdep splat.
>
> Signed-off-by: Jing Lin <kayano050408@xxxxxxxxx>
> ---

I'm going to need some time to refresh my memory on how all this stuff
works in the current driver before I can review these patches properly.
And since I'm going to be very busy during the next few days with other
matters, it will be a while before I can reply.

But first, one thought about coordinating setup packets and their
replies. It seems that there's an unavoidable race between a gadget
driver queuing a request in response to an old setup packet and the UDC
driver invoking the gadget driver's ->setup() callback for a newly
arrived setup packet:

UDC driver Gadget driver
---------- -------------
Setup packet arrives
Call ->setup()
->setup() returns DELAYED_STATUS
Prepare proper reply to IN request
or carry out actions needed for
OUT request
New setup packet arrives
Call ->setup Call usb_ep_queue() with reply to
or status for first setup

At this point there's no way for the UDC driver to know whether the
request it was just asked to queue is a response to the old setup packet
or the new one. This is a real flaw in the gadget API.

I've often thought that UDC drivers should assign a sequential ID number
to each setup packet and pass this number to the ->setup() callback, and
gadget drivers should include the number in their response so that the
UDC driver can tell whether the response is obsolete. Too late to
change the API now, unfortunately.

Alan Stern