Skip to content

Commit

Permalink
usbip: stub-dev synchronize sysfs code paths
Browse files Browse the repository at this point in the history
commit 9dbf34a upstream.

Fuzzing uncovered race condition between sysfs code paths in usbip
drivers. Device connect/disconnect code paths initiated through
sysfs interface are prone to races if disconnect happens during
connect and vice versa.

Use sysfs_lock to protect sysfs paths in stub-dev.

Cc: stable@vger.kernel.org
Reported-and-tested-by: syzbot+a93fba6d384346a761e3@syzkaller.appspotmail.com
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
Link: https://lore.kernel.org/r/2b182f3561b4a065bf3bf6dce3b0e9944ba17b3f.1616807117.git.skhan@linuxfoundation.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
shuahkh authored and gregkh committed Apr 14, 2021
1 parent 32fa347 commit 4f72d80
Showing 1 changed file with 9 additions and 2 deletions.
11 changes: 9 additions & 2 deletions drivers/usb/usbip/stub_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *a

dev_info(dev, "stub up\n");

mutex_lock(&sdev->ud.sysfs_lock);
spin_lock_irq(&sdev->ud.lock);

if (sdev->ud.status != SDEV_ST_AVAILABLE) {
Expand All @@ -87,13 +88,13 @@ static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *a
tcp_rx = kthread_create(stub_rx_loop, &sdev->ud, "stub_rx");
if (IS_ERR(tcp_rx)) {
sockfd_put(socket);
return -EINVAL;
goto unlock_mutex;
}
tcp_tx = kthread_create(stub_tx_loop, &sdev->ud, "stub_tx");
if (IS_ERR(tcp_tx)) {
kthread_stop(tcp_rx);
sockfd_put(socket);
return -EINVAL;
goto unlock_mutex;
}

/* get task structs now */
Expand All @@ -112,6 +113,8 @@ static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *a
wake_up_process(sdev->ud.tcp_rx);
wake_up_process(sdev->ud.tcp_tx);

mutex_unlock(&sdev->ud.sysfs_lock);

} else {
dev_info(dev, "stub down\n");

Expand All @@ -122,6 +125,7 @@ static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *a
spin_unlock_irq(&sdev->ud.lock);

usbip_event_add(&sdev->ud, SDEV_EVENT_DOWN);
mutex_unlock(&sdev->ud.sysfs_lock);
}

return count;
Expand All @@ -130,6 +134,8 @@ static ssize_t usbip_sockfd_store(struct device *dev, struct device_attribute *a
sockfd_put(socket);
err:
spin_unlock_irq(&sdev->ud.lock);
unlock_mutex:
mutex_unlock(&sdev->ud.sysfs_lock);
return -EINVAL;
}
static DEVICE_ATTR_WO(usbip_sockfd);
Expand Down Expand Up @@ -270,6 +276,7 @@ static struct stub_device *stub_device_alloc(struct usb_device *udev)
sdev->ud.side = USBIP_STUB;
sdev->ud.status = SDEV_ST_AVAILABLE;
spin_lock_init(&sdev->ud.lock);
mutex_init(&sdev->ud.sysfs_lock);
sdev->ud.tcp_socket = NULL;
sdev->ud.sockfd = -1;

Expand Down

0 comments on commit 4f72d80

Please sign in to comment.