* [PATCH] usb: xhci: validate CAPLENGTH in xhci_gen_setup()
@ 2026-08-22 10:23 erdaitianjiao
2026-08-22 10:33 ` Greg Kroah-Hartman
2026-08-22 10:34 ` Greg Kroah-Hartman
0 siblings, 2 replies; 4+ messages in thread
From: erdaitianjiao @ 2026-08-22 10:23 UTC (permalink / raw)
To: Mathias Nyman, Greg Kroah-Hartman; +Cc: linux-usb, linux-kernel
xhci_hcd can be bound to arbitrary PCI devices via the
driver_override sysfs knob. When this happens to a device whose
MMIO registers are not xHCI capability registers,
xhci_gen_setup() reads CAPLENGTH from the foreign register
layout and uses it as a byte offset to compute op_regs.
A non-xHCI device can return a CAPLENGTH value that is
- not large enough to fit the capability register block, or
- not 4-byte aligned (e.g. the NVMe CAP register's low byte is
0xff, which becomes CAPLENGTH = 0xff).
The unaligned case is especially harmful on arm64: MMIO is
Device memory and Device-nGnRE accesses require natural
alignment, so readl(&op_regs->command) faults with an
alignment exception even when the address is within the
ioremapped region.
Validate CAPLENGTH in xhci_gen_setup() and fail probe with
-ENODEV if the value is smaller than 0x20 (capability registers
are 32 bytes per the xHCI spec), not 4-byte aligned, or leaves
no room for the operational register space within the mapped
region.
The run_regs_off read on the next line has the same shape, but
is not reachable on the xhci_halt code path and is left
untouched here.
Reproduced on a QEMU virt machine with a syzkaller repro that
unbinds the NVMe driver on 0000:00:02.0 and binds xhci_hcd via
driver_override. Before this patch the kernel Oopses and
panics; after, the probe is rejected cleanly. Ran the repro for
over two hours (66,709 consecutive probe attempts) with zero
Oopses.
Reported-by: syzbot+c90273bf9017ef1462af@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?id=44c85514940262c7e2fad6f8fd0c07d8f2884154
Fixes: 552e0c4f12fe ("usb/xhci: move xhci_gen_setup() away from -pci.")
Signed-off-by: erdaitianjiao <erdaitianjiao@gmail.com>
---
drivers/usb/host/xhci.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 091c82ca8ee2..fb0075d0530f 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -5432,7 +5432,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
*/
struct device *dev = hcd->self.sysdev;
int retval;
- u32 hcs_params1;
+ u32 hcs_params1, capbase;
/* Accept arbitrarily long scatter-gather lists */
hcd->self.sg_tablesize = ~0;
@@ -5453,8 +5453,16 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
mutex_init(&xhci->mutex);
xhci->main_hcd = hcd;
xhci->cap_regs = hcd->regs;
- xhci->op_regs = hcd->regs +
- HC_LENGTH(readl(&xhci->cap_regs->hc_capbase));
+ capbase = readl(&xhci->cap_regs->hc_capbase);
+ if (HC_LENGTH(capbase) < 0x20 ||
+ (HC_LENGTH(capbase) & 0x3) ||
+ (hcd->rsrc_len &&
+ HC_LENGTH(capbase) + sizeof(struct xhci_op_regs) > hcd->rsrc_len)) {
+ xhci_err(xhci, "Invalid CAPLENGTH %#x (rsrc_len %#lx)\n",
+ HC_LENGTH(capbase), (unsigned long)hcd->rsrc_len);
+ return -ENODEV;
+ }
+ xhci->op_regs = hcd->regs + HC_LENGTH(capbase);
xhci->run_regs = hcd->regs +
(readl(&xhci->cap_regs->run_regs_off) & RTSOFF_MASK);
/* Cache read-only capability registers */
--
2.55.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] usb: xhci: validate CAPLENGTH in xhci_gen_setup()
2026-08-22 10:23 [PATCH] usb: xhci: validate CAPLENGTH in xhci_gen_setup() erdaitianjiao
@ 2026-08-22 10:33 ` Greg Kroah-Hartman
2026-08-22 10:34 ` Greg Kroah-Hartman
1 sibling, 0 replies; 4+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-22 10:33 UTC (permalink / raw)
To: erdaitianjiao; +Cc: Mathias Nyman, linux-usb, linux-kernel
On Sat, Aug 22, 2026 at 06:23:57PM +0800, erdaitianjiao wrote:
> xhci_hcd can be bound to arbitrary PCI devices via the
> driver_override sysfs knob. When this happens to a device whose
> MMIO registers are not xHCI capability registers,
> xhci_gen_setup() reads CAPLENGTH from the foreign register
> layout and uses it as a byte offset to compute op_regs.
>
> A non-xHCI device can return a CAPLENGTH value that is
> - not large enough to fit the capability register block, or
> - not 4-byte aligned (e.g. the NVMe CAP register's low byte is
> 0xff, which becomes CAPLENGTH = 0xff).
>
> The unaligned case is especially harmful on arm64: MMIO is
> Device memory and Device-nGnRE accesses require natural
> alignment, so readl(&op_regs->command) faults with an
> alignment exception even when the address is within the
> ioremapped region.
>
> Validate CAPLENGTH in xhci_gen_setup() and fail probe with
> -ENODEV if the value is smaller than 0x20 (capability registers
> are 32 bytes per the xHCI spec), not 4-byte aligned, or leaves
> no room for the operational register space within the mapped
> region.
>
> The run_regs_off read on the next line has the same shape, but
> is not reachable on the xhci_halt code path and is left
> untouched here.
>
> Reproduced on a QEMU virt machine with a syzkaller repro that
> unbinds the NVMe driver on 0000:00:02.0 and binds xhci_hcd via
> driver_override. Before this patch the kernel Oopses and
> panics; after, the probe is rejected cleanly. Ran the repro for
> over two hours (66,709 consecutive probe attempts) with zero
> Oopses.
>
> Reported-by: syzbot+c90273bf9017ef1462af@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?id=44c85514940262c7e2fad6f8fd0c07d8f2884154
> Fixes: 552e0c4f12fe ("usb/xhci: move xhci_gen_setup() away from -pci.")
> Signed-off-by: erdaitianjiao <erdaitianjiao@gmail.com>
> ---
> drivers/usb/host/xhci.c | 14 +++++++++++---
> 1 file changed, 11 insertions(+), 3 deletions(-)
Hi,
This is the friendly patch-bot of Greg Kroah-Hartman. You have sent him
a patch that has triggered this response. He used to manually respond
to these common problems, but in order to save his sanity (he kept
writing the same thing over and over, yet to different people), I was
created. Hopefully you will not take offence and will fix the problem
in your patch and resubmit it so that it can be accepted into the Linux
kernel tree.
You are receiving this message because of the following common error(s)
as indicated below:
- It looks like you did not use your "real" name for the patch on either
the Signed-off-by: line, or the From: line (both of which have to
match). Please read the kernel file,
Documentation/process/submitting-patches.rst for how to do this
correctly.
If you wish to discuss this problem further, or you have questions about
how to resolve this issue, please feel free to respond to this email and
Greg will reply once he has dug out from the pending patches received
from other developers.
thanks,
greg k-h's patch email bot
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] usb: xhci: validate CAPLENGTH in xhci_gen_setup()
2026-08-22 10:23 [PATCH] usb: xhci: validate CAPLENGTH in xhci_gen_setup() erdaitianjiao
2026-08-22 10:33 ` Greg Kroah-Hartman
@ 2026-08-22 10:34 ` Greg Kroah-Hartman
2026-08-22 11:06 ` Tianjiao Erdai
1 sibling, 1 reply; 4+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-22 10:34 UTC (permalink / raw)
To: erdaitianjiao; +Cc: Mathias Nyman, linux-usb, linux-kernel
On Sat, Aug 22, 2026 at 06:23:57PM +0800, erdaitianjiao wrote:
> xhci_hcd can be bound to arbitrary PCI devices via the
> driver_override sysfs knob. When this happens to a device whose
> MMIO registers are not xHCI capability registers,
> xhci_gen_setup() reads CAPLENGTH from the foreign register
> layout and uses it as a byte offset to compute op_regs.
>
> A non-xHCI device can return a CAPLENGTH value that is
> - not large enough to fit the capability register block, or
> - not 4-byte aligned (e.g. the NVMe CAP register's low byte is
> 0xff, which becomes CAPLENGTH = 0xff).
That's crazy, and I'm getting tired of rejecting patches like this.
Again, if you use 'bind' to attach a device to a driver you HAVE to know
what you are doing. Attempting to fix up each and every driver to
handle this is not ok, and will not happen.
sorry, syzbot is broken and needs to be fixed,
greg k-h
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] usb: xhci: validate CAPLENGTH in xhci_gen_setup()
2026-08-22 10:34 ` Greg Kroah-Hartman
@ 2026-08-22 11:06 ` Tianjiao Erdai
0 siblings, 0 replies; 4+ messages in thread
From: Tianjiao Erdai @ 2026-08-22 11:06 UTC (permalink / raw)
To: Greg Kroah-Hartman; +Cc: Mathias Nyman, linux-usb, linux-kernel
Understood, thanks for the explanation. I'll skip driver_override
triggered issues going forward and pick bugs with more meaningful
trigger paths.
Best regards,
Tianjiao Erdai
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-08-22 11:06 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-22 10:23 [PATCH] usb: xhci: validate CAPLENGTH in xhci_gen_setup() erdaitianjiao
2026-08-22 10:33 ` Greg Kroah-Hartman
2026-08-22 10:34 ` Greg Kroah-Hartman
2026-08-22 11:06 ` Tianjiao Erdai
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox