* [PATCH 1/3] usb: xhci: Fix memory leak in xhci_disable_slot()
2026-03-04 22:36 [PATCH 0/3] xhci fixes for usb-linus Mathias Nyman
@ 2026-03-04 22:36 ` Mathias Nyman
2026-03-04 22:36 ` [PATCH 2/3] usb: xhci: Prevent interrupt storm on host controller error (HCE) Mathias Nyman
2026-03-04 22:36 ` [PATCH 3/3] xhci: Fix NULL pointer dereference when reading portli debugfs files Mathias Nyman
2 siblings, 0 replies; 4+ messages in thread
From: Mathias Nyman @ 2026-03-04 22:36 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Zilin Guan, stable, Mathias Nyman
From: Zilin Guan <zilin@seu.edu.cn>
xhci_alloc_command() allocates a command structure and, when the
second argument is true, also allocates a completion structure.
Currently, the error handling path in xhci_disable_slot() only frees
the command structure using kfree(), causing the completion structure
to leak.
Use xhci_free_command() instead of kfree(). xhci_free_command() correctly
frees both the command structure and the associated completion structure.
Since the command structure is allocated with zero-initialization,
command->in_ctx is NULL and will not be erroneously freed by
xhci_free_command().
This bug was found using an experimental static analysis tool we are
developing. The tool is based on the LLVM framework and is specifically
designed to detect memory management issues. It is currently under
active development and not yet publicly available, but we plan to
open-source it after our research is published.
The bug was originally detected on v6.13-rc1 using our static analysis
tool, and we have verified that the issue persists in the latest mainline
kernel.
We performed build testing on x86_64 with allyesconfig using GCC=11.4.0.
Since triggering these error paths in xhci_disable_slot() requires specific
hardware conditions or abnormal state, we were unable to construct a test
case to reliably trigger these specific error paths at runtime.
Fixes: 7faac1953ed1 ("xhci: avoid race between disable slot command and host runtime suspend")
CC: stable@vger.kernel.org
Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index c36ab323d68e..ef6d8662adec 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -4146,7 +4146,7 @@ int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id)
if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING) ||
(xhci->xhc_state & XHCI_STATE_HALTED)) {
spin_unlock_irqrestore(&xhci->lock, flags);
- kfree(command);
+ xhci_free_command(xhci, command);
return -ENODEV;
}
@@ -4154,7 +4154,7 @@ int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id)
slot_id);
if (ret) {
spin_unlock_irqrestore(&xhci->lock, flags);
- kfree(command);
+ xhci_free_command(xhci, command);
return ret;
}
xhci_ring_cmd_db(xhci);
--
2.43.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 2/3] usb: xhci: Prevent interrupt storm on host controller error (HCE)
2026-03-04 22:36 [PATCH 0/3] xhci fixes for usb-linus Mathias Nyman
2026-03-04 22:36 ` [PATCH 1/3] usb: xhci: Fix memory leak in xhci_disable_slot() Mathias Nyman
@ 2026-03-04 22:36 ` Mathias Nyman
2026-03-04 22:36 ` [PATCH 3/3] xhci: Fix NULL pointer dereference when reading portli debugfs files Mathias Nyman
2 siblings, 0 replies; 4+ messages in thread
From: Mathias Nyman @ 2026-03-04 22:36 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Dayu Jiang, stable, Mathias Nyman
From: Dayu Jiang <jiangdayu@xiaomi.com>
The xHCI controller reports a Host Controller Error (HCE) in UAS Storage
Device plug/unplug scenarios on Android devices. HCE is checked in
xhci_irq() function and causes an interrupt storm (since the interrupt
isn’t cleared), leading to severe system-level faults.
When the xHC controller reports HCE in the interrupt handler, the driver
only logs a warning and assumes xHC activity will stop as stated in xHCI
specification. An interrupt storm does however continue on some hosts
even after HCE, and only ceases after manually disabling xHC interrupt
and stopping the controller by calling xhci_halt().
Add xhci_halt() to xhci_irq() function where STS_HCE status is checked,
mirroring the existing error handling pattern used for STS_FATAL errors.
This only fixes the interrupt storm. Proper HCE recovery requires resetting
and re-initializing the xHC.
CC: stable@vger.kernel.org
Signed-off-by: Dayu Jiang <jiangdayu@xiaomi.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci-ring.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 9315ba18310d..1cbefee3c4ca 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3195,6 +3195,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
if (status & STS_HCE) {
xhci_warn(xhci, "WARNING: Host Controller Error\n");
+ xhci_halt(xhci);
goto out;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 3/3] xhci: Fix NULL pointer dereference when reading portli debugfs files
2026-03-04 22:36 [PATCH 0/3] xhci fixes for usb-linus Mathias Nyman
2026-03-04 22:36 ` [PATCH 1/3] usb: xhci: Fix memory leak in xhci_disable_slot() Mathias Nyman
2026-03-04 22:36 ` [PATCH 2/3] usb: xhci: Prevent interrupt storm on host controller error (HCE) Mathias Nyman
@ 2026-03-04 22:36 ` Mathias Nyman
2 siblings, 0 replies; 4+ messages in thread
From: Mathias Nyman @ 2026-03-04 22:36 UTC (permalink / raw)
To: gregkh; +Cc: linux-usb, Mathias Nyman, Michal Pecio, stable
Michal reported and debgged a NULL pointer dereference bug in the
recently added portli debugfs files
Oops is caused when there are more port registers counted in
xhci->max_ports than ports reported by Supported Protocol capabilities.
This is possible if max_ports is more than maximum port number, or
if there are gaps between ports of different speeds the 'Supported
Protocol' capabilities.
In such cases port->rhub will be NULL so we can't reach xhci behind it.
Add an explicit NULL check for this case, and print portli in hex
without dereferencing port->rhub.
Reported-by: Michal Pecio <michal.pecio@gmail.com>
Closes: https://lore.kernel.org/linux-usb/20260304103856.48b785fd.michal.pecio@gmail.com
Fixes: 384c57ec7205 ("usb: xhci: Add debugfs support for xHCI Port Link Info (PORTLI) register.")
Cc: stable@vger.kernel.org
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci-debugfs.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c
index 890fc5e892f1..ade178ab34a7 100644
--- a/drivers/usb/host/xhci-debugfs.c
+++ b/drivers/usb/host/xhci-debugfs.c
@@ -386,11 +386,19 @@ static const struct file_operations port_fops = {
static int xhci_portli_show(struct seq_file *s, void *unused)
{
struct xhci_port *port = s->private;
- struct xhci_hcd *xhci = hcd_to_xhci(port->rhub->hcd);
+ struct xhci_hcd *xhci;
u32 portli;
portli = readl(&port->port_reg->portli);
+ /* port without protocol capability isn't added to a roothub */
+ if (!port->rhub) {
+ seq_printf(s, "0x%08x\n", portli);
+ return 0;
+ }
+
+ xhci = hcd_to_xhci(port->rhub->hcd);
+
/* PORTLI fields are valid if port is a USB3 or eUSB2V2 port */
if (port->rhub == &xhci->usb3_rhub)
seq_printf(s, "0x%08x LEC=%u RLC=%u TLC=%u\n", portli,
--
2.43.0
^ permalink raw reply related [flat|nested] 4+ messages in thread