diff options
Diffstat (limited to 'libre/linux-libre/0004-xhci-Fix-USB3-NULL-pointer-dereference-at-logical-di.patch')
-rw-r--r-- | libre/linux-libre/0004-xhci-Fix-USB3-NULL-pointer-dereference-at-logical-di.patch | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/libre/linux-libre/0004-xhci-Fix-USB3-NULL-pointer-dereference-at-logical-di.patch b/libre/linux-libre/0004-xhci-Fix-USB3-NULL-pointer-dereference-at-logical-di.patch new file mode 100644 index 000000000..009251cb3 --- /dev/null +++ b/libre/linux-libre/0004-xhci-Fix-USB3-NULL-pointer-dereference-at-logical-di.patch @@ -0,0 +1,63 @@ +From 005c2f4576d9bab5ff97dac4b3d27aafa2f1f153 Mon Sep 17 00:00:00 2001 +Message-Id: <005c2f4576d9bab5ff97dac4b3d27aafa2f1f153.1526520264.git.jan.steffens@gmail.com> +In-Reply-To: <1d8e17daf031e219d904ef93718081534c9e8cea.1526520263.git.jan.steffens@gmail.com> +References: <1d8e17daf031e219d904ef93718081534c9e8cea.1526520263.git.jan.steffens@gmail.com> +From: Mathias Nyman <mathias.nyman@linux.intel.com> +Date: Mon, 14 May 2018 11:57:23 +0300 +Subject: [PATCH 4/4] xhci: Fix USB3 NULL pointer dereference at logical + disconnect. + +Hub driver will try to disable a USB3 device twice at logical disconnect, +racing with xhci_free_dev() callback from the first port disable. + +This can be triggered with "udisksctl power-off --block-device <disk>" +or by writing "1" to the "remove" sysfs file for a USB3 device +in 4.17-rc4. + +USB3 devices don't have a similar disabled link state as USB2 devices, +and use a U3 suspended link state instead. In this state the port +is still enabled and connected. + +hub_port_connect() first disconnects the device, then later it notices +that device is still enabled (due to U3 states) it will try to disable +the port again (set to U3). + +The xhci_free_dev() called during device disable is async, so checking +for existing xhci->devs[i] when setting link state to U3 the second time +was successful, even if device was being freed. + +The regression was caused by, and whole thing revealed by, +Commit 44a182b9d177 ("xhci: Fix use-after-free in xhci_free_virt_device") +which sets xhci->devs[i]->udev to NULL before xhci_virt_dev() returned. +and causes a NULL pointer dereference the second time we try to set U3. + +Fix this by checking xhci->devs[i]->udev exists before setting link state. + +The original patch went to stable so this fix needs to be applied there as +well. + +Fixes: 44a182b9d177 ("xhci: Fix use-after-free in xhci_free_virt_device") +Cc: <stable@vger.kernel.org> +Reported-by: Jordan Glover <Golden_Miller83@protonmail.ch> +Tested-by: Jordan Glover <Golden_Miller83@protonmail.ch> +Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> +--- + drivers/usb/host/xhci-hub.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c +index 72ebbc908e19..32cd52ca8318 100644 +--- a/drivers/usb/host/xhci-hub.c ++++ b/drivers/usb/host/xhci-hub.c +@@ -354,7 +354,7 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, + + slot_id = 0; + for (i = 0; i < MAX_HC_SLOTS; i++) { +- if (!xhci->devs[i]) ++ if (!xhci->devs[i] || !xhci->devs[i]->udev) + continue; + speed = xhci->devs[i]->udev->speed; + if (((speed >= USB_SPEED_SUPER) == (hcd->speed >= HCD_USB3)) +-- +2.17.0 + |