Skip to content

Commit 65a205e

Browse files
jhovoldgregkh
authored andcommitted
USB: cdc-acm: fix racy tty buffer accesses
A recent change that started reporting break events to the line discipline caused the tty-buffer insertions to no longer be serialised by inserting events also from the completion handler for the interrupt endpoint. Completion calls for distinct endpoints are not guaranteed to be serialised. For example, in case a host-controller driver uses bottom-half completion, the interrupt and bulk-in completion handlers can end up running in parallel on two CPUs (high-and low-prio tasklets, respectively) thereby breaking the tty layer's single producer assumption. Fix this by holding the read lock also when inserting characters from the bulk endpoint. Fixes: 08dff27 ("cdc-acm: fix BREAK rx code path adding necessary calls") Cc: [email protected] Acked-by: Oliver Neukum <[email protected]> Signed-off-by: Johan Hovold <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 0560c9c commit 65a205e

File tree

1 file changed

+5
-0
lines changed

1 file changed

+5
-0
lines changed

drivers/usb/class/cdc-acm.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,11 +475,16 @@ static int acm_submit_read_urbs(struct acm *acm, gfp_t mem_flags)
475475

476476
static void acm_process_read_urb(struct acm *acm, struct urb *urb)
477477
{
478+
unsigned long flags;
479+
478480
if (!urb->actual_length)
479481
return;
480482

483+
spin_lock_irqsave(&acm->read_lock, flags);
481484
tty_insert_flip_string(&acm->port, urb->transfer_buffer,
482485
urb->actual_length);
486+
spin_unlock_irqrestore(&acm->read_lock, flags);
487+
483488
tty_flip_buffer_push(&acm->port);
484489
}
485490

0 commit comments

Comments
 (0)