[ldv-project] [PATCH] usb: gadget: bdc_udc: fix race condition in bdc_udc_exit()

Alexey Khoroshilov khoroshilov at ispras.ru
Sat Feb 27 01:33:14 MSK 2016


bdc_ep_disable() expects to be called with bdc->lock held.
The assumption is met in all the cases except for call from bdc_udc_exit(),
that is called from bdc_remove(). As a result a race can happen or unheld
bdc->lock can be unlocked in bdc_req_complete().

The patch proposes to acquire-release bdc->lock around bdc_ep_disable()
in bdc_udc_exit().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshilov at ispras.ru>
---
 drivers/usb/gadget/udc/bdc/bdc_udc.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/usb/gadget/udc/bdc/bdc_udc.c b/drivers/usb/gadget/udc/bdc/bdc_udc.c
index 7f77db5d1278..aae7458d8986 100644
--- a/drivers/usb/gadget/udc/bdc/bdc_udc.c
+++ b/drivers/usb/gadget/udc/bdc/bdc_udc.c
@@ -581,8 +581,13 @@ err0:
 
 void bdc_udc_exit(struct bdc *bdc)
 {
+	unsigned long flags;
+
 	dev_dbg(bdc->dev, "%s()\n", __func__);
+	spin_lock_irqsave(&bdc->lock, flags);
 	bdc_ep_disable(bdc->bdc_ep_array[1]);
+	spin_unlock_irqrestore(&bdc->lock, flags);
+
 	usb_del_gadget_udc(&bdc->gadget);
 	bdc_free_ep(bdc);
 }
-- 
1.9.1




More information about the ldv-project mailing list