[PATCH] usb: atm: cxacru: stop polling on device shutdown
Anuj Bolewar via B4 Relay <[email protected]> Tue, 04 Aug 2026 22:28:36 +0530
| Newsgroups | org.kernel.vger.linux-usb,org.kernel.feeds.b4-sent,org.kernel.vger.linux-kernel,org.kernel.vger.netdev |
|---|---|
| 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]>