[PATCH v2 2/2] nfc: pn533: add timeout to USB frame send completion wait
flat view
COOLING4d
From: Zhao Feng <hidden>
Date: 2026-10-27 07:01:40
Also in:
lkml, stable
Subsystem:
nfc subsystem, the rest · Maintainers:
David Heidelberg, Linus Torvalds
pn533_usb_send_frame() waits unboundedly for the out URB to complete. A device that never completes the transfer makes the task sleep forever in TASK_UNINTERRUPTIBLE while holding the command mutex, as reported by syzbot (hung task in pn533_usb_send_frame). Use a 1 second timeout instead. On timeout, kill the URB and return -ETIMEDOUT so the command in progress fails gracefully instead of hanging the task. The transfer may complete between the timeout expiring and usb_kill_urb(); in that case urb->status is 0 after the kill and the send proceeds normally instead of reporting a spurious failure, mirroring what usb_start_wait_urb() does. Fixes: 9dab880d675b ("nfc: pn533: Wait for out_urb's completion in pn533_usb_send_frame()") Reported-by: <redacted> Closes: https://syzbot.org/bug?extid=1c5368988052dc2d8201 Signed-off-by: Zhao Feng <redacted> Cc: <redacted> --- v2: check urb->status after killing the URB on timeout and carry on if the transfer completed in the race window; add Fixes tag and Cc stable; the pn533_wq_cmd() error handling fix is now patch 1/2. Issues reported by the Sashiko AI review. drivers/nfc/pn533/usb.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c
index 0b7e3b118d..265baf2213 100644
--- a/drivers/nfc/pn533/usb.c
+++ b/drivers/nfc/pn533/usb.c@@ -30,6 +30,9 @@ #define ACS_VENDOR_ID 0x072f #define ACR122U_PRODUCT_ID 0x2200 +/* How long to wait for the out URB to complete */ +#define PN533_USB_SEND_TIMEOUT_MS 1000 + static const struct usb_device_id pn533_usb_table[] = { { USB_DEVICE(PN533_VENDOR_ID, PN533_PRODUCT_ID), .driver_info = PN533_DEVICE_STD },
@@ -184,8 +187,20 @@ static int pn533_usb_send_frame(struct pn533 *dev, if (rc) return rc; - wait_for_completion(&arg.done); - phy->out_urb->context = cntx; + if (!wait_for_completion_timeout(&arg.done, + msecs_to_jiffies(PN533_USB_SEND_TIMEOUT_MS))) { + usb_kill_urb(phy->out_urb); + phy->out_urb->context = cntx; + /* + * The transfer may have completed between the timeout + * expiring and the urb being killed; if so, carry on as + * usual instead of reporting a bogus failure. + */ + if (phy->out_urb->status) + return -ETIMEDOUT; + } else { + phy->out_urb->context = cntx; + } if (dev->protocol_type == PN533_PROTO_REQ_RESP) { /* request for response for sent packet directly */
--
2.39.2