Commit 258c81b3 authored by Anirudh Rayabharam's avatar Anirudh Rayabharam Committed by Greg Kroah-Hartman

usbip: give back URBs for unsent unlink requests during cleanup

In vhci_device_unlink_cleanup(), the URBs for unsent unlink requests are
not given back. This sometimes causes usb_kill_urb to wait indefinitely
for that urb to be given back. syzbot has reported a hung task issue [1]
for this.

To fix this, give back the urbs corresponding to unsent unlink requests
(unlink_tx list) similar to how urbs corresponding to unanswered unlink
requests (unlink_rx list) are given back.

[1]: https://syzkaller.appspot.com/bug?id=08f12df95ae7da69814e64eb5515d5a85ed06b76

Reported-by: syzbot+74d6ef051d3d2eacf428@syzkaller.appspotmail.com
Tested-by: syzbot+74d6ef051d3d2eacf428@syzkaller.appspotmail.com
Reviewed-by: default avatarShuah Khan <skhan@linuxfoundation.org>
Signed-off-by: default avatarAnirudh Rayabharam <mail@anirudhrb.com>
Link: https://lore.kernel.org/r/20210820190122.16379-2-mail@anirudhrb.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 5786b433
...@@ -957,8 +957,32 @@ static void vhci_device_unlink_cleanup(struct vhci_device *vdev) ...@@ -957,8 +957,32 @@ static void vhci_device_unlink_cleanup(struct vhci_device *vdev)
spin_lock(&vdev->priv_lock); spin_lock(&vdev->priv_lock);
list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) { list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) {
struct urb *urb;
/* give back urb of unsent unlink request */
pr_info("unlink cleanup tx %lu\n", unlink->unlink_seqnum); pr_info("unlink cleanup tx %lu\n", unlink->unlink_seqnum);
urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum);
if (!urb) {
list_del(&unlink->list);
kfree(unlink);
continue;
}
urb->status = -ENODEV;
usb_hcd_unlink_urb_from_ep(hcd, urb);
list_del(&unlink->list); list_del(&unlink->list);
spin_unlock(&vdev->priv_lock);
spin_unlock_irqrestore(&vhci->lock, flags);
usb_hcd_giveback_urb(hcd, urb, urb->status);
spin_lock_irqsave(&vhci->lock, flags);
spin_lock(&vdev->priv_lock);
kfree(unlink); kfree(unlink);
} }
......
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