diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/core/devio.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index e909ff7b9094..3466fdc5bb11 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -1207,6 +1207,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1207 | free_async(as); | 1207 | free_async(as); |
1208 | return -ENOMEM; | 1208 | return -ENOMEM; |
1209 | } | 1209 | } |
1210 | /* Isochronous input data may end up being discontiguous | ||
1211 | * if some of the packets are short. Clear the buffer so | ||
1212 | * that the gaps don't leak kernel data to userspace. | ||
1213 | */ | ||
1214 | if (is_in && uurb->type == USBDEVFS_URB_TYPE_ISO) | ||
1215 | memset(as->urb->transfer_buffer, 0, | ||
1216 | uurb->buffer_length); | ||
1210 | } | 1217 | } |
1211 | as->urb->dev = ps->dev; | 1218 | as->urb->dev = ps->dev; |
1212 | as->urb->pipe = (uurb->type << 30) | | 1219 | as->urb->pipe = (uurb->type << 30) | |
@@ -1345,10 +1352,14 @@ static int processcompl(struct async *as, void __user * __user *arg) | |||
1345 | void __user *addr = as->userurb; | 1352 | void __user *addr = as->userurb; |
1346 | unsigned int i; | 1353 | unsigned int i; |
1347 | 1354 | ||
1348 | if (as->userbuffer && urb->actual_length) | 1355 | if (as->userbuffer && urb->actual_length) { |
1349 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, | 1356 | if (urb->number_of_packets > 0) /* Isochronous */ |
1350 | urb->actual_length)) | 1357 | i = urb->transfer_buffer_length; |
1358 | else /* Non-Isoc */ | ||
1359 | i = urb->actual_length; | ||
1360 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, i)) | ||
1351 | goto err_out; | 1361 | goto err_out; |
1362 | } | ||
1352 | if (put_user(as->status, &userurb->status)) | 1363 | if (put_user(as->status, &userurb->status)) |
1353 | goto err_out; | 1364 | goto err_out; |
1354 | if (put_user(urb->actual_length, &userurb->actual_length)) | 1365 | if (put_user(urb->actual_length, &userurb->actual_length)) |