Skip to content

Commit e752dbc

Browse files
shimodaygregkh
authored andcommitted
usb: gadget: udc: renesas_usb3: Fix a race in usb3_start_pipen()
The usb3_start_pipen() is called by renesas_usb3_ep_queue() and usb3_request_done_pipen() so that usb3_start_pipen() is possible to cause a race when getting usb3_first_req like below: renesas_usb3_ep_queue() spin_lock_irqsave() list_add_tail() spin_unlock_irqrestore() usb3_start_pipen() usb3_first_req = usb3_get_request() --- [1] --- interrupt --- usb3_irq_dma_int() usb3_request_done_pipen() usb3_get_request() usb3_start_pipen() usb3_first_req = usb3_get_request() ... (the req is possible to be finished in the interrupt) The usb3_first_req [1] above may have been finished after the interrupt ended so that this driver caused to start a transfer wrongly. To fix this issue, getting/checking the usb3_first_req are under spin_lock_irqsave() in the same section. Fixes: 746bfe6 ("usb: gadget: renesas_usb3: add support for Renesas USB3.0 peripheral controller") Cc: stable <[email protected]> Signed-off-by: Yoshihiro Shimoda <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent a20dcf5 commit e752dbc

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

drivers/usb/gadget/udc/renesas_usb3.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,15 +1488,16 @@ static void usb3_start_pipen(struct renesas_usb3_ep *usb3_ep,
14881488
struct renesas_usb3_request *usb3_req)
14891489
{
14901490
struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep);
1491-
struct renesas_usb3_request *usb3_req_first = usb3_get_request(usb3_ep);
1491+
struct renesas_usb3_request *usb3_req_first;
14921492
unsigned long flags;
14931493
int ret = -EAGAIN;
14941494
u32 enable_bits = 0;
14951495

14961496
spin_lock_irqsave(&usb3->lock, flags);
14971497
if (usb3_ep->halt || usb3_ep->started)
14981498
goto out;
1499-
if (usb3_req != usb3_req_first)
1499+
usb3_req_first = __usb3_get_request(usb3_ep);
1500+
if (!usb3_req_first || usb3_req != usb3_req_first)
15001501
goto out;
15011502

15021503
if (usb3_pn_change(usb3, usb3_ep->num) < 0)

0 commit comments

Comments
 (0)