From nobody Tue Dec 16 21:26:50 2025 Received: from out30-74.freemail.mail.aliyun.com (out30-74.freemail.mail.aliyun.com [115.124.30.74]) (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 C86922D0C80 for ; Tue, 2 Dec 2025 18:22:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764699743; cv=none; b=OXahUHk0CLTpvT+xWea/8seVrMhyJsAqrsqHfQXUXqnAVItvOqEMr5mWPUdWnQs4QGeKU/5FdLnbUmUpIS5YJG547DmOPk79z2rs9ExcbcPFicb+xP/m39KyRpm/Mi5f56BhiEtZf+TFcSYoQY+6KXCWehKYS30Ec5rXWi8N0DM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764699743; c=relaxed/simple; bh=wMXUquGmCLh8xhczjIJfnnLxmdSZ2bFKOmc47IK+oBA=; h=Date:From:To:Subject:Message-ID:MIME-Version:Content-Type: Content-Disposition; b=NQeKl31GBDHMmWhN/ULNwAnumUOY5XKypQHwPi1jLlsmCGdldACJbyC+TrIJMnOP8vuu27KPeLjXpp7menPX7igzBD56mZMsEUjDO8v7MPoWV4URV7s2VdwXxjzItDEPPYazVIh1QgN4ndE4S3+7IMwBEexsuG/D6puexGs/S/w= 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=TUrY6u9N; arc=none smtp.client-ip=115.124.30.74 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="TUrY6u9N" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aliyun.com; s=s1024; t=1764699739; h=Date:From:To:Subject:Message-ID:MIME-Version:Content-Type; bh=43Z+6YU1jcdWT/ySItftgvu9uMoMRRIwlJCZgUIbD6k=; b=TUrY6u9NIPE1TW1uTUXtmkSieLLORKUMuW6nwh6M8OI/B4f55L9MFPAp6Ptl6xF8KI+7Bhz9rc3aQfCWTqTH1FT1ydFApTWVFFIXBC0Y6lmRPMwaKwEMNggjK8eAVM4Q1NSrNIaiJfysnnbpdCs7ANSXJbxc581LQTD0qhWeY7k= Received: from aliyun.com(mailfrom:ekorenevsky@aliyun.com fp:SMTPD_---0WtxZP9a_1764699736 cluster:ay36) by smtp.aliyun-inc.com; Wed, 03 Dec 2025 02:22:18 +0800 Date: Tue, 2 Dec 2025 21:22:13 +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 v4] 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. 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 v3->v4: * Replace do-while with for. A bit exceeded 80 hard limit but still in 100 soft limit * Restore `pos` type. This is subject of another patch if we prefer minimalism --- drivers/nvme/host/core.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index f1f719351f3f..253d35937f03 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1540,6 +1540,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *c= trl, bool csi_seen =3D false; int status, pos, len; void *data; + struct nvme_ns_id_desc *cur; =20 if (ctrl->vs < NVME_VS(1, 3, 0) && !nvme_multi_css(ctrl)) return 0; @@ -1563,11 +1564,14 @@ 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; + for (pos =3D 0; pos < NVME_IDENTIFY_DATA_SIZE - sizeof(*cur); pos +=3D le= n) { + 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) --=20 2.47.3