summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukas Czerner <lczerner@redhat.com>2018-04-24 11:31:44 -0400
committerTheodore Ts'o <tytso@mit.edu>2018-04-24 11:31:44 -0400
commit22be37acce25d66ecf6403fc8f44df9c5ded2372 (patch)
treecfaaf985798f7c7aa10a66d9cead8c89cb0ebe8c
parentb2569260d55228b617bd82aba6d0db2faeeb4116 (diff)
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 <lczerner@redhat.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu> Reported-by: Ilya Dryomov <idryomov@gmail.com> Fixes: 7dac4a1726a9 ("ext4: add validity checks for bitmap block numbers") Cc: stable@vger.kernel.org
-rw-r--r--fs/ext4/balloc.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index a33d8fb1bf2a..508b905d744d 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -321,6 +321,7 @@ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb,
321 struct ext4_sb_info *sbi = EXT4_SB(sb); 321 struct ext4_sb_info *sbi = EXT4_SB(sb);
322 ext4_grpblk_t offset; 322 ext4_grpblk_t offset;
323 ext4_grpblk_t next_zero_bit; 323 ext4_grpblk_t next_zero_bit;
324 ext4_grpblk_t max_bit = EXT4_CLUSTERS_PER_GROUP(sb);
324 ext4_fsblk_t blk; 325 ext4_fsblk_t blk;
325 ext4_fsblk_t group_first_block; 326 ext4_fsblk_t group_first_block;
326 327
@@ -338,7 +339,7 @@ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb,
338 /* check whether block bitmap block number is set */ 339 /* check whether block bitmap block number is set */
339 blk = ext4_block_bitmap(sb, desc); 340 blk = ext4_block_bitmap(sb, desc);
340 offset = blk - group_first_block; 341 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 ||
342 !ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data)) 343 !ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data))
343 /* bad block bitmap */ 344 /* bad block bitmap */
344 return blk; 345 return blk;
@@ -346,7 +347,7 @@ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb,
346 /* check whether the inode bitmap block number is set */ 347 /* check whether the inode bitmap block number is set */
347 blk = ext4_inode_bitmap(sb, desc); 348 blk = ext4_inode_bitmap(sb, desc);
348 offset = blk - group_first_block; 349 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 ||
350 !ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data)) 351 !ext4_test_bit(EXT4_B2C(sbi, offset), bh->b_data))
351 /* bad block bitmap */ 352 /* bad block bitmap */
352 return blk; 353 return blk;
@@ -354,8 +355,8 @@ static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb,
354 /* check whether the inode table block number is set */ 355 /* check whether the inode table block number is set */
355 blk = ext4_inode_table(sb, desc); 356 blk = ext4_inode_table(sb, desc);
356 offset = blk - group_first_block; 357 offset = blk - group_first_block;
357 if (offset < 0 || EXT4_B2C(sbi, offset) >= sb->s_blocksize || 358 if (offset < 0 || EXT4_B2C(sbi, offset) >= max_bit ||
358 EXT4_B2C(sbi, offset + sbi->s_itb_per_group) >= sb->s_blocksize) 359 EXT4_B2C(sbi, offset + sbi->s_itb_per_group) >= max_bit)
359 return blk; 360 return blk;
360 next_zero_bit = ext4_find_next_zero_bit(bh->b_data, 361 next_zero_bit = ext4_find_next_zero_bit(bh->b_data,
361 EXT4_B2C(sbi, offset + sbi->s_itb_per_group), 362 EXT4_B2C(sbi, offset + sbi->s_itb_per_group),