From nobody Mon Dec 1 21:30:51 2025 Received: from out30-77.freemail.mail.aliyun.com (out30-77.freemail.mail.aliyun.com [115.124.30.77]) (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 8AAD4221D92 for ; Mon, 1 Dec 2025 19:43:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.77 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764618212; cv=none; b=X/Glh+H0aE5t+khdVQUHbrVwU1DVO9TcZo5AgPsgBFO8EtCxJhmv8yDMU7+XCesaX/NuQ3y7JLS8yjtg/rVS1RDdCjWF3mmS4Gli9N/twoufi1fch/Pq0iRWmbCfTkLmOehntmZ+CQMzYMqfdX6aQB4EDLFoKJgNgk+hn+cx5mY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764618212; c=relaxed/simple; bh=iVXtVTF/9gRyBnAwhBbIVBcUHFiQRkjtgYKK/Mo5Zqc=; h=Date:From:To:Subject:Message-ID:MIME-Version:Content-Type: Content-Disposition; b=t7EQ9MFkQMfLMk9E4vPQJb+0YWNR4low5NH1YeVZejq8AqJafSnRw/4NLtxnte1v3lJoVTrnPdi9E2+yxy7P9FN61zdM+UUDo4QyyyeA5uLCs8wSP2RGUKUvWAtfavLyPOifjUkP2PTHYxdl1oMcSYEV6UnSDmCOmQonqPjnLu4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=aliyun.com; spf=pass smtp.mailfrom=aliyun.com; dkim=pass (1024-bit key) header.d=aliyun.com header.i=@aliyun.com header.b=WDj4SAyw; arc=none smtp.client-ip=115.124.30.77 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=aliyun.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=aliyun.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=aliyun.com header.i=@aliyun.com header.b="WDj4SAyw" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aliyun.com; s=s1024; t=1764618208; h=Date:From:To:Subject:Message-ID:MIME-Version:Content-Type; bh=2JWxJbOofoBM/+VVtNq/4gaPlvGNVnbgA53eVeG52eA=; b=WDj4SAywusbYFiPsyXg1vtm4ca72UEGQNFjhhRgiypkJx68O4oyZ6hJJdGyqI1l+U34718wAJsoYuR7gS0o291C6uyDFNZgF5am0hKeRqtaM4MiMa4OogYdJMseiyZt/jcQHhsHVYQRLgS+3+KaqWq5B9x2dhdQnbuFnpVR0YGs= Received: from aliyun.com(mailfrom:ekorenevsky@aliyun.com fp:SMTPD_---0WttVQ--_1764618205 cluster:ay36) by smtp.aliyun-inc.com; Tue, 02 Dec 2025 03:43:27 +0800 Date: Mon, 1 Dec 2025 22:43:23 +0300 From: Eugene Korenevsky To: Keith Busch , Jens Axboe , Christoph Hellwig , Sagi Grimberg , linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v3] nvme: nvme_identify_ns_descs: prevent oob Message-ID: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Broken or malicious controller can send invalid ns id. Out-of-band memory access may occur if remaining buffer size is less than .nidl (ns id length) field of `struct nvme_ns_id_desc` Fix this issue by checking (header size + .nidl) against remaining buffer length. Also small minor related fix: `pos` should be unsigned size_t, not signed int. Signed-off-by: Eugene Korenevsky --- v1->v2: * Simplification: do not touch nvme_process_ns_desc() * Update commit description v2->v3: * Even more simplification * Replace while with do-while as first pre-loop condition check is pointless * Change `pos` type: int -> size_t * Update commit description --- drivers/nvme/host/core.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index f1f719351f3f..73263545e3cd 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1538,8 +1538,10 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *= ctrl, { struct nvme_command c =3D { }; bool csi_seen =3D false; - int status, pos, len; + int status, len; + size_t pos; void *data; + struct nvme_ns_id_desc *cur; =20 if (ctrl->vs < NVME_VS(1, 3, 0) && !nvme_multi_css(ctrl)) return 0; @@ -1563,18 +1565,23 @@ static int nvme_identify_ns_descs(struct nvme_ctrl = *ctrl, goto free_data; } =20 - for (pos =3D 0; pos < NVME_IDENTIFY_DATA_SIZE; pos +=3D len) { - struct nvme_ns_id_desc *cur =3D data + pos; + pos =3D 0; + do { + cur =3D data + pos; =20 if (cur->nidl =3D=3D 0) break; + /* check ns id desc does not exceed remaining buffer by size */ + if (cur->nidl + sizeof(*cur) > NVME_IDENTIFY_DATA_SIZE - pos) + break; =20 len =3D nvme_process_ns_desc(ctrl, &info->ids, cur, &csi_seen); if (len < 0) break; =20 - len +=3D sizeof(*cur); - } + pos +=3D sizeof(*cur); + pos +=3D len; + } while (pos < NVME_IDENTIFY_DATA_SIZE - sizeof(*cur)); =20 if (nvme_multi_css(ctrl) && !csi_seen) { dev_warn(ctrl->device, "Command set not reported for nsid:%d\n", --=20 2.47.3