add patch factor-out-loop-for-freeing-inode-xattr-space
[ext4-patch-queue.git] / validate-that-metadata-blocks-do-not-overlap-superblock
blobc1ac2dd6597a8bd55348cc26e7e7f34c40ca9115
1 ext4: validate that metadata blocks do not overlap superblock
3 A number of fuzzing failures seem to be caused by allocation bitmaps
4 or other metadata blocks being pointed at the superblock.
6 This can cause kernel BUG or WARNings once the superblock is
7 overwritten, so validate the group descriptor blocks to make sure this
8 doesn't happen.
10 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
11 ---
12  fs/ext4/super.c | 18 +++++++++++++++++-
13  1 file changed, 17 insertions(+), 1 deletion(-)
15 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
16 index e2622ba..2942fda 100644
17 --- a/fs/ext4/super.c
18 +++ b/fs/ext4/super.c
19 @@ -2211,6 +2211,7 @@ void ext4_group_desc_csum_set(struct super_block *sb, __u32 block_group,
21  /* Called at mount-time, super-block is locked */
22  static int ext4_check_descriptors(struct super_block *sb,
23 +                                 ext4_fsblk_t sb_block,
24                                   ext4_group_t *first_not_zeroed)
25  {
26         struct ext4_sb_info *sbi = EXT4_SB(sb);
27 @@ -2241,6 +2242,11 @@ static int ext4_check_descriptors(struct super_block *sb,
28                         grp = i;
30                 block_bitmap = ext4_block_bitmap(sb, gdp);
31 +               if (block_bitmap == sb_block) {
32 +                       ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
33 +                                "Block bitmap for group %u overlaps "
34 +                                "superblock", i);
35 +               }
36                 if (block_bitmap < first_block || block_bitmap > last_block) {
37                         ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
38                                "Block bitmap for group %u not in group "
39 @@ -2248,6 +2254,11 @@ static int ext4_check_descriptors(struct super_block *sb,
40                         return 0;
41                 }
42                 inode_bitmap = ext4_inode_bitmap(sb, gdp);
43 +               if (inode_bitmap == sb_block) {
44 +                       ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
45 +                                "Inode bitmap for group %u overlaps "
46 +                                "superblock", i);
47 +               }
48                 if (inode_bitmap < first_block || inode_bitmap > last_block) {
49                         ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
50                                "Inode bitmap for group %u not in group "
51 @@ -2255,6 +2266,11 @@ static int ext4_check_descriptors(struct super_block *sb,
52                         return 0;
53                 }
54                 inode_table = ext4_inode_table(sb, gdp);
55 +               if (inode_table == sb_block) {
56 +                       ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
57 +                                "Inode table for group %u overlaps "
58 +                                "superblock", i);
59 +               }
60                 if (inode_table < first_block ||
61                     inode_table + sbi->s_itb_per_group - 1 > last_block) {
62                         ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
63 @@ -3757,7 +3773,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
64                         goto failed_mount2;
65                 }
66         }
67 -       if (!ext4_check_descriptors(sb, &first_not_zeroed)) {
68 +       if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) {
69                 ext4_msg(sb, KERN_ERR, "group descriptors corrupted!");
70                 ret = -EFSCORRUPTED;
71                 goto failed_mount2;