[PATCH] nfc: pn533: fix unbounded wait in pn533_acr122_poweron_rdr()

Nguyen Ngoc Thang posted 1 patch 2 weeks ago
drivers/nfc/pn533/usb.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
[PATCH] nfc: pn533: fix unbounded wait in pn533_acr122_poweron_rdr()
Posted by Nguyen Ngoc Thang 2 weeks ago
pn533_acr122_poweron_rdr() submits phy->in_urb and then calls
wait_for_completion() with no timeout. This runs from pn533_usb_probe(),
which the USB core calls with the device's dev->mutex held (via
hub_event -> usb_new_device -> device_add -> really_probe). If the
device never answers that bulk-in read, the wait never returns: the
hub_event kworker hangs forever inside probe() while still holding
dev->mutex, and every other task that needs that same mutex (e.g.
usbdev_open()) hangs too.

Bound the wait with wait_for_completion_timeout(), matching the 5000ms
timeout already used by usb_bulk_msg() for the TX half of the same
exchange. On timeout, kill the urb and fail probe with -ETIMEDOUT
instead of hanging indefinitely.

Reported-by: syzbot+8996fbe184c5b84f89d4@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=8996fbe184c5b84f89d4
Signed-off-by: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
---
 drivers/nfc/pn533/usb.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c
index efb07f944fce..ad4d84614241 100644
--- a/drivers/nfc/pn533/usb.c
+++ b/drivers/nfc/pn533/usb.c
@@ -416,10 +416,17 @@ static int pn533_acr122_poweron_rdr(struct pn533_usb_phy *phy)
 		return rc;
 	}
 
-	wait_for_completion(&arg.done);
+	/* device may never reply: don't hang probe(), bound the wait */
+	if (!wait_for_completion_timeout(&arg.done, msecs_to_jiffies(5000))) {
+		usb_kill_urb(phy->in_urb); /* waits for the handler, so &arg can't outlive us */
+		nfc_err(&phy->udev->dev, "Reader poweron response timeout\n");
+		rc = -ETIMEDOUT;
+	} else {
+		rc = arg.rc;
+	}
 	phy->in_urb->context = cntx; /* restore context */
 
-	return arg.rc;
+	return rc;
 }
 
 static void pn533_out_complete(struct urb *urb)
-- 
2.43.0