]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 11 Oct 2018 09:21:01 +0000 (11:21 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 11 Oct 2018 09:21:01 +0000 (11:21 +0200)
added patches:
ext4-add-corruption-check-in-ext4_xattr_set_entry.patch
ext4-add-more-inode-number-paranoia-checks.patch
ext4-always-check-block-group-bounds-in-ext4_init_block_bitmap.patch
ext4-always-verify-the-magic-number-in-xattr-blocks.patch
ext4-avoid-running-out-of-journal-credits-when-appending-to-an-inline-file.patch
ext4-fix-check-to-prevent-initializing-reserved-inodes.patch
ext4-fix-false-negatives-and-false-positives-in-ext4_check_descriptors.patch
ext4-never-move-the-system.data-xattr-out-of-the-inode-body.patch
ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch
jbd2-don-t-mark-block-as-modified-if-the-handle-is-out-of-credits.patch

queue-3.18/ext4-add-corruption-check-in-ext4_xattr_set_entry.patch [new file with mode: 0644]
queue-3.18/ext4-add-more-inode-number-paranoia-checks.patch [new file with mode: 0644]
queue-3.18/ext4-always-check-block-group-bounds-in-ext4_init_block_bitmap.patch [new file with mode: 0644]
queue-3.18/ext4-always-verify-the-magic-number-in-xattr-blocks.patch [new file with mode: 0644]
queue-3.18/ext4-avoid-running-out-of-journal-credits-when-appending-to-an-inline-file.patch [new file with mode: 0644]
queue-3.18/ext4-fix-check-to-prevent-initializing-reserved-inodes.patch [new file with mode: 0644]
queue-3.18/ext4-fix-false-negatives-and-false-positives-in-ext4_check_descriptors.patch [new file with mode: 0644]
queue-3.18/ext4-never-move-the-system.data-xattr-out-of-the-inode-body.patch [new file with mode: 0644]
queue-3.18/ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch [new file with mode: 0644]
queue-3.18/jbd2-don-t-mark-block-as-modified-if-the-handle-is-out-of-credits.patch [new file with mode: 0644]
queue-3.18/series

diff --git a/queue-3.18/ext4-add-corruption-check-in-ext4_xattr_set_entry.patch b/queue-3.18/ext4-add-corruption-check-in-ext4_xattr_set_entry.patch
new file mode 100644 (file)
index 0000000..4f905cc
--- /dev/null
@@ -0,0 +1,101 @@
+From 5369a762c882c0b6e9599e4ebbb3a9ba9eee7e2d Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Wed, 13 Jun 2018 00:23:11 -0400
+Subject: ext4: add corruption check in ext4_xattr_set_entry()
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 5369a762c882c0b6e9599e4ebbb3a9ba9eee7e2d upstream.
+
+In theory this should have been caught earlier when the xattr list was
+verified, but in case it got missed, it's simple enough to add check
+to make sure we don't overrun the xattr buffer.
+
+This addresses CVE-2018-10879.
+
+https://bugzilla.kernel.org/show_bug.cgi?id=200001
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Reviewed-by: Andreas Dilger <adilger@dilger.ca>
+[bwh: Backported to 3.16:
+ - Add inode parameter to ext4_xattr_set_entry() and update callers
+ - Return -EIO instead of -EFSCORRUPTED on error
+ - Adjust context]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Hackmann <ghackmann@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/xattr.c |   22 ++++++++++++++--------
+ 1 file changed, 14 insertions(+), 8 deletions(-)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -637,14 +637,20 @@ static size_t ext4_xattr_free_space(stru
+ }
+ static int
+-ext4_xattr_set_entry(struct ext4_xattr_info *i, struct ext4_xattr_search *s)
++ext4_xattr_set_entry(struct ext4_xattr_info *i, struct ext4_xattr_search *s,
++                   struct inode *inode)
+ {
+-      struct ext4_xattr_entry *last;
++      struct ext4_xattr_entry *last, *next;
+       size_t free, min_offs = s->end - s->base, name_len = strlen(i->name);
+       /* Compute min_offs and last. */
+       last = s->first;
+-      for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
++      for (; !IS_LAST_ENTRY(last); last = next) {
++              next = EXT4_XATTR_NEXT(last);
++              if ((void *)next >= s->end) {
++                      EXT4_ERROR_INODE(inode, "corrupted xattr entries");
++                      return -EIO;
++              }
+               if (!last->e_value_block && last->e_value_size) {
+                       size_t offs = le16_to_cpu(last->e_value_offs);
+                       if (offs < min_offs)
+@@ -825,7 +831,7 @@ ext4_xattr_block_set(handle_t *handle, s
+                               ce = NULL;
+                       }
+                       ea_bdebug(bs->bh, "modifying in-place");
+-                      error = ext4_xattr_set_entry(i, s);
++                      error = ext4_xattr_set_entry(i, s, inode);
+                       if (!error) {
+                               if (!IS_LAST_ENTRY(s->first))
+                                       ext4_xattr_rehash(header(s->base),
+@@ -877,7 +883,7 @@ ext4_xattr_block_set(handle_t *handle, s
+               s->end = s->base + sb->s_blocksize;
+       }
+-      error = ext4_xattr_set_entry(i, s);
++      error = ext4_xattr_set_entry(i, s, inode);
+       if (error == -EIO)
+               goto bad_block;
+       if (error)
+@@ -1038,7 +1044,7 @@ int ext4_xattr_ibody_inline_set(handle_t
+       if (EXT4_I(inode)->i_extra_isize == 0)
+               return -ENOSPC;
+-      error = ext4_xattr_set_entry(i, s);
++      error = ext4_xattr_set_entry(i, s, inode);
+       if (error) {
+               if (error == -ENOSPC &&
+                   ext4_has_inline_data(inode)) {
+@@ -1050,7 +1056,7 @@ int ext4_xattr_ibody_inline_set(handle_t
+                       error = ext4_xattr_ibody_find(inode, i, is);
+                       if (error)
+                               return error;
+-                      error = ext4_xattr_set_entry(i, s);
++                      error = ext4_xattr_set_entry(i, s, inode);
+               }
+               if (error)
+                       return error;
+@@ -1076,7 +1082,7 @@ static int ext4_xattr_ibody_set(handle_t
+       if (EXT4_I(inode)->i_extra_isize == 0)
+               return -ENOSPC;
+-      error = ext4_xattr_set_entry(i, s);
++      error = ext4_xattr_set_entry(i, s, inode);
+       if (error)
+               return error;
+       header = IHDR(inode, ext4_raw_inode(&is->iloc));
diff --git a/queue-3.18/ext4-add-more-inode-number-paranoia-checks.patch b/queue-3.18/ext4-add-more-inode-number-paranoia-checks.patch
new file mode 100644 (file)
index 0000000..f74bc19
--- /dev/null
@@ -0,0 +1,70 @@
+From c37e9e013469521d9adb932d17a1795c139b36db Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sun, 17 Jun 2018 00:41:14 -0400
+Subject: ext4: add more inode number paranoia checks
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit c37e9e013469521d9adb932d17a1795c139b36db upstream.
+
+If there is a directory entry pointing to a system inode (such as a
+journal inode), complain and declare the file system to be corrupted.
+
+Also, if the superblock's first inode number field is too small,
+refuse to mount the file system.
+
+This addresses CVE-2018-10882.
+
+https://bugzilla.kernel.org/show_bug.cgi?id=200069
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+[bwh: Backported to 3.16: adjust context]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Hackmann <ghackmann@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/ext4.h  |    5 -----
+ fs/ext4/inode.c |    3 ++-
+ fs/ext4/super.c |    5 +++++
+ 3 files changed, 7 insertions(+), 6 deletions(-)
+
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -1386,11 +1386,6 @@ static inline struct timespec ext4_curre
+ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
+ {
+       return ino == EXT4_ROOT_INO ||
+-              ino == EXT4_USR_QUOTA_INO ||
+-              ino == EXT4_GRP_QUOTA_INO ||
+-              ino == EXT4_BOOT_LOADER_INO ||
+-              ino == EXT4_JOURNAL_INO ||
+-              ino == EXT4_RESIZE_INO ||
+               (ino >= EXT4_FIRST_INO(sb) &&
+                ino <= le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count));
+ }
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -3737,7 +3737,8 @@ static int __ext4_get_inode_loc(struct i
+       int                     inodes_per_block, inode_offset;
+       iloc->bh = NULL;
+-      if (!ext4_valid_inum(sb, inode->i_ino))
++      if (inode->i_ino < EXT4_ROOT_INO ||
++          inode->i_ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count))
+               return -EIO;
+       iloc->block_group = (inode->i_ino - 1) / EXT4_INODES_PER_GROUP(sb);
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -3794,6 +3794,11 @@ static int ext4_fill_super(struct super_
+       } else {
+               sbi->s_inode_size = le16_to_cpu(es->s_inode_size);
+               sbi->s_first_ino = le32_to_cpu(es->s_first_ino);
++              if (sbi->s_first_ino < EXT4_GOOD_OLD_FIRST_INO) {
++                      ext4_msg(sb, KERN_ERR, "invalid first ino: %u",
++                               sbi->s_first_ino);
++                      goto failed_mount;
++              }
+               if ((sbi->s_inode_size < EXT4_GOOD_OLD_INODE_SIZE) ||
+                   (!is_power_of_2(sbi->s_inode_size)) ||
+                   (sbi->s_inode_size > blocksize)) {
diff --git a/queue-3.18/ext4-always-check-block-group-bounds-in-ext4_init_block_bitmap.patch b/queue-3.18/ext4-always-check-block-group-bounds-in-ext4_init_block_bitmap.patch
new file mode 100644 (file)
index 0000000..7031fc9
--- /dev/null
@@ -0,0 +1,60 @@
+From 819b23f1c501b17b9694325471789e6b5cc2d0d2 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Wed, 13 Jun 2018 23:00:48 -0400
+Subject: ext4: always check block group bounds in ext4_init_block_bitmap()
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 819b23f1c501b17b9694325471789e6b5cc2d0d2 upstream.
+
+Regardless of whether the flex_bg feature is set, we should always
+check to make sure the bits we are setting in the block bitmap are
+within the block group bounds.
+
+https://bugzilla.kernel.org/show_bug.cgi?id=199865
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+[bwh: Backported to 3.16: adjust context]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Hackmann <ghackmann@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/balloc.c |   10 +++-------
+ 1 file changed, 3 insertions(+), 7 deletions(-)
+
+--- a/fs/ext4/balloc.c
++++ b/fs/ext4/balloc.c
+@@ -184,7 +184,6 @@ static int ext4_init_block_bitmap(struct
+       unsigned int bit, bit_max;
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       ext4_fsblk_t start, tmp;
+-      int flex_bg = 0;
+       struct ext4_group_info *grp;
+       J_ASSERT_BH(bh, buffer_locked(bh));
+@@ -217,22 +216,19 @@ static int ext4_init_block_bitmap(struct
+       start = ext4_group_first_block_no(sb, block_group);
+-      if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
+-              flex_bg = 1;
+-
+       /* Set bits for block and inode bitmaps, and inode table */
+       tmp = ext4_block_bitmap(sb, gdp);
+-      if (!flex_bg || ext4_block_in_group(sb, tmp, block_group))
++      if (ext4_block_in_group(sb, tmp, block_group))
+               ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data);
+       tmp = ext4_inode_bitmap(sb, gdp);
+-      if (!flex_bg || ext4_block_in_group(sb, tmp, block_group))
++      if (ext4_block_in_group(sb, tmp, block_group))
+               ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data);
+       tmp = ext4_inode_table(sb, gdp);
+       for (; tmp < ext4_inode_table(sb, gdp) +
+                    sbi->s_itb_per_group; tmp++) {
+-              if (!flex_bg || ext4_block_in_group(sb, tmp, block_group))
++              if (ext4_block_in_group(sb, tmp, block_group))
+                       ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data);
+       }
diff --git a/queue-3.18/ext4-always-verify-the-magic-number-in-xattr-blocks.patch b/queue-3.18/ext4-always-verify-the-magic-number-in-xattr-blocks.patch
new file mode 100644 (file)
index 0000000..f87517f
--- /dev/null
@@ -0,0 +1,50 @@
+From 513f86d73855ce556ea9522b6bfd79f87356dc3a Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Wed, 13 Jun 2018 00:51:28 -0400
+Subject: ext4: always verify the magic number in xattr blocks
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 513f86d73855ce556ea9522b6bfd79f87356dc3a upstream.
+
+If there an inode points to a block which is also some other type of
+metadata block (such as a block allocation bitmap), the
+buffer_verified flag can be set when it was validated as that other
+metadata block type; however, it would make a really terrible external
+attribute block.  The reason why we use the verified flag is to avoid
+constantly reverifying the block.  However, it doesn't take much
+overhead to make sure the magic number of the xattr block is correct,
+and this will avoid potential crashes.
+
+This addresses CVE-2018-10879.
+
+https://bugzilla.kernel.org/show_bug.cgi?id=200001
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Reviewed-by: Andreas Dilger <adilger@dilger.ca>
+Cc: stable@kernel.org
+[ghackmann@google.com: 3.18 backport: adjust context]
+Signed-off-by: Greg Hackmann <ghackmann@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/xattr.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -218,12 +218,12 @@ ext4_xattr_check_block(struct inode *ino
+ {
+       int error;
+-      if (buffer_verified(bh))
+-              return 0;
+-
+       if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) ||
+           BHDR(bh)->h_blocks != cpu_to_le32(1))
+               return -EIO;
++      if (buffer_verified(bh))
++              return 0;
++
+       if (!ext4_xattr_block_csum_verify(inode, bh->b_blocknr, BHDR(bh)))
+               return -EIO;
+       error = ext4_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size,
diff --git a/queue-3.18/ext4-avoid-running-out-of-journal-credits-when-appending-to-an-inline-file.patch b/queue-3.18/ext4-avoid-running-out-of-journal-credits-when-appending-to-an-inline-file.patch
new file mode 100644 (file)
index 0000000..aa96b5c
--- /dev/null
@@ -0,0 +1,125 @@
+From 8bc1379b82b8e809eef77a9fedbb75c6c297be19 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sat, 16 Jun 2018 23:41:59 -0400
+Subject: ext4: avoid running out of journal credits when appending to an inline file
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 8bc1379b82b8e809eef77a9fedbb75c6c297be19 upstream.
+
+Use a separate journal transaction if it turns out that we need to
+convert an inline file to use an data block.  Otherwise we could end
+up failing due to not having journal credits.
+
+This addresses CVE-2018-10883.
+
+https://bugzilla.kernel.org/show_bug.cgi?id=200071
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+[bwh: Backported to 3.16: adjust context]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Hackmann <ghackmann@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/ext4.h   |    3 ---
+ fs/ext4/inline.c |   38 +-------------------------------------
+ fs/ext4/xattr.c  |   18 ++----------------
+ 3 files changed, 3 insertions(+), 56 deletions(-)
+
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -2663,9 +2663,6 @@ extern struct buffer_head *ext4_get_firs
+ extern int ext4_inline_data_fiemap(struct inode *inode,
+                                  struct fiemap_extent_info *fieinfo,
+                                  int *has_inline);
+-extern int ext4_try_to_evict_inline_data(handle_t *handle,
+-                                       struct inode *inode,
+-                                       int needed);
+ extern void ext4_inline_data_truncate(struct inode *inode, int *has_inline);
+ extern int ext4_convert_inline_data(struct inode *inode);
+--- a/fs/ext4/inline.c
++++ b/fs/ext4/inline.c
+@@ -873,11 +873,11 @@ retry_journal:
+       }
+       if (ret == -ENOSPC) {
++              ext4_journal_stop(handle);
+               ret = ext4_da_convert_inline_data_to_extent(mapping,
+                                                           inode,
+                                                           flags,
+                                                           fsdata);
+-              ext4_journal_stop(handle);
+               if (ret == -ENOSPC &&
+                   ext4_should_retry_alloc(inode->i_sb, &retries))
+                       goto retry_journal;
+@@ -1842,42 +1842,6 @@ out:
+       return (error < 0 ? error : 0);
+ }
+-/*
+- * Called during xattr set, and if we can sparse space 'needed',
+- * just create the extent tree evict the data to the outer block.
+- *
+- * We use jbd2 instead of page cache to move data to the 1st block
+- * so that the whole transaction can be committed as a whole and
+- * the data isn't lost because of the delayed page cache write.
+- */
+-int ext4_try_to_evict_inline_data(handle_t *handle,
+-                                struct inode *inode,
+-                                int needed)
+-{
+-      int error;
+-      struct ext4_xattr_entry *entry;
+-      struct ext4_inode *raw_inode;
+-      struct ext4_iloc iloc;
+-
+-      error = ext4_get_inode_loc(inode, &iloc);
+-      if (error)
+-              return error;
+-
+-      raw_inode = ext4_raw_inode(&iloc);
+-      entry = (struct ext4_xattr_entry *)((void *)raw_inode +
+-                                          EXT4_I(inode)->i_inline_off);
+-      if (EXT4_XATTR_LEN(entry->e_name_len) +
+-          EXT4_XATTR_SIZE(le32_to_cpu(entry->e_value_size)) < needed) {
+-              error = -ENOSPC;
+-              goto out;
+-      }
+-
+-      error = ext4_convert_inline_data_nolock(handle, inode, &iloc);
+-out:
+-      brelse(iloc.bh);
+-      return error;
+-}
+-
+ void ext4_inline_data_truncate(struct inode *inode, int *has_inline)
+ {
+       handle_t *handle;
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -1045,22 +1045,8 @@ int ext4_xattr_ibody_inline_set(handle_t
+       if (EXT4_I(inode)->i_extra_isize == 0)
+               return -ENOSPC;
+       error = ext4_xattr_set_entry(i, s, inode);
+-      if (error) {
+-              if (error == -ENOSPC &&
+-                  ext4_has_inline_data(inode)) {
+-                      error = ext4_try_to_evict_inline_data(handle, inode,
+-                                      EXT4_XATTR_LEN(strlen(i->name) +
+-                                      EXT4_XATTR_SIZE(i->value_len)));
+-                      if (error)
+-                              return error;
+-                      error = ext4_xattr_ibody_find(inode, i, is);
+-                      if (error)
+-                              return error;
+-                      error = ext4_xattr_set_entry(i, s, inode);
+-              }
+-              if (error)
+-                      return error;
+-      }
++      if (error)
++              return error;
+       header = IHDR(inode, ext4_raw_inode(&is->iloc));
+       if (!IS_LAST_ENTRY(s->first)) {
+               header->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC);
diff --git a/queue-3.18/ext4-fix-check-to-prevent-initializing-reserved-inodes.patch b/queue-3.18/ext4-fix-check-to-prevent-initializing-reserved-inodes.patch
new file mode 100644 (file)
index 0000000..0aacd6d
--- /dev/null
@@ -0,0 +1,73 @@
+From 5012284700775a4e6e3fbe7eac4c543c4874b559 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sat, 28 Jul 2018 08:12:04 -0400
+Subject: ext4: fix check to prevent initializing reserved inodes
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 5012284700775a4e6e3fbe7eac4c543c4874b559 upstream.
+
+Commit 8844618d8aa7: "ext4: only look at the bg_flags field if it is
+valid" will complain if block group zero does not have the
+EXT4_BG_INODE_ZEROED flag set.  Unfortunately, this is not correct,
+since a freshly created file system has this flag cleared.  It gets
+almost immediately after the file system is mounted read-write --- but
+the following somewhat unlikely sequence will end up triggering a
+false positive report of a corrupted file system:
+
+   mkfs.ext4 /dev/vdc
+   mount -o ro /dev/vdc /vdc
+   mount -o remount,rw /dev/vdc
+
+Instead, when initializing the inode table for block group zero, test
+to make sure that itable_unused count is not too large, since that is
+the case that will result in some or all of the reserved inodes
+getting cleared.
+
+This fixes the failures reported by Eric Whiteney when running
+generic/230 and generic/231 in the the nojournal test case.
+
+Fixes: 8844618d8aa7 ("ext4: only look at the bg_flags field if it is valid")
+Reported-by: Eric Whitney <enwlinux@gmail.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+[bwh: Backported to 3.16: adjust context]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Hackmann <ghackmann@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/ialloc.c |    5 ++++-
+ fs/ext4/super.c  |    8 +-------
+ 2 files changed, 5 insertions(+), 8 deletions(-)
+
+--- a/fs/ext4/ialloc.c
++++ b/fs/ext4/ialloc.c
+@@ -1253,7 +1253,10 @@ int ext4_init_inode_table(struct super_b
+                           ext4_itable_unused_count(sb, gdp)),
+                           sbi->s_inodes_per_block);
+-      if ((used_blks < 0) || (used_blks > sbi->s_itb_per_group)) {
++      if ((used_blks < 0) || (used_blks > sbi->s_itb_per_group) ||
++          ((group == 0) && ((EXT4_INODES_PER_GROUP(sb) -
++                             ext4_itable_unused_count(sb, gdp)) <
++                            EXT4_FIRST_INO(sb)))) {
+               ext4_error(sb, "Something is wrong with group %u: "
+                          "used itable blocks: %d; "
+                          "itable unused count: %u",
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -3140,14 +3140,8 @@ static ext4_group_t ext4_has_uninit_itab
+               if (!gdp)
+                       continue;
+-              if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED))
+-                      continue;
+-              if (group != 0)
++              if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED)))
+                       break;
+-              ext4_error(sb, "Inode table for bg 0 marked as "
+-                         "needing zeroing");
+-              if (sb->s_flags & MS_RDONLY)
+-                      return ngroups;
+       }
+       return group;
diff --git a/queue-3.18/ext4-fix-false-negatives-and-false-positives-in-ext4_check_descriptors.patch b/queue-3.18/ext4-fix-false-negatives-and-false-positives-in-ext4_check_descriptors.patch
new file mode 100644 (file)
index 0000000..fdf58bf
--- /dev/null
@@ -0,0 +1,55 @@
+From 44de022c4382541cebdd6de4465d1f4f465ff1dd Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sun, 8 Jul 2018 19:35:02 -0400
+Subject: ext4: fix false negatives *and* false positives in ext4_check_descriptors()
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 44de022c4382541cebdd6de4465d1f4f465ff1dd upstream.
+
+Ext4_check_descriptors() was getting called before s_gdb_count was
+initialized.  So for file systems w/o the meta_bg feature, allocation
+bitmaps could overlap the block group descriptors and ext4 wouldn't
+notice.
+
+For file systems with the meta_bg feature enabled, there was a
+fencepost error which would cause the ext4_check_descriptors() to
+incorrectly believe that the block allocation bitmap overlaps with the
+block group descriptor blocks, and it would reject the mount.
+
+Fix both of these problems.
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+[bwh: Backported to 3.16: adjust context]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Hackmann <ghackmann@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/super.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -2064,7 +2064,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 last_bg_block = sb_block + ext4_bg_num_gdb(sb, 0);
+       ext4_fsblk_t block_bitmap;
+       ext4_fsblk_t inode_bitmap;
+       ext4_fsblk_t inode_table;
+@@ -4018,12 +4018,12 @@ static int ext4_fill_super(struct super_
+                       goto failed_mount2;
+               }
+       }
++      sbi->s_gdb_count = db_count;
+       if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) {
+               ext4_msg(sb, KERN_ERR, "group descriptors corrupted!");
+               goto failed_mount2;
+       }
+-      sbi->s_gdb_count = db_count;
+       get_random_bytes(&sbi->s_next_generation, sizeof(u32));
+       spin_lock_init(&sbi->s_next_gen_lock);
diff --git a/queue-3.18/ext4-never-move-the-system.data-xattr-out-of-the-inode-body.patch b/queue-3.18/ext4-never-move-the-system.data-xattr-out-of-the-inode-body.patch
new file mode 100644 (file)
index 0000000..d412ff6
--- /dev/null
@@ -0,0 +1,41 @@
+From 8cdb5240ec5928b20490a2bb34cb87e9a5f40226 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sat, 16 Jun 2018 15:40:48 -0400
+Subject: ext4: never move the system.data xattr out of the inode body
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 8cdb5240ec5928b20490a2bb34cb87e9a5f40226 upstream.
+
+When expanding the extra isize space, we must never move the
+system.data xattr out of the inode body.  For performance reasons, it
+doesn't make any sense, and the inline data implementation assumes
+that system.data xattr is never in the external xattr block.
+
+This addresses CVE-2018-10880
+
+https://bugzilla.kernel.org/show_bug.cgi?id=200005
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+[bwh: Backported to 3.16: adjust context]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Hackmann <ghackmann@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/xattr.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -1391,6 +1391,11 @@ retry:
+               /* Find the entry best suited to be pushed into EA block */
+               entry = NULL;
+               for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) {
++                      /* never move system.data out of the inode */
++                      if ((last->e_name_len == 4) &&
++                          (last->e_name_index == EXT4_XATTR_INDEX_SYSTEM) &&
++                          !memcmp(last->e_name, "data", 4))
++                              continue;
+                       total_size =
+                       EXT4_XATTR_SIZE(le32_to_cpu(last->e_value_size)) +
+                                       EXT4_XATTR_LEN(last->e_name_len);
diff --git a/queue-3.18/ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch b/queue-3.18/ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch
new file mode 100644 (file)
index 0000000..fc89b2d
--- /dev/null
@@ -0,0 +1,140 @@
+From 8844618d8aa7a9973e7b527d038a2a589665002c Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Thu, 14 Jun 2018 00:58:00 -0400
+Subject: ext4: only look at the bg_flags field if it is valid
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 8844618d8aa7a9973e7b527d038a2a589665002c upstream.
+
+The bg_flags field in the block group descripts is only valid if the
+uninit_bg or metadata_csum feature is enabled.  We were not
+consistently looking at this field; fix this.
+
+Also block group #0 must never have uninitialized allocation bitmaps,
+or need to be zeroed, since that's where the root inode, and other
+special inodes are set up.  Check for these conditions and mark the
+file system as corrupted if they are detected.
+
+This addresses CVE-2018-10876.
+
+https://bugzilla.kernel.org/show_bug.cgi?id=199403
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+[bwh: Backported to 3.16:
+ - ext4_read_block_bitmap_nowait() and ext4_read_inode_bitmap() return
+   a pointer (NULL on error) instead of an error code
+ - Open-code sb_rdonly()
+ - Adjust context]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+[ghackmann@google.com: forward-port to 3.18: adjust context]
+Signed-off-by: Greg Hackmann <ghackmann@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/balloc.c  |   11 ++++++++++-
+ fs/ext4/ialloc.c  |   14 ++++++++++++--
+ fs/ext4/mballoc.c |    6 ++++--
+ fs/ext4/super.c   |   11 ++++++++++-
+ 4 files changed, 36 insertions(+), 6 deletions(-)
+
+--- a/fs/ext4/balloc.c
++++ b/fs/ext4/balloc.c
+@@ -451,9 +451,18 @@ ext4_read_block_bitmap_nowait(struct sup
+               goto verify;
+       }
+       ext4_lock_group(sb, block_group);
+-      if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
++      if (ext4_has_group_desc_csum(sb) &&
++          (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) {
+               int err;
++              if (block_group == 0) {
++                      ext4_unlock_group(sb, block_group);
++                      unlock_buffer(bh);
++                      ext4_error(sb, "Block bitmap for bg 0 marked "
++                                 "uninitialized");
++                      put_bh(bh);
++                      return NULL;
++              }
+               err = ext4_init_block_bitmap(sb, bh, block_group, desc);
+               set_bitmap_uptodate(bh);
+               set_buffer_uptodate(bh);
+--- a/fs/ext4/ialloc.c
++++ b/fs/ext4/ialloc.c
+@@ -117,7 +117,16 @@ ext4_read_inode_bitmap(struct super_bloc
+       }
+       ext4_lock_group(sb, block_group);
+-      if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
++      if (ext4_has_group_desc_csum(sb) &&
++          (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT))) {
++              if (block_group == 0) {
++                      ext4_unlock_group(sb, block_group);
++                      unlock_buffer(bh);
++                      ext4_error(sb, "Inode bitmap for bg 0 marked "
++                                 "uninitialized");
++                      put_bh(bh);
++                      return NULL;
++              }
+               memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8);
+               ext4_mark_bitmap_end(EXT4_INODES_PER_GROUP(sb),
+                                    sb->s_blocksize * 8, bh->b_data);
+@@ -873,7 +882,8 @@ got:
+               /* recheck and clear flag under lock if we still need to */
+               ext4_lock_group(sb, group);
+-              if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
++              if (ext4_has_group_desc_csum(sb) &&
++                  (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) {
+                       gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
+                       ext4_free_group_clusters_set(sb, gdp,
+                               ext4_free_clusters_after_init(sb, group, gdp));
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -2415,7 +2415,8 @@ int ext4_mb_add_groupinfo(struct super_b
+        * initialize bb_free to be able to skip
+        * empty groups without initialization
+        */
+-      if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
++      if (ext4_has_group_desc_csum(sb) &&
++          (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) {
+               meta_group_info[i]->bb_free =
+                       ext4_free_clusters_after_init(sb, group, desc);
+       } else {
+@@ -2942,7 +2943,8 @@ ext4_mb_mark_diskspace_used(struct ext4_
+ #endif
+       ext4_set_bits(bitmap_bh->b_data, ac->ac_b_ex.fe_start,
+                     ac->ac_b_ex.fe_len);
+-      if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
++      if (ext4_has_group_desc_csum(sb) &&
++          (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) {
+               gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT);
+               ext4_free_group_clusters_set(sb, gdp,
+                                            ext4_free_clusters_after_init(sb,
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -3132,13 +3132,22 @@ static ext4_group_t ext4_has_uninit_itab
+       ext4_group_t group, ngroups = EXT4_SB(sb)->s_groups_count;
+       struct ext4_group_desc *gdp = NULL;
++      if (!ext4_has_group_desc_csum(sb))
++              return ngroups;
++
+       for (group = 0; group < ngroups; group++) {
+               gdp = ext4_get_group_desc(sb, group, NULL);
+               if (!gdp)
+                       continue;
+-              if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED)))
++              if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED))
++                      continue;
++              if (group != 0)
+                       break;
++              ext4_error(sb, "Inode table for bg 0 marked as "
++                         "needing zeroing");
++              if (sb->s_flags & MS_RDONLY)
++                      return ngroups;
+       }
+       return group;
diff --git a/queue-3.18/jbd2-don-t-mark-block-as-modified-if-the-handle-is-out-of-credits.patch b/queue-3.18/jbd2-don-t-mark-block-as-modified-if-the-handle-is-out-of-credits.patch
new file mode 100644 (file)
index 0000000..bd02aec
--- /dev/null
@@ -0,0 +1,46 @@
+From e09463f220ca9a1a1ecfda84fcda658f99a1f12a Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sat, 16 Jun 2018 20:21:45 -0400
+Subject: jbd2: don't mark block as modified if the handle is out of credits
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit e09463f220ca9a1a1ecfda84fcda658f99a1f12a upstream.
+
+Do not set the b_modified flag in block's journal head should not
+until after we're sure that jbd2_journal_dirty_metadat() will not
+abort with an error due to there not being enough space reserved in
+the jbd2 handle.
+
+Otherwise, future attempts to modify the buffer may lead a large
+number of spurious errors and warnings.
+
+This addresses CVE-2018-10883.
+
+https://bugzilla.kernel.org/show_bug.cgi?id=200071
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+[bwh: Backported to 3.16: Drop the added logging statement, as it's on
+ a code path that doesn't exist here]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Hackmann <ghackmann@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/jbd2/transaction.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -1283,11 +1283,11 @@ int jbd2_journal_dirty_metadata(handle_t
+                * of the transaction. This needs to be done
+                * once a transaction -bzzz
+                */
+-              jh->b_modified = 1;
+               if (handle->h_buffer_credits <= 0) {
+                       ret = -ENOSPC;
+                       goto out_unlock_bh;
+               }
++              jh->b_modified = 1;
+               handle->h_buffer_credits--;
+       }
index 0659b5918dc3137c0e5f4fef2d2a1d966ed5d7e7..9cefb4c0db61d60a8dc5de94d54e705999072ab1 100644 (file)
@@ -105,3 +105,13 @@ pci-reprogram-bridge-prefetch-registers-on-resume.patch
 mac80211-fix-setting-ieee80211_key_flag_rx_mgmt-for-ap-mode-keys.patch
 pm-core-clear-the-direct_complete-flag-on-errors.patch
 usb-serial-simple-add-motorola-tetra-mtp6550-id.patch
+ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch
+ext4-fix-check-to-prevent-initializing-reserved-inodes.patch
+ext4-always-check-block-group-bounds-in-ext4_init_block_bitmap.patch
+ext4-fix-false-negatives-and-false-positives-in-ext4_check_descriptors.patch
+ext4-add-corruption-check-in-ext4_xattr_set_entry.patch
+ext4-always-verify-the-magic-number-in-xattr-blocks.patch
+ext4-never-move-the-system.data-xattr-out-of-the-inode-body.patch
+ext4-add-more-inode-number-paranoia-checks.patch
+jbd2-don-t-mark-block-as-modified-if-the-handle-is-out-of-credits.patch
+ext4-avoid-running-out-of-journal-credits-when-appending-to-an-inline-file.patch