From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-oa1-f69.google.com (mail-oa1-f69.google.com [209.85.160.69]) (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 6EB502D0602 for ; Fri, 21 Aug 2026 12:52:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.69 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787316746; cv=none; b=iw0HWaHjkbuT3fhKFEP7jD7BEJo/KLdvjkIKz7LrKmHYoO1BhwM+mjYoeuKoz0Tx+UCNOfm1Jrc8MbzBKaCYsU8uxm702YVrs1LgFLJxdnbtMrg1eUHJyVbGQuG3RIV8MP/CJXvORrTAQmVXhB/floxuZvna0k7c3YqocAXZIsQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787316746; c=relaxed/simple; bh=wROpV3vCBIJNUJJLYMwtzHznHp75qKkdOlbIh4Z8ji0=; h=MIME-Version:Date:In-Reply-To:Message-ID:Subject:From:To: Content-Type; b=J8eiTFUB4/QKK4XXXvRHbEMW4xDSlszaojUtZl/evKhL3vpjRT/lym7hhon4L85IfamFX4FbN5SJaV2/uEtuZukmrTqmzhJepMs5X/J/QarzcHdrIXyGGFUb8gGE/htAEbq6SXEpSVengohU/uGHV7F0iUiMaABlqPpsCH2/j1c= 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.160.69 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-oa1-f69.google.com with SMTP id 586e51a60fabf-44aeefa1a30so2084913fac.3 for ; Fri, 21 Aug 2026 05:52:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787316743; x=1787921543; 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=mz0uIECykkSrOkjPrz/+sgRBGIifTILVW/xUrbIMUz0=; b=r+j3i4TAkxDh6XI9tc63qCRos5pWFx1+/JaXi/SAKEsP/+D2p/YqAahE/337K1rQRU bTJOy+S9jprL6En0n+nqn8Ln09meiyzUEbNbJ/h+kqc5L9uwnreIhyJwFZ+0WmMsvGcQ bLtRQLeLPiflmYHELM3OuTxmTDxfj+fQ0SSyWh9ytVHd1jgdg5xVNWeOLLKmG85MPFSD grC/RL+RNOWvtJxmS4KUXOhsrj+liFEQf4dBBFUwfaN1jtsjqVBH96pX5HrT5TK5/NLj qoxhtPLdxwhXSv1DJ8icF+kG6EecHHGyCEIU+Sv/gZkcgmpR3Zk3WA3LbqTJfNob1kMQ 6Lmw== X-Gm-Message-State: AOJu0YzRvWQU2NkuBBRMqEbTJcY8fbKUY2AqGYCasuKJ7+TxPN/8ODes 1t90D58hFdjMVTSREfUQ5dHgHJ/RQ5lUmIEFvNnh7Iil3hALoOPoSPNcIft5jvntEuv4VTuBA9T CLrjE9E5sabobKaEeeXM46Um7HJu5+HrDiMrlZvydvd4i9Nn8+BSUcRdUozI= 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:6820:3407:20b0:6b1:3417:548b with SMTP id 006d021491bc7-6b1593f0db1mr4617582eaf.24.1787316743347; Fri, 21 Aug 2026 05:52:23 -0700 (PDT) Date: Fri, 21 Aug 2026 05:52:23 -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: <6a884a07.91706f20.16b6e3.02aa.GAE@google.com> Subject: Forwarded: Re: [syzbot] [usb?] BUG: unable to handle kernel paging request in xhci_halt 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: Re: [syzbot] [usb?] BUG: unable to handle kernel paging request in xhci_halt Author: erdaitianjiao@gmail.com #syz test >From f7f2199964ee2b4204aabd4d1190845f5ad1da62 Mon Sep 17 00:00:00 2001 From: erdaitianjiao Date: Fri, 21 Aug 2026 19:07:10 +0800 Subject: [PATCH] usb: xhci: validate CAPLENGTH in xhci_gen_setup() 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) ", + 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