[PATCH] mmc: vub300: complete the pending request when the device is gone
From: Yogesh Gaur
Date: Tue Oct 06 2026 - 08:52:42 EST
vub300_mmc_request() hands the request to vub300_cmndwork_thread() and
returns; the work is what eventually calls mmc_request_done(). But if
vub300_disconnect() has cleared vub300->interface by the time the work
runs, the work just drops its reference and returns, and the request
is never completed.
The MMC core waits for it with no timeout, and vub300_disconnect() then
waits for the core: mmc_remove_host() cancels mmc_rescan(), which is
the one stuck on the request. syzbot hits this as two hung tasks:
INFO: task kworker/1:2:984 blocked for more than 143 seconds.
Workqueue: events_freezable mmc_rescan
mmc_wait_for_req_done+0xcd/0x3d0 drivers/mmc/core/core.c:408
mmc_wait_for_cmd+0x154/0x200 drivers/mmc/core/core.c:645
mmc_app_cmd+0x170/0x340 drivers/mmc/core/sd_ops.c:64
...
mmc_attach_sd+0xb8/0x3d0 drivers/mmc/core/sd.c:1854
mmc_rescan+0xcd5/0x11c0 drivers/mmc/core/core.c:2316
INFO: task kworker/0:5:5709 blocked for more than 143 seconds.
Workqueue: usb_hub_wq hub_event
cancel_delayed_work_sync+0xd1/0xf0 kernel/workqueue.c:4642
mmc_stop_host+0xe9/0x400 drivers/mmc/core/core.c:2373
mmc_remove_host+0x15/0x60 drivers/mmc/core/host.c:681
vub300_disconnect+0x12d/0x170 drivers/mmc/host/vub300.c:2387
Fail the request with -ESHUTDOWN in that case, as vub300_mmc_request()
already does when it sees the interface gone before queueing the work.
Fixes: 88095e7b473a ("mmc: Add new VUB300 USB-to-SD/SDIO/MMC driver")
Reported-by: syzbot+c6d8091b47243f2023b8@xxxxxxxxxxxxxxxxxxxxxxxxx
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: LLM
Signed-off-by: Yogesh Gaur <yogeshgaur.83@xxxxxxxxx>
---
Built with W=1 only; not runtime-tested.
drivers/mmc/host/vub300.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c
index 2dae474dcd06..01fa7f9e9659 100644
--- a/drivers/mmc/host/vub300.c
+++ b/drivers/mmc/host/vub300.c
@@ -1739,6 +1739,16 @@ static void vub300_cmndwork_thread(struct work_struct *work)
struct vub300_mmc_host *vub300 =
container_of(work, struct vub300_mmc_host, cmndwork);
if (!vub300->interface) {
+ struct mmc_request *req = vub300->req;
+
+ /* the core waits for this request, so finish it */
+ if (req) {
+ vub300->req = NULL;
+ vub300->cmd = NULL;
+ vub300->data = NULL;
+ req->cmd->error = -ESHUTDOWN;
+ mmc_request_done(vub300->mmc, req);
+ }
kref_put(&vub300->kref, vub300_delete);
return;
} else {
--
2.55.0.windows.5