free_async(as);
                        return -ENOMEM;
                }
+               /* Isochronous input data may end up being discontiguous
+                * if some of the packets are short.  Clear the buffer so
+                * that the gaps don't leak kernel data to userspace.
+                */
+               if (is_in && uurb->type == USBDEVFS_URB_TYPE_ISO)
+                       memset(as->urb->transfer_buffer, 0,
+                                       uurb->buffer_length);
        }
        as->urb->dev = ps->dev;
        as->urb->pipe = (uurb->type << 30) |
        void __user *addr = as->userurb;
        unsigned int i;
 
-       if (as->userbuffer && urb->actual_length)
-               if (copy_to_user(as->userbuffer, urb->transfer_buffer,
-                                urb->actual_length))
+       if (as->userbuffer && urb->actual_length) {
+               if (urb->number_of_packets > 0)         /* Isochronous */
+                       i = urb->transfer_buffer_length;
+               else                                    /* Non-Isoc */
+                       i = urb->actual_length;
+               if (copy_to_user(as->userbuffer, urb->transfer_buffer, i))
                        goto err_out;
+       }
        if (put_user(as->status, &userurb->status))
                goto err_out;
        if (put_user(urb->actual_length, &userurb->actual_length))