Skip to content

Commit 22be37a

Browse files
Lukas Czernertytso
authored andcommitted
ext4: fix bitmap position validation
Currently in ext4_valid_block_bitmap() we expect the bitmap to be positioned anywhere between 0 and s_blocksize clusters, but that's wrong because the bitmap can be placed anywhere in the block group. This causes false positives when validating bitmaps on perfectly valid file system layouts. Fix it by checking whether the bitmap is within the group boundary. The problem can be reproduced using the following mkfs -t ext3 -E stride=256 /dev/vdb1 mount /dev/vdb1 /mnt/test cd /mnt/test wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.16.3.tar.xz tar xf linux-4.16.3.tar.xz This will result in the warnings in the logs EXT4-fs error (device vdb1): ext4_validate_block_bitmap:399: comm tar: bg 84: block 2774529: invalid block bitmap [ Changed slightly for clarity and to not drop a overflow test -- TYT ] Signed-off-by: Lukas Czerner <[email protected]> Signed-off-by: Theodore Ts'o <[email protected]> Reported-by: Ilya Dryomov <[email protected]> Fixes: 7dac4a1 ("ext4: add validity checks for bitmap block numbers") Cc: [email protected]
1 parent b256926 commit 22be37a

File tree

1 file changed

+5
-4
lines changed

1 file changed

+5
-4
lines changed

fs/ext4/balloc.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb,
321321
struct ext4_sb_info *sbi = EXT4_SB(sb);
322322
ext4_grpblk_t offset;
323323
ext4_grpblk_t next_zero_bit;
324+
ext4_grpblk_t max_bit = EXT4_CLUSTERS_PER_GROUP(sb);
324325
ext4_fsblk_t blk;
325326
ext4_fsblk_t group_first_block;
326327

@@ -338,24 +339,24 @@ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb,
338339
/* check whether block bitmap block number is set */
339340
blk = ext4_block_bitmap(sb, desc);
340341
offset = blk - group_first_block;
341-
if (offset < 0 || EXT4_B2C(sbi, offset) >= sb->s_blocksize ||
342+
if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit ||
342343
!ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data))
343344
/* bad block bitmap */
344345
return blk;
345346

346347
/* check whether the inode bitmap block number is set */
347348
blk = ext4_inode_bitmap(sb, desc);
348349
offset = blk - group_first_block;
349-
if (offset < 0 || EXT4_B2C(sbi, offset) >= sb->s_blocksize ||
350+
if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit ||
350351
!ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data))
351352
/* bad block bitmap */
352353
return blk;
353354

354355
/* check whether the inode table block number is set */
355356
blk = ext4_inode_table(sb, desc);
356357
offset = blk - group_first_block;
357-
if (offset < 0 || EXT4_B2C(sbi, offset) >= sb->s_blocksize ||
358-
EXT4_B2C(sbi, offset + sbi->s_itb_per_group) >= sb->s_blocksize)
358+
if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit ||
359+
EXT4_B2C(sbi, offset + sbi->s_itb_per_group) >= max_bit)
359360
return blk;
360361
next_zero_bit = ext4_find_next_zero_bit(bh->b_data,
361362
EXT4_B2C(sbi, offset + sbi->s_itb_per_group),

0 commit comments

Comments
 (0)