| From 77260807d1170a8cf35dbb06e07461a655f67eee Mon Sep 17 00:00:00 2001 |
| From: Theodore Ts'o <tytso@mit.edu> |
| Date: Wed, 13 Jun 2018 23:08:26 -0400 |
| Subject: ext4: make sure bitmaps and the inode table don't overlap with bg descriptors |
| |
| From: Theodore Ts'o <tytso@mit.edu> |
| |
| commit 77260807d1170a8cf35dbb06e07461a655f67eee upstream. |
| |
| It's really bad when the allocation bitmaps and the inode table |
| overlap with the block group descriptors, since it causes random |
| corruption of the bg descriptors. So we really want to head those off |
| at the pass. |
| |
| https://bugzilla.kernel.org/show_bug.cgi?id=199865 |
| |
| Signed-off-by: Theodore Ts'o <tytso@mit.edu> |
| Cc: stable@kernel.org |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| fs/ext4/super.c | 25 +++++++++++++++++++++++++ |
| 1 file changed, 25 insertions(+) |
| |
| --- a/fs/ext4/super.c |
| +++ b/fs/ext4/super.c |
| @@ -2102,6 +2102,7 @@ static int ext4_check_descriptors(struct |
| struct ext4_sb_info *sbi = EXT4_SB(sb); |
| ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block); |
| ext4_fsblk_t last_block; |
| + ext4_fsblk_t last_bg_block = sb_block + ext4_bg_num_gdb(sb, 0) + 1; |
| ext4_fsblk_t block_bitmap; |
| ext4_fsblk_t inode_bitmap; |
| ext4_fsblk_t inode_table; |
| @@ -2134,6 +2135,14 @@ static int ext4_check_descriptors(struct |
| if (!(sb->s_flags & MS_RDONLY)) |
| return 0; |
| } |
| + if (block_bitmap >= sb_block + 1 && |
| + block_bitmap <= last_bg_block) { |
| + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " |
| + "Block bitmap for group %u overlaps " |
| + "block group descriptors", i); |
| + if (!(sb->s_flags & MS_RDONLY)) |
| + return 0; |
| + } |
| if (block_bitmap < first_block || block_bitmap > last_block) { |
| ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " |
| "Block bitmap for group %u not in group " |
| @@ -2148,6 +2157,14 @@ static int ext4_check_descriptors(struct |
| if (!(sb->s_flags & MS_RDONLY)) |
| return 0; |
| } |
| + if (inode_bitmap >= sb_block + 1 && |
| + inode_bitmap <= last_bg_block) { |
| + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " |
| + "Inode bitmap for group %u overlaps " |
| + "block group descriptors", i); |
| + if (!(sb->s_flags & MS_RDONLY)) |
| + return 0; |
| + } |
| if (inode_bitmap < first_block || inode_bitmap > last_block) { |
| ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " |
| "Inode bitmap for group %u not in group " |
| @@ -2162,6 +2179,14 @@ static int ext4_check_descriptors(struct |
| if (!(sb->s_flags & MS_RDONLY)) |
| return 0; |
| } |
| + if (inode_table >= sb_block + 1 && |
| + inode_table <= last_bg_block) { |
| + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " |
| + "Inode table for group %u overlaps " |
| + "block group descriptors", i); |
| + if (!(sb->s_flags & MS_RDONLY)) |
| + return 0; |
| + } |
| if (inode_table < first_block || |
| inode_table + sbi->s_itb_per_group - 1 > last_block) { |
| ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " |