Skip to content

Commit 7a68d9f

Browse files
oneukumgregkh
authored andcommitted
USB: usbdevfs: sanitize flags more
Requesting a ZERO_PACKET or not is sensible only for output. In the input direction the device decides. Likewise accepting short packets makes sense only for input. This allows operation with panic_on_warn without opening up a local DOS. Signed-off-by: Oliver Neukum <[email protected]> Reported-by: [email protected] Fixes: 0cb54a3 ("USB: debugging code shouldn't alter control flow") Cc: stable <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent e871db8 commit 7a68d9f

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

drivers/usb/core/devio.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,10 +1434,13 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
14341434
struct async *as = NULL;
14351435
struct usb_ctrlrequest *dr = NULL;
14361436
unsigned int u, totlen, isofrmlen;
1437-
int i, ret, is_in, num_sgs = 0, ifnum = -1;
1437+
int i, ret, num_sgs = 0, ifnum = -1;
14381438
int number_of_packets = 0;
14391439
unsigned int stream_id = 0;
14401440
void *buf;
1441+
bool is_in;
1442+
bool allow_short = false;
1443+
bool allow_zero = false;
14411444
unsigned long mask = USBDEVFS_URB_SHORT_NOT_OK |
14421445
USBDEVFS_URB_BULK_CONTINUATION |
14431446
USBDEVFS_URB_NO_FSBR |
@@ -1471,6 +1474,8 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
14711474
u = 0;
14721475
switch (uurb->type) {
14731476
case USBDEVFS_URB_TYPE_CONTROL:
1477+
if (is_in)
1478+
allow_short = true;
14741479
if (!usb_endpoint_xfer_control(&ep->desc))
14751480
return -EINVAL;
14761481
/* min 8 byte setup packet */
@@ -1511,6 +1516,10 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
15111516
break;
15121517

15131518
case USBDEVFS_URB_TYPE_BULK:
1519+
if (!is_in)
1520+
allow_zero = true;
1521+
else
1522+
allow_short = true;
15141523
switch (usb_endpoint_type(&ep->desc)) {
15151524
case USB_ENDPOINT_XFER_CONTROL:
15161525
case USB_ENDPOINT_XFER_ISOC:
@@ -1531,6 +1540,10 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
15311540
if (!usb_endpoint_xfer_int(&ep->desc))
15321541
return -EINVAL;
15331542
interrupt_urb:
1543+
if (!is_in)
1544+
allow_zero = true;
1545+
else
1546+
allow_short = true;
15341547
break;
15351548

15361549
case USBDEVFS_URB_TYPE_ISO:
@@ -1676,9 +1689,9 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
16761689
u = (is_in ? URB_DIR_IN : URB_DIR_OUT);
16771690
if (uurb->flags & USBDEVFS_URB_ISO_ASAP)
16781691
u |= URB_ISO_ASAP;
1679-
if (uurb->flags & USBDEVFS_URB_SHORT_NOT_OK && is_in)
1692+
if (allow_short && uurb->flags & USBDEVFS_URB_SHORT_NOT_OK)
16801693
u |= URB_SHORT_NOT_OK;
1681-
if (uurb->flags & USBDEVFS_URB_ZERO_PACKET)
1694+
if (allow_zero && uurb->flags & USBDEVFS_URB_ZERO_PACKET)
16821695
u |= URB_ZERO_PACKET;
16831696
if (uurb->flags & USBDEVFS_URB_NO_INTERRUPT)
16841697
u |= URB_NO_INTERRUPT;

0 commit comments

Comments
 (0)