summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/driver-api/usb/error-codes.rst3
-rw-r--r--drivers/usb/core/urb.c6
2 files changed, 9 insertions, 0 deletions
diff --git a/Documentation/driver-api/usb/error-codes.rst b/Documentation/driver-api/usb/error-codes.rst
index a3e84bfac776..8f9790c2d6f8 100644
--- a/Documentation/driver-api/usb/error-codes.rst
+++ b/Documentation/driver-api/usb/error-codes.rst
@@ -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).
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 279b3921ff8f..30727729a44c 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -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",
+ le16_to_cpu(setup->wLength),
+ urb->transfer_buffer_length);
+ return -EBADR;
+ }
} else {
is_out = usb_endpoint_dir_out(&ep->desc);
}