diff options
author | Endre Kollar <taxy443@gmail.com> | 2010-07-27 06:40:00 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-07-27 14:08:31 -0400 |
commit | b7a937e90c3631cf3662a518cf2e4bf07f72967c (patch) | |
tree | 2ec71fa97df5d8261c1aa9f0aafc01c9214d4024 | |
parent | ab30f12d4ef11cc92fa9a657bf0c9b9951f24011 (diff) |
Staging: usbip: Filtering illegal flags from remote driver
The usb_submit_urb function in debug mode monitors the bogus flags. The
client driver errors should not be conveyed to the local USB device.
Signed-off-by: Endre Kollar <taxy443@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/staging/usbip/stub_rx.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c index c6022602749e..3e9d46358dde 100644 --- a/drivers/staging/usbip/stub_rx.c +++ b/drivers/staging/usbip/stub_rx.c | |||
@@ -424,6 +424,60 @@ static int get_pipe(struct stub_device *sdev, int epnum, int dir) | |||
424 | return 0; | 424 | return 0; |
425 | } | 425 | } |
426 | 426 | ||
427 | static void masking_bogus_flags(struct urb *urb) | ||
428 | { | ||
429 | int xfertype; | ||
430 | struct usb_device *dev; | ||
431 | struct usb_host_endpoint *ep; | ||
432 | int is_out; | ||
433 | unsigned int allowed; | ||
434 | |||
435 | if (!urb || urb->hcpriv || !urb->complete) | ||
436 | return; | ||
437 | dev = urb->dev; | ||
438 | if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED)) | ||
439 | return; | ||
440 | |||
441 | ep = (usb_pipein(urb->pipe) ? dev->ep_in : dev->ep_out) | ||
442 | [usb_pipeendpoint(urb->pipe)]; | ||
443 | if (!ep) | ||
444 | return; | ||
445 | |||
446 | xfertype = usb_endpoint_type(&ep->desc); | ||
447 | if (xfertype == USB_ENDPOINT_XFER_CONTROL) { | ||
448 | struct usb_ctrlrequest *setup = | ||
449 | (struct usb_ctrlrequest *) urb->setup_packet; | ||
450 | |||
451 | if (!setup) | ||
452 | return; | ||
453 | is_out = !(setup->bRequestType & USB_DIR_IN) || | ||
454 | !setup->wLength; | ||
455 | } else { | ||
456 | is_out = usb_endpoint_dir_out(&ep->desc); | ||
457 | } | ||
458 | |||
459 | /* enforce simple/standard policy */ | ||
460 | allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | | ||
461 | URB_NO_INTERRUPT | URB_DIR_MASK | URB_FREE_BUFFER); | ||
462 | switch (xfertype) { | ||
463 | case USB_ENDPOINT_XFER_BULK: | ||
464 | if (is_out) | ||
465 | allowed |= URB_ZERO_PACKET; | ||
466 | /* FALLTHROUGH */ | ||
467 | case USB_ENDPOINT_XFER_CONTROL: | ||
468 | allowed |= URB_NO_FSBR; /* only affects UHCI */ | ||
469 | /* FALLTHROUGH */ | ||
470 | default: /* all non-iso endpoints */ | ||
471 | if (!is_out) | ||
472 | allowed |= URB_SHORT_NOT_OK; | ||
473 | break; | ||
474 | case USB_ENDPOINT_XFER_ISOC: | ||
475 | allowed |= URB_ISO_ASAP; | ||
476 | break; | ||
477 | } | ||
478 | urb->transfer_flags &= allowed; | ||
479 | } | ||
480 | |||
427 | static void stub_recv_cmd_submit(struct stub_device *sdev, | 481 | static void stub_recv_cmd_submit(struct stub_device *sdev, |
428 | struct usbip_header *pdu) | 482 | struct usbip_header *pdu) |
429 | { | 483 | { |
@@ -490,6 +544,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev, | |||
490 | /* no need to submit an intercepted request, but harmless? */ | 544 | /* no need to submit an intercepted request, but harmless? */ |
491 | tweak_special_requests(priv->urb); | 545 | tweak_special_requests(priv->urb); |
492 | 546 | ||
547 | masking_bogus_flags(priv->urb); | ||
493 | /* urb is now ready to submit */ | 548 | /* urb is now ready to submit */ |
494 | ret = usb_submit_urb(priv->urb, GFP_KERNEL); | 549 | ret = usb_submit_urb(priv->urb, GFP_KERNEL); |
495 | 550 | ||