From 7a90034e8d48471daf47d65f3c3b1e1f8ead3691 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Tue, 5 Jul 2016 20:05:41 -0400 Subject: [PATCH] add patch validate-reserved_gdt_blocks-on-mount --- series | 1 + timestamps | 7 ++--- validate-reserved_gdt_blocks-on-mount | 50 +++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 validate-reserved_gdt_blocks-on-mount diff --git a/series b/series index 99cb49ab..94208a9b 100644 --- a/series +++ b/series @@ -17,6 +17,7 @@ fix-deadlock-during-page-writeback fix-warn-on-once-in-ext4_commit_super dont-call-ext4_should_journal_data-on-journal-inode remove-unused-page_idx +validate-reserved_gdt_blocks-on-mount ########################################## # unstable patches diff --git a/timestamps b/timestamps index 367c204b..4ce108fa 100755 --- a/timestamps +++ b/timestamps @@ -45,7 +45,8 @@ touch -d @1467638021 fix-deadlock-during-page-writeback.orig touch -d @1467641641 fix-deadlock-during-page-writeback touch -d @1467642292 fix-warn-on-once-in-ext4_commit_super touch -d @1467644580 dont-call-ext4_should_journal_data-on-journal-inode -touch -d @1467749970 timestamps touch -d @1467750752 remove-unused-page_idx -touch -d @1467750782 series -touch -d @1467750790 status +touch -d @1467763312 validate-reserved_gdt_blocks-on-mount +touch -d @1467763423 timestamps +touch -d @1467763524 series +touch -d @1467763527 status diff --git a/validate-reserved_gdt_blocks-on-mount b/validate-reserved_gdt_blocks-on-mount new file mode 100644 index 00000000..69d57bc9 --- /dev/null +++ b/validate-reserved_gdt_blocks-on-mount @@ -0,0 +1,50 @@ +ext4: validate s_reserved_gdt_blocks on mount + +If s_reserved_gdt_blocks is extremely large, it's possible for +ext4_init_block_bitmap(), which is called when ext4 sets up an +uninitialized block bitmap, to corrupt random kernel memory. Add the +same checks which e2fsck has --- it must never be larger than +blocksize / sizeof(__u32) --- and then add a backup check in +ext4_init_block_bitmap() in case the superblock gets modified after +the file system is mounted. + +Reported-by: Vegard Nossum +Signed-off-by: Theodore Ts'o +Cc: stable@vger.kernel.org +--- + fs/ext4/balloc.c | 3 +++ + fs/ext4/super.c | 7 +++++++ + 2 files changed, 10 insertions(+) + +diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c +index 0b8105b..799a92b 100644 +--- a/fs/ext4/balloc.c ++++ b/fs/ext4/balloc.c +@@ -208,6 +208,9 @@ static int ext4_init_block_bitmap(struct super_block *sb, + memset(bh->b_data, 0, sb->s_blocksize); + + bit_max = ext4_num_base_meta_clusters(sb, block_group); ++ if ((bit_max >> 3) >= bh->b_size) ++ return -EFSCORRUPTED; ++ + for (bit = 0; bit < bit_max; bit++) + ext4_set_bit(bit, bh->b_data); + +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 5664ee6..13c49af7 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -3416,6 +3416,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) + goto failed_mount; + } + ++ if (le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) > (blocksize / 4)) { ++ ext4_msg(sb, KERN_ERR, ++ "Number of reserved GDT blocks insanely large: %d", ++ le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks)); ++ goto failed_mount; ++ } ++ + if (sbi->s_mount_opt & EXT4_MOUNT_DAX) { + err = bdev_dax_supported(sb, blocksize); + if (err) -- 2.11.4.GIT