Commit 7652dd2c authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman
Browse files

USB: core: Check buffer length matches wLength for control transfers

A type of inconsistency that can show up in control URBs is when the
setup packet's wLength value does not match the URB's
transfer_buffer_length field.  The two should always be equal;
differences could lead to information leaks or undefined behavior for
OUT transfers or overruns for IN transfers.

This patch adds a test for such mismatches during URB submission.  If
the test fails, the submission is rejected with a -EBADR error code
(which is not used elsewhere in the USB core), and a debugging message
is logged for people interested in tracking down these errors.

Reviewed-by: default avatarJohan Hovold <>
Signed-off-by: default avatarAlan Stern <>

Signed-off-by: default avatarGreg Kroah-Hartman <>
parent 61a140f0
......@@ -61,6 +61,9 @@ USB-specific:
(c) requested data transfer length is invalid: negative
or too large for the host controller.
``-EBADR`` The wLength value in a control URB's setup packet does
not match the URB's transfer_buffer_length.
``-ENOSPC`` This request would overcommit the usb bandwidth reserved
for periodic transfers (interrupt, isochronous).
......@@ -410,6 +410,12 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
dev_WARN_ONCE(&dev->dev, (usb_pipeout(urb->pipe) != is_out),
"BOGUS control dir, pipe %x doesn't match bRequestType %x\n",
urb->pipe, setup->bRequestType);
if (le16_to_cpu(setup->wLength) != urb->transfer_buffer_length) {
dev_dbg(&dev->dev, "BOGUS control len %d doesn't match transfer length %d\n",
return -EBADR;
} else {
is_out = usb_endpoint_dir_out(&ep->desc);
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment