aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2009-12-11 16:20:20 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-03-02 14:53:07 -0800
commitf661c6f8c67bd55e93348f160d590ff9edf08904 (patch)
tree9b5abdda44f9bfb0b6a6dcb51217701a67ed40a0
parenta91b0c502285fd0c569fae1222fdd945ef739233 (diff)
downloadkernel_samsung_smdk4412-f661c6f8c67bd55e93348f160d590ff9edf08904.zip
kernel_samsung_smdk4412-f661c6f8c67bd55e93348f160d590ff9edf08904.tar.gz
kernel_samsung_smdk4412-f661c6f8c67bd55e93348f160d590ff9edf08904.tar.bz2
USB: check the endpoint type against the pipe type
This patch (as1316) adds some error checking to usb_submit_urb(). It's conditional on CONFIG_USB_DEBUG, so it won't affect normal users. The new check makes sure that the actual type of the endpoint described by urb->pipe agrees with the type encoded in the pipe value. The USB error code documentation is updated to include the code returned by the new check, and the usbfs SUBMITURB handler is updated to use the correct pipe type when legacy user code tries to submit a bulk transfer to an interrupt endpoint. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--Documentation/usb/error-codes.txt6
-rw-r--r--drivers/usb/core/devio.c22
-rw-r--r--drivers/usb/core/urb.c7
3 files changed, 24 insertions, 11 deletions
diff --git a/Documentation/usb/error-codes.txt b/Documentation/usb/error-codes.txt
index 9cf83e8..d83703e 100644
--- a/Documentation/usb/error-codes.txt
+++ b/Documentation/usb/error-codes.txt
@@ -41,8 +41,8 @@ USB-specific:
-EFBIG Host controller driver can't schedule that many ISO frames.
--EPIPE Specified endpoint is stalled. For non-control endpoints,
- reset this status with usb_clear_halt().
+-EPIPE The pipe type specified in the URB doesn't match the
+ endpoint's actual type.
-EMSGSIZE (a) endpoint maxpacket size is zero; it is not usable
in the current interface altsetting.
@@ -60,6 +60,8 @@ USB-specific:
-EHOSTUNREACH URB was rejected because the device is suspended.
+-ENOEXEC A control URB doesn't contain a Setup packet.
+
**************************************************************************
* Error codes returned by in urb->status *
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index a678186..431d172 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -1104,13 +1104,25 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
case USB_ENDPOINT_XFER_CONTROL:
case USB_ENDPOINT_XFER_ISOC:
return -EINVAL;
- /* allow single-shot interrupt transfers, at bogus rates */
+ case USB_ENDPOINT_XFER_INT:
+ /* allow single-shot interrupt transfers */
+ uurb->type = USBDEVFS_URB_TYPE_INTERRUPT;
+ goto interrupt_urb;
}
uurb->number_of_packets = 0;
if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
return -EINVAL;
break;
+ case USBDEVFS_URB_TYPE_INTERRUPT:
+ if (!usb_endpoint_xfer_int(&ep->desc))
+ return -EINVAL;
+ interrupt_urb:
+ uurb->number_of_packets = 0;
+ if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
+ return -EINVAL;
+ break;
+
case USBDEVFS_URB_TYPE_ISO:
/* arbitrary limit */
if (uurb->number_of_packets < 1 ||
@@ -1143,14 +1155,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
uurb->buffer_length = totlen;
break;
- case USBDEVFS_URB_TYPE_INTERRUPT:
- uurb->number_of_packets = 0;
- if (!usb_endpoint_xfer_int(&ep->desc))
- return -EINVAL;
- if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
- return -EINVAL;
- break;
-
default:
return -EINVAL;
}
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index e7cae13..e2bd153 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -387,6 +387,13 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
{
unsigned int orig_flags = urb->transfer_flags;
unsigned int allowed;
+ static int pipetypes[4] = {
+ PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT
+ };
+
+ /* Check that the pipe's type matches the endpoint's type */
+ if (usb_pipetype(urb->pipe) != pipetypes[xfertype])
+ return -EPIPE; /* The most suitable error code :-) */
/* enforce simple/standard policy */
allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP |