From: "syzbot" <syzbot@kernel.org>
To: syzkaller-upstream-moderation@googlegroups.com
Cc: syzbot@lists.linux.dev
Subject: [PATCH RFC] mmc: vub300: fix sleeping in softirq during host cleanup
Date: Fri, 7 Aug 2026 05:35:37 +0000 (UTC) [thread overview]
Message-ID: <49982079-95f4-4e8c-bbbc-bcb127e2f378@mail.kernel.org> (raw)
The `vub300` driver uses a timer (`vub300->inactivity_timer`) to monitor
inactivity. When this timer expires, its callback
`vub300_inactivity_timer_expired()` is executed in softirq (atomic)
context. Inside the timer callback, if the device has been disconnected, it
drops its reference to the host by calling `kref_put(&vub300->kref,
vub300_delete)`. If this timer holds the last reference, `vub300_delete()`
is invoked synchronously in the same atomic context.
`vub300_delete()` calls `mmc_free_host()`. Since commit 1036f69e2513 ("mmc:
core: Cancel delayed work before releasing host"), `mmc_free_host()` calls
`cancel_delayed_work_sync()`, which can sleep. This triggers a "BUG:
sleeping function called from invalid context" when executed from the
softirq context:
BUG: sleeping function called from invalid context at
kernel/workqueue.c:4487
in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 0, name: swapper/0
...
Call Trace:
<IRQ>
dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
__might_resched+0x378/0x4d0 kernel/sched/core.c:9197
__cancel_work_sync+0x6d/0x110 kernel/workqueue.c:4487
mmc_free_host+0x19/0x30 drivers/mmc/core/host.c:700
call_timer_fn+0x192/0x5e0 kernel/time/timer.c:1748
expire_timers kernel/time/timer.c:1799 [inline]
__run_timers kernel/time/timer.c:2374 [inline]
__run_timer_base+0x652/0x8b0 kernel/time/timer.c:2386
run_timer_base kernel/time/timer.c:2395 [inline]
run_timer_softirq+0xb7/0x170 kernel/time/timer.c:2405
handle_softirqs+0x216/0x830 kernel/softirq.c:622
__do_softirq kernel/softirq.c:656 [inline]
invoke_softirq kernel/softirq.c:496 [inline]
__irq_exit_rcu+0xc0/0x210 kernel/softirq.c:735
irq_exit_rcu+0x9/0x30 kernel/softirq.c:752
instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1062
[inline]
sysvec_apic_timer_interrupt+0x92/0xb0 arch/x86/kernel/apic/apic.c:1062
</IRQ>
To fix this, defer the cleanup operations in `vub300_delete()` to a
workqueue. A dedicated `work_struct` is added to `struct vub300_mmc_host`
and queued on the driver's `deadworkqueue` when the `kref` reaches zero.
Using `deadworkqueue` ensures that the work is safely flushed during module
unload.
Additionally, the order of cleanup operations is adjusted to prevent a
use-after-free. `usb_put_dev()` is called after `mmc_free_host()` because
`mmc_free_host()` accesses the USB device structure via `host->parent`. The
`udev` pointer is saved in a local variable before `mmc_free_host()` frees
the `vub300` structure.
Fixes: 1036f69e2513 ("mmc: core: Cancel delayed work before releasing host")
Assisted-by: Gemini:gemini-3.5-flash Gemini:gemini-3.1-pro-preview syzbot
Reported-by: syzbot+1ee4f3b9228e35f14677@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=1ee4f3b9228e35f14677
Link: https://syzkaller.appspot.com/ai_job?id=f105b557-f491-4cff-97a1-a15b027fdeec
To: <linux-mmc@vger.kernel.org>
To: "Ulf Hansson" <ulfh@kernel.org>
To: "Geert Uytterhoeven" <geert+renesas@glider.be>
Cc: "Johan Hovold" <johan@kernel.org>
Cc: "Guangshuo Li" <lgs201920130244@gmail.com>
Cc: <linux-kernel@vger.kernel.org>
Cc: "Runyu Xiao" <runyu.xiao@seu.edu.cn>
---
diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c
index 2dae474dc..28d97024f 100644
--- a/drivers/mmc/host/vub300.c
+++ b/drivers/mmc/host/vub300.c
@@ -346,6 +346,7 @@ struct vub300_mmc_host {
struct timer_list inactivity_timer;
struct work_struct deadwork;
struct work_struct cmndwork;
+ struct work_struct free_work;
struct delayed_work pollwork;
struct host_controller_info hc_info;
struct sd_status_header system_port_status;
@@ -366,21 +367,25 @@ struct vub300_mmc_host {
#define GET_HC_INF0 1
#define GET_SYSTEM_PORT_STATUS 0
-static void vub300_delete(struct kref *kref)
-{ /* kref callback - softirq */
- struct vub300_mmc_host *vub300 = kref_to_vub300_mmc_host(kref);
+static void vub300_free_work(struct work_struct *work)
+{
+ struct vub300_mmc_host *vub300 =
+ container_of(work, struct vub300_mmc_host, free_work);
struct mmc_host *mmc = vub300->mmc;
+ struct usb_device *udev = vub300->udev;
usb_free_urb(vub300->command_out_urb);
- vub300->command_out_urb = NULL;
usb_free_urb(vub300->command_res_urb);
- vub300->command_res_urb = NULL;
- usb_put_dev(vub300->udev);
mmc_free_host(mmc);
- /*
- * and hence also frees vub300
- * which is contained at the end of struct mmc
- */
+ usb_put_dev(udev);
+}
+
+static void vub300_delete(struct kref *kref)
+{
+ struct vub300_mmc_host *vub300 = kref_to_vub300_mmc_host(kref);
+
+ INIT_WORK(&vub300->free_work, vub300_free_work);
+ queue_work(deadworkqueue, &vub300->free_work);
}
static void vub300_queue_cmnd_work(struct vub300_mmc_host *vub300)
base-commit: 075b74841bd0065a3bda3440873c747938e69b68
--
This is an AI-generated patch subject to moderation.
Reply with '#syz upstream' to Sign-off the patch as a human author
and send it to the upstream kernel mailing lists.
Reply with '#syz reject' to reject it ('#syz unreject' to undo).
See https://goo.gle/syzbot-ai-patches for information about AI-generated patches.
The person who has signed off on the patch is responsible for
addressing comments.
syzbot engineers can be reached at syzkaller@googlegroups.com.
reply other threads:[~2026-08-07 5:35 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=49982079-95f4-4e8c-bbbc-bcb127e2f378@mail.kernel.org \
--to=syzbot@kernel.org \
--cc=syzbot@lists.linux.dev \
--cc=syzkaller-upstream-moderation@googlegroups.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.