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