[PATCH] usb: atm: cxacru: stop polling on device shutdown

Anuj Bolewar via B4 Relay <[email protected]>
Newsgroups gmane.linux.kernel,gmane.linux.network,gmane.linux.usb.general
Message-ID <20260804-usb-atm-cxacru-stop-polling-on-device-shutdown-v1-1-d7fd757cee31@gmail.com>
From: Anuj Bolewar <[email protected]>

cxacru_unbind() sets poll_state to CXPOLL_SHUTDOWN under
poll_state_serialize and then calls cancel_delayed_work_sync(). If
cxacru_poll_status() is already running it only stops rescheduling when
it observes CXPOLL_STOPPED; CXPOLL_SHUTDOWN is ignored, so a running
worker re-queues itself. cancel_delayed_work_sync() then returns while a
delayed work is still pending, and the work fires after cxacru_unbind()
has freed the instance, causing a use-after-free.

Treat CXPOLL_SHUTDOWN like CXPOLL_STOPPED in the reschedule decision so
a worker that sees the shutdown state stops polling and cannot re-queue
itself after unbind.

Reported-by: [email protected]
Closes: https://syzkaller.appspot.com/bug?extid=e4b1171e7c5ae2556f9e
Assisted-by: deepseek:v4-pro
Signed-off-by: Anuj Bolewar <[email protected]>
---
cxacru_poll_status() reschedules itself with schedule_delayed_work()
unless poll_state is CXPOLL_STOPPED. cxacru_unbind() sets poll_state
to CXPOLL_SHUTDOWN and relies on cancel_delayed_work_sync() to stop
the worker, but a worker that is already running when unbind starts
never observes CXPOLL_STOPPED and re-queues itself, so the delayed
work still fires after the instance has been freed.

Treat CXPOLL_SHUTDOWN like CXPOLL_STOPPED when deciding whether to
reschedule, so a running worker cannot re-queue itself during unbind.
---
 drivers/usb/atm/cxacru.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index f1900c567ba..a9902973914 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -923,7 +923,8 @@ static void cxacru_poll_status(struct work_struct *work)
 				instance->line_status == 0) /* down */
 		instance->poll_state = CXPOLL_STOPPED;
 
-	if (instance->poll_state == CXPOLL_STOPPED)
+	if (instance->poll_state == CXPOLL_STOPPED ||
+	    instance->poll_state == CXPOLL_SHUTDOWN)
 		keep_polling = 0;
 	mutex_unlock(&instance->poll_state_serialize);
 

---
base-commit: 848acc8ffe1b7cd5f1bf427b93069becfebc2c9d
change-id: 20260804-usb-atm-cxacru-stop-polling-on-device-shutdown-bc9c6f771624

Best regards,
--  
Anuj Bolewar <[email protected]>
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.