Re: [PATCH] USB: do not convert negative transfer_buffer_lengths to positive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello.

Greg KH wrote:

vi include/linux/usb.h +1373
struct urb {
	...
	int transfer_buffer_length;
	...
}
So I think something like this is needed?

Have you ever seen a transfer_buffer_length set to anywhere close to the
MAX_INT value to trigger this?  Or a negative value?

I observed this by code inspection.

How about just changing transfer_buffer_length to a u32, that should
solve it, right?

That seems a sensible solution, but transfer_buffer_length is used in many
drivers. It will require a lot of changes. Maybe better leave it as is at
least until a real problem occurs.

How will it require a lot of changes?  No one should ever be assuming
that it is signed, do you see any problems?

And here's the patch that I just applied to the usb patch queue to
resolve this issue.

Any objections?

   Only a little.

thanks,

greg k-h


From foo@baz Tue Mar  3 16:44:13 PST 2009

   Interesting author. :-)

Date: Tue, 03 Mar 2009 16:44:13 -0800
To: Greg KH <greg@xxxxxxxxx>
From: Greg Kroah-Hartman <gregkh@xxxxxxx>
Subject: USB: make some struct urb fields u32

Roel Kluin pointed out that transfer_buffer_lengths in struct urb was
declared as an 'int'.  This patch changes this field, and the
actual_length field to be 'u32' to prevent any potential negative
conversion and comparison errors.

This triggered a few compiler warning messages when these fields were
being used with the min/max macros, so they have also been fixed up in
this patch.

Cc: Roel Kluin <roel.kluin@xxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx>

--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -1437,7 +1437,7 @@ restart:
 					}
 					if (urb->transfer_buffer_length > 1)
 						buf [1] = 0;
-					urb->actual_length = min (2,
+					urb->actual_length = min ((u32)2,

   I'm not sure what this p[articular change gives us...

 						urb->transfer_buffer_length);
 					value = 0;
 					status = 0;
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -772,7 +772,7 @@ static int isp116x_urb_enqueue(struct us
 		break;
 	case PIPE_INTERRUPT:
 		urb->interval = ep->period;
-		ep->length = min((int)ep->maxpacket,
+		ep->length = min((u32)ep->maxpacket,


   Consider using min_t(u32, ) instead...

 				 urb->transfer_buffer_length);
/* urb submitted for already existing endpoint */
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -1394,7 +1394,7 @@ static void packet_write(struct r8a66597
 			   (int)urb->iso_frame_desc[td->iso_cnt].length);
 	} else {
 		buf = (u16 *)(urb->transfer_buffer + urb->actual_length);
-		size = min((int)bufsize,
+		size = min((u32)bufsize,
 			   urb->transfer_buffer_length - urb->actual_length);
 	}
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -230,7 +230,7 @@ static void in_packet(
 	writeb(usb_pipedevice(urb->pipe), data_reg);
sl811_write(sl811, bank + SL11H_HOSTCTLREG, control);
-	ep->length = min((int)len,
+	ep->length = min((u32)len,
 			urb->transfer_buffer_length - urb->actual_length);
 	PACKET("IN%s/%d qh%p len%d\n", ep->nak_count ? "/retry" : "",
 			!!usb_gettoggle(urb->dev, ep->epnum, 0), ep, len);
@@ -255,7 +255,7 @@ static void out_packet(
 	buf = urb->transfer_buffer + urb->actual_length;
 	prefetch(buf);
- len = min((int)ep->maxpacket,
+	len = min((u32)ep->maxpacket,
 			urb->transfer_buffer_length - urb->actual_length);
if (!(control & SL11H_HCTLMASK_ISOCH)
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -1498,7 +1498,7 @@ __acquires(uhci->lock)
 		 * complete successfully.  Either it failed or the URB was
 		 * unlinked first.  Regardless, don't confuse people with a
 		 * negative length. */
-		urb->actual_length = max(urb->actual_length, 0);
+		urb->actual_length = max(urb->actual_length, (u32)0);

   Why this is needed?

 	}
/* When giving back the first URB in an Isochronous queue,
--- a/drivers/usb/misc/ftdi-elan.c
+++ b/drivers/usb/misc/ftdi-elan.c
@@ -1702,7 +1702,7 @@ static int ftdi_elan_edset_output(struct
                                 | (address << 0);
                         command->width = usb_maxpacket(urb->dev, urb->pipe,
                                 usb_pipeout(urb->pipe));
-                        command->follows = min(1024,
+                        command->follows = min((u32)1024,

   And this?

                                 urb->transfer_buffer_length -
                                 urb->actual_length);
                         command->value = 0;
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -1942,7 +1942,7 @@ static void ftdi_process_read(struct wor
 			priv->prev_status = new_status;
 		}
- length = min(PKTSZ, urb->actual_length-packet_offset)-2;
+		length = min((u32)PKTSZ, urb->actual_length-packet_offset)-2;

   And this?
   In any case, min_t() would seem preferrable...

WBR, Sergei
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux