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

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

 



On Wed, Mar 04, 2009 at 10:55:42AM -0500, Alan Stern wrote:
> On Tue, 3 Mar 2009, Greg KH wrote:
> 
> > And here's the patch that I just applied to the usb patch queue to
> > resolve this issue.
> > 
> > Any objections?
> 
> > --- 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);
> >  	}
> >  
> >  	/* When giving back the first URB in an Isochronous queue,
> 
> As other people have noticed, this change makes no sense.  The 
> appropriate change is given below.
> 
> Alan Stern
> 
> 
> 
> Index: usb-2.6/drivers/usb/host/uhci-q.c
> ===================================================================
> --- usb-2.6.orig/drivers/usb/host/uhci-q.c
> +++ usb-2.6/drivers/usb/host/uhci-q.c
> @@ -900,7 +900,7 @@ static int uhci_submit_control(struct uh
>  	if (qh->state != QH_STATE_ACTIVE)
>  		qh->skel = skel;
>  
> -	urb->actual_length = -8;	/* Account for the SETUP packet */
> +	urb->actual_length = (u32) -8;	/* Account for the SETUP packet */

Oh horrors.

How about we just leave actual_length as int to allow this to work
properly?  Putting a negative value in an unsigned variable, while
workable, is just a mess.

How about the patch below instead for the whole thing?

thanks,

greg k-h


>From foo@baz Tue Mar  3 16:44:13 PST 2009
Date: Tue, 03 Mar 2009 16:44:13 -0800
To: Greg KH <greg@xxxxxxxxx>
From: Greg Kroah-Hartman <gregkh@xxxxxxx>
Subject: USB: make transfer_buffer_lengths in struct urb field u32

Roel Kluin pointed out that transfer_buffer_lengths in struct urb was
declared as an 'int'.  This patch changes this 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 macro, so they have also been fixed up in this
patch.

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

---
 drivers/usb/gadget/dummy_hcd.c  |    2 +-
 drivers/usb/host/isp116x-hcd.c  |    2 +-
 drivers/usb/host/r8a66597-hcd.c |    2 +-
 drivers/usb/host/sl811-hcd.c    |    4 ++--
 drivers/usb/misc/ftdi-elan.c    |    6 +++---
 include/linux/usb.h             |    2 +-
 6 files changed, 9 insertions(+), 9 deletions(-)

--- 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_t(u32, 2,
 						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_t(u32, ep->maxpacket,
 				 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_t(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_t(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_t(u32, ep->maxpacket,
 			urb->transfer_buffer_length - urb->actual_length);
 
 	if (!(control & SL11H_HCTLMASK_ISOCH)
--- a/drivers/usb/misc/ftdi-elan.c
+++ b/drivers/usb/misc/ftdi-elan.c
@@ -1568,7 +1568,7 @@ static int ftdi_elan_edset_input(struct 
                         struct u132_target *target = &ftdi->target[ed];
                         struct u132_command *command = &ftdi->command[
                                 COMMAND_MASK & ftdi->command_next];
-                        int remaining_length = urb->transfer_buffer_length -
+                        u32 remaining_length = urb->transfer_buffer_length -
                                 urb->actual_length;
                         command->header = 0x82 | (ed << 5);
                         if (remaining_length == 0) {
@@ -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_t(u32, 1024,
                                 urb->transfer_buffer_length -
                                 urb->actual_length);
                         command->value = 0;
@@ -1766,7 +1766,7 @@ static int ftdi_elan_edset_single(struct
                 mutex_lock(&ftdi->u132_lock);
                 command_size = ftdi->command_next - ftdi->command_head;
                 if (command_size < COMMAND_SIZE) {
-                        int remaining_length = urb->transfer_buffer_length -
+                        u32 remaining_length = urb->transfer_buffer_length -
                                 urb->actual_length;
                         struct u132_target *target = &ftdi->target[ed];
                         struct u132_command *command = &ftdi->command[
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -1177,7 +1177,7 @@ struct urb {
 	unsigned int transfer_flags;	/* (in) URB_SHORT_NOT_OK | ...*/
 	void *transfer_buffer;		/* (in) associated data buffer */
 	dma_addr_t transfer_dma;	/* (in) dma addr for transfer_buffer */
-	int transfer_buffer_length;	/* (in) data buffer length */
+	u32 transfer_buffer_length;	/* (in) data buffer length */
 	int actual_length;		/* (return) actual transfer length */
 	unsigned char *setup_packet;	/* (in) setup packet (control only) */
 	dma_addr_t setup_dma;		/* (in) dma addr for setup_packet */
--
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