Re: [PATCH] fs/ntfs3: fix missing run load for vcn0 in attr_data_get_block_locked()

Konstantin Komarov <[email protected]>
Newsgroups dev.linux.lists.ntfs3,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On 3/19/26 08:45, Deepanshu Kartikey wrote:

> When a compressed or sparse attribute has its clusters frame-aligned,
> vcn is rounded down to the frame start using cmask, which can result
> in vcn != vcn0. In this case, vcn and vcn0 may reside in different
> attribute segments.
>
> The code already handles the case where vcn is in a different segment
> by loading its runs before allocation. However, it fails to load runs
> for vcn0 when vcn0 resides in a different segment than vcn. This causes
> run_lookup_entry() to return SPARSE_LCN for vcn0 since its segment was
> never loaded into the in-memory run list, triggering the WARN_ON(1).
>
> Fix this by adding a missing check for vcn0 after the existing vcn
> segment check. If vcn0 falls outside the current segment range
> [svcn, evcn1), find and load the attribute segment containing vcn0
> before performing the run lookup.
>
> The following scenario triggers the bug:
>    attr_data_get_block_locked()
>      vcn = vcn0 & cmask        <- vcn != vcn0 after frame alignment
>      load runs for vcn segment <- vcn0 segment not loaded!
>      attr_allocate_clusters()  <- allocation succeeds
>      run_lookup_entry(vcn0)    <- vcn0 not in run -> SPARSE_LCN
>      WARN_ON(1)                <- bug fires here!
>
> Reported-by: [email protected]
> Closes: https://syzkaller.appspot.com/bug?extid=c1e9aedbd913fadad617
> Fixes: c380b52f6c57 ("fs/ntfs3: Change new sparse cluster processing")
> Signed-off-by: Deepanshu Kartikey <[email protected]>
> ---
>   fs/ntfs3/attrib.c | 14 ++++++++++++++
>   1 file changed, 14 insertions(+)
>
> diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c
> index 6cb9bc5d605c..6ef7db82a35d 100644
> --- a/fs/ntfs3/attrib.c
> +++ b/fs/ntfs3/attrib.c
> @@ -1152,6 +1152,21 @@ int attr_data_get_block_locked(struct ntfs_inode *ni, CLST vcn, CLST clen,
>   			if (err)
>   				goto out;
>   		}
> +
> +		if (vcn0 < svcn || evcn1 <= vcn0) {
> +			struct ATTRIB *attr2;
> +
> +			attr2 = ni_find_attr(ni, attr_b, &le_b, ATTR_DATA, NULL,
> +					       0, &vcn0, &mi);
> +			if (!attr2) {
> +				err = -EINVAL;
> +				goto out;
> +			}
> +			err = attr_load_runs(attr2, ni, run, NULL);
> +			if (err)
> +				goto out;
> +		}
> +
>   		da = false; /* no delalloc for compressed file. */
>   	}
>   

Hello,

Queued for the next merge window, thank you.

Regards,
Konstantin
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.