Skip to content

Commit af8e119

Browse files
matnymangregkh
authored andcommitted
xhci: Fix Panther point NULL pointer deref at full-speed re-enumeration
re-enumerating full-speed devices after a failed address device command can trigger a NULL pointer dereference. Full-speed devices may need to reconfigure the endpoint 0 Max Packet Size value during enumeration. Usb core calls usb_ep0_reinit() in this case, which ends up calling xhci_configure_endpoint(). On Panther point xHC the xhci_configure_endpoint() function will additionally check and reserve bandwidth in software. Other hosts do this in hardware If xHC address device command fails then a new xhci_virt_device structure is allocated as part of re-enabling the slot, but the bandwidth table pointers are not set up properly here. This triggers the NULL pointer dereference the next time usb_ep0_reinit() is called and xhci_configure_endpoint() tries to check and reserve bandwidth [46710.713538] usb 3-1: new full-speed USB device number 5 using xhci_hcd [46710.713699] usb 3-1: Device not responding to setup address. [46710.917684] usb 3-1: Device not responding to setup address. [46711.125536] usb 3-1: device not accepting address 5, error -71 [46711.125594] BUG: kernel NULL pointer dereference, address: 0000000000000008 [46711.125600] #PF: supervisor read access in kernel mode [46711.125603] #PF: error_code(0x0000) - not-present page [46711.125606] PGD 0 P4D 0 [46711.125610] Oops: Oops: 0000 [#1] PREEMPT SMP PTI [46711.125615] CPU: 1 PID: 25760 Comm: kworker/1:2 Not tainted 6.10.3_2 #1 [46711.125620] Hardware name: Gigabyte Technology Co., Ltd. [46711.125623] Workqueue: usb_hub_wq hub_event [usbcore] [46711.125668] RIP: 0010:xhci_reserve_bandwidth (drivers/usb/host/xhci.c Fix this by making sure bandwidth table pointers are set up correctly after a failed address device command, and additionally by avoiding checking for bandwidth in cases like this where no actual endpoints are added or removed, i.e. only context for default control endpoint 0 is evaluated. Reported-by: Karel Balej <[email protected]> Closes: https://lore.kernel.org/linux-usb/[email protected]/ Cc: [email protected] Fixes: 651aaf3 ("usb: xhci: Handle USB transaction error on address command") Signed-off-by: Mathias Nyman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 3ed486e commit af8e119

File tree

1 file changed

+5
-3
lines changed

1 file changed

+5
-3
lines changed

drivers/usb/host/xhci.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2837,7 +2837,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
28372837
xhci->num_active_eps);
28382838
return -ENOMEM;
28392839
}
2840-
if ((xhci->quirks & XHCI_SW_BW_CHECKING) &&
2840+
if ((xhci->quirks & XHCI_SW_BW_CHECKING) && !ctx_change &&
28412841
xhci_reserve_bandwidth(xhci, virt_dev, command->in_ctx)) {
28422842
if ((xhci->quirks & XHCI_EP_LIMIT_QUIRK))
28432843
xhci_free_host_resources(xhci, ctrl_ctx);
@@ -4200,8 +4200,10 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev,
42004200
mutex_unlock(&xhci->mutex);
42014201
ret = xhci_disable_slot(xhci, udev->slot_id);
42024202
xhci_free_virt_device(xhci, udev->slot_id);
4203-
if (!ret)
4204-
xhci_alloc_dev(hcd, udev);
4203+
if (!ret) {
4204+
if (xhci_alloc_dev(hcd, udev) == 1)
4205+
xhci_setup_addressable_virt_dev(xhci, udev);
4206+
}
42054207
kfree(command->completion);
42064208
kfree(command);
42074209
return -EPROTO;

0 commit comments

Comments
 (0)