--- /dev/null
+From 829fa70dddadf9dd041d62b82cd7cea63943899d Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Mon, 1 Aug 2016 00:51:02 -0400
+Subject: ext4: validate that metadata blocks do not overlap superblock
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 829fa70dddadf9dd041d62b82cd7cea63943899d upstream.
+
+A number of fuzzing failures seem to be caused by allocation bitmaps
+or other metadata blocks being pointed at the superblock.
+
+This can cause kernel BUG or WARNings once the superblock is
+overwritten, so validate the group descriptor blocks to make sure this
+doesn't happen.
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/super.c | 18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -2071,6 +2071,7 @@ void ext4_group_desc_csum_set(struct sup
+
+ /* Called at mount-time, super-block is locked */
+ static int ext4_check_descriptors(struct super_block *sb,
++ ext4_fsblk_t sb_block,
+ ext4_group_t *first_not_zeroed)
+ {
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+@@ -2101,6 +2102,11 @@ static int ext4_check_descriptors(struct
+ grp = i;
+
+ block_bitmap = ext4_block_bitmap(sb, gdp);
++ if (block_bitmap == sb_block) {
++ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
++ "Block bitmap for group %u overlaps "
++ "superblock", i);
++ }
+ 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 "
+@@ -2108,6 +2114,11 @@ static int ext4_check_descriptors(struct
+ return 0;
+ }
+ inode_bitmap = ext4_inode_bitmap(sb, gdp);
++ if (inode_bitmap == sb_block) {
++ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
++ "Inode bitmap for group %u overlaps "
++ "superblock", i);
++ }
+ 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 "
+@@ -2115,6 +2126,11 @@ static int ext4_check_descriptors(struct
+ return 0;
+ }
+ inode_table = ext4_inode_table(sb, gdp);
++ if (inode_table == sb_block) {
++ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
++ "Inode table for group %u overlaps "
++ "superblock", i);
++ }
+ if (inode_table < first_block ||
+ inode_table + sbi->s_itb_per_group - 1 > last_block) {
+ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
+@@ -3869,7 +3885,7 @@ static int ext4_fill_super(struct super_
+ goto failed_mount2;
+ }
+ }
+- if (!ext4_check_descriptors(sb, &first_not_zeroed)) {
++ if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) {
+ ext4_msg(sb, KERN_ERR, "group descriptors corrupted!");
+ goto failed_mount2;
+ }