提交 71d2718f 编写于 作者: R Roel Kluin 提交者: Greg Kroah-Hartman

USB: more u32 conversion after transfer_buffer_length and actual_length

transfer_buffer_length and actual_length have become unsigned, therefore some
additional conversion of local variables, function arguments and print
specifications is desired.

A test for a negative urb->transfer_buffer_length became obsolete; instead
we ensure that it does not exceed INT_MAX. Also, urb->actual_length is always
less than urb->transfer_buffer_length.

rh_string() does no longer return -EPIPE in the case of an unsupported ID.
Instead its only caller, rh_call_control() does the check.
Signed-off-by: NRoel Kluin <roel.kluin@gmail.com>
Acked-by: NAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 d2ad67b3
...@@ -302,7 +302,7 @@ static struct async *async_getpending(struct dev_state *ps, ...@@ -302,7 +302,7 @@ static struct async *async_getpending(struct dev_state *ps,
static void snoop_urb(struct urb *urb, void __user *userurb) static void snoop_urb(struct urb *urb, void __user *userurb)
{ {
int j; unsigned j;
unsigned char *data = urb->transfer_buffer; unsigned char *data = urb->transfer_buffer;
if (!usbfs_snoop) if (!usbfs_snoop)
...@@ -311,9 +311,9 @@ static void snoop_urb(struct urb *urb, void __user *userurb) ...@@ -311,9 +311,9 @@ static void snoop_urb(struct urb *urb, void __user *userurb)
dev_info(&urb->dev->dev, "direction=%s\n", dev_info(&urb->dev->dev, "direction=%s\n",
usb_urb_dir_in(urb) ? "IN" : "OUT"); usb_urb_dir_in(urb) ? "IN" : "OUT");
dev_info(&urb->dev->dev, "userurb=%p\n", userurb); dev_info(&urb->dev->dev, "userurb=%p\n", userurb);
dev_info(&urb->dev->dev, "transfer_buffer_length=%d\n", dev_info(&urb->dev->dev, "transfer_buffer_length=%u\n",
urb->transfer_buffer_length); urb->transfer_buffer_length);
dev_info(&urb->dev->dev, "actual_length=%d\n", urb->actual_length); dev_info(&urb->dev->dev, "actual_length=%u\n", urb->actual_length);
dev_info(&urb->dev->dev, "data: "); dev_info(&urb->dev->dev, "data: ");
for (j = 0; j < urb->transfer_buffer_length; ++j) for (j = 0; j < urb->transfer_buffer_length; ++j)
printk("%02x ", data[j]); printk("%02x ", data[j]);
......
...@@ -279,9 +279,9 @@ static const u8 hs_rh_config_descriptor [] = { ...@@ -279,9 +279,9 @@ static const u8 hs_rh_config_descriptor [] = {
* helper routine for returning string descriptors in UTF-16LE * helper routine for returning string descriptors in UTF-16LE
* input can actually be ISO-8859-1; ASCII is its 7-bit subset * input can actually be ISO-8859-1; ASCII is its 7-bit subset
*/ */
static int ascii2utf (char *s, u8 *utf, int utfmax) static unsigned ascii2utf(char *s, u8 *utf, int utfmax)
{ {
int retval; unsigned retval;
for (retval = 0; *s && utfmax > 1; utfmax -= 2, retval += 2) { for (retval = 0; *s && utfmax > 1; utfmax -= 2, retval += 2) {
*utf++ = *s++; *utf++ = *s++;
...@@ -304,19 +304,15 @@ static int ascii2utf (char *s, u8 *utf, int utfmax) ...@@ -304,19 +304,15 @@ static int ascii2utf (char *s, u8 *utf, int utfmax)
* Produces either a manufacturer, product or serial number string for the * Produces either a manufacturer, product or serial number string for the
* virtual root hub device. * virtual root hub device.
*/ */
static int rh_string ( static unsigned rh_string(int id, struct usb_hcd *hcd, u8 *data, unsigned len)
int id, {
struct usb_hcd *hcd,
u8 *data,
int len
) {
char buf [100]; char buf [100];
// language ids // language ids
if (id == 0) { if (id == 0) {
buf[0] = 4; buf[1] = 3; /* 4 bytes string data */ buf[0] = 4; buf[1] = 3; /* 4 bytes string data */
buf[2] = 0x09; buf[3] = 0x04; /* MSFT-speak for "en-us" */ buf[2] = 0x09; buf[3] = 0x04; /* MSFT-speak for "en-us" */
len = min (len, 4); len = min_t(unsigned, len, 4);
memcpy (data, buf, len); memcpy (data, buf, len);
return len; return len;
...@@ -332,10 +328,7 @@ static int rh_string ( ...@@ -332,10 +328,7 @@ static int rh_string (
} else if (id == 3) { } else if (id == 3) {
snprintf (buf, sizeof buf, "%s %s %s", init_utsname()->sysname, snprintf (buf, sizeof buf, "%s %s %s", init_utsname()->sysname,
init_utsname()->release, hcd->driver->description); init_utsname()->release, hcd->driver->description);
}
// unsupported IDs --> "protocol stall"
} else
return -EPIPE;
switch (len) { /* All cases fall through */ switch (len) { /* All cases fall through */
default: default:
...@@ -360,9 +353,8 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) ...@@ -360,9 +353,8 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
u8 tbuf [sizeof (struct usb_hub_descriptor)] u8 tbuf [sizeof (struct usb_hub_descriptor)]
__attribute__((aligned(4))); __attribute__((aligned(4)));
const u8 *bufp = tbuf; const u8 *bufp = tbuf;
int len = 0; unsigned len = 0;
int status; int status;
int n;
u8 patch_wakeup = 0; u8 patch_wakeup = 0;
u8 patch_protocol = 0; u8 patch_protocol = 0;
...@@ -456,10 +448,11 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) ...@@ -456,10 +448,11 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
patch_wakeup = 1; patch_wakeup = 1;
break; break;
case USB_DT_STRING << 8: case USB_DT_STRING << 8:
n = rh_string (wValue & 0xff, hcd, ubuf, wLength); if ((wValue & 0xff) < 4)
if (n < 0) urb->actual_length = rh_string(wValue & 0xff,
hcd, ubuf, wLength);
else /* unsupported IDs --> "protocol stall" */
goto error; goto error;
urb->actual_length = n;
break; break;
default: default:
goto error; goto error;
...@@ -629,7 +622,7 @@ static int rh_queue_status (struct usb_hcd *hcd, struct urb *urb) ...@@ -629,7 +622,7 @@ static int rh_queue_status (struct usb_hcd *hcd, struct urb *urb)
{ {
int retval; int retval;
unsigned long flags; unsigned long flags;
int len = 1 + (urb->dev->maxchild / 8); unsigned len = 1 + (urb->dev->maxchild / 8);
spin_lock_irqsave (&hcd_root_hub_lock, flags); spin_lock_irqsave (&hcd_root_hub_lock, flags);
if (hcd->status_urb || urb->transfer_buffer_length < len) { if (hcd->status_urb || urb->transfer_buffer_length < len) {
......
...@@ -392,7 +392,7 @@ static void hub_irq(struct urb *urb) ...@@ -392,7 +392,7 @@ static void hub_irq(struct urb *urb)
{ {
struct usb_hub *hub = urb->context; struct usb_hub *hub = urb->context;
int status = urb->status; int status = urb->status;
int i; unsigned i;
unsigned long bits; unsigned long bits;
switch (status) { switch (status) {
......
...@@ -59,7 +59,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) ...@@ -59,7 +59,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length)
retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status); retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status);
dev_dbg(&urb->dev->dev, dev_dbg(&urb->dev->dev,
"%s timed out on ep%d%s len=%d/%d\n", "%s timed out on ep%d%s len=%u/%u\n",
current->comm, current->comm,
usb_endpoint_num(&urb->ep->desc), usb_endpoint_num(&urb->ep->desc),
usb_urb_dir_in(urb) ? "in" : "out", usb_urb_dir_in(urb) ? "in" : "out",
......
...@@ -370,7 +370,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) ...@@ -370,7 +370,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
} }
/* the I/O buffer must be mapped/unmapped, except when length=0 */ /* the I/O buffer must be mapped/unmapped, except when length=0 */
if (urb->transfer_buffer_length < 0) if (urb->transfer_buffer_length > INT_MAX)
return -EMSGSIZE; return -EMSGSIZE;
#ifdef DEBUG #ifdef DEBUG
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册