Freeing bulk streams concurretnly with URB execution

From: Michal Pecio

Date: Fri Jun 12 2026 - 07:28:18 EST


On Thu, 11 Jun 2026 20:53:40 +0300, Mathias Nyman wrote:
> On 6/11/26 11:33, 胡连勤 wrote:
> > If we free stream_info first (outside the lock), then acquire the
> > lock to clear the pointer, there is a window where the interrupt
> > handler can still see the old (dangling) pointer and dereference
> > freed memory. So we need to clear the reference under the lock
> > first, then free the memory outside.
>
> Good point, but the need for this reveals another bug.
>
> This means xhci_free_streams() can queue a configure endpoint command
> to remove streams, and xhci_irq() can ring the doorbell of a stream
> at the same time xHC controller is processing the command to remove
> the stream

Yes, nothing seems to prevent that if there are URBs on the endpoint.
Without URBs the doorbell won't be rung, though UAF would still occur
with my proposal in absence of improved guards against it.

8df75f42f8e6 added the GETTING_(NO)_STREAMS flags to block new URBs
on transitioning endpoints and prevented enabling streams if URBs are
already pending, but not disabling streams.

So question is, can usbcore / uas actually try to disable streams with
pending URBs, or submit new URBs concurrently?

If so then we probably need to fail the attempt or flush the URBs, and
I suspect that storage (Cc) may not like the former option.

Otherwise, the URBs not only get in the way of cleaning things up, but
it's not even clear how they would complete. The HW won't execute them
anymore, probably someone will have to unlink, relying on the hack for
removing URBs from nonexistent rings and logging a dev_err().

On the upside, the above suggests that it's not a common occurrence if
nobody complained in 15 years...

> So I think this is a good targeted patch for this specific issue.
> We should start fixing the other issues and hopefully end up where
> Michal suggested.

Indeed, I see no way to simplify this patch without much work.

Regards,
Michal