summaryrefslogtreecommitdiffstats
path: root/queue-3.16
diff options
context:
space:
mode:
authorBen Hutchings <ben@decadent.org.uk>2018-09-13 20:00:21 +0100
committerBen Hutchings <ben@decadent.org.uk>2018-09-13 20:00:21 +0100
commit8e318d2dbee66930f40a40c3b782bc26291f818e (patch)
tree4d40ab488941522e21fb6458841b1ae9285b9052 /queue-3.16
parent5e2643d1961aff902ca81943f7f18de615297745 (diff)
downloadlinux-stable-queue-8e318d2dbee66930f40a40c3b782bc26291f818e.tar.gz
Add various security fixes
Diffstat (limited to 'queue-3.16')
-rw-r--r--queue-3.16/bluetooth-hidp-buffer-overflow-in-hidp_process_report.patch46
-rw-r--r--queue-3.16/ext4-add-corruption-check-in-ext4_xattr_set_entry.patch93
-rw-r--r--queue-3.16/ext4-add-more-inode-number-paranoia-checks.patch65
-rw-r--r--queue-3.16/ext4-always-check-block-group-bounds-in-ext4_init_block_bitmap.patch55
-rw-r--r--queue-3.16/ext4-always-verify-the-magic-number-in-xattr-blocks.patch45
-rw-r--r--queue-3.16/ext4-avoid-running-out-of-journal-credits-when-appending-to-an.patch116
-rw-r--r--queue-3.16/ext4-clear-i_data-in-ext4_inode_info-when-removing-inline-data.patch43
-rw-r--r--queue-3.16/ext4-don-t-allow-r-w-mounts-if-metadata-blocks-overlap-the.patch56
-rw-r--r--queue-3.16/ext4-fix-check-to-prevent-initializing-reserved-inodes.patch68
-rw-r--r--queue-3.16/ext4-fix-false-negatives-and-false-positives-in.patch53
-rw-r--r--queue-3.16/ext4-make-sure-bitmaps-and-the-inode-table-don-t-overlap-with-bg.patch76
-rw-r--r--queue-3.16/ext4-never-move-the-system.data-xattr-out-of-the-inode-body.patch36
-rw-r--r--queue-3.16/ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch133
-rw-r--r--queue-3.16/ext4-verify-the-depth-of-extent-tree-in-ext4_find_extent.patch47
-rw-r--r--queue-3.16/fix-up-non-directory-creation-in-sgid-directories.patch43
-rw-r--r--queue-3.16/infiniband-fix-a-possible-use-after-free-bug.patch51
-rw-r--r--queue-3.16/jbd2-don-t-mark-block-as-modified-if-the-handle-is-out-of-credits.patch38
-rw-r--r--queue-3.16/scsi-libsas-defer-ata-device-eh-commands-to-libata.patch127
-rw-r--r--queue-3.16/series21
-rw-r--r--queue-3.16/usb-yurex-fix-out-of-bounds-uaccess-in-read-handler.patch65
-rw-r--r--queue-3.16/x86-entry-64-remove-ebx-handling-from-error_entry-exit.patch133
-rw-r--r--queue-3.16/xfs-set-format-back-to-extents-if-xfs_bmap_extents_to_btree.patch37
22 files changed, 1447 insertions, 0 deletions
diff --git a/queue-3.16/bluetooth-hidp-buffer-overflow-in-hidp_process_report.patch b/queue-3.16/bluetooth-hidp-buffer-overflow-in-hidp_process_report.patch
new file mode 100644
index 00000000..4d68332d
--- /dev/null
+++ b/queue-3.16/bluetooth-hidp-buffer-overflow-in-hidp_process_report.patch
@@ -0,0 +1,46 @@
+From: Mark Salyzyn <salyzyn@android.com>
+Date: Tue, 31 Jul 2018 15:02:13 -0700
+Subject: Bluetooth: hidp: buffer overflow in hidp_process_report
+
+commit 7992c18810e568b95c869b227137a2215702a805 upstream.
+
+CVE-2018-9363
+
+The buffer length is unsigned at all layers, but gets cast to int and
+checked in hidp_process_report and can lead to a buffer overflow.
+Switch len parameter to unsigned int to resolve issue.
+
+This affects 3.18 and newer kernels.
+
+Signed-off-by: Mark Salyzyn <salyzyn@android.com>
+Fixes: a4b1b5877b514b276f0f31efe02388a9c2836728 ("HID: Bluetooth: hidp: make sure input buffers are big enough")
+Cc: Marcel Holtmann <marcel@holtmann.org>
+Cc: Johan Hedberg <johan.hedberg@gmail.com>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Kees Cook <keescook@chromium.org>
+Cc: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Cc: linux-bluetooth@vger.kernel.org
+Cc: netdev@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org
+Cc: security@kernel.org
+Cc: kernel-team@android.com
+Acked-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ net/bluetooth/hidp/core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/bluetooth/hidp/core.c
++++ b/net/bluetooth/hidp/core.c
+@@ -429,8 +429,8 @@ static void hidp_del_timer(struct hidp_s
+ del_timer(&session->timer);
+ }
+
+-static void hidp_process_report(struct hidp_session *session,
+- int type, const u8 *data, int len, int intr)
++static void hidp_process_report(struct hidp_session *session, int type,
++ const u8 *data, unsigned int len, int intr)
+ {
+ if (len > HID_MAX_BUFFER_SIZE)
+ len = HID_MAX_BUFFER_SIZE;
diff --git a/queue-3.16/ext4-add-corruption-check-in-ext4_xattr_set_entry.patch b/queue-3.16/ext4-add-corruption-check-in-ext4_xattr_set_entry.patch
new file mode 100644
index 00000000..c98f9442
--- /dev/null
+++ b/queue-3.16/ext4-add-corruption-check-in-ext4_xattr_set_entry.patch
@@ -0,0 +1,93 @@
+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()
+
+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>
+---
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -610,14 +610,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)
+@@ -798,7 +804,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),
+@@ -851,7 +857,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)
+@@ -1021,7 +1027,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)) {
+@@ -1033,7 +1039,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;
+@@ -1059,7 +1065,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.16/ext4-add-more-inode-number-paranoia-checks.patch b/queue-3.16/ext4-add-more-inode-number-paranoia-checks.patch
new file mode 100644
index 00000000..f4c9eb29
--- /dev/null
+++ b/queue-3.16/ext4-add-more-inode-number-paranoia-checks.patch
@@ -0,0 +1,65 @@
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sun, 17 Jun 2018 00:41:14 -0400
+Subject: ext4: add more inode number paranoia checks
+
+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>
+---
+ 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
+@@ -1422,11 +1422,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
+@@ -3957,7 +3957,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
+@@ -3771,6 +3771,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.16/ext4-always-check-block-group-bounds-in-ext4_init_block_bitmap.patch b/queue-3.16/ext4-always-check-block-group-bounds-in-ext4_init_block_bitmap.patch
new file mode 100644
index 00000000..218f5482
--- /dev/null
+++ b/queue-3.16/ext4-always-check-block-group-bounds-in-ext4_init_block_bitmap.patch
@@ -0,0 +1,55 @@
+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()
+
+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>
+---
+ 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.16/ext4-always-verify-the-magic-number-in-xattr-blocks.patch b/queue-3.16/ext4-always-verify-the-magic-number-in-xattr-blocks.patch
new file mode 100644
index 00000000..579f63c7
--- /dev/null
+++ b/queue-3.16/ext4-always-verify-the-magic-number-in-xattr-blocks.patch
@@ -0,0 +1,45 @@
+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
+
+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>
+[bwh: Backported to 3.16: adjust context]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ fs/ext4/xattr.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -213,12 +213,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))
+ return -EIO;
+ error = ext4_xattr_check_names(BFIRST(bh), bh->b_data + bh->b_size,
diff --git a/queue-3.16/ext4-avoid-running-out-of-journal-credits-when-appending-to-an.patch b/queue-3.16/ext4-avoid-running-out-of-journal-credits-when-appending-to-an.patch
new file mode 100644
index 00000000..af1d0b4c
--- /dev/null
+++ b/queue-3.16/ext4-avoid-running-out-of-journal-credits-when-appending-to-an.patch
@@ -0,0 +1,116 @@
+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
+
+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>
+---
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -2701,9 +2701,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
+@@ -877,11 +877,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;
+@@ -1839,42 +1839,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
+@@ -1028,22 +1028,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.16/ext4-clear-i_data-in-ext4_inode_info-when-removing-inline-data.patch b/queue-3.16/ext4-clear-i_data-in-ext4_inode_info-when-removing-inline-data.patch
new file mode 100644
index 00000000..41fe68a4
--- /dev/null
+++ b/queue-3.16/ext4-clear-i_data-in-ext4_inode_info-when-removing-inline-data.patch
@@ -0,0 +1,43 @@
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Fri, 15 Jun 2018 12:28:16 -0400
+Subject: ext4: clear i_data in ext4_inode_info when removing inline data
+
+commit 6e8ab72a812396996035a37e5ca4b3b99b5d214b upstream.
+
+When converting from an inode from storing the data in-line to a data
+block, ext4_destroy_inline_data_nolock() was only clearing the on-disk
+copy of the i_blocks[] array. It was not clearing copy of the
+i_blocks[] in ext4_inode_info, in i_data[], which is the copy actually
+used by ext4_map_blocks().
+
+This didn't matter much if we are using extents, since the extents
+header would be invalid and thus the extents could would re-initialize
+the extents tree. But if we are using indirect blocks, the previous
+contents of the i_blocks array will be treated as block numbers, with
+potentially catastrophic results to the file system integrity and/or
+user data.
+
+This gets worse if the file system is using a 1k block size and
+s_first_data is zero, but even without this, the file system can get
+quite badly corrupted.
+
+This addresses CVE-2018-10881.
+
+https://bugzilla.kernel.org/show_bug.cgi?id=200015
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ fs/ext4/inline.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/ext4/inline.c
++++ b/fs/ext4/inline.c
+@@ -438,6 +438,7 @@ static int ext4_destroy_inline_data_nolo
+
+ memset((void *)ext4_raw_inode(&is.iloc)->i_block,
+ 0, EXT4_MIN_INLINE_DATA_SIZE);
++ memset(ei->i_data, 0, EXT4_MIN_INLINE_DATA_SIZE);
+
+ if (EXT4_HAS_INCOMPAT_FEATURE(inode->i_sb,
+ EXT4_FEATURE_INCOMPAT_EXTENTS)) {
diff --git a/queue-3.16/ext4-don-t-allow-r-w-mounts-if-metadata-blocks-overlap-the.patch b/queue-3.16/ext4-don-t-allow-r-w-mounts-if-metadata-blocks-overlap-the.patch
new file mode 100644
index 00000000..2adfd509
--- /dev/null
+++ b/queue-3.16/ext4-don-t-allow-r-w-mounts-if-metadata-blocks-overlap-the.patch
@@ -0,0 +1,56 @@
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Thu, 29 Mar 2018 22:10:35 -0400
+Subject: ext4: don't allow r/w mounts if metadata blocks overlap the
+ superblock
+
+commit 18db4b4e6fc31eda838dd1c1296d67dbcb3dc957 upstream.
+
+If some metadata block, such as an allocation bitmap, overlaps the
+superblock, it's very likely that if the file system is mounted
+read/write, the results will not be pretty. So disallow r/w mounts
+for file systems corrupted in this particular way.
+
+Backport notes:
+3.18.y is missing bc98a42c1f7d ("VFS: Convert sb->s_flags & MS_RDONLY
+to sb_rdonly(sb)") and e462ec50cb5f ("VFS: Differentiate mount flags
+(MS_*) from internal superblock flags") so we simply use the sb
+MS_RDONLY check from pre bc98a42c1f7d in place of the sb_rdonly
+function used in the upstream variant of the patch.
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Harsh Shandilya <harsh@prjkt.io>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ fs/ext4/super.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -2115,6 +2115,8 @@ static int ext4_check_descriptors(struct
+ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
+ "Block bitmap for group %u overlaps "
+ "superblock", i);
++ if (!(sb->s_flags & MS_RDONLY))
++ return 0;
+ }
+ if (block_bitmap < first_block || block_bitmap > last_block) {
+ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
+@@ -2127,6 +2129,8 @@ static int ext4_check_descriptors(struct
+ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
+ "Inode bitmap for group %u overlaps "
+ "superblock", i);
++ if (!(sb->s_flags & MS_RDONLY))
++ return 0;
+ }
+ if (inode_bitmap < first_block || inode_bitmap > last_block) {
+ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
+@@ -2139,6 +2143,8 @@ static int ext4_check_descriptors(struct
+ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
+ "Inode table for group %u overlaps "
+ "superblock", i);
++ if (!(sb->s_flags & MS_RDONLY))
++ return 0;
+ }
+ if (inode_table < first_block ||
+ inode_table + sbi->s_itb_per_group - 1 > last_block) {
diff --git a/queue-3.16/ext4-fix-check-to-prevent-initializing-reserved-inodes.patch b/queue-3.16/ext4-fix-check-to-prevent-initializing-reserved-inodes.patch
new file mode 100644
index 00000000..e095c6ec
--- /dev/null
+++ b/queue-3.16/ext4-fix-check-to-prevent-initializing-reserved-inodes.patch
@@ -0,0 +1,68 @@
+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
+
+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>
+---
+ 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
+@@ -1289,7 +1289,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
+@@ -3088,14 +3088,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.16/ext4-fix-false-negatives-and-false-positives-in.patch b/queue-3.16/ext4-fix-false-negatives-and-false-positives-in.patch
new file mode 100644
index 00000000..10f67953
--- /dev/null
+++ b/queue-3.16/ext4-fix-false-negatives-and-false-positives-in.patch
@@ -0,0 +1,53 @@
+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()
+
+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>
+---
+ fs/ext4/super.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -2086,7 +2086,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;
+@@ -3987,6 +3987,7 @@ 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;
+@@ -3999,7 +4000,6 @@ static int ext4_fill_super(struct super_
+ 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.16/ext4-make-sure-bitmaps-and-the-inode-table-don-t-overlap-with-bg.patch b/queue-3.16/ext4-make-sure-bitmaps-and-the-inode-table-don-t-overlap-with-bg.patch
new file mode 100644
index 00000000..48efb4a7
--- /dev/null
+++ b/queue-3.16/ext4-make-sure-bitmaps-and-the-inode-table-don-t-overlap-with-bg.patch
@@ -0,0 +1,76 @@
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Wed, 13 Jun 2018 23:08:26 -0400
+Subject: ext4: make sure bitmaps and the inode table don't overlap with bg
+ descriptors
+
+commit 77260807d1170a8cf35dbb06e07461a655f67eee upstream.
+
+It's really bad when the allocation bitmaps and the inode table
+overlap with the block group descriptors, since it causes random
+corruption of the bg descriptors. So we really want to head those off
+at the pass.
+
+https://bugzilla.kernel.org/show_bug.cgi?id=199865
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+[bwh: Backported to 3.16: Open-code sb_rdonly()]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ fs/ext4/super.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -2086,6 +2086,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 block_bitmap;
+ ext4_fsblk_t inode_bitmap;
+ ext4_fsblk_t inode_table;
+@@ -2118,6 +2119,14 @@ static int ext4_check_descriptors(struct
+ if (!(sb->s_flags & MS_RDONLY))
+ return 0;
+ }
++ if (block_bitmap >= sb_block + 1 &&
++ block_bitmap <= last_bg_block) {
++ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
++ "Block bitmap for group %u overlaps "
++ "block group descriptors", i);
++ if (!(sb->s_flags & MS_RDONLY))
++ return 0;
++ }
+ 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 "
+@@ -2132,6 +2141,14 @@ static int ext4_check_descriptors(struct
+ if (!(sb->s_flags & MS_RDONLY))
+ return 0;
+ }
++ if (inode_bitmap >= sb_block + 1 &&
++ inode_bitmap <= last_bg_block) {
++ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
++ "Inode bitmap for group %u overlaps "
++ "block group descriptors", i);
++ if (!(sb->s_flags & MS_RDONLY))
++ return 0;
++ }
+ 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 "
+@@ -2146,6 +2163,14 @@ static int ext4_check_descriptors(struct
+ if (!(sb->s_flags & MS_RDONLY))
+ return 0;
+ }
++ if (inode_table >= sb_block + 1 &&
++ inode_table <= last_bg_block) {
++ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
++ "Inode table for group %u overlaps "
++ "block group descriptors", i);
++ if (!(sb->s_flags & MS_RDONLY))
++ return 0;
++ }
+ if (inode_table < first_block ||
+ inode_table + sbi->s_itb_per_group - 1 > last_block) {
+ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: "
diff --git a/queue-3.16/ext4-never-move-the-system.data-xattr-out-of-the-inode-body.patch b/queue-3.16/ext4-never-move-the-system.data-xattr-out-of-the-inode-body.patch
new file mode 100644
index 00000000..7a79e66d
--- /dev/null
+++ b/queue-3.16/ext4-never-move-the-system.data-xattr-out-of-the-inode-body.patch
@@ -0,0 +1,36 @@
+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
+
+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>
+---
+ fs/ext4/xattr.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -1370,6 +1370,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.16/ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch b/queue-3.16/ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch
new file mode 100644
index 00000000..a3df4672
--- /dev/null
+++ b/queue-3.16/ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch
@@ -0,0 +1,133 @@
+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
+
+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>
+[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>
+---
+ 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
+@@ -453,9 +453,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
+@@ -156,7 +156,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;
++ }
+ ext4_init_inode_bitmap(sb, bh, block_group, desc);
+ set_bitmap_uptodate(bh);
+ set_buffer_uptodate(bh);
+@@ -910,7 +919,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
+@@ -2418,7 +2418,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 {
+@@ -2943,7 +2944,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
+@@ -3080,13 +3080,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.16/ext4-verify-the-depth-of-extent-tree-in-ext4_find_extent.patch b/queue-3.16/ext4-verify-the-depth-of-extent-tree-in-ext4_find_extent.patch
new file mode 100644
index 00000000..a5e0cfbf
--- /dev/null
+++ b/queue-3.16/ext4-verify-the-depth-of-extent-tree-in-ext4_find_extent.patch
@@ -0,0 +1,47 @@
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Thu, 14 Jun 2018 12:55:10 -0400
+Subject: ext4: verify the depth of extent tree in ext4_find_extent()
+
+commit bc890a60247171294acc0bd67d211fa4b88d40ba upstream.
+
+If there is a corupted file system where the claimed depth of the
+extent tree is -1, this can cause a massive buffer overrun leading to
+sadness.
+
+This addresses CVE-2018-10877.
+
+https://bugzilla.kernel.org/show_bug.cgi?id=199417
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+[bwh: Backported to 3.16: return -EIO instead of -EFSCORRUPTED]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ fs/ext4/ext4_extents.h | 1 +
+ fs/ext4/extents.c | 6 ++++++
+ 2 files changed, 7 insertions(+)
+
+--- a/fs/ext4/ext4_extents.h
++++ b/fs/ext4/ext4_extents.h
+@@ -103,6 +103,7 @@ struct ext4_extent_header {
+ };
+
+ #define EXT4_EXT_MAGIC cpu_to_le16(0xf30a)
++#define EXT4_MAX_EXTENT_DEPTH 5
+
+ #define EXT4_EXTENT_TAIL_OFFSET(hdr) \
+ (sizeof(struct ext4_extent_header) + \
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -851,6 +851,12 @@ ext4_ext_find_extent(struct inode *inode
+
+ eh = ext_inode_hdr(inode);
+ depth = ext_depth(inode);
++ if (depth < 0 || depth > EXT4_MAX_EXTENT_DEPTH) {
++ EXT4_ERROR_INODE(inode, "inode has invalid extent depth: %d",
++ depth);
++ ret = -EIO;
++ goto err;
++ }
+
+ /* account possible depth increase */
+ if (!path) {
diff --git a/queue-3.16/fix-up-non-directory-creation-in-sgid-directories.patch b/queue-3.16/fix-up-non-directory-creation-in-sgid-directories.patch
new file mode 100644
index 00000000..3c3d8633
--- /dev/null
+++ b/queue-3.16/fix-up-non-directory-creation-in-sgid-directories.patch
@@ -0,0 +1,43 @@
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Tue, 3 Jul 2018 17:10:19 -0700
+Subject: Fix up non-directory creation in SGID directories
+
+commit 0fa3ecd87848c9c93c2c828ef4c3a8ca36ce46c7 upstream.
+
+sgid directories have special semantics, making newly created files in
+the directory belong to the group of the directory, and newly created
+subdirectories will also become sgid. This is historically used for
+group-shared directories.
+
+But group directories writable by non-group members should not imply
+that such non-group members can magically join the group, so make sure
+to clear the sgid bit on non-directories for non-members (but remember
+that sgid without group execute means "mandatory locking", just to
+confuse things even more).
+
+Reported-by: Jann Horn <jannh@google.com>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ fs/inode.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -1827,8 +1827,14 @@ void inode_init_owner(struct inode *inod
+ inode->i_uid = current_fsuid();
+ if (dir && dir->i_mode & S_ISGID) {
+ inode->i_gid = dir->i_gid;
++
++ /* Directories are special, and always inherit S_ISGID */
+ if (S_ISDIR(mode))
+ mode |= S_ISGID;
++ else if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP) &&
++ !in_group_p(inode->i_gid) &&
++ !capable_wrt_inode_uidgid(dir, CAP_FSETID))
++ mode &= ~S_ISGID;
+ } else
+ inode->i_gid = current_fsgid();
+ inode->i_mode = mode;
diff --git a/queue-3.16/infiniband-fix-a-possible-use-after-free-bug.patch b/queue-3.16/infiniband-fix-a-possible-use-after-free-bug.patch
new file mode 100644
index 00000000..b3895b1c
--- /dev/null
+++ b/queue-3.16/infiniband-fix-a-possible-use-after-free-bug.patch
@@ -0,0 +1,51 @@
+From: Cong Wang <xiyou.wangcong@gmail.com>
+Date: Fri, 1 Jun 2018 11:31:44 -0700
+Subject: infiniband: fix a possible use-after-free bug
+
+commit cb2595c1393b4a5211534e6f0a0fbad369e21ad8 upstream.
+
+ucma_process_join() will free the new allocated "mc" struct,
+if there is any error after that, especially the copy_to_user().
+
+But in parallel, ucma_leave_multicast() could find this "mc"
+through idr_find() before ucma_process_join() frees it, since it
+is already published.
+
+So "mc" could be used in ucma_leave_multicast() after it is been
+allocated and freed in ucma_process_join(), since we don't refcnt
+it.
+
+Fix this by separating "publish" from ID allocation, so that we
+can get an ID first and publish it later after copy_to_user().
+
+Fixes: c8f6a362bf3e ("RDMA/cma: Add multicast communication support")
+Reported-by: Noam Rathaus <noamr@beyondsecurity.com>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ drivers/infiniband/core/ucma.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/infiniband/core/ucma.c
++++ b/drivers/infiniband/core/ucma.c
+@@ -180,7 +180,7 @@ static struct ucma_multicast* ucma_alloc
+ return NULL;
+
+ mutex_lock(&mut);
+- mc->id = idr_alloc(&multicast_idr, mc, 0, 0, GFP_KERNEL);
++ mc->id = idr_alloc(&multicast_idr, NULL, 0, 0, GFP_KERNEL);
+ mutex_unlock(&mut);
+ if (mc->id < 0)
+ goto error;
+@@ -1285,6 +1285,10 @@ static ssize_t ucma_process_join(struct
+ goto err3;
+ }
+
++ mutex_lock(&mut);
++ idr_replace(&multicast_idr, mc, mc->id);
++ mutex_unlock(&mut);
++
+ mutex_unlock(&file->mut);
+ ucma_put_ctx(ctx);
+ return 0;
diff --git a/queue-3.16/jbd2-don-t-mark-block-as-modified-if-the-handle-is-out-of-credits.patch b/queue-3.16/jbd2-don-t-mark-block-as-modified-if-the-handle-is-out-of-credits.patch
new file mode 100644
index 00000000..48dcac3a
--- /dev/null
+++ b/queue-3.16/jbd2-don-t-mark-block-as-modified-if-the-handle-is-out-of-credits.patch
@@ -0,0 +1,38 @@
+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
+
+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>
+---
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -1288,11 +1288,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.16/scsi-libsas-defer-ata-device-eh-commands-to-libata.patch b/queue-3.16/scsi-libsas-defer-ata-device-eh-commands-to-libata.patch
new file mode 100644
index 00000000..46cc6429
--- /dev/null
+++ b/queue-3.16/scsi-libsas-defer-ata-device-eh-commands-to-libata.patch
@@ -0,0 +1,127 @@
+From: Jason Yan <yanaijie@huawei.com>
+Date: Thu, 8 Mar 2018 10:34:53 +0800
+Subject: scsi: libsas: defer ata device eh commands to libata
+
+commit 318aaf34f1179b39fa9c30fa0f3288b645beee39 upstream.
+
+When ata device doing EH, some commands still attached with tasks are
+not passed to libata when abort failed or recover failed, so libata did
+not handle these commands. After these commands done, sas task is freed,
+but ata qc is not freed. This will cause ata qc leak and trigger a
+warning like below:
+
+WARNING: CPU: 0 PID: 28512 at drivers/ata/libata-eh.c:4037
+ata_eh_finish+0xb4/0xcc
+CPU: 0 PID: 28512 Comm: kworker/u32:2 Tainted: G W OE 4.14.0#1
+......
+Call trace:
+[<ffff0000088b7bd0>] ata_eh_finish+0xb4/0xcc
+[<ffff0000088b8420>] ata_do_eh+0xc4/0xd8
+[<ffff0000088b8478>] ata_std_error_handler+0x44/0x8c
+[<ffff0000088b8068>] ata_scsi_port_error_handler+0x480/0x694
+[<ffff000008875fc4>] async_sas_ata_eh+0x4c/0x80
+[<ffff0000080f6be8>] async_run_entry_fn+0x4c/0x170
+[<ffff0000080ebd70>] process_one_work+0x144/0x390
+[<ffff0000080ec100>] worker_thread+0x144/0x418
+[<ffff0000080f2c98>] kthread+0x10c/0x138
+[<ffff0000080855dc>] ret_from_fork+0x10/0x18
+
+If ata qc leaked too many, ata tag allocation will fail and io blocked
+for ever.
+
+As suggested by Dan Williams, defer ata device commands to libata and
+merge sas_eh_finish_cmd() with sas_eh_defer_cmd(). libata will handle
+ata qcs correctly after this.
+
+Signed-off-by: Jason Yan <yanaijie@huawei.com>
+CC: Xiaofei Tan <tanxiaofei@huawei.com>
+CC: John Garry <john.garry@huawei.com>
+CC: Dan Williams <dan.j.williams@intel.com>
+Reviewed-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ drivers/scsi/libsas/sas_scsi_host.c | 33 ++++++++++++-----------------
+ 1 file changed, 13 insertions(+), 20 deletions(-)
+
+--- a/drivers/scsi/libsas/sas_scsi_host.c
++++ b/drivers/scsi/libsas/sas_scsi_host.c
+@@ -250,6 +250,7 @@ out_done:
+ static void sas_eh_finish_cmd(struct scsi_cmnd *cmd)
+ {
+ struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(cmd->device->host);
++ struct domain_device *dev = cmd_to_domain_dev(cmd);
+ struct sas_task *task = TO_SAS_TASK(cmd);
+
+ /* At this point, we only get called following an actual abort
+@@ -258,6 +259,14 @@ static void sas_eh_finish_cmd(struct scs
+ */
+ sas_end_task(cmd, task);
+
++ if (dev_is_sata(dev)) {
++ /* defer commands to libata so that libata EH can
++ * handle ata qcs correctly
++ */
++ list_move_tail(&cmd->eh_entry, &sas_ha->eh_ata_q);
++ return;
++ }
++
+ /* now finish the command and move it on to the error
+ * handler done list, this also takes it off the
+ * error handler pending list.
+@@ -265,22 +274,6 @@ static void sas_eh_finish_cmd(struct scs
+ scsi_eh_finish_cmd(cmd, &sas_ha->eh_done_q);
+ }
+
+-static void sas_eh_defer_cmd(struct scsi_cmnd *cmd)
+-{
+- struct domain_device *dev = cmd_to_domain_dev(cmd);
+- struct sas_ha_struct *ha = dev->port->ha;
+- struct sas_task *task = TO_SAS_TASK(cmd);
+-
+- if (!dev_is_sata(dev)) {
+- sas_eh_finish_cmd(cmd);
+- return;
+- }
+-
+- /* report the timeout to libata */
+- sas_end_task(cmd, task);
+- list_move_tail(&cmd->eh_entry, &ha->eh_ata_q);
+-}
+-
+ static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd *my_cmd)
+ {
+ struct scsi_cmnd *cmd, *n;
+@@ -288,7 +281,7 @@ static void sas_scsi_clear_queue_lu(stru
+ list_for_each_entry_safe(cmd, n, error_q, eh_entry) {
+ if (cmd->device->sdev_target == my_cmd->device->sdev_target &&
+ cmd->device->lun == my_cmd->device->lun)
+- sas_eh_defer_cmd(cmd);
++ sas_eh_finish_cmd(cmd);
+ }
+ }
+
+@@ -677,12 +670,12 @@ static void sas_eh_handle_sas_errors(str
+ case TASK_IS_DONE:
+ SAS_DPRINTK("%s: task 0x%p is done\n", __func__,
+ task);
+- sas_eh_defer_cmd(cmd);
++ sas_eh_finish_cmd(cmd);
+ continue;
+ case TASK_IS_ABORTED:
+ SAS_DPRINTK("%s: task 0x%p is aborted\n",
+ __func__, task);
+- sas_eh_defer_cmd(cmd);
++ sas_eh_finish_cmd(cmd);
+ continue;
+ case TASK_IS_AT_LU:
+ SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task);
+@@ -693,7 +686,7 @@ static void sas_eh_handle_sas_errors(str
+ "recovered\n",
+ SAS_ADDR(task->dev),
+ cmd->device->lun);
+- sas_eh_defer_cmd(cmd);
++ sas_eh_finish_cmd(cmd);
+ sas_scsi_clear_queue_lu(work_q, cmd);
+ goto Again;
+ }
diff --git a/queue-3.16/series b/queue-3.16/series
index ff6ba44c..9263751b 100644
--- a/queue-3.16/series
+++ b/queue-3.16/series
@@ -18,3 +18,24 @@ kvm-x86-use-correct-privilege-level-for-sgdt-sidt-fxsave-fxrstor-access.patch
sr-pass-down-correctly-sized-scsi-sense-buffer.patch
jfs-fix-inconsistency-between-memory-allocation-and-ea_buf-max_size.patch
scsi-sg-allocate-with-__gfp_zero-in-sg_build_indirect.patch
+bluetooth-hidp-buffer-overflow-in-hidp_process_report.patch
+scsi-libsas-defer-ata-device-eh-commands-to-libata.patch
+xfs-set-format-back-to-extents-if-xfs_bmap_extents_to_btree.patch
+ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch
+ext4-fix-check-to-prevent-initializing-reserved-inodes.patch
+ext4-verify-the-depth-of-extent-tree-in-ext4_find_extent.patch
+ext4-always-check-block-group-bounds-in-ext4_init_block_bitmap.patch
+ext4-don-t-allow-r-w-mounts-if-metadata-blocks-overlap-the.patch
+ext4-make-sure-bitmaps-and-the-inode-table-don-t-overlap-with-bg.patch
+ext4-fix-false-negatives-and-false-positives-in.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-clear-i_data-in-ext4_inode_info-when-removing-inline-data.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.patch
+fix-up-non-directory-creation-in-sgid-directories.patch
+x86-entry-64-remove-ebx-handling-from-error_entry-exit.patch
+infiniband-fix-a-possible-use-after-free-bug.patch
+usb-yurex-fix-out-of-bounds-uaccess-in-read-handler.patch
diff --git a/queue-3.16/usb-yurex-fix-out-of-bounds-uaccess-in-read-handler.patch b/queue-3.16/usb-yurex-fix-out-of-bounds-uaccess-in-read-handler.patch
new file mode 100644
index 00000000..f3839ee3
--- /dev/null
+++ b/queue-3.16/usb-yurex-fix-out-of-bounds-uaccess-in-read-handler.patch
@@ -0,0 +1,65 @@
+From: Jann Horn <jannh@google.com>
+Date: Fri, 6 Jul 2018 17:12:56 +0200
+Subject: USB: yurex: fix out-of-bounds uaccess in read handler
+
+commit f1e255d60ae66a9f672ff9a207ee6cd8e33d2679 upstream.
+
+In general, accessing userspace memory beyond the length of the supplied
+buffer in VFS read/write handlers can lead to both kernel memory corruption
+(via kernel_read()/kernel_write(), which can e.g. be triggered via
+sys_splice()) and privilege escalation inside userspace.
+
+Fix it by using simple_read_from_buffer() instead of custom logic.
+
+Fixes: 6bc235a2e24a ("USB: add driver for Meywa-Denki & Kayac YUREX")
+Signed-off-by: Jann Horn <jannh@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ drivers/usb/misc/yurex.c | 23 ++++++-----------------
+ 1 file changed, 6 insertions(+), 17 deletions(-)
+
+--- a/drivers/usb/misc/yurex.c
++++ b/drivers/usb/misc/yurex.c
+@@ -413,8 +413,7 @@ static int yurex_release(struct inode *i
+ static ssize_t yurex_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+ {
+ struct usb_yurex *dev;
+- int retval = 0;
+- int bytes_read = 0;
++ int len = 0;
+ char in_buffer[20];
+ unsigned long flags;
+
+@@ -422,26 +421,16 @@ static ssize_t yurex_read(struct file *f
+
+ mutex_lock(&dev->io_mutex);
+ if (!dev->interface) { /* already disconnected */
+- retval = -ENODEV;
+- goto exit;
++ mutex_unlock(&dev->io_mutex);
++ return -ENODEV;
+ }
+
+ spin_lock_irqsave(&dev->lock, flags);
+- bytes_read = snprintf(in_buffer, 20, "%lld\n", dev->bbu);
++ len = snprintf(in_buffer, 20, "%lld\n", dev->bbu);
+ spin_unlock_irqrestore(&dev->lock, flags);
+-
+- if (*ppos < bytes_read) {
+- if (copy_to_user(buffer, in_buffer + *ppos, bytes_read - *ppos))
+- retval = -EFAULT;
+- else {
+- retval = bytes_read - *ppos;
+- *ppos += bytes_read;
+- }
+- }
+-
+-exit:
+ mutex_unlock(&dev->io_mutex);
+- return retval;
++
++ return simple_read_from_buffer(buffer, count, ppos, in_buffer, len);
+ }
+
+ static ssize_t yurex_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos)
diff --git a/queue-3.16/x86-entry-64-remove-ebx-handling-from-error_entry-exit.patch b/queue-3.16/x86-entry-64-remove-ebx-handling-from-error_entry-exit.patch
new file mode 100644
index 00000000..4e8e6ffd
--- /dev/null
+++ b/queue-3.16/x86-entry-64-remove-ebx-handling-from-error_entry-exit.patch
@@ -0,0 +1,133 @@
+From: Andy Lutomirski <luto@kernel.org>
+Date: Sun, 22 Jul 2018 11:05:09 -0700
+Subject: x86/entry/64: Remove %ebx handling from error_entry/exit
+
+commit b3681dd548d06deb2e1573890829dff4b15abf46 upstream.
+
+error_entry and error_exit communicate the user vs. kernel status of
+the frame using %ebx. This is unnecessary -- the information is in
+regs->cs. Just use regs->cs.
+
+This makes error_entry simpler and makes error_exit more robust.
+
+It also fixes a nasty bug. Before all the Spectre nonsense, the
+xen_failsafe_callback entry point returned like this:
+
+ ALLOC_PT_GPREGS_ON_STACK
+ SAVE_C_REGS
+ SAVE_EXTRA_REGS
+ ENCODE_FRAME_POINTER
+ jmp error_exit
+
+And it did not go through error_entry. This was bogus: RBX
+contained garbage, and error_exit expected a flag in RBX.
+
+Fortunately, it generally contained *nonzero* garbage, so the
+correct code path was used. As part of the Spectre fixes, code was
+added to clear RBX to mitigate certain speculation attacks. Now,
+depending on kernel configuration, RBX got zeroed and, when running
+some Wine workloads, the kernel crashes. This was introduced by:
+
+ commit 3ac6d8c787b8 ("x86/entry/64: Clear registers for exceptions/interrupts, to reduce speculation attack surface")
+
+With this patch applied, RBX is no longer needed as a flag, and the
+problem goes away.
+
+I suspect that malicious userspace could use this bug to crash the
+kernel even without the offending patch applied, though.
+
+[ Historical note: I wrote this patch as a cleanup before I was aware
+ of the bug it fixed. ]
+
+[ Note to stable maintainers: this should probably get applied to all
+ kernels. If you're nervous about that, a more conservative fix to
+ add xorl %ebx,%ebx; incl %ebx before the jump to error_exit should
+ also fix the problem. ]
+
+Reported-and-tested-by: M. Vefa Bicakci <m.v.b@runbox.com>
+Signed-off-by: Andy Lutomirski <luto@kernel.org>
+Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Brian Gerst <brgerst@gmail.com>
+Cc: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: Denys Vlasenko <dvlasenk@redhat.com>
+Cc: Dominik Brodowski <linux@dominikbrodowski.net>
+Cc: Greg KH <gregkh@linuxfoundation.org>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Juergen Gross <jgross@suse.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: xen-devel@lists.xenproject.org
+Fixes: 3ac6d8c787b8 ("x86/entry/64: Clear registers for exceptions/interrupts, to reduce speculation attack surface")
+Link: http://lkml.kernel.org/r/b5010a090d3586b2d6e06c7ad3ec5542d1241c45.1532282627.git.luto@kernel.org
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+[bwh: Backported to 3.16:
+ - error_exit moved EBX to EAX before testing it, so delete both instructions
+ - error_exit does RESTORE_REST earlier, so adjust the offset to saved CS
+ accordingly
+ - Drop inapplicable comment changes
+ - Adjust filename, context]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+--- a/arch/x86/kernel/entry_64.S
++++ b/arch/x86/kernel/entry_64.S
+@@ -1135,7 +1135,7 @@ ENTRY(\sym)
+ .if \paranoid
+ jmp paranoid_exit /* %ebx: no swapgs flag */
+ .else
+- jmp error_exit /* %ebx: no swapgs flag */
++ jmp error_exit
+ .endif
+
+ CFI_ENDPROC
+@@ -1411,7 +1411,6 @@ END(paranoid_exit)
+
+ /*
+ * Exception entry point. This expects an error code/orig_rax on the stack.
+- * returns in "no swapgs flag" in %ebx.
+ */
+ ENTRY(error_entry)
+ XCPT_FRAME
+@@ -1440,7 +1439,6 @@ ENTRY(error_entry)
+ * the kernel CR3 here.
+ */
+ SWITCH_KERNEL_CR3
+- xorl %ebx,%ebx
+ testl $3,CS+8(%rsp)
+ je error_kernelspace
+ error_swapgs:
+@@ -1456,7 +1454,6 @@ error_sti:
+ * for these here too.
+ */
+ error_kernelspace:
+- incl %ebx
+ leaq native_irq_return_iret(%rip),%rcx
+ cmpq %rcx,RIP+8(%rsp)
+ je error_bad_iret
+@@ -1477,22 +1474,18 @@ error_bad_iret:
+ mov %rsp,%rdi
+ call fixup_bad_iret
+ mov %rax,%rsp
+- decl %ebx /* Return to usergs */
+ jmp error_sti
+ CFI_ENDPROC
+ END(error_entry)
+
+-
+-/* ebx: no swapgs flag (1: don't need swapgs, 0: need it) */
+ ENTRY(error_exit)
+ DEFAULT_FRAME
+- movl %ebx,%eax
+ RESTORE_REST
+ DISABLE_INTERRUPTS(CLBR_NONE)
+ TRACE_IRQS_OFF
+ GET_THREAD_INFO(%rcx)
+- testl %eax,%eax
+- jne retint_kernel
++ testb $3, CS-ARGOFFSET(%rsp)
++ jz retint_kernel
+ LOCKDEP_SYS_EXIT_IRQ
+ movl TI_flags(%rcx),%edx
+ movl $_TIF_WORK_MASK,%edi
diff --git a/queue-3.16/xfs-set-format-back-to-extents-if-xfs_bmap_extents_to_btree.patch b/queue-3.16/xfs-set-format-back-to-extents-if-xfs_bmap_extents_to_btree.patch
new file mode 100644
index 00000000..83d6e382
--- /dev/null
+++ b/queue-3.16/xfs-set-format-back-to-extents-if-xfs_bmap_extents_to_btree.patch
@@ -0,0 +1,37 @@
+From: Eric Sandeen <sandeen@redhat.com>
+Date: Mon, 16 Apr 2018 23:07:27 -0700
+Subject: xfs: set format back to extents if xfs_bmap_extents_to_btree
+
+commit 2c4306f719b083d17df2963bc761777576b8ad1b upstream.
+
+If xfs_bmap_extents_to_btree fails in a mode where we call
+xfs_iroot_realloc(-1) to de-allocate the root, set the
+format back to extents.
+
+Otherwise we can assume we can dereference ifp->if_broot
+based on the XFS_DINODE_FMT_BTREE format, and crash.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=199423
+Signed-off-by: Eric Sandeen <sandeen@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+[bwh: Backported to 3.16:
+ - Only one failure path needs to be patched
+ - Adjust filename]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ fs/xfs/xfs_bmap.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/fs/xfs/xfs_bmap.c
++++ b/fs/xfs/xfs_bmap.c
+@@ -822,6 +822,8 @@ xfs_bmap_extents_to_btree(
+ *logflagsp = 0;
+ if ((error = xfs_alloc_vextent(&args))) {
+ xfs_iroot_realloc(ip, -1, whichfork);
++ ASSERT(ifp->if_broot == NULL);
++ XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS);
+ xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
+ return error;
+ }