diff options
author | Jan Kara <jack@suse.cz> | 2024-06-24 17:12:56 +0200 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2024-06-26 12:54:11 +0200 |
commit | 322a6aff03937aa1ece33b4e46c298eafaf9ac41 (patch) | |
tree | 8ef3271c7709f2da92d2db6c3d3d00bbc3b04629 /fs/ext2/balloc.c | |
parent | udf: prevent integer overflow in udf_bitmap_free_blocks() (diff) | |
download | linux-322a6aff03937aa1ece33b4e46c298eafaf9ac41.tar.xz linux-322a6aff03937aa1ece33b4e46c298eafaf9ac41.zip |
ext2: Verify bitmap and itable block numbers before using them
Verify bitmap block numbers and inode table blocks are sane before using
them for checking bits in the block bitmap.
CC: stable@vger.kernel.org
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/ext2/balloc.c')
-rw-r--r-- | fs/ext2/balloc.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index 1bfd6ab11038..b8cfab8f98b9 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c @@ -77,26 +77,33 @@ static int ext2_valid_block_bitmap(struct super_block *sb, ext2_grpblk_t next_zero_bit; ext2_fsblk_t bitmap_blk; ext2_fsblk_t group_first_block; + ext2_grpblk_t max_bit; group_first_block = ext2_group_first_block_no(sb, block_group); + max_bit = ext2_group_last_block_no(sb, block_group) - group_first_block; /* check whether block bitmap block number is set */ bitmap_blk = le32_to_cpu(desc->bg_block_bitmap); offset = bitmap_blk - group_first_block; - if (!ext2_test_bit(offset, bh->b_data)) + if (offset < 0 || offset > max_bit || + !ext2_test_bit(offset, bh->b_data)) /* bad block bitmap */ goto err_out; /* check whether the inode bitmap block number is set */ bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap); offset = bitmap_blk - group_first_block; - if (!ext2_test_bit(offset, bh->b_data)) + if (offset < 0 || offset > max_bit || + !ext2_test_bit(offset, bh->b_data)) /* bad block bitmap */ goto err_out; /* check whether the inode table block number is set */ bitmap_blk = le32_to_cpu(desc->bg_inode_table); offset = bitmap_blk - group_first_block; + if (offset < 0 || offset > max_bit || + offset + EXT2_SB(sb)->s_itb_per_group - 1 > max_bit) + goto err_out; next_zero_bit = ext2_find_next_zero_bit(bh->b_data, offset + EXT2_SB(sb)->s_itb_per_group, offset); |