[PATCH] ntfs: fix s64 overflow in ntfs_mapping_pairs_decompress()

From: Zhan Xusheng

Date: Tue Apr 21 2026 - 23:08:34 EST


In ntfs_mapping_pairs_decompress(), deltaxcn is decoded from the
on-disk mapping pairs array and negative values are rejected, but
large positive values up to S64_MAX pass through unchecked. The
subsequent `vcn += deltaxcn` can then wrap the s64 accumulator to a
negative value, breaking the monotonically-increasing VCN invariant
that ntfs_rl_vcn_to_lcn() and related helpers rely on.

A crafted NTFS image with a single 8-byte run-length of S64_MAX
triggers this when lowest_vcn > 0, leading to incorrect LCN lookups
and potential reads/writes to wrong disk sectors.

Add an overflow check before the addition and treat the on-disk data
as corrupt (-EIO) when the result would exceed S64_MAX.

Signed-off-by: Zhan Xusheng <zhanxusheng@xxxxxxxxxx>
---
fs/ntfs/runlist.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/fs/ntfs/runlist.c b/fs/ntfs/runlist.c
index b213b4976d2b..a32affb57d29 100644
--- a/fs/ntfs/runlist.c
+++ b/fs/ntfs/runlist.c
@@ -823,7 +823,16 @@ struct runlist_element *ntfs_mapping_pairs_decompress(const struct ntfs_volume *
* element.
*/
rl[rlpos].length = deltaxcn;
- /* Increment the current vcn by the current run length. */
+ /*
+ * Increment the current vcn by the current run length.
+ * Both are non-negative here; guard against s64 overflow
+ * from a crafted mapping pairs array to preserve the
+ * monotonically-increasing vcn invariant.
+ */
+ if (unlikely(deltaxcn > S64_MAX - vcn)) {
+ ntfs_error(vol->sb, "VCN overflow in mapping pairs array.");
+ goto err_out;
+ }
vcn += deltaxcn;
/*
* There might be no lcn change at all, as is the case for
--
2.43.0