From nobody Wed Jun 17 04:14:28 2026 Received: from mail-pf1-f177.google.com (mail-pf1-f177.google.com [209.85.210.177]) (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 E294126E71F for ; Wed, 22 Apr 2026 09:47:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776851266; cv=none; b=QJ93i7p9Henfz/ITjyWz/mmDsJ7bgGHvNhAm5g6Z86iInsFByMe+bNFhXtF3cHv8wvf1o4n8wFc4S6+Wnd6gNKWt/3CZNGQa7lHx4fSygYRHIeFGvsjStRS11drbl2RkMM10r53fTdm8BDhqXGZMfu3tDuTtX5xw1OXRzUm35j4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776851266; c=relaxed/simple; bh=or+9GmJFvEjUIs8ezh8O5LdPLBI+95FYLJskutQ1wRY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hoCzYh3uEFYNsq6Y+qVeXLFLQkVy0MRxSSoFfRjOzMzzWT2MaBN2U/RBe1mL4+LmrssamwON9kNzK6kPQp3p/EjuSV4LBfJftlv34QEsCYTJ/Bxj7acoQNoKXZW6rigEJBOLYs7Qlx8wfzN/A9SSJ8morlxW20RNcM3Qbqh9KeI= 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=a/TEDMqK; arc=none smtp.client-ip=209.85.210.177 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="a/TEDMqK" Received: by mail-pf1-f177.google.com with SMTP id d2e1a72fcca58-82ce2e2880cso3492908b3a.0 for ; Wed, 22 Apr 2026 02:47:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776851264; x=1777456064; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=B1aICTJnChD2VnWBKaFQv7Zohky9zRn/IDcQ6gWOlYg=; b=a/TEDMqK/rSw6oHLLQBaOFAvgn1JblzYweraczx2UmY9dy0hQ+q+us1xexUjpcj4aU pBL1PTqMruPW7WEiEHljxkEMFntWSmEYDGK7ZNgBLD6C+0fQpAkmwhSWR/7FmYWlJJ2g Al7lRry1JU/lzui6q/R5Dy1er9tBvuNoVd+3pgSWEK6w8NrIEbHGbuZDfcRmF3DkYx+y el/O05ceCBwETRMj4hCZc70oaYsTGzAJF8gOBvgiVsdCiaICRqnJgViVKqwvo+RXtEUk jz+WAM7PwzFOAO/3i7v8o+FUoqsSbPTZAD4PslC3SlUubQ1aPoUXFGn5cb8aSbPSYePF Kf1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776851264; x=1777456064; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=B1aICTJnChD2VnWBKaFQv7Zohky9zRn/IDcQ6gWOlYg=; b=KwCbszjlorVoRlLbdsiZJc3Wzc/SNxr1RDeC+P7OxVmTbx1E6fQ2v54P17D2rr3z9A WpD00GbOJ1xsvnB3QeywsslO1tjMRz1jSo1cE3qaYvkBQXxoPmDedG1nhH2JrEXi+Wmx vb9On5Evlmm2FKY2/b6X6gRKFXmh3YJL0s2cd+IwHlFFuHlF6I2408Vo4BJvYVJbUKPa g9hzeUjQaMGW2xIhG6OMfPpPyKYnEtR3G2yBe4/Q1vqam1ucgu1eMCp7z8Cm6IqSuRP2 /pyVj9+ePcwcmCeE7MLeL82A7r1BFnFnoMFbC5QUL6ovblpuPYD07vEM7DoghFHEPpnN HdAQ== X-Forwarded-Encrypted: i=1; AFNElJ9kA7pkw/ndgBPHybEfpW9WICRSYrPO5V0w5kmTRpmLbVqTpH8PMtpSGV1DNae5bYlCNjVYfcF16Fm0ftc=@vger.kernel.org X-Gm-Message-State: AOJu0YynZ2eAQuapKwgqR/A2uwZ8EreCJo2Nr7Ig5RVs+Ak/02GNk+9m iO4A2WzLQqHHJv+4YZSmTZchRR1Jho3bf3wwl7HCAn/ZPstjboeeqaj2 X-Gm-Gg: AeBDieu9D5ILPJDPcOkfYB56NBUjZW0zb0jlO23yF2XBICcnawEGOsbNOLJJ2ijyxMz Ss8D7rqQIcLUXYSntDeS2RMSn7sgzBsjViv2DlcBuKrZLP+xLReB4r2i/uRuRH9c/IXTTfJ8S3p iQk4f78UYEf4iQZ8f4EcY3fhtodCHQ9wSMNWujwd/UBFYRbSzDAYlGVaxSTOoOlj4VOUc+nnjp3 vhK/axDG7MzJ/eFIbTFfWU3rveUEzv4nsdSSHmLjmESvEfA7jsNXXNCgeBtq8MlJ5wnydhXe8Jp MMW6vz8YzvEGRRm+/9zFBIEQg/gRQbFf9MbbSeqWR1B+x5Jpruh7YRzAGVXttHaY+ULwG46GdUz jAMIP0Q1vS2PuojzPp+xEiGEj3iaiROa9kZ42XS4WxYZXGTAIIGhy5x7wFOXjspMFDiUH551aLw B/A7svcbzj3G6o1AeEvY7LwurGz/7ChNG8Y/t1QbYbAhkxbTvxr6abaDuHvxLpxU5fqa5P X-Received: by 2002:a05:6a00:2308:b0:82d:162c:581f with SMTP id d2e1a72fcca58-82f8c97c71emr22298338b3a.48.1776851264230; Wed, 22 Apr 2026 02:47:44 -0700 (PDT) Received: from DESKTOP-MOQC9AF.mioffice.cn ([43.224.245.246]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-82f932dac13sm16136446b3a.35.2026.04.22.02.47.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Apr 2026 02:47:43 -0700 (PDT) From: Zhan Xusheng X-Google-Original-From: Zhan Xusheng To: Hyunchul Lee Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, Zhan Xusheng Subject: [PATCH v2] ntfs: fix VCN overflow in ntfs_mapping_pairs_decompress() Date: Wed, 22 Apr 2026 17:47:37 +0800 Message-ID: <20260422094737.194069-1-zhanxusheng@xiaomi.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: 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" In ntfs_mapping_pairs_decompress(), lowest_vcn is read from on-disk metadata and used as the initial vcn without validation. A malformed value can introduce an invalid (e.g. negative) vcn, corrupting the runlist from the start. Additionally, the accumulation vcn +=3D deltaxcn does not check for s64 overflow. A crafted mapping pairs array can wrap vcn to a negative value, breaking the monotonically- increasing invariant relied upon by ntfs_rl_vcn_to_lcn() and related helpers. Fix this by validating lowest_vcn and using check_add_overflow() for vcn accumulation. Signed-off-by: Zhan Xusheng --- v2: - Validate lowest_vcn from on-disk metadata - Use check_add_overflow() for vcn accumulation --- fs/ntfs/runlist.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/fs/ntfs/runlist.c b/fs/ntfs/runlist.c index b213b4976d2b..ee68258ebffb 100644 --- a/fs/ntfs/runlist.c +++ b/fs/ntfs/runlist.c @@ -749,6 +749,12 @@ struct runlist_element *ntfs_mapping_pairs_decompress(= const struct ntfs_volume * #endif /* Start at vcn =3D lowest_vcn and lcn 0. */ vcn =3D le64_to_cpu(attr->data.non_resident.lowest_vcn); + /* Validate lowest_vcn from on-disk metadata to ensure it is sane. */ + if (unlikely(vcn < 0)) { + ntfs_error(vol->sb, "Invalid lowest_vcn in mapping pairs."); + goto err_out; + } + lcn =3D 0; /* Get start of the mapping pairs array. */ buf =3D (u8 *)attr + @@ -823,8 +829,17 @@ struct runlist_element *ntfs_mapping_pairs_decompress(= const struct ntfs_volume * * element. */ rl[rlpos].length =3D deltaxcn; - /* Increment the current vcn by the current run length. */ - vcn +=3D deltaxcn; + /* + * Increment the current vcn by the current run length. + * Guard against s64 overflow from a crafted mapping + * pairs array to preserve the monotonically-increasing + * vcn invariant. + */ + if (unlikely(check_add_overflow(vcn, deltaxcn, &vcn))) { + ntfs_error(vol->sb, "VCN overflow in mapping pairs array."); + goto err_out; + } + /* * There might be no lcn change at all, as is the case for * sparse clusters on NTFS 3.0+, in which case we set the lcn --=20 2.43.0