On Mon, 16 Oct 2017, Hans de Goede wrote:
> Taking the uurb->buffer_length userspace passes in as a maximum for the
> actual urbs transfer_buffer_length causes 2 serious issues:
>
> 1) It breaks isochronous support for all userspace apps using libusb,
> as existing libusb versions pass in 0 for uurb->buffer_length,
> relying on the kernel using the lenghts of the usbdevfs_iso_packet_desc
> descriptors passed in added together as buffer length.
>
> This for example causes redirection of USB audio and Webcam's into
> virtual machines using qemu-kvm to no longer work. This is a userspace
> ABI break and as such must be reverted.
>
> Note that the original commit does not protect other users / the
> kernels memory, it only stops the userspace process making the call
> from shooting itself in the foot.
Okay, breaking userspace is reason enough all by itself to revert this
change. I didn't realize that libusb sets the buffer_length to 0 for
isochronous URBs.
> 2) It may cause the kernel to program host controllers to DMA over random
> memory. Just as the devio code used to only look at the iso_packet_desc
> lenghts, the host drivers do the same, relying on the submitter of the
> urbs to make sure the entire buffer is large enough and not checking
> transfer_buffer_length.
>
> But the "USB: devio: Don't corrupt user memory" commit now takes the
> userspace provided uurb->buffer_length for the buffer-size while copying
> over the user-provided iso_packet_desc lengths 1:1, allowing the user
> to specify a small buffer size while programming the host controller to
> dma a lot more data.
Wow! You're right, of course. I don't know what I was thinking when I
reviewed that patch.
> (Atleast the ohci, uhci, xhci and fhci drivers do not check
> transfer_buffer_length for isoc transfers.)
>
> This reverts commit fa1ed74eb1c2 ("USB: devio: Don't corrupt user memory")
> fixing both these issues.
>
> Cc: Dan Carpenter <[email protected]>
> Cc: Alan Stern <[email protected]>
> Cc: Greg Kroah-Hartman <[email protected]>
> Cc: [email protected]
> Signed-off-by: Hans de Goede <[email protected]>
> ---
> drivers/usb/core/devio.c | 6 +-----
> 1 file changed, 1 insertion(+), 5 deletions(-)
>
> diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
> index 4664e543cf2f..e9326f31db8d 100644
> --- a/drivers/usb/core/devio.c
> +++ b/drivers/usb/core/devio.c
> @@ -1576,11 +1576,7 @@ static int proc_do_submiturb(struct usb_dev_state *ps,
> struct usbdevfs_urb *uurb
> totlen += isopkt[u].length;
> }
> u *= sizeof(struct usb_iso_packet_descriptor);
> - if (totlen <= uurb->buffer_length)
> - uurb->buffer_length = totlen;
> - else
> - WARN_ONCE(1, "uurb->buffer_length is too short %d vs
> %d",
> - totlen, uurb->buffer_length);
> + uurb->buffer_length = totlen;
> break;
>
> default:
For what it's worth:
Acked-by: Alan Stern <[email protected]>
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html