diff options
author | Alexey Khoroshilov <khoroshilov@ispras.ru> | 2016-02-26 17:33:14 -0500 |
---|---|---|
committer | Felipe Balbi <balbi@kernel.org> | 2016-03-04 08:14:47 -0500 |
commit | cff5638ef7852196879f9687e70d49ea291bbb33 (patch) | |
tree | c5f7866cbd378848b28157ff007e37972f89db7f | |
parent | ead22caf8507c0533aab6b89e26776414b477b6f (diff) |
usb: gadget: bdc_udc: fix race condition in bdc_udc_exit()
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@ispras.ru>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
-rw-r--r-- | drivers/usb/gadget/udc/bdc/bdc_udc.c | 5 |
1 files changed, 5 insertions, 0 deletions
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: | |||
581 | 581 | ||
582 | void bdc_udc_exit(struct bdc *bdc) | 582 | void bdc_udc_exit(struct bdc *bdc) |
583 | { | 583 | { |
584 | unsigned long flags; | ||
585 | |||
584 | dev_dbg(bdc->dev, "%s()\n", __func__); | 586 | dev_dbg(bdc->dev, "%s()\n", __func__); |
587 | spin_lock_irqsave(&bdc->lock, flags); | ||
585 | bdc_ep_disable(bdc->bdc_ep_array[1]); | 588 | bdc_ep_disable(bdc->bdc_ep_array[1]); |
589 | spin_unlock_irqrestore(&bdc->lock, flags); | ||
590 | |||
586 | usb_del_gadget_udc(&bdc->gadget); | 591 | usb_del_gadget_udc(&bdc->gadget); |
587 | bdc_free_ep(bdc); | 592 | bdc_free_ep(bdc); |
588 | } | 593 | } |