aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2009-11-04 11:35:53 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-11-17 19:46:34 -0500
commitfca94748c5136ff390eadc443871b82f1f77dcd6 (patch)
tree494d3707070aaf4dd952e2bd69f69c76012cc905 /drivers/usb
parent5294bea40666db5c5d6c336b8e4e55d69fa576ca (diff)
USB: usbmon: fix bug in mon_buff_area_shrink
This patch (as1299b) fixes a bug in an error-handling path of usbmon's binary interface. The storage area for URB data is divided into fixed-size blocks. If an URB's data can't be copied, the area reserved for it should be decreased to the size of the truncated information (rounded up to a block boundary). Rounding up the amount to be removed and subtracting it from the reserved size is definitely the wrong thing to do. Also, when the data for an isochronous URB can't be copied, we can still copy the isoc packet descriptors. In fact the current code does copy the descriptors, but then sets the capture length to 0 so they remain inaccessible. The capture length should be reduced to the length of the descriptors, not set to 0. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Acked-by: Pete Zaitcev <zaitcev@redhat.com> CC: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/mon/mon_bin.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
index 9ed3e741bee1..10f3205798e8 100644
--- a/drivers/usb/mon/mon_bin.c
+++ b/drivers/usb/mon/mon_bin.c
@@ -348,12 +348,12 @@ static unsigned int mon_buff_area_alloc_contiguous(struct mon_reader_bin *rp,
348 348
349/* 349/*
350 * Return a few (kilo-)bytes to the head of the buffer. 350 * Return a few (kilo-)bytes to the head of the buffer.
351 * This is used if a DMA fetch fails. 351 * This is used if a data fetch fails.
352 */ 352 */
353static void mon_buff_area_shrink(struct mon_reader_bin *rp, unsigned int size) 353static void mon_buff_area_shrink(struct mon_reader_bin *rp, unsigned int size)
354{ 354{
355 355
356 size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); 356 /* size &= ~(PKT_ALIGN-1); -- we're called with aligned size */
357 rp->b_cnt -= size; 357 rp->b_cnt -= size;
358 if (rp->b_in < size) 358 if (rp->b_in < size)
359 rp->b_in += rp->b_size; 359 rp->b_in += rp->b_size;
@@ -433,6 +433,7 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
433 unsigned int urb_length; 433 unsigned int urb_length;
434 unsigned int offset; 434 unsigned int offset;
435 unsigned int length; 435 unsigned int length;
436 unsigned int delta;
436 unsigned int ndesc, lendesc; 437 unsigned int ndesc, lendesc;
437 unsigned char dir; 438 unsigned char dir;
438 struct mon_bin_hdr *ep; 439 struct mon_bin_hdr *ep;
@@ -537,8 +538,10 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
537 if (length != 0) { 538 if (length != 0) {
538 ep->flag_data = mon_bin_get_data(rp, offset, urb, length); 539 ep->flag_data = mon_bin_get_data(rp, offset, urb, length);
539 if (ep->flag_data != 0) { /* Yes, it's 0x00, not '0' */ 540 if (ep->flag_data != 0) { /* Yes, it's 0x00, not '0' */
540 ep->len_cap = 0; 541 delta = (ep->len_cap + PKT_ALIGN-1) & ~(PKT_ALIGN-1);
541 mon_buff_area_shrink(rp, length); 542 ep->len_cap -= length;
543 delta -= (ep->len_cap + PKT_ALIGN-1) & ~(PKT_ALIGN-1);
544 mon_buff_area_shrink(rp, delta);
542 } 545 }
543 } else { 546 } else {
544 ep->flag_data = data_tag; 547 ep->flag_data = data_tag;