]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
btrfs: tree-checker: ensure free space tree entries won't overflow
authorQu Wenruo <wqu@suse.com>
Mon, 11 May 2026 00:56:50 +0000 (10:26 +0930)
committerDavid Sterba <dsterba@suse.com>
Mon, 8 Jun 2026 13:53:33 +0000 (15:53 +0200)
Add an extra check to ensure the free space extent/bitmap and space info
keys won't overflow.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/tree-checker.c

index caaf4115d0d9b9fa3f017721b63de51bf6f88a9e..5431f71e2a471fd1bb0d6d061f2585cf78f4d362 100644 (file)
@@ -2102,6 +2102,7 @@ static int check_free_space_info(struct extent_buffer *leaf, struct btrfs_key *k
        struct btrfs_fs_info *fs_info = leaf->fs_info;
        struct btrfs_free_space_info *fsi;
        const u32 blocksize = fs_info->sectorsize;
+       u64 end;
        u32 flags;
 
        if (unlikely(!IS_ALIGNED(key->objectid, blocksize))) {
@@ -2116,6 +2117,12 @@ static int check_free_space_info(struct extent_buffer *leaf, struct btrfs_key *k
                            blocksize, BTRFS_KEY_FMT_VALUE(key));
                return -EUCLEAN;
        }
+       if (unlikely(check_add_overflow(key->objectid, key->offset, &end))) {
+               generic_err(leaf, slot,
+                           "free space info key overflows, has " BTRFS_KEY_FMT,
+                           BTRFS_KEY_FMT_VALUE(key));
+               return -EUCLEAN;
+       }
        if (unlikely(btrfs_item_size(leaf, slot) !=
                     sizeof(struct btrfs_free_space_info))) {
                generic_err(leaf, slot,
@@ -2148,6 +2155,7 @@ static int check_free_space_common_key(struct extent_buffer *leaf, struct btrfs_
        struct btrfs_fs_info *fs_info = leaf->fs_info;
        const u32 blocksize = fs_info->sectorsize;
        const char *type_str = (key->type == BTRFS_FREE_SPACE_EXTENT_KEY) ? "extent" : "bitmap";
+       u64 end;
 
        if (unlikely(!IS_ALIGNED(key->objectid, blocksize))) {
                generic_err(leaf, slot,
@@ -2165,6 +2173,12 @@ static int check_free_space_common_key(struct extent_buffer *leaf, struct btrfs_
                generic_err(leaf, slot, "free space %s length is 0", type_str);
                return -EUCLEAN;
        }
+       if (unlikely(check_add_overflow(key->objectid, key->offset, &end))) {
+               generic_err(leaf, slot,
+                           "free space %s end overflow, have objectid %llu offset %llu",
+                           type_str, key->objectid, key->offset);
+               return -EUCLEAN;
+       }
        return 0;
 }