On Wed, Jun 10, 2026 at 01:55:47PM +0300, Mikhail Dmitrichenko wrote:
> bkey sizes are stored in sectors as u32, while fiemap reports byte
> lengths as u64. Shifting k.k->size before widening performs the
> conversion in 32 bits, so an extent of 4 GiB or larger can wrap before
> it is passed to fiemap_fill_next_extent().
> 
> Compute the byte length after casting the sector count to u64 and reuse
> it for all bch2_fill_extent() cases.
> 
> Found by Linux Verification Center (linuxtesting.org) with SVACE.
> 
> Signed-off-by: Mikhail Dmitrichenko <[email protected]>

Nice catch! Applied.

> ---
>  fs/bcachefs/vfs/fiemap.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/bcachefs/vfs/fiemap.c b/fs/bcachefs/vfs/fiemap.c
> index 067e191cf8d0..18a44622a7b0 100644
> --- a/fs/bcachefs/vfs/fiemap.c
> +++ b/fs/bcachefs/vfs/fiemap.c
> @@ -23,6 +23,7 @@ static int bch2_fill_extent(struct bch_fs *c,
>                           struct bch_fiemap_extent *fe)
>  {
>       struct bkey_s_c k = bkey_i_to_s_c(fe->kbuf.k);
> +     u64 len = (u64) k.k->size << 9;
>       unsigned flags = fe->flags;
>  
>       BUG_ON(!k.k->size);
> @@ -54,20 +55,20 @@ static int bch2_fill_extent(struct bch_fs *c,
>                       try(fiemap_fill_next_extent(info,
>                                               bkey_start_offset(k.k) << 9,
>                                               offset << 9,
> -                                             k.k->size << 9, flags|flags2));
> +                                             len, flags|flags2));
>               }
>  
>               return 0;
>       } else if (bkey_extent_is_inline_data(k.k)) {
>               return fiemap_fill_next_extent(info,
>                                              bkey_start_offset(k.k) << 9,
> -                                            0, k.k->size << 9,
> +                                            0, len,
>                                              flags|
>                                              FIEMAP_EXTENT_DATA_INLINE);
>       } else if (k.k->type == KEY_TYPE_reservation) {
>               return fiemap_fill_next_extent(info,
>                                              bkey_start_offset(k.k) << 9,
> -                                            0, k.k->size << 9,
> +                                            0, len,
>                                              flags|
>                                              FIEMAP_EXTENT_DELALLOC|
>                                              FIEMAP_EXTENT_UNWRITTEN);
> -- 
> 2.54.0.windows.1
> 

Reply via email to