lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250807195700.GS2672022@frogsfrogsfrogs>
Date: Thu, 7 Aug 2025 12:57:00 -0700
From: "Darrick J. Wong" <djwong@...nel.org>
To: Ojaswin Mujoo <ojaswin@...ux.ibm.com>
Cc: linux-ext4@...r.kernel.org, Theodore Ts'o <tytso@....edu>,
	Ritesh Harjani <ritesh.list@...il.com>,
	Zhang Yi <yi.zhang@...wei.com>, linux-kernel@...r.kernel.org,
	linux-fsdevel@...r.kernel.org, Disha Goel <disgoel@...ux.ibm.com>
Subject: Re: [PATCH 1/2] ext4: Fix fsmap end of range reporting with bigalloc

On Tue, Aug 05, 2025 at 02:00:30PM +0530, Ojaswin Mujoo wrote:
> With bigalloc enabled, the logic to report last extent has a bug since
> we try to use cluster units instead of block units. This can cause an issue
> where extra incorrect entries might be returned back to the user. This was
> flagged by generic/365 with 64k bs and -O bigalloc.
> 
> ** Details of issue **
> 
> The issue was noticed on 5G 64k blocksize FS with -O bigalloc which has
> only 1 bg.
> 
> $ xfs_io -c "fsmap -d" /mnt/scratch
> 
>   0: 253:48 [0..127]: static fs metadata 128   /* sb */
>   1: 253:48 [128..255]: special 102:1 128   /* gdt */
>   3: 253:48 [256..383]: special 102:3 128   /* block bitmap */
>   4: 253:48 [384..2303]: unknown 1920       /* flex bg empty space */
>   5: 253:48 [2304..2431]: special 102:4 128   /* inode bitmap */
>   6: 253:48 [2432..4351]: unknown 1920      /* flex bg empty space */
>   7: 253:48 [4352..6911]: inodes 2560
>   8: 253:48 [6912..538623]: unknown 531712
>   9: 253:48 [538624..10485759]: free space 9947136
> 
> The issue can be seen with:
> 
> $ xfs_io -c "fsmap -d 0 3" /mnt/scratch
> 
>   0: 253:48 [0..127]: static fs metadata 128
>   1: 253:48 [384..2047]: unknown 1664
> 
> Only the first entry was expected to be returned but we get 2. This is
> because:
> 
> ext4_getfsmap_datadev()
>   first_cluster, last_cluster = 0
>   ...
>   info->gfi_last = true;
>   ext4_getfsmap_datadev_helper(sb, end_ag, last_cluster + 1, 0, info);
>     fsb = C2B(1) = 16
>     fslen = 0
>     ...
>     /* Merge in any relevant extents from the meta_list */
>     list_for_each_entry_safe(p, tmp, &info->gfi_meta_list, fmr_list) {
>       ...
>       // since fsb = 16, considers all metadata which starts before 16 blockno
>       iter 1: error = ext4_getfsmap_helper(sb, info, p);  // p = sb (0,1), nop
>         info->gfi_next_fsblk = 1
>       iter 2: error = ext4_getfsmap_helper(sb, info, p);  // p = gdt (1,2), nop
>         info->gfi_next_fsblk = 2
>       iter 3: error = ext4_getfsmap_helper(sb, info, p);  // p = blk bitmap (2,3), nop
>         info->gfi_next_fsblk = 3
>       iter 4: error = ext4_getfsmap_helper(sb, info, p);  // p = ino bitmap (18,19)
>         if (rec_blk > info->gfi_next_fsblk) { // (18 > 3)
>           // emits an extra entry ** BUG **
>         }
>     }
> 
> Fix this by directly calling ext4_getfsmap_datadev() with a dummy record
> that has fmr_physical set to (end_fsb + 1) instead of last_cluster + 1. By
> using the block instead of cluster we get the correct behavior.
> 
> Replacing ext4_getfsmap_datadev_helper() with ext4_getfsmap_helper() is
> okay since the gfi_lastfree and metadata checks in
> ext4_getfsmap_datadev_helper() are anyways redundant when we only want to
> emit the last allocated block of the range, as we have already taken care
> of emitting metadata and any last free blocks.
> 
> Reported-by: Disha Goel <disgoel@...ux.ibm.com>
> Fixes: 4a622e4d477b ("ext4: fix FS_IOC_GETFSMAP handling")
> Signed-off-by: Ojaswin Mujoo <ojaswin@...ux.ibm.com>

Looks fine to me
Reviewed-by: "Darrick J. Wong" <djwong@...nel.org>

--D

> ---
>  fs/ext4/fsmap.c | 15 ++++++++++++---
>  1 file changed, 12 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/ext4/fsmap.c b/fs/ext4/fsmap.c
> index 383c6edea6dd..9d63c39f6077 100644
> --- a/fs/ext4/fsmap.c
> +++ b/fs/ext4/fsmap.c
> @@ -526,6 +526,7 @@ static int ext4_getfsmap_datadev(struct super_block *sb,
>  	ext4_group_t end_ag;
>  	ext4_grpblk_t first_cluster;
>  	ext4_grpblk_t last_cluster;
> +	struct ext4_fsmap irec;
>  	int error = 0;
>  
>  	bofs = le32_to_cpu(sbi->s_es->s_first_data_block);
> @@ -609,10 +610,18 @@ static int ext4_getfsmap_datadev(struct super_block *sb,
>  			goto err;
>  	}
>  
> -	/* Report any gaps at the end of the bg */
> +	/*
> +	 * The dummy record below will cause ext4_getfsmap_helper() to report
> +	 * any allocated blocks at the end of the range.
> +	 */
> +	irec.fmr_device = 0;
> +	irec.fmr_physical = end_fsb + 1;
> +	irec.fmr_length = 0;
> +	irec.fmr_owner = EXT4_FMR_OWN_FREE;
> +	irec.fmr_flags = 0;
> +
>  	info->gfi_last = true;
> -	error = ext4_getfsmap_datadev_helper(sb, end_ag, last_cluster + 1,
> -					     0, info);
> +	error = ext4_getfsmap_helper(sb, info, &irec);
>  	if (error)
>  		goto err;
>  
> -- 
> 2.49.0
> 
> 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ