Commit 3ecdb9ac authored by Sergei Shtylyov's avatar Sergei Shtylyov Committed by Greg Kroah-Hartman

USB: musb: be careful with 64K+ transfer lengths, host side

Feeding 32-bit length cast down to 'u16' to min() to calculate the FIFO
count in musb_host_tx() risks sending a short packet prematurely for
transfer sizes over 64 KB.

Similarly, although data transfer size shouldn't exceed 65535 bytes for
the control endpoint, making musb_h_ep0_continue() more robust WRT URBs
with possibly oversized buffer will not hurt either...
Signed-off-by: default avatarSergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Cc: Felipe Balbi <felipe.balbi@nokia.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 51d9f3e1
...@@ -937,8 +937,8 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb) ...@@ -937,8 +937,8 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb)
switch (musb->ep0_stage) { switch (musb->ep0_stage) {
case MUSB_EP0_IN: case MUSB_EP0_IN:
fifo_dest = urb->transfer_buffer + urb->actual_length; fifo_dest = urb->transfer_buffer + urb->actual_length;
fifo_count = min(len, ((u16) (urb->transfer_buffer_length fifo_count = min_t(size_t, len, urb->transfer_buffer_length -
- urb->actual_length))); urb->actual_length);
if (fifo_count < len) if (fifo_count < len)
urb->status = -EOVERFLOW; urb->status = -EOVERFLOW;
...@@ -971,10 +971,9 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb) ...@@ -971,10 +971,9 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb)
} }
/* FALLTHROUGH */ /* FALLTHROUGH */
case MUSB_EP0_OUT: case MUSB_EP0_OUT:
fifo_count = min(qh->maxpacket, ((u16) fifo_count = min_t(size_t, qh->maxpacket,
(urb->transfer_buffer_length urb->transfer_buffer_length -
- urb->actual_length))); urb->actual_length);
if (fifo_count) { if (fifo_count) {
fifo_dest = (u8 *) (urb->transfer_buffer fifo_dest = (u8 *) (urb->transfer_buffer
+ urb->actual_length); + urb->actual_length);
...@@ -1304,7 +1303,8 @@ void musb_host_tx(struct musb *musb, u8 epnum) ...@@ -1304,7 +1303,8 @@ void musb_host_tx(struct musb *musb, u8 epnum)
* packets before updating TXCSR ... other docs disagree ... * packets before updating TXCSR ... other docs disagree ...
*/ */
/* PIO: start next packet in this URB */ /* PIO: start next packet in this URB */
wLength = min(qh->maxpacket, (u16) wLength); if (wLength > qh->maxpacket)
wLength = qh->maxpacket;
musb_write_fifo(hw_ep, wLength, buf); musb_write_fifo(hw_ep, wLength, buf);
qh->segsize = wLength; qh->segsize = wLength;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment