All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hyunchul Lee <hyc.lee@gmail.com>
To: Zhan Xusheng <zhanxusheng1024@gmail.com>
Cc: linux-kernel@vger.kernel.org,
	Zhan Xusheng <zhanxusheng@xiaomi.com>,
	linkinjeon@kernel.org
Subject: Re: [PATCH v3] ntfs: fix VCN overflow in ntfs_mapping_pairs_decompress()
Date: Mon, 27 Apr 2026 13:52:34 +0900	[thread overview]
Message-ID: <ae7rktak3d7uj_qB@hyunchul-PC02> (raw)
In-Reply-To: <20260423045227.249857-1-zhanxusheng@xiaomi.com>

Hello Zhan,

On Thu, Apr 23, 2026 at 12:52:26PM +0800, Zhan Xusheng wrote:
> 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 += 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 <zhanxusheng@xiaomi.com>

The recipient is wrong.
Anyway looks good to me.

Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com>

> ---
> v3:
>  - Use overflows_type() for lowest_vcn validation (Hyunchul)
> v2:
>  - Validate lowest_vcn from on-disk metadata
>  - Use check_add_overflow() for vcn accumulation
> ---
>  fs/ntfs/runlist.c | 24 +++++++++++++++++++++---
>  1 file changed, 21 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/ntfs/runlist.c b/fs/ntfs/runlist.c
> index b213b4976d2b..be6ca3d374bb 100644
> --- a/fs/ntfs/runlist.c
> +++ b/fs/ntfs/runlist.c
> @@ -15,6 +15,8 @@
>   * Copyright (c) 2007-2022 Jean-Pierre Andre
>   */
>  
> +#include <linux/overflow.h>
> +
>  #include "ntfs.h"
>  #include "attrib.h"
>  
> @@ -739,6 +741,7 @@ struct runlist_element *ntfs_mapping_pairs_decompress(const struct ntfs_volume *
>  	int rlsize;		/* Size of runlist buffer. */
>  	u16 rlpos;		/* Current runlist position in units of struct runlist_elements. */
>  	u8 b;			/* Current byte offset in buf. */
> +	u64 lowest_vcn;		/* Raw on-disk lowest_vcn. */
>  
>  #ifdef DEBUG
>  	/* Make sure attr exists and is non-resident. */
> @@ -747,8 +750,14 @@ struct runlist_element *ntfs_mapping_pairs_decompress(const struct ntfs_volume *
>  		return ERR_PTR(-EINVAL);
>  	}
>  #endif
> +	lowest_vcn = le64_to_cpu(attr->data.non_resident.lowest_vcn);
> +	/* Validate lowest_vcn from on-disk metadata to ensure it is sane. */
> +	if (overflows_type(lowest_vcn, vcn)) {
> +		ntfs_error(vol->sb, "Invalid lowest_vcn in mapping pairs.");
> +		goto err_out;
> +	}
>  	/* Start at vcn = lowest_vcn and lcn 0. */
> -	vcn = le64_to_cpu(attr->data.non_resident.lowest_vcn);
> +	vcn = lowest_vcn;
>  	lcn = 0;
>  	/* Get start of the mapping pairs array. */
>  	buf = (u8 *)attr +
> @@ -823,8 +832,17 @@ 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. */
> -		vcn += 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
> -- 
> 2.43.0
> 
> 

-- 
Thanks,
Hyunchul

  reply	other threads:[~2026-04-27  4:52 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-22  3:05 [PATCH] ntfs: fix s64 overflow in ntfs_mapping_pairs_decompress() Zhan Xusheng
2026-04-22  7:45 ` Hyunchul Lee
2026-04-22  9:47   ` [PATCH v2] ntfs: fix VCN " Zhan Xusheng
2026-04-22 23:57     ` Hyunchul Lee
2026-04-23  4:52       ` [PATCH v3] " Zhan Xusheng
2026-04-27  4:52         ` Hyunchul Lee [this message]
2026-04-27 13:34         ` Namjae Jeon
2026-04-27  0:18       ` [PATCH v2] " Hyunchul Lee

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ae7rktak3d7uj_qB@hyunchul-PC02 \
    --to=hyc.lee@gmail.com \
    --cc=linkinjeon@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=zhanxusheng1024@gmail.com \
    --cc=zhanxusheng@xiaomi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.