Re: [PATCH] mmc: vub300: fix Use-After-Free of inactivity_timer on disconnect and probe failure
Muhammad Bilal <[email protected]>
| Newsgroups | org.kernel.vger.linux-mmc,org.kernel.vger.linux-kernel,org.kernel.vger.stable |
|---|---|
| Message-ID | <CADqcGB=ZbfAkM_90ty7=_QD3eqJd8f7urXKvTnagdv09U9RRAA@mail.gmail.com> |
Hi Johan, You're right, thank you for catching this. I traced through vub300_probe() and vub300_inactivity_timer_expired() again: the kref_get() taken right before add_timer() is exactly the extra reference the timer holds, and the timer callback releases it itself and stops rearming once vub300->interface is NULL. So the UAF I described can't happen with the code as it stands. I should also be upfront that this was flagged by Sashiko, and I did not verify the reference counting closely enough myself before sending it. That's on me. Dropping this patch. Sorry for the noise. Muhammad Bilal On Wed, Aug 19, 2026 at 7:19 PM Johan Hovold <[email protected]> wrote: > > On Wed, Aug 19, 2026 at 02:03:22AM +0500, Muhammad Bilal wrote: > > The vub300 driver arms inactivity_timer during probe and acquires a kref > > reference for the running timer. However, vub300_disconnect() sets > > vub300->interface = NULL and drops the driver's kref without shutting down > > the timer via timer_shutdown_sync(). > > > > If the timer expires after the host is removed and vub300 is freed, > > or if concurrent work items re-arm the timer, > > vub300_inactivity_timer_expired() accesses the already freed vub300 > > structure, causing a Use-After-Free. > > No, this cannot happen as the timer holds another reference. > > > Fix this by explicitly shutting down inactivity_timer via > > timer_shutdown_sync() and releasing the timer's kref reference in > > vub300_disconnect() and probe error cleanup paths. > > > > Fixes: 88095e7b473a ("mmc: Add new VUB300 USB-to-SD/SDIO/MMC driver") > > Signed-off-by: Muhammad Bilal <[email protected]> > > How was this "issue" found? Are you using an LLM? > > > --- > > drivers/mmc/host/vub300.c | 4 ++++ > > 1 file changed, 4 insertions(+) > > > > diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c > > index 8e45dc1a4a12..9f84bd1531e2 100644 > > --- a/drivers/mmc/host/vub300.c > > +++ b/drivers/mmc/host/vub300.c > > @@ -2350,6 +2350,8 @@ static int vub300_probe(struct usb_interface *interface, > > > > err_stop_io: > > vub300->interface = NULL; > > + timer_shutdown_sync(&vub300->inactivity_timer); > > + kref_put(&vub300->kref, vub300_delete); > > kref_put(&vub300->kref, vub300_delete); > > And this results in a reference underflow. > > Johan