From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-oi1-f197.google.com (mail-oi1-f197.google.com [209.85.167.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 384D939A806 for ; Fri, 21 Aug 2026 13:15:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.197 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787318141; cv=none; b=sP609ADop4UIBSQXLCjmQ+1F8+DHl+j4poMM1JFX79SGUagjcoIuc4ysx4STkn6SCMFtsVljSPxgamVvlHyNH6u4HsRj7y4EHYkaqMayyXYW2eS/Wqvi99SBAjLC3hvBexbwssBrD/GE2bZkNUDmYJcbbRkavrGZRB4YxdT4dg4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787318141; c=relaxed/simple; bh=leSDWVxObA//A5UbGzhn3GW0rA6uTtNZSXD2JlDiUvg=; h=MIME-Version:Date:In-Reply-To:Message-ID:Subject:From:To: Content-Type; b=A2a8S5/YesBhCAsM+N6n2PJ0+HpNm2KKiIVRnRaXvVWaD82Npl52XiTbwJDyP7b+uMbL9uTB/uc34uwdTnvVUWmyRwBXPcgw7S3vJOCLRpTRF1Dde7okcQppwp9XIemsYHWKnHdSoyfsmfqmVFkI0NaXC1J6M/HtQq3ZXV8ERp4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=syzkaller.appspotmail.com; spf=pass smtp.mailfrom=M3KW2WVRGUFZ5GODRSRYTGD7.apphosting.bounces.google.com; arc=none smtp.client-ip=209.85.167.197 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=syzkaller.appspotmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=M3KW2WVRGUFZ5GODRSRYTGD7.apphosting.bounces.google.com Received: by mail-oi1-f197.google.com with SMTP id 5614622812f47-49aa4525b82so1480071b6e.1 for ; Fri, 21 Aug 2026 06:15:22 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787318117; x=1787922917; h=content-type:to:from:subject:message-id:in-reply-to:date :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to:content-type; bh=9Zjz76x72j6Om11Km16BTYs/c8Jn4XMnq+I4hKUCl/Q=; b=SSxk++EepzSj/lkC/+FHgCetsbFQ6ZfR+QVUBc0bjIHq1C1McpjNlvs3A/kSfoHm5b aBlLLDvTePwe99I3spnsVHzDPLw2QM0InUx8MGnnqK4GyDotiyusC1jmH/E79V7hAEG1 xs6fRshSM+xuWwOgfddMIA3rQgS29fUcPFkDeLFMNVylVWBlAQxtfr9BTfu95ItmXC3u at1G8nuFuUC36jnkTIRGLXaUV1/Y+A/FpvOhaYj3CNtxt4xv2HozeHVKObfsKSJA4Aab V+B6yGe5yMEUstxM/pygePO0rpVTD6LwgRrbsSPDPU3zooAFrlhhKlyFz7Zho3E0H0Bg jxLQ== X-Gm-Message-State: AOJu0Ywm8ee4T7fUDRcp+dNhFb5T6hd0ygtfz29yvuQfsjHMNqs5gemo Bham00X7Pz4uvkA1SIM3pi7QsT/18mwUQ8UIiBGgoK0/U6FYaFoDs0Ok0h2EBZQloDbvr0TtHYC IRckSsYpnEdLlinHDldVdRcJdSnTktJom2WCagOqHFHHtHWnhR3q/24JqZAU= Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Received: by 2002:a05:6808:124d:b0:489:a387:1e29 with SMTP id 5614622812f47-4b2ef4eeeb6mr5104426b6e.20.1787318117067; Fri, 21 Aug 2026 06:15:17 -0700 (PDT) Date: Fri, 21 Aug 2026 06:15:17 -0700 In-Reply-To: <6a8803bf.dbb3a75c.13dd47.000a.GAE@google.com> X-Google-Appengine-App-Id: s~syzkaller X-Google-Appengine-App-Id-Alias: syzkaller Message-ID: <6a884f65.dbb3a75c.13dd47.001c.GAE@google.com> Subject: Forwarded: [PATCH] usb: xhci: validate CAPLENGTH in xhci_gen_setup() From: syzbot To: linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com Content-Type: text/plain; charset="UTF-8" For archival purposes, forwarding an incoming command email to linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com. *** Subject: [PATCH] usb: xhci: validate CAPLENGTH in xhci_gen_setup() Author: erdaitianjiao@gmail.com #syz test 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 (verified with 46 consecutive probe attempts, 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 --- 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