USB: core: Check buffer length matches wLength for control transfers
Subsystems (2)
PATCH 1/1 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.
---
[as1961]
Documentation/driver-api/usb/error-codes.rst | 3 +++ drivers/usb/core/urb.c | 6 ++++++ 2 files changed, 9 insertions(+)
drivers/usb/core/urb.c +6 -0
@@ -410,6 +410,12 @@ int usb_submit_urb(struct urb *urb, gfp_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); }
Documentation/driver-api/usb/error-codes.rst +3 -0
@@ -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).
Quoted 6 lines · Alan Stern
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_lengthfield. The two should always be equal; differences could lead to information leaks or undefined behavior for OUT transfers or overruns for IN transfers.
Quoted 7 lines
This patch adds a test for such mismatches during URB submission. If the test fails, the submission is rejected with a
-EBADRerror code (which is not used elsewhere in the USB core), and a debugging message is logged for people interested in tracking down these errors.Signed-off-by Alan Stern <[email protected]>CC Johan Hovold <[email protected]>
Looks good.
Quoted 41 lines
---
[as1961]
Documentation/driver-api/usb/error-codes.rst | 3 +++ drivers/usb/core/urb.c | 6 ++++++ 2 files changed, 9 insertions(+)Index:
usb-devel/drivers/usb/core/urb.c
===================================================================drivers/usb/core/urb.c +6
-0@@ -410,6 +410,12 @@ int usb_submit_urb(struct urb *urb, gfp_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); }Index:
usb-devel/Documentation/driver-api/usb/error-codes.rst
===================================================================Documentation/driver-api/usb/error-codes.rst +3
-0@@ -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).
Quoted 29 lines · Alan Stern
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_lengthfield. 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
-EBADRerror code (which is not used elsewhere in the USB core), and a debugging message is logged for people interested in tracking down these errors.Signed-off-by Alan Stern <[email protected]>CC Johan Hovold <[email protected]>---
[as1961]
Documentation/driver-api/usb/error-codes.rst | 3 +++ drivers/usb/core/urb.c | 6 ++++++ 2 files changed, 9 insertions(+)Index:
usb-devel/drivers/usb/core/urb.c
===================================================================
drivers/usb/core/urb.c int usb_submit_urb(struct urb *urb, gfp_ · line 418
Quoted 9 lines
drivers/usb/core/urb.c +6
-0@@ -410,6 +410,12 @@ int usb_submit_urb(struct urb *urb, gfp_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 ; + }
Looks good, let's see if this catches anything :)
now queued up, thanks.
greg k-h