From: Greg Kroah-Hartman Date: Thu, 11 Oct 2018 09:21:01 +0000 (+0200) Subject: 3.18-stable patches X-Git-Tag: v3.18.124~30 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b7da765b66c38521e8baa6e9c659732c202f85fe;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches 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 --- 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 index 00000000000..4f905cc5e87 --- /dev/null +++ b/queue-3.18/ext4-add-corruption-check-in-ext4_xattr_set_entry.patch @@ -0,0 +1,101 @@ +From 5369a762c882c0b6e9599e4ebbb3a9ba9eee7e2d Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Wed, 13 Jun 2018 00:23:11 -0400 +Subject: ext4: add corruption check in ext4_xattr_set_entry() + +From: Theodore Ts'o + +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 +Reviewed-by: Andreas Dilger +[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 +Signed-off-by: Greg Hackmann +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..f74bc1907f4 --- /dev/null +++ b/queue-3.18/ext4-add-more-inode-number-paranoia-checks.patch @@ -0,0 +1,70 @@ +From c37e9e013469521d9adb932d17a1795c139b36db Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Sun, 17 Jun 2018 00:41:14 -0400 +Subject: ext4: add more inode number paranoia checks + +From: Theodore Ts'o + +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 +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings +Signed-off-by: Greg Hackmann +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..7031fc993d0 --- /dev/null +++ b/queue-3.18/ext4-always-check-block-group-bounds-in-ext4_init_block_bitmap.patch @@ -0,0 +1,60 @@ +From 819b23f1c501b17b9694325471789e6b5cc2d0d2 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +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 + +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 +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings +Signed-off-by: Greg Hackmann +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..f87517f61a0 --- /dev/null +++ b/queue-3.18/ext4-always-verify-the-magic-number-in-xattr-blocks.patch @@ -0,0 +1,50 @@ +From 513f86d73855ce556ea9522b6bfd79f87356dc3a Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Wed, 13 Jun 2018 00:51:28 -0400 +Subject: ext4: always verify the magic number in xattr blocks + +From: Theodore Ts'o + +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 +Reviewed-by: Andreas Dilger +Cc: stable@kernel.org +[ghackmann@google.com: 3.18 backport: adjust context] +Signed-off-by: Greg Hackmann +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..aa96b5ca015 --- /dev/null +++ b/queue-3.18/ext4-avoid-running-out-of-journal-credits-when-appending-to-an-inline-file.patch @@ -0,0 +1,125 @@ +From 8bc1379b82b8e809eef77a9fedbb75c6c297be19 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +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 + +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 +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings +Signed-off-by: Greg Hackmann +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..0aacd6d07f6 --- /dev/null +++ b/queue-3.18/ext4-fix-check-to-prevent-initializing-reserved-inodes.patch @@ -0,0 +1,73 @@ +From 5012284700775a4e6e3fbe7eac4c543c4874b559 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Sat, 28 Jul 2018 08:12:04 -0400 +Subject: ext4: fix check to prevent initializing reserved inodes + +From: Theodore Ts'o + +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 +Signed-off-by: Theodore Ts'o +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings +Signed-off-by: Greg Hackmann +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..fdf58bf34f9 --- /dev/null +++ b/queue-3.18/ext4-fix-false-negatives-and-false-positives-in-ext4_check_descriptors.patch @@ -0,0 +1,55 @@ +From 44de022c4382541cebdd6de4465d1f4f465ff1dd Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +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 + +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 +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings +Signed-off-by: Greg Hackmann +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..d412ff6f7a2 --- /dev/null +++ b/queue-3.18/ext4-never-move-the-system.data-xattr-out-of-the-inode-body.patch @@ -0,0 +1,41 @@ +From 8cdb5240ec5928b20490a2bb34cb87e9a5f40226 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +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 + +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 +[bwh: Backported to 3.16: adjust context] +Signed-off-by: Ben Hutchings +Signed-off-by: Greg Hackmann +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..fc89b2d8024 --- /dev/null +++ b/queue-3.18/ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch @@ -0,0 +1,140 @@ +From 8844618d8aa7a9973e7b527d038a2a589665002c Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +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 + +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 +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 +[ghackmann@google.com: forward-port to 3.18: adjust context] +Signed-off-by: Greg Hackmann +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..bd02aec40cb --- /dev/null +++ b/queue-3.18/jbd2-don-t-mark-block-as-modified-if-the-handle-is-out-of-credits.patch @@ -0,0 +1,46 @@ +From e09463f220ca9a1a1ecfda84fcda658f99a1f12a Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +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 + +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 +[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 +Signed-off-by: Greg Hackmann +Signed-off-by: Greg Kroah-Hartman +--- + 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--; + } + diff --git a/queue-3.18/series b/queue-3.18/series index 0659b5918dc..9cefb4c0db6 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -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