Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 71d2718f authored by Roel Kluin's avatar Roel Kluin Committed by Greg Kroah-Hartman
Browse files

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: default avatarRoel Kluin <roel.kluin@gmail.com>
Acked-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent d2ad67b3
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -302,7 +302,7 @@ static struct async *async_getpending(struct dev_state *ps,

static void snoop_urb(struct urb *urb, void __user *userurb)
{
	int j;
	unsigned j;
	unsigned char *data = urb->transfer_buffer;

	if (!usbfs_snoop)
@@ -311,9 +311,9 @@ static void snoop_urb(struct urb *urb, void __user *userurb)
	dev_info(&urb->dev->dev, "direction=%s\n",
			usb_urb_dir_in(urb) ? "IN" : "OUT");
	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);
	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: ");
	for (j = 0; j < urb->transfer_buffer_length; ++j)
		printk("%02x ", data[j]);
+12 −19
Original line number Diff line number Diff line
@@ -279,9 +279,9 @@ static const u8 hs_rh_config_descriptor [] = {
 * helper routine for returning string descriptors in UTF-16LE
 * 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) {
		*utf++ = *s++;
@@ -304,19 +304,15 @@ static int ascii2utf (char *s, u8 *utf, int utfmax)
 * Produces either a manufacturer, product or serial number string for the
 * virtual root hub device.
 */
static int rh_string (
	int		id,
	struct usb_hcd	*hcd,
	u8		*data,
	int		len
) {
static unsigned rh_string(int id, struct usb_hcd *hcd, u8 *data, unsigned len)
{
	char buf [100];

	// language ids
	if (id == 0) {
		buf[0] = 4;    buf[1] = 3;	/* 4 bytes string data */
		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);
		return len;

@@ -332,10 +328,7 @@ static int rh_string (
	} else if (id == 3) {
		snprintf (buf, sizeof buf, "%s %s %s", init_utsname()->sysname,
			init_utsname()->release, hcd->driver->description);

	// unsupported IDs --> "protocol stall"
	} else
		return -EPIPE;
	}

	switch (len) {		/* All cases fall through */
	default:
@@ -360,9 +353,8 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
	u8		tbuf [sizeof (struct usb_hub_descriptor)]
		__attribute__((aligned(4)));
	const u8	*bufp = tbuf;
	int		len = 0;
	unsigned	len = 0;
	int		status;
	int		n;
	u8		patch_wakeup = 0;
	u8		patch_protocol = 0;

@@ -456,10 +448,11 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
				patch_wakeup = 1;
			break;
		case USB_DT_STRING << 8:
			n = rh_string (wValue & 0xff, hcd, ubuf, wLength);
			if (n < 0)
			if ((wValue & 0xff) < 4)
				urb->actual_length = rh_string(wValue & 0xff,
						hcd, ubuf, wLength);
			else /* unsupported IDs --> "protocol stall" */
				goto error;
			urb->actual_length = n;
			break;
		default:
			goto error;
@@ -629,7 +622,7 @@ static int rh_queue_status (struct usb_hcd *hcd, struct urb *urb)
{
	int		retval;
	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);
	if (hcd->status_urb || urb->transfer_buffer_length < len) {
+1 −1
Original line number Diff line number Diff line
@@ -392,7 +392,7 @@ static void hub_irq(struct urb *urb)
{
	struct usb_hub *hub = urb->context;
	int status = urb->status;
	int i;
	unsigned i;
	unsigned long bits;

	switch (status) {
+1 −1
Original line number Diff line number Diff line
@@ -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);

		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,
			usb_endpoint_num(&urb->ep->desc),
			usb_urb_dir_in(urb) ? "in" : "out",
+1 −1
Original line number Diff line number Diff line
@@ -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 */
	if (urb->transfer_buffer_length < 0)
	if (urb->transfer_buffer_length > INT_MAX)
		return -EMSGSIZE;

#ifdef DEBUG