aboutsummaryrefslogtreecommitdiffstats
path: root/queue-5.15
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-04-01 16:52:59 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-04-01 16:52:59 +0200
commitea614c9ace53808156f1faf9742d4e4e1e76deb2 (patch)
tree5f8d81fa9ad564d79644954b029c0e7fed6c88c1 /queue-5.15
parente50e02f7ebf51e5a5f317e874df46c26d9e042cf (diff)
downloadstable-queue-ea614c9ace53808156f1faf9742d4e4e1e76deb2.tar.gz
5.15-stable patches
added patches: usb-core-fix-deadlock-in-usb_deauthorize_interface.patch
Diffstat (limited to 'queue-5.15')
-rw-r--r--queue-5.15/series1
-rw-r--r--queue-5.15/usb-core-fix-deadlock-in-usb_deauthorize_interface.patch70
2 files changed, 71 insertions, 0 deletions
diff --git a/queue-5.15/series b/queue-5.15/series
index fe8805f92e..f3ec76e282 100644
--- a/queue-5.15/series
+++ b/queue-5.15/series
@@ -603,3 +603,4 @@ scsi-qla2xxx-delay-i-o-abort-on-pci-error.patch
x86-cpu-enable-stibp-on-amd-if-automatic-ibrs-is-enabled.patch
pci-dpc-quirk-pio-log-size-for-intel-ice-lake-root-ports.patch
scsi-lpfc-correct-size-for-wqe-for-memset.patch
+usb-core-fix-deadlock-in-usb_deauthorize_interface.patch
diff --git a/queue-5.15/usb-core-fix-deadlock-in-usb_deauthorize_interface.patch b/queue-5.15/usb-core-fix-deadlock-in-usb_deauthorize_interface.patch
new file mode 100644
index 0000000000..35b9d573d5
--- /dev/null
+++ b/queue-5.15/usb-core-fix-deadlock-in-usb_deauthorize_interface.patch
@@ -0,0 +1,70 @@
+From 80ba43e9f799cbdd83842fc27db667289b3150f5 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 12 Mar 2024 11:48:23 -0400
+Subject: USB: core: Fix deadlock in usb_deauthorize_interface()
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 80ba43e9f799cbdd83842fc27db667289b3150f5 upstream.
+
+Among the attribute file callback routines in
+drivers/usb/core/sysfs.c, the interface_authorized_store() function is
+the only one which acquires a device lock on an ancestor device: It
+calls usb_deauthorize_interface(), which locks the interface's parent
+USB device.
+
+The will lead to deadlock if another process already owns that lock
+and tries to remove the interface, whether through a configuration
+change or because the device has been disconnected. As part of the
+removal procedure, device_del() waits for all ongoing sysfs attribute
+callbacks to complete. But usb_deauthorize_interface() can't complete
+until the device lock has been released, and the lock won't be
+released until the removal has finished.
+
+The mechanism provided by sysfs to prevent this kind of deadlock is
+to use the sysfs_break_active_protection() function, which tells sysfs
+not to wait for the attribute callback.
+
+Reported-and-tested by: Yue Sun <samsun1006219@gmail.com>
+Reported by: xingwei lee <xrivendell7@gmail.com>
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/linux-usb/CAEkJfYO6jRVC8Tfrd_R=cjO0hguhrV31fDPrLrNOOHocDkPoAA@mail.gmail.com/#r
+Fixes: 310d2b4124c0 ("usb: interface authorization: SysFS part of USB interface authorization")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/1c37eea1-9f56-4534-b9d8-b443438dc869@rowland.harvard.edu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/sysfs.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/core/sysfs.c
++++ b/drivers/usb/core/sysfs.c
+@@ -1169,14 +1169,24 @@ static ssize_t interface_authorized_stor
+ {
+ struct usb_interface *intf = to_usb_interface(dev);
+ bool val;
++ struct kernfs_node *kn;
+
+ if (strtobool(buf, &val) != 0)
+ return -EINVAL;
+
+- if (val)
++ if (val) {
+ usb_authorize_interface(intf);
+- else
+- usb_deauthorize_interface(intf);
++ } else {
++ /*
++ * Prevent deadlock if another process is concurrently
++ * trying to unregister intf.
++ */
++ kn = sysfs_break_active_protection(&dev->kobj, &attr->attr);
++ if (kn) {
++ usb_deauthorize_interface(intf);
++ sysfs_unbreak_active_protection(kn);
++ }
++ }
+
+ return count;
+ }