]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 11 Apr 2021 07:25:54 +0000 (09:25 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 11 Apr 2021 07:25:54 +0000 (09:25 +0200)
added patches:
i2c-turn-recovery-error-on-init-to-debug.patch
usbip-add-sysfs_lock-to-synchronize-sysfs-code-paths.patch
usbip-stub-dev-synchronize-sysfs-code-paths.patch
usbip-synchronize-event-handler-with-sysfs-code-paths.patch
usbip-vudc-synchronize-sysfs-code-paths.patch

queue-5.4/i2c-turn-recovery-error-on-init-to-debug.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/usbip-add-sysfs_lock-to-synchronize-sysfs-code-paths.patch [new file with mode: 0644]
queue-5.4/usbip-stub-dev-synchronize-sysfs-code-paths.patch [new file with mode: 0644]
queue-5.4/usbip-synchronize-event-handler-with-sysfs-code-paths.patch [new file with mode: 0644]
queue-5.4/usbip-vudc-synchronize-sysfs-code-paths.patch [new file with mode: 0644]

diff --git a/queue-5.4/i2c-turn-recovery-error-on-init-to-debug.patch b/queue-5.4/i2c-turn-recovery-error-on-init-to-debug.patch
new file mode 100644 (file)
index 0000000..3e02056
--- /dev/null
@@ -0,0 +1,51 @@
+From e409a6a3e0690efdef9b8a96197bc61ff117cfaf Mon Sep 17 00:00:00 2001
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Date: Mon, 15 Mar 2021 12:50:08 +0100
+Subject: i2c: turn recovery error on init to debug
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+commit e409a6a3e0690efdef9b8a96197bc61ff117cfaf upstream.
+
+In some configurations, recovery is optional. So, don't throw an error
+when it is not used because e.g. pinctrl settings for recovery are not
+provided. Reword the message and make it debug output.
+
+Reported-by: Klaus Kudielka <klaus.kudielka@gmail.com>
+Tested-by: Klaus Kudielka <klaus.kudielka@gmail.com>
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/i2c/i2c-core-base.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/i2c/i2c-core-base.c
++++ b/drivers/i2c/i2c-core-base.c
+@@ -254,13 +254,14 @@ EXPORT_SYMBOL_GPL(i2c_recover_bus);
+ static void i2c_init_recovery(struct i2c_adapter *adap)
+ {
+       struct i2c_bus_recovery_info *bri = adap->bus_recovery_info;
+-      char *err_str;
++      char *err_str, *err_level = KERN_ERR;
+       if (!bri)
+               return;
+       if (!bri->recover_bus) {
+-              err_str = "no recover_bus() found";
++              err_str = "no suitable method provided";
++              err_level = KERN_DEBUG;
+               goto err;
+       }
+@@ -290,7 +291,7 @@ static void i2c_init_recovery(struct i2c
+       return;
+  err:
+-      dev_err(&adap->dev, "Not using recovery: %s\n", err_str);
++      dev_printk(err_level, &adap->dev, "Not using recovery: %s\n", err_str);
+       adap->bus_recovery_info = NULL;
+ }
index 41bc997ae448f75d147b7e3e1eef935bc107d097..28bf6d8dbd171441d071543cbef082966dd17b2e 100644 (file)
@@ -33,4 +33,9 @@ mac80211-fix-txq-ac-confusion.patch
 net-hsr-reset-mac-header-for-tx-path.patch
 net-ipv6-bugfix-raw-sctp-switch-to-ipv6_can_nonlocal_bind.patch
 net-let-skb_orphan_partial-wake-up-waiters.patch
+usbip-add-sysfs_lock-to-synchronize-sysfs-code-paths.patch
+usbip-stub-dev-synchronize-sysfs-code-paths.patch
+usbip-vudc-synchronize-sysfs-code-paths.patch
+usbip-synchronize-event-handler-with-sysfs-code-paths.patch
+i2c-turn-recovery-error-on-init-to-debug.patch
 net-sched-fix-action-overwrite-reference-counting.patch
diff --git a/queue-5.4/usbip-add-sysfs_lock-to-synchronize-sysfs-code-paths.patch b/queue-5.4/usbip-add-sysfs_lock-to-synchronize-sysfs-code-paths.patch
new file mode 100644 (file)
index 0000000..13402c5
--- /dev/null
@@ -0,0 +1,149 @@
+From 4e9c93af7279b059faf5bb1897ee90512b258a12 Mon Sep 17 00:00:00 2001
+From: Shuah Khan <skhan@linuxfoundation.org>
+Date: Mon, 29 Mar 2021 19:36:48 -0600
+Subject: usbip: add sysfs_lock to synchronize sysfs code paths
+
+From: Shuah Khan <skhan@linuxfoundation.org>
+
+commit 4e9c93af7279b059faf5bb1897ee90512b258a12 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.
+
+This problem is common to all drivers while it can be reproduced easily
+in vhci_hcd. Add a sysfs_lock to usbip_device struct to protect the paths.
+
+Use this in vhci_hcd to protect sysfs paths. For a complete fix, usip_host
+and usip-vudc drivers and the event handler will have to use this lock to
+protect the paths. These changes will be done in subsequent patches.
+
+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/b6568f7beae702bbc236a545d3c020106ca75eac.1616807117.git.skhan@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/usbip/usbip_common.h |    3 +++
+ drivers/usb/usbip/vhci_hcd.c     |    1 +
+ drivers/usb/usbip/vhci_sysfs.c   |   30 +++++++++++++++++++++++++-----
+ 3 files changed, 29 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/usbip/usbip_common.h
++++ b/drivers/usb/usbip/usbip_common.h
+@@ -263,6 +263,9 @@ struct usbip_device {
+       /* lock for status */
+       spinlock_t lock;
++      /* mutex for synchronizing sysfs store paths */
++      struct mutex sysfs_lock;
++
+       int sockfd;
+       struct socket *tcp_socket;
+--- a/drivers/usb/usbip/vhci_hcd.c
++++ b/drivers/usb/usbip/vhci_hcd.c
+@@ -1096,6 +1096,7 @@ static void vhci_device_init(struct vhci
+       vdev->ud.side   = USBIP_VHCI;
+       vdev->ud.status = VDEV_ST_NULL;
+       spin_lock_init(&vdev->ud.lock);
++      mutex_init(&vdev->ud.sysfs_lock);
+       INIT_LIST_HEAD(&vdev->priv_rx);
+       INIT_LIST_HEAD(&vdev->priv_tx);
+--- a/drivers/usb/usbip/vhci_sysfs.c
++++ b/drivers/usb/usbip/vhci_sysfs.c
+@@ -185,6 +185,8 @@ static int vhci_port_disconnect(struct v
+       usbip_dbg_vhci_sysfs("enter\n");
++      mutex_lock(&vdev->ud.sysfs_lock);
++
+       /* lock */
+       spin_lock_irqsave(&vhci->lock, flags);
+       spin_lock(&vdev->ud.lock);
+@@ -195,6 +197,7 @@ static int vhci_port_disconnect(struct v
+               /* unlock */
+               spin_unlock(&vdev->ud.lock);
+               spin_unlock_irqrestore(&vhci->lock, flags);
++              mutex_unlock(&vdev->ud.sysfs_lock);
+               return -EINVAL;
+       }
+@@ -205,6 +208,8 @@ static int vhci_port_disconnect(struct v
+       usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN);
++      mutex_unlock(&vdev->ud.sysfs_lock);
++
+       return 0;
+ }
+@@ -349,30 +354,36 @@ static ssize_t attach_store(struct devic
+       else
+               vdev = &vhci->vhci_hcd_hs->vdev[rhport];
++      mutex_lock(&vdev->ud.sysfs_lock);
++
+       /* Extract socket from fd. */
+       socket = sockfd_lookup(sockfd, &err);
+       if (!socket) {
+               dev_err(dev, "failed to lookup sock");
+-              return -EINVAL;
++              err = -EINVAL;
++              goto unlock_mutex;
+       }
+       if (socket->type != SOCK_STREAM) {
+               dev_err(dev, "Expecting SOCK_STREAM - found %d",
+                       socket->type);
+               sockfd_put(socket);
+-              return -EINVAL;
++              err = -EINVAL;
++              goto unlock_mutex;
+       }
+       /* create threads before locking */
+       tcp_rx = kthread_create(vhci_rx_loop, &vdev->ud, "vhci_rx");
+       if (IS_ERR(tcp_rx)) {
+               sockfd_put(socket);
+-              return -EINVAL;
++              err = -EINVAL;
++              goto unlock_mutex;
+       }
+       tcp_tx = kthread_create(vhci_tx_loop, &vdev->ud, "vhci_tx");
+       if (IS_ERR(tcp_tx)) {
+               kthread_stop(tcp_rx);
+               sockfd_put(socket);
+-              return -EINVAL;
++              err = -EINVAL;
++              goto unlock_mutex;
+       }
+       /* get task structs now */
+@@ -397,7 +408,8 @@ static ssize_t attach_store(struct devic
+                * Will be retried from userspace
+                * if there's another free port.
+                */
+-              return -EBUSY;
++              err = -EBUSY;
++              goto unlock_mutex;
+       }
+       dev_info(dev, "pdev(%u) rhport(%u) sockfd(%d)\n",
+@@ -422,7 +434,15 @@ static ssize_t attach_store(struct devic
+       rh_port_connect(vdev, speed);
++      dev_info(dev, "Device attached\n");
++
++      mutex_unlock(&vdev->ud.sysfs_lock);
++
+       return count;
++
++unlock_mutex:
++      mutex_unlock(&vdev->ud.sysfs_lock);
++      return err;
+ }
+ static DEVICE_ATTR_WO(attach);
diff --git a/queue-5.4/usbip-stub-dev-synchronize-sysfs-code-paths.patch b/queue-5.4/usbip-stub-dev-synchronize-sysfs-code-paths.patch
new file mode 100644 (file)
index 0000000..bfe8f6b
--- /dev/null
@@ -0,0 +1,85 @@
+From 9dbf34a834563dada91366c2ac266f32ff34641a Mon Sep 17 00:00:00 2001
+From: Shuah Khan <skhan@linuxfoundation.org>
+Date: Mon, 29 Mar 2021 19:36:49 -0600
+Subject: usbip: stub-dev synchronize sysfs code paths
+
+From: Shuah Khan <skhan@linuxfoundation.org>
+
+commit 9dbf34a834563dada91366c2ac266f32ff34641a 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>
+---
+ drivers/usb/usbip/stub_dev.c |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/usbip/stub_dev.c
++++ b/drivers/usb/usbip/stub_dev.c
+@@ -63,6 +63,7 @@ static ssize_t usbip_sockfd_store(struct
+               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) {
+@@ -87,13 +88,13 @@ static ssize_t usbip_sockfd_store(struct
+               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 */
+@@ -112,6 +113,8 @@ static ssize_t usbip_sockfd_store(struct
+               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");
+@@ -122,6 +125,7 @@ static ssize_t usbip_sockfd_store(struct
+               spin_unlock_irq(&sdev->ud.lock);
+               usbip_event_add(&sdev->ud, SDEV_EVENT_DOWN);
++              mutex_unlock(&sdev->ud.sysfs_lock);
+       }
+       return count;
+@@ -130,6 +134,8 @@ sock_err:
+       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);
+@@ -270,6 +276,7 @@ static struct stub_device *stub_device_a
+       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;
diff --git a/queue-5.4/usbip-synchronize-event-handler-with-sysfs-code-paths.patch b/queue-5.4/usbip-synchronize-event-handler-with-sysfs-code-paths.patch
new file mode 100644 (file)
index 0000000..5f0818c
--- /dev/null
@@ -0,0 +1,44 @@
+From 363eaa3a450abb4e63bd6e3ad79d1f7a0f717814 Mon Sep 17 00:00:00 2001
+From: Shuah Khan <skhan@linuxfoundation.org>
+Date: Mon, 29 Mar 2021 19:36:51 -0600
+Subject: usbip: synchronize event handler with sysfs code paths
+
+From: Shuah Khan <skhan@linuxfoundation.org>
+
+commit 363eaa3a450abb4e63bd6e3ad79d1f7a0f717814 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 synchronize event handler with sysfs paths
+in usbip drivers.
+
+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/c5c8723d3f29dfe3d759cfaafa7dd16b0dfe2918.1616807117.git.skhan@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/usbip/usbip_event.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/usbip/usbip_event.c
++++ b/drivers/usb/usbip/usbip_event.c
+@@ -70,6 +70,7 @@ static void event_handler(struct work_st
+       while ((ud = get_event()) != NULL) {
+               usbip_dbg_eh("pending event %lx\n", ud->event);
++              mutex_lock(&ud->sysfs_lock);
+               /*
+                * NOTE: shutdown must come first.
+                * Shutdown the device.
+@@ -90,6 +91,7 @@ static void event_handler(struct work_st
+                       ud->eh_ops.unusable(ud);
+                       unset_event(ud, USBIP_EH_UNUSABLE);
+               }
++              mutex_unlock(&ud->sysfs_lock);
+               wake_up(&ud->eh_waitq);
+       }
diff --git a/queue-5.4/usbip-vudc-synchronize-sysfs-code-paths.patch b/queue-5.4/usbip-vudc-synchronize-sysfs-code-paths.patch
new file mode 100644 (file)
index 0000000..fa70cd2
--- /dev/null
@@ -0,0 +1,71 @@
+From bd8b82042269a95db48074b8bb400678dbac1815 Mon Sep 17 00:00:00 2001
+From: Shuah Khan <skhan@linuxfoundation.org>
+Date: Mon, 29 Mar 2021 19:36:50 -0600
+Subject: usbip: vudc synchronize sysfs code paths
+
+From: Shuah Khan <skhan@linuxfoundation.org>
+
+commit bd8b82042269a95db48074b8bb400678dbac1815 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 vudc.
+
+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/caabcf3fc87bdae970509b5ff32d05bb7ce2fb15.1616807117.git.skhan@linuxfoundation.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/usbip/vudc_dev.c   |    1 +
+ drivers/usb/usbip/vudc_sysfs.c |    5 +++++
+ 2 files changed, 6 insertions(+)
+
+--- a/drivers/usb/usbip/vudc_dev.c
++++ b/drivers/usb/usbip/vudc_dev.c
+@@ -572,6 +572,7 @@ static int init_vudc_hw(struct vudc *udc
+       init_waitqueue_head(&udc->tx_waitq);
+       spin_lock_init(&ud->lock);
++      mutex_init(&ud->sysfs_lock);
+       ud->status = SDEV_ST_AVAILABLE;
+       ud->side = USBIP_VUDC;
+--- a/drivers/usb/usbip/vudc_sysfs.c
++++ b/drivers/usb/usbip/vudc_sysfs.c
+@@ -112,6 +112,7 @@ static ssize_t usbip_sockfd_store(struct
+               dev_err(dev, "no device");
+               return -ENODEV;
+       }
++      mutex_lock(&udc->ud.sysfs_lock);
+       spin_lock_irqsave(&udc->lock, flags);
+       /* Don't export what we don't have */
+       if (!udc->driver || !udc->pullup) {
+@@ -187,6 +188,8 @@ static ssize_t usbip_sockfd_store(struct
+               wake_up_process(udc->ud.tcp_rx);
+               wake_up_process(udc->ud.tcp_tx);
++
++              mutex_unlock(&udc->ud.sysfs_lock);
+               return count;
+       } else {
+@@ -207,6 +210,7 @@ static ssize_t usbip_sockfd_store(struct
+       }
+       spin_unlock_irqrestore(&udc->lock, flags);
++      mutex_unlock(&udc->ud.sysfs_lock);
+       return count;
+@@ -216,6 +220,7 @@ unlock_ud:
+       spin_unlock_irq(&udc->ud.lock);
+ unlock:
+       spin_unlock_irqrestore(&udc->lock, flags);
++      mutex_unlock(&udc->ud.sysfs_lock);
+       return ret;
+ }