[PATCH] usb: atm: cxacru: fix use-after-free in cxacru_poll_status

Nguyen Quang Le Kien <[email protected]>
Newsgroups org.kernel.vger.netdev,org.kernel.vger.linux-kernel,org.kernel.vger.linux-usb
Message-ID <[email protected]>
In cxacru_unbind(), cancel_delayed_work_sync() was conditionally skipped
when poll_state was CXPOLL_STOPPED. However, a work item previously
scheduled when poll_state was CXPOLL_POLLING may still be pending in the
workqueue at the time poll_state transitions to CXPOLL_STOPPED. Skipping
cancel_delayed_work_sync() in this case allows the work to fire after
cxacru_data is freed, causing a use-after-free when cxacru_poll_status()
attempts to acquire instance->poll_state_serialize.

Fix this by always calling cancel_delayed_work_sync() regardless of
poll_state, ensuring no pending or in-flight work can access the freed
instance.

Reported-by: [email protected]
Closes: https://syzkaller.appspot.com/bug?extid=24eb38c789655fc43663
Signed-off-by: Nguyen Quang Le Kien <[email protected]>
---
 drivers/usb/atm/cxacru.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index f1900c567..fd644ae52 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -1231,8 +1231,6 @@ static void cxacru_unbind(struct usbatm_data *usbatm_instance,
 		struct usb_interface *intf)
 {
 	struct cxacru_data *instance = usbatm_instance->driver_data;
-	int is_polling = 1;
-
 	usb_dbg(usbatm_instance, "cxacru_unbind entered\n");
 
 	if (!instance) {
@@ -1243,17 +1241,11 @@ static void cxacru_unbind(struct usbatm_data *usbatm_instance,
 	mutex_lock(&instance->poll_state_serialize);
 	BUG_ON(instance->poll_state == CXPOLL_SHUTDOWN);
 
-	/* ensure that status polling continues unless
-	 * it has already stopped */
-	if (instance->poll_state == CXPOLL_STOPPED)
-		is_polling = 0;
-
 	/* stop polling from being stopped or started */
 	instance->poll_state = CXPOLL_SHUTDOWN;
 	mutex_unlock(&instance->poll_state_serialize);
 
-	if (is_polling)
-		cancel_delayed_work_sync(&instance->poll_work);
+	cancel_delayed_work_sync(&instance->poll_work);
 
 	usb_kill_urb(instance->snd_urb);
 	usb_kill_urb(instance->rcv_urb);
-- 
2.34.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.