Skip to content

Commit

Permalink
USB: ldusb: fix ring-buffer locking
Browse files Browse the repository at this point in the history
The custom ring-buffer implementation was merged without any locking or
explicit memory barriers, but a spinlock was later added by commit
9d33efd ("USB: ldusb bugfix").

The lock did not cover the update of the tail index once the entry had
been processed, something which could lead to memory corruption on
weakly ordered architectures or due to compiler optimisations.

Specifically, a completion handler running on another CPU might observe
the incremented tail index and update the entry before ld_usb_read() is
done with it.

Fixes: 2824bd2 ("[PATCH] USB: add ldusb driver")
Fixes: 9d33efd ("USB: ldusb bugfix")
Cc: stable <[email protected]>     # 2.6.13
Signed-off-by: Johan Hovold <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
jhovold authored and gregkh committed Oct 28, 2019
1 parent d482c7b commit d98ee2a
Showing 1 changed file with 2 additions and 2 deletions.
4 changes: 2 additions & 2 deletions drivers/usb/misc/ldusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,11 +495,11 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
retval = -EFAULT;
goto unlock_exit;
}
dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size;

retval = bytes_to_read;

spin_lock_irq(&dev->rbsl);
dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size;

if (dev->buffer_overflow) {
dev->buffer_overflow = 0;
spin_unlock_irq(&dev->rbsl);
Expand Down

0 comments on commit d98ee2a

Please sign in to comment.