Forwarded: [PATCH] WARNING: ODEBUG bug in vub300_disconnect

syzbot posted 1 patch 1 week, 3 days ago
There is a newer version of this series
Forwarded: [PATCH] WARNING: ODEBUG bug in vub300_disconnect
Posted by syzbot 1 week, 3 days ago
For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org.

***

Subject: [PATCH] WARNING: ODEBUG bug in vub300_disconnect
Author: jchuang26@m.fudan.edu.cn

#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 50d05c7c76c96b90462f24debacca971d2e86713

Reported-by: syzbot+f4a0159ce6802a0a4774@syzkaller.appspotmail.com

diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c
index 2dae474dc..5b30303ad 100644
--- a/drivers/mmc/host/vub300.c
+++ b/drivers/mmc/host/vub300.c
@@ -2382,10 +2382,25 @@ static void vub300_disconnect(struct usb_interface *interface)
 		} else {
 			int ifnum = interface_to_InterfaceNumber(interface);
 			usb_set_intfdata(interface, NULL);
+			/*
+			 * The inactivity timer holds a reference to the host
+			 * and can be rearmed by work items.  Shut it down
+			 * before clearing interface, otherwise its callback
+			 * can drop the timer reference while a concurrent
+			 * work item is rearming the timer, leaving the host
+			 * to be freed while the timer is still active.
+			 */
+			timer_shutdown_sync(&vub300->inactivity_timer);
 			/* prevent more I/O from starting */
 			vub300->interface = NULL;
 			mmc_remove_host(mmc);
 			kref_put(&vub300->kref, vub300_delete);
+			/*
+			 * The timer is shut down, so it will no longer drop
+			 * the reference that was acquired for it in
+			 * vub300_probe().  Drop it here.
+			 */
+			kref_put(&vub300->kref, vub300_delete);
 			pr_info("USB vub300 remote SDIO host controller[%d]"
 				" now disconnected", ifnum);
 			return;