From nobody Sun May 24 19:34:47 2026 Received: from mout02.posteo.de (mout02.posteo.de [185.67.36.66]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D817C2848BE for ; Sat, 23 May 2026 08:28:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.67.36.66 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779524901; cv=none; b=NUnOoU44kTWiauxUMVouxEQLwv6aCfA1YHpues6Nef2LDJpvUHAEjsbyh2BoDjdwioxHIeJGGbQOULAtYSXQfkWFPxJOrmPmcM95gxXlc+63P49f8FTza1tDSovl1ld0sGlD6TnQa4ZBpz5feRHI5hTsezPrYwVDst6RkkxAb1k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779524901; c=relaxed/simple; bh=u08EqPnGi1SwIhP7SHBFPosf/yQCYiAgFRaE0UatDwo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PoRXsIJJXlsCvjoGzNm6pgjj0NOCqFV6TetOcVIboG2LjuWUm5Z3dpYuLXNRX25Z/z+k6XZE8RlCUHa/XBSjgrlkrXoJxqz1wcmFkaEO+nAddULxRV8/x/gSJUKOWJ2JQxC8n4XljIc/iMomNLPzkT32yrz+ALCWibm71BxCCU0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=posteo.net; spf=pass smtp.mailfrom=posteo.net; dkim=pass (2048-bit key) header.d=posteo.net header.i=@posteo.net header.b=DZeQIvgb; arc=none smtp.client-ip=185.67.36.66 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=posteo.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=posteo.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=posteo.net header.i=@posteo.net header.b="DZeQIvgb" Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id 13301240105 for ; Sat, 23 May 2026 10:28:17 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=posteo.net; s=2017; t=1779524897; bh=nRayta8UwcV8dzi6cswzoiVqf0L06wQLACt1viHd5Kw=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version: Content-Transfer-Encoding:From; b=DZeQIvgbYY/BLX5SMZZbdnyhFUHzguX8ZT+Bb0Dxy+zZq60ppxX+GH7NJVJHDuLHN 7JhIribjruTJJQbjaIRUYeTSCACxgdWcEinCUsjhEs/PA+ILepTpd/KhE0570nmYkR eg6RswFqAFUoUPqxvByQgQTcI9RRp4lngZ77Z2pt8mcXI9AWv6Jtx/oUn55ll4Kqx8 sOSqvC53b8bpMSxCqo/b+Gh0AE4y95cTyMf+iodBQjhE/qkX1pLUuU/+abr9hq4JeV SjXXd9epng1PlcWUYrpPhDBQErcAysMMM4KitpRhmsnvLMt2jrPSftnCW0YWTFncpu bU2kZvtgaprKA== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4gMwJb5fXVz9rxG; Sat, 23 May 2026 10:28:15 +0200 (CEST) From: Mateusz Nowicki To: Keith Busch , Jens Axboe , Christoph Hellwig , Sagi Grimberg Cc: Caleb Sander Mateos , Sung-woo Kim , linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v2] nvme-pci: fix out-of-bounds access in nvme_setup_descriptor_pools Date: Sat, 23 May 2026 08:28:16 +0000 Message-ID: <20260523082751.20453-1-mateusz.nowicki@posteo.net> In-Reply-To: <20260522150628.399288-1-mateusz.nowicki@posteo.net> References: <20260522150628.399288-1-mateusz.nowicki@posteo.net> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" nvme_setup_descriptor_pools() indexes dev->descriptor_pools[] using the numa_node forwarded from hctx->numa_node by its single caller, nvme_init_hctx_common(). On a non-NUMA kernel hctx->numa_node is NUMA_NO_NODE (-1). Because the parameter was declared 'unsigned', the value becomes UINT_MAX and the index walks off the array (sized to nr_node_ids), faulting during nvme_alloc_ns() and leaving the namespace without a /dev node. Reproduces on any NVMe controller probed by a CONFIG_NUMA=3Dn kernel: BUG: unable to handle page fault for address: ffff889101603d38 RIP: 0010:nvme_init_hctx_common+0x5a/0x190 [nvme] Call Trace: nvme_init_hctx+0x10/0x20 [nvme] nvme_alloc_ns+0x9e/0xa10 [nvme_core] nvme_scan_ns+0x301/0x3b0 [nvme_core] nvme_scan_ns_async+0x23/0x30 [nvme_core] Switch the parameter to int and fall back to node 0 when it is NUMA_NO_NODE; node 0 is always present. Fixes: d977506f8863 ("nvme-pci: make PRP list DMA pools per-NUMA-node") Reported-by: Sung-woo Kim Link: https://lore.kernel.org/r/20260309062840.2937858-2-iam@sung-woo.kim Signed-off-by: Mateusz Nowicki --- v2: - drop the (numa_node >=3D nr_node_ids) check: cpu_to_node() never returns that in practice, so NUMA_NO_NODE is the only out-of-range value worth guarding against. (Caleb Sander) - test against NUMA_NO_NODE explicitly instead of (numa_node < 0) - add Fixes: tag, Reported-by/Link to Sung-woo Kim's earlier report. drivers/nvme/host/pci.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 9fd04cd7c5cb..9815823c974e 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -587,11 +587,16 @@ static bool nvme_dbbuf_update_and_check_event(u16 val= ue, __le32 *dbbuf_db, } =20 static struct nvme_descriptor_pools * -nvme_setup_descriptor_pools(struct nvme_dev *dev, unsigned numa_node) +nvme_setup_descriptor_pools(struct nvme_dev *dev, int numa_node) { - struct nvme_descriptor_pools *pools =3D &dev->descriptor_pools[numa_node]; + struct nvme_descriptor_pools *pools; size_t small_align =3D NVME_SMALL_POOL_SIZE; =20 + if (numa_node =3D=3D NUMA_NO_NODE) + numa_node =3D 0; + + pools =3D &dev->descriptor_pools[numa_node]; + if (pools->small) return pools; /* already initialized */ =20 --=20 2.53.0