From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pz2-f9.google.com (mail-pz2-f9.google.com [74.125.228.9]) (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 1E5CA30567B for ; Sat, 22 Aug 2026 10:24:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.228.9 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787394249; cv=none; b=XAHWkQU3om+B/ZDQve3/8nJDLtCPwsdTa5DrHL4fll830YIEAbl7KbdkRDK5LXNtTq6LE2NHCASnIQwTqHoQMX36Xsn3NYY7o3gdrFM1X1LBCzs4KuC2NS0oM7osOeAf3YM8uPG1nChRzL4WZZ0J4/nupwzPoNPU/jxVCwpwI0U= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787394249; c=relaxed/simple; bh=MY+mnpwfABl43+R4lLwnYc5uAZ2mnNN0/kYDMO9ThH4=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=k6HXESaAjNamEqD7tuOAm9W8aBEshToe1uSpU2LPOMdWLs6VHtm50Rly4CuPe04xGN7NM13Fj9MyisbgEJsQUwFN7Gb9RW5ZzJXzUj/znNJYYjUv1J0YqqYhyg2uDuLlXPrgyLTJaufpEiZLGIj5M/01xsuKsj5+Ja2cnz+ygE0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=kd4Mo14o; arc=none smtp.client-ip=74.125.228.9 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="kd4Mo14o" Received: by mail-pz2-f9.google.com with SMTP id 41be03b00d2f7-cc188c38a4cso525102a12.0 for ; Sat, 22 Aug 2026 03:24:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787394247; x=1787999047; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=uGCc+Ym03Fgjj1SDrqU2gGDlotBz612tbq+Cy7bXAYc=; b=kd4Mo14oL3bWjdANnRkrC4Sr9MmDv8Kpd//dfJ+66ryEXkcHBzT1cwg+G+rcwc31oc i0VLLtlGLeoZxrASqdosqXJbvMoHdzSc/L5Q/Bby6dwIEQaN82ZtyRE30BCE5CWHyibi fDtn1eR+yLQ3o4NCEFWl2beERNhWloi+DXwF+H8puapnHgJG8QN8KkrbdzGhXMQQ6zw8 rzndGh9USJ0p1nOub6hi6GvNhuN+idlsBHz4mrn+bBABOYu9q+frcjkaFoG1oJ9bojmh XHGHHow89kl8R0/Vs8FHtLwxWf1RHaNtQo5TGJ5lIwOxOhf+t+1ZsWU8fzwgxGk9SRel eY+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787394247; x=1787999047; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=uGCc+Ym03Fgjj1SDrqU2gGDlotBz612tbq+Cy7bXAYc=; b=qv0w59fbhnSnDYLjSqFiSwjqBQVe+cTyzsjWCDNrlIk38Kt/MT80aFqjRnGzIV0+MV WuT5IKv1Mdb+rNrsXJrOUqyhlsAhbuYtc8LKgwI0StCWFVUfwl2IZR+u+FA44viWhpPD sbTl6twaKRp5ma6h51tD9lOJVStdwnW2hNbo4kq87V49HTDnQg7PhTqINuXOcfcjOS8k fc0c/+6V/In5PjfLd17ZLxfYF4bkbdFuAmCxFzKkCq1W/UIMSDlSp+QtHUOH3fsKH6iD YSKMOJF9eH/c0z/gwwsm7iZcDUd6wvNysvjDU9VzQDPGdRnredWoGqOlJdoLVn8VxOlf V5eg== X-Forwarded-Encrypted: i=1; AHgh+Rqk+1dACR691gNrxSJmBLO0qpGiM4aMOpdMYiuSb0lsHbmUaUU3y87Dq3cr3NdJd1jDledMdlRNw8rzxto=@vger.kernel.org X-Gm-Message-State: AFuF++nL4oOYZimeFj3omX3C5MJywZBzoFf6VLn5B5+2+QtW6A8skjSA l3HsH/4T5bWIKdgmqfNY7joeoTKHP7N6bSlY09/OUhC7/xXB7BgQ5DkqFuqRvMa/zi2E6Q== X-Gm-Gg: AR+sD10QdOTIGFBPDhGKqsY/tfBQegIUKKd/HOv/8yvEkwIrhnI1y4OnZrv4NO3VvSN cI4o9Fta5MA3GtJvObGY4Kb6taa8Z4gX8EebeoRKnjS4STgHjxzQjR62KsxBtQ+f0t/TS3YkNCV zHFhRRoO1++tevoxZNZ73n9NXtHdoMO/9K9W3E0mxx2C2Pyry3wDJWNQjTIpyXS7qQz71cQExWD ovIMfA+Ka/9ywCvVNZQUN+Es7KLm+EqhLY4QGU+t478MQIPC1HDZJNiDhu+AhCBSGP/mN3UE400 qPS5q7ABWWrZj+ONEiGgPbOeiKYWQNpH1cjX3JgJezao/ZSinjCkyffaYX1Z2c8spISrTshlgUq JTksGAjYEHcpzyl5d7J+98gHNvenRt+W0RK6tIAWOjfNaEmKmFTEHCUTeq3sUpRHqwFm+iIALUT LSaccU6W+eURwKFcedngdbIUsJMx5U+RS+cA3v60J3T1BbPJLZffGFSYxOJYVzr/jpq/UQklCRa 7a9Q51kbBBOJtNiAxMnCX2GMTvTcOs1NBzde1cdM9M3pqd6Zmkr7nCiuYi1p1fcubF6HR3n X-Received: by 2002:a05:6a00:b42:b0:848:62ab:7b7 with SMTP id d2e1a72fcca58-8520be923e7mr7327295b3a.16.1787394247324; Sat, 22 Aug 2026 03:24:07 -0700 (PDT) Received: from erdaitian.tail85cd49.ts.net (2001-b030-a81d-0a00-0000-0000-0082-2410.hinet-ip6.hinet.net. [2001:b030:a81d:a00::82:2410]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8520ef07a12sm503958b3a.16.2026.08.22.03.24.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 22 Aug 2026 03:24:06 -0700 (PDT) From: erdaitianjiao To: Mathias Nyman , Greg Kroah-Hartman Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] usb: xhci: validate CAPLENGTH in xhci_gen_setup() Date: Sat, 22 Aug 2026 18:23:57 +0800 Message-ID: <20260822102357.4634-1-erdaitianjiao@gmail.com> X-Mailer: git-send-email 2.55.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 --- 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