--- /dev/null
+From 2e81a4eeedcaa66e35f58b81e0755b87057ce392 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 11 Aug 2016 12:38:55 -0400
+Subject: ext4: avoid deadlock when expanding inode size
+
+From: Jan Kara <jack@suse.cz>
+
+commit 2e81a4eeedcaa66e35f58b81e0755b87057ce392 upstream.
+
+When we need to move xattrs into external xattr block, we call
+ext4_xattr_block_set() from ext4_expand_extra_isize_ea(). That may end
+up calling ext4_mark_inode_dirty() again which will recurse back into
+the inode expansion code leading to deadlocks.
+
+Protect from recursion using EXT4_STATE_NO_EXPAND inode flag and move
+its management into ext4_expand_extra_isize_ea() since its manipulation
+is safe there (due to xattr_sem) from possible races with
+ext4_xattr_set_handle() which plays with it as well.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/inode.c | 2 --
+ fs/ext4/xattr.c | 19 +++++++++++++------
+ 2 files changed, 13 insertions(+), 8 deletions(-)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -5186,8 +5186,6 @@ int ext4_mark_inode_dirty(handle_t *hand
+ sbi->s_want_extra_isize,
+ iloc, handle);
+ if (ret) {
+- ext4_set_inode_state(inode,
+- EXT4_STATE_NO_EXPAND);
+ if (mnt_count !=
+ le16_to_cpu(sbi->s_es->s_mnt_count)) {
+ ext4_warning(inode->i_sb,
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -1269,12 +1269,14 @@ int ext4_expand_extra_isize_ea(struct in
+ int isize_diff; /* How much do we need to grow i_extra_isize */
+
+ down_write(&EXT4_I(inode)->xattr_sem);
++ /*
++ * Set EXT4_STATE_NO_EXPAND to avoid recursion when marking inode dirty
++ */
++ ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND);
+ retry:
+ isize_diff = new_extra_isize - EXT4_I(inode)->i_extra_isize;
+- if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) {
+- up_write(&EXT4_I(inode)->xattr_sem);
+- return 0;
+- }
++ if (EXT4_I(inode)->i_extra_isize >= new_extra_isize)
++ goto out;
+
+ header = IHDR(inode, raw_inode);
+ entry = IFIRST(header);
+@@ -1299,8 +1301,7 @@ retry:
+ (void *)header, total_ino,
+ inode->i_sb->s_blocksize);
+ EXT4_I(inode)->i_extra_isize = new_extra_isize;
+- error = 0;
+- goto cleanup;
++ goto out;
+ }
+
+ /*
+@@ -1460,6 +1461,8 @@ retry:
+ kfree(bs);
+ }
+ brelse(bh);
++out:
++ ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND);
+ up_write(&EXT4_I(inode)->xattr_sem);
+ return 0;
+
+@@ -1471,6 +1474,10 @@ cleanup:
+ kfree(is);
+ kfree(bs);
+ brelse(bh);
++ /*
++ * We deliberately leave EXT4_STATE_NO_EXPAND set here since inode
++ * size expansion failed.
++ */
+ up_write(&EXT4_I(inode)->xattr_sem);
+ return error;
+ }
--- /dev/null
+From b47820edd1634dc1208f9212b7ecfb4230610a23 Mon Sep 17 00:00:00 2001
+From: Daeho Jeong <daeho.jeong@samsung.com>
+Date: Sun, 3 Jul 2016 17:51:39 -0400
+Subject: ext4: avoid modifying checksum fields directly during checksum verification
+
+From: Daeho Jeong <daeho.jeong@samsung.com>
+
+commit b47820edd1634dc1208f9212b7ecfb4230610a23 upstream.
+
+We temporally change checksum fields in buffers of some types of
+metadata into '0' for verifying the checksum values. By doing this
+without locking the buffer, some metadata's checksums, which are
+being committed or written back to the storage, could be damaged.
+In our test, several metadata blocks were found with damaged metadata
+checksum value during recovery process. When we only verify the
+checksum value, we have to avoid modifying checksum fields directly.
+
+Signed-off-by: Daeho Jeong <daeho.jeong@samsung.com>
+Signed-off-by: Youngjin Gil <youngjin.gil@samsung.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Cc: Török Edwin <edwin@etorok.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/inode.c | 38 ++++++++++++++++++++++----------------
+ fs/ext4/namei.c | 9 ++++-----
+ fs/ext4/super.c | 18 +++++++++---------
+ fs/ext4/xattr.c | 13 +++++++------
+ 4 files changed, 42 insertions(+), 36 deletions(-)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -51,25 +51,31 @@ static __u32 ext4_inode_csum(struct inod
+ struct ext4_inode_info *ei)
+ {
+ struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+- __u16 csum_lo;
+- __u16 csum_hi = 0;
+ __u32 csum;
++ __u16 dummy_csum = 0;
++ int offset = offsetof(struct ext4_inode, i_checksum_lo);
++ unsigned int csum_size = sizeof(dummy_csum);
+
+- csum_lo = le16_to_cpu(raw->i_checksum_lo);
+- raw->i_checksum_lo = 0;
+- if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE &&
+- EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi)) {
+- csum_hi = le16_to_cpu(raw->i_checksum_hi);
+- raw->i_checksum_hi = 0;
+- }
+-
+- csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)raw,
+- EXT4_INODE_SIZE(inode->i_sb));
++ csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)raw, offset);
++ csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, csum_size);
++ offset += csum_size;
++ csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset,
++ EXT4_GOOD_OLD_INODE_SIZE - offset);
+
+- raw->i_checksum_lo = cpu_to_le16(csum_lo);
+- if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE &&
+- EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi))
+- raw->i_checksum_hi = cpu_to_le16(csum_hi);
++ if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) {
++ offset = offsetof(struct ext4_inode, i_checksum_hi);
++ csum = ext4_chksum(sbi, csum, (__u8 *)raw +
++ EXT4_GOOD_OLD_INODE_SIZE,
++ offset - EXT4_GOOD_OLD_INODE_SIZE);
++ if (EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi)) {
++ csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum,
++ csum_size);
++ offset += csum_size;
++ csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset,
++ EXT4_INODE_SIZE(inode->i_sb) -
++ offset);
++ }
++ }
+
+ return csum;
+ }
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -420,15 +420,14 @@ static __le32 ext4_dx_csum(struct inode
+ struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+ struct ext4_inode_info *ei = EXT4_I(inode);
+ __u32 csum;
+- __le32 save_csum;
+ int size;
++ __u32 dummy_csum = 0;
++ int offset = offsetof(struct dx_tail, dt_checksum);
+
+ size = count_offset + (count * sizeof(struct dx_entry));
+- save_csum = t->dt_checksum;
+- t->dt_checksum = 0;
+ csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)dirent, size);
+- csum = ext4_chksum(sbi, csum, (__u8 *)t, sizeof(struct dx_tail));
+- t->dt_checksum = save_csum;
++ csum = ext4_chksum(sbi, csum, (__u8 *)t, offset);
++ csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, sizeof(dummy_csum));
+
+ return cpu_to_le32(csum);
+ }
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -2030,23 +2030,25 @@ failed:
+ static __le16 ext4_group_desc_csum(struct super_block *sb, __u32 block_group,
+ struct ext4_group_desc *gdp)
+ {
+- int offset;
++ int offset = offsetof(struct ext4_group_desc, bg_checksum);
+ __u16 crc = 0;
+ __le32 le_group = cpu_to_le32(block_group);
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+
+ if (ext4_has_metadata_csum(sbi->s_sb)) {
+ /* Use new metadata_csum algorithm */
+- __le16 save_csum;
+ __u32 csum32;
++ __u16 dummy_csum = 0;
+
+- save_csum = gdp->bg_checksum;
+- gdp->bg_checksum = 0;
+ csum32 = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&le_group,
+ sizeof(le_group));
+- csum32 = ext4_chksum(sbi, csum32, (__u8 *)gdp,
+- sbi->s_desc_size);
+- gdp->bg_checksum = save_csum;
++ csum32 = ext4_chksum(sbi, csum32, (__u8 *)gdp, offset);
++ csum32 = ext4_chksum(sbi, csum32, (__u8 *)&dummy_csum,
++ sizeof(dummy_csum));
++ offset += sizeof(dummy_csum);
++ if (offset < sbi->s_desc_size)
++ csum32 = ext4_chksum(sbi, csum32, (__u8 *)gdp + offset,
++ sbi->s_desc_size - offset);
+
+ crc = csum32 & 0xFFFF;
+ goto out;
+@@ -2056,8 +2058,6 @@ static __le16 ext4_group_desc_csum(struc
+ if (!ext4_has_feature_gdt_csum(sb))
+ return 0;
+
+- offset = offsetof(struct ext4_group_desc, bg_checksum);
+-
+ crc = crc16(~0, sbi->s_es->s_uuid, sizeof(sbi->s_es->s_uuid));
+ crc = crc16(crc, (__u8 *)&le_group, sizeof(le_group));
+ crc = crc16(crc, (__u8 *)gdp, offset);
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -123,17 +123,18 @@ static __le32 ext4_xattr_block_csum(stru
+ {
+ struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
+ __u32 csum;
+- __le32 save_csum;
+ __le64 dsk_block_nr = cpu_to_le64(block_nr);
++ __u32 dummy_csum = 0;
++ int offset = offsetof(struct ext4_xattr_header, h_checksum);
+
+- save_csum = hdr->h_checksum;
+- hdr->h_checksum = 0;
+ csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&dsk_block_nr,
+ sizeof(dsk_block_nr));
+- csum = ext4_chksum(sbi, csum, (__u8 *)hdr,
+- EXT4_BLOCK_SIZE(inode->i_sb));
++ csum = ext4_chksum(sbi, csum, (__u8 *)hdr, offset);
++ csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, sizeof(dummy_csum));
++ offset += sizeof(dummy_csum);
++ csum = ext4_chksum(sbi, csum, (__u8 *)hdr + offset,
++ EXT4_BLOCK_SIZE(inode->i_sb) - offset);
+
+- hdr->h_checksum = save_csum;
+ return cpu_to_le32(csum);
+ }
+
--- /dev/null
+From 418c12d08dc64a45107c467ec1ba29b5e69b0715 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 11 Aug 2016 11:58:32 -0400
+Subject: ext4: fix xattr shifting when expanding inodes part 2
+
+From: Jan Kara <jack@suse.cz>
+
+commit 418c12d08dc64a45107c467ec1ba29b5e69b0715 upstream.
+
+When multiple xattrs need to be moved out of inode, we did not properly
+recompute total size of xattr headers in the inode and the new header
+position. Thus when moving the second and further xattr we asked
+ext4_xattr_shift_entries() to move too much and from the wrong place,
+resulting in possible xattr value corruption or general memory
+corruption.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/xattr.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -1423,6 +1423,7 @@ retry:
+ error = ext4_xattr_ibody_set(handle, inode, &i, is);
+ if (error)
+ goto cleanup;
++ total_ino -= entry_size;
+
+ entry = IFIRST(header);
+ if (entry_size + EXT4_XATTR_SIZE(size) >= isize_diff)
+@@ -1433,11 +1434,11 @@ retry:
+ ext4_xattr_shift_entries(entry, -shift_bytes,
+ (void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE +
+ EXT4_I(inode)->i_extra_isize + shift_bytes,
+- (void *)header, total_ino - entry_size,
+- inode->i_sb->s_blocksize);
++ (void *)header, total_ino, inode->i_sb->s_blocksize);
+
+ isize_diff -= shift_bytes;
+ EXT4_I(inode)->i_extra_isize += shift_bytes;
++ header = IHDR(inode, raw_inode);
+
+ i.name = b_entry_name;
+ i.value = buffer;
--- /dev/null
+From d0141191a20289f8955c1e03dad08e42e6f71ca9 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 11 Aug 2016 11:50:30 -0400
+Subject: ext4: fix xattr shifting when expanding inodes
+
+From: Jan Kara <jack@suse.cz>
+
+commit d0141191a20289f8955c1e03dad08e42e6f71ca9 upstream.
+
+The code in ext4_expand_extra_isize_ea() treated new_extra_isize
+argument sometimes as the desired target i_extra_isize and sometimes as
+the amount by which we need to grow current i_extra_isize. These happen
+to coincide when i_extra_isize is 0 which used to be the common case and
+so nobody noticed this until recently when we added i_projid to the
+inode and so i_extra_isize now needs to grow from 28 to 32 bytes.
+
+The result of these bugs was that we sometimes unnecessarily decided to
+move xattrs out of inode even if there was enough space and we often
+ended up corrupting in-inode xattrs because arguments to
+ext4_xattr_shift_entries() were just wrong. This could demonstrate
+itself as BUG_ON in ext4_xattr_shift_entries() triggering.
+
+Fix the problem by introducing new isize_diff variable and use it where
+appropriate.
+
+Reported-by: Dave Chinner <david@fromorbit.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/xattr.c | 27 ++++++++++++++-------------
+ 1 file changed, 14 insertions(+), 13 deletions(-)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -1264,11 +1264,13 @@ int ext4_expand_extra_isize_ea(struct in
+ size_t min_offs, free;
+ int total_ino;
+ void *base, *start, *end;
+- int extra_isize = 0, error = 0, tried_min_extra_isize = 0;
++ int error = 0, tried_min_extra_isize = 0;
+ int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize);
++ int isize_diff; /* How much do we need to grow i_extra_isize */
+
+ down_write(&EXT4_I(inode)->xattr_sem);
+ retry:
++ isize_diff = new_extra_isize - EXT4_I(inode)->i_extra_isize;
+ if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) {
+ up_write(&EXT4_I(inode)->xattr_sem);
+ return 0;
+@@ -1289,7 +1291,7 @@ retry:
+ total_ino = sizeof(struct ext4_xattr_ibody_header);
+
+ free = ext4_xattr_free_space(last, &min_offs, base, &total_ino);
+- if (free >= new_extra_isize) {
++ if (free >= isize_diff) {
+ entry = IFIRST(header);
+ ext4_xattr_shift_entries(entry, EXT4_I(inode)->i_extra_isize
+ - new_extra_isize, (void *)raw_inode +
+@@ -1321,7 +1323,7 @@ retry:
+ end = bh->b_data + bh->b_size;
+ min_offs = end - base;
+ free = ext4_xattr_free_space(first, &min_offs, base, NULL);
+- if (free < new_extra_isize) {
++ if (free < isize_diff) {
+ if (!tried_min_extra_isize && s_min_extra_isize) {
+ tried_min_extra_isize++;
+ new_extra_isize = s_min_extra_isize;
+@@ -1335,7 +1337,7 @@ retry:
+ free = inode->i_sb->s_blocksize;
+ }
+
+- while (new_extra_isize > 0) {
++ while (isize_diff > 0) {
+ size_t offs, size, entry_size;
+ struct ext4_xattr_entry *small_entry = NULL;
+ struct ext4_xattr_info i = {
+@@ -1366,7 +1368,7 @@ retry:
+ EXT4_XATTR_SIZE(le32_to_cpu(last->e_value_size)) +
+ EXT4_XATTR_LEN(last->e_name_len);
+ if (total_size <= free && total_size < min_total_size) {
+- if (total_size < new_extra_isize) {
++ if (total_size < isize_diff) {
+ small_entry = last;
+ } else {
+ entry = last;
+@@ -1423,20 +1425,19 @@ retry:
+ goto cleanup;
+
+ entry = IFIRST(header);
+- if (entry_size + EXT4_XATTR_SIZE(size) >= new_extra_isize)
+- shift_bytes = new_extra_isize;
++ if (entry_size + EXT4_XATTR_SIZE(size) >= isize_diff)
++ shift_bytes = isize_diff;
+ else
+ shift_bytes = entry_size + size;
+ /* Adjust the offsets and shift the remaining entries ahead */
+- ext4_xattr_shift_entries(entry, EXT4_I(inode)->i_extra_isize -
+- shift_bytes, (void *)raw_inode +
+- EXT4_GOOD_OLD_INODE_SIZE + extra_isize + shift_bytes,
++ ext4_xattr_shift_entries(entry, -shift_bytes,
++ (void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE +
++ EXT4_I(inode)->i_extra_isize + shift_bytes,
+ (void *)header, total_ino - entry_size,
+ inode->i_sb->s_blocksize);
+
+- extra_isize += shift_bytes;
+- new_extra_isize -= shift_bytes;
+- EXT4_I(inode)->i_extra_isize = extra_isize;
++ isize_diff -= shift_bytes;
++ EXT4_I(inode)->i_extra_isize += shift_bytes;
+
+ i.name = b_entry_name;
+ i.value = buffer;
--- /dev/null
+From 443a8c41cd49de66a3fda45b32b9860ea0292b84 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 11 Aug 2016 12:00:01 -0400
+Subject: ext4: properly align shifted xattrs when expanding inodes
+
+From: Jan Kara <jack@suse.cz>
+
+commit 443a8c41cd49de66a3fda45b32b9860ea0292b84 upstream.
+
+We did not count with the padding of xattr value when computing desired
+shift of xattrs in the inode when expanding i_extra_isize. As a result
+we could create unaligned start of inline xattrs. Account for alignment
+properly.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/xattr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -1429,7 +1429,7 @@ retry:
+ if (entry_size + EXT4_XATTR_SIZE(size) >= isize_diff)
+ shift_bytes = isize_diff;
+ else
+- shift_bytes = entry_size + size;
++ shift_bytes = entry_size + EXT4_XATTR_SIZE(size);
+ /* Adjust the offsets and shift the remaining entries ahead */
+ ext4_xattr_shift_entries(entry, -shift_bytes,
+ (void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE +
--- /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
+@@ -2093,6 +2093,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);
+@@ -2123,6 +2124,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 "
+@@ -2130,6 +2136,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 "
+@@ -2137,6 +2148,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: "
+@@ -3640,7 +3656,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!");
+ ret = -EFSCORRUPTED;
+ goto failed_mount2;
keys-fix-asn.1-indefinite-length-object-parsing.patch
kernel-add-noaudit-variant-of-ns_capable.patch
net-use-ns_capable_noaudit-when-determining-net-sysctl-permissions.patch
+ext4-validate-that-metadata-blocks-do-not-overlap-superblock.patch
+ext4-fix-xattr-shifting-when-expanding-inodes.patch
+ext4-fix-xattr-shifting-when-expanding-inodes-part-2.patch
+ext4-properly-align-shifted-xattrs-when-expanding-inodes.patch
+ext4-avoid-deadlock-when-expanding-inode-size.patch
+ext4-avoid-modifying-checksum-fields-directly-during-checksum-verification.patch