]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 Jul 2018 12:52:07 +0000 (14:52 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 Jul 2018 12:52:07 +0000 (14:52 +0200)
added patches:
cifs-fix-infinite-loop-when-using-hard-mount-option.patch
drbd-fix-access-after-free.patch
drm-udl-fix-display-corruption-of-the-last-line.patch
drm-use-kvzalloc-for-allocating-blob-property-memory.patch
ext4-add-more-inode-number-paranoia-checks.patch
ext4-add-more-mount-time-checks-of-the-superblock.patch
ext4-always-check-block-group-bounds-in-ext4_init_block_bitmap.patch
ext4-check-superblock-mapped-prior-to-committing.patch
ext4-clear-i_data-in-ext4_inode_info-when-removing-inline-data.patch
ext4-include-the-illegal-physical-block-in-the-bad-map-ext4_error-msg.patch
ext4-make-sure-bitmaps-and-the-inode-table-don-t-overlap-with-bg-descriptors.patch
ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch
ext4-verify-the-depth-of-extent-tree-in-ext4_find_extent.patch
jbd2-don-t-mark-block-as-modified-if-the-handle-is-out-of-credits.patch
s390-correct-register-corruption-in-critical-section-cleanup.patch

16 files changed:
queue-4.9/cifs-fix-infinite-loop-when-using-hard-mount-option.patch [new file with mode: 0644]
queue-4.9/drbd-fix-access-after-free.patch [new file with mode: 0644]
queue-4.9/drm-udl-fix-display-corruption-of-the-last-line.patch [new file with mode: 0644]
queue-4.9/drm-use-kvzalloc-for-allocating-blob-property-memory.patch [new file with mode: 0644]
queue-4.9/ext4-add-more-inode-number-paranoia-checks.patch [new file with mode: 0644]
queue-4.9/ext4-add-more-mount-time-checks-of-the-superblock.patch [new file with mode: 0644]
queue-4.9/ext4-always-check-block-group-bounds-in-ext4_init_block_bitmap.patch [new file with mode: 0644]
queue-4.9/ext4-check-superblock-mapped-prior-to-committing.patch [new file with mode: 0644]
queue-4.9/ext4-clear-i_data-in-ext4_inode_info-when-removing-inline-data.patch [new file with mode: 0644]
queue-4.9/ext4-include-the-illegal-physical-block-in-the-bad-map-ext4_error-msg.patch [new file with mode: 0644]
queue-4.9/ext4-make-sure-bitmaps-and-the-inode-table-don-t-overlap-with-bg-descriptors.patch [new file with mode: 0644]
queue-4.9/ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch [new file with mode: 0644]
queue-4.9/ext4-verify-the-depth-of-extent-tree-in-ext4_find_extent.patch [new file with mode: 0644]
queue-4.9/jbd2-don-t-mark-block-as-modified-if-the-handle-is-out-of-credits.patch [new file with mode: 0644]
queue-4.9/s390-correct-register-corruption-in-critical-section-cleanup.patch [new file with mode: 0644]
queue-4.9/series

diff --git a/queue-4.9/cifs-fix-infinite-loop-when-using-hard-mount-option.patch b/queue-4.9/cifs-fix-infinite-loop-when-using-hard-mount-option.patch
new file mode 100644 (file)
index 0000000..8cae963
--- /dev/null
@@ -0,0 +1,129 @@
+From 7ffbe65578b44fafdef577a360eb0583929f7c6e Mon Sep 17 00:00:00 2001
+From: Paulo Alcantara <paulo@paulo.ac>
+Date: Thu, 5 Jul 2018 13:46:34 -0300
+Subject: cifs: Fix infinite loop when using hard mount option
+
+From: Paulo Alcantara <paulo@paulo.ac>
+
+commit 7ffbe65578b44fafdef577a360eb0583929f7c6e upstream.
+
+For every request we send, whether it is SMB1 or SMB2+, we attempt to
+reconnect tcon (cifs_reconnect_tcon or smb2_reconnect) before carrying
+out the request.
+
+So, while server->tcpStatus != CifsNeedReconnect, we wait for the
+reconnection to succeed on wait_event_interruptible_timeout(). If it
+returns, that means that either the condition was evaluated to true, or
+timeout elapsed, or it was interrupted by a signal.
+
+Since we're not handling the case where the process woke up due to a
+received signal (-ERESTARTSYS), the next call to
+wait_event_interruptible_timeout() will _always_ fail and we end up
+looping forever inside either cifs_reconnect_tcon() or smb2_reconnect().
+
+Here's an example of how to trigger that:
+
+$ mount.cifs //foo/share /mnt/test -o
+username=foo,password=foo,vers=1.0,hard
+
+(break connection to server before executing bellow cmd)
+$ stat -f /mnt/test & sleep 140
+[1] 2511
+
+$ ps -aux -q 2511
+USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
+root      2511  0.0  0.0  12892  1008 pts/0    S    12:24   0:00 stat -f
+/mnt/test
+
+$ kill -9 2511
+
+(wait for a while; process is stuck in the kernel)
+$ ps -aux -q 2511
+USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
+root      2511 83.2  0.0  12892  1008 pts/0    R    12:24  30:01 stat -f
+/mnt/test
+
+By using 'hard' mount point means that cifs.ko will keep retrying
+indefinitely, however we must allow the process to be killed otherwise
+it would hang the system.
+
+Signed-off-by: Paulo Alcantara <palcantara@suse.de>
+Cc: stable@vger.kernel.org
+Reviewed-by: Aurelien Aptel <aaptel@suse.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/cifssmb.c |   10 ++++++++--
+ fs/cifs/smb2pdu.c |   18 ++++++++++++------
+ 2 files changed, 20 insertions(+), 8 deletions(-)
+
+--- a/fs/cifs/cifssmb.c
++++ b/fs/cifs/cifssmb.c
+@@ -150,8 +150,14 @@ cifs_reconnect_tcon(struct cifs_tcon *tc
+        * greater than cifs socket timeout which is 7 seconds
+        */
+       while (server->tcpStatus == CifsNeedReconnect) {
+-              wait_event_interruptible_timeout(server->response_q,
+-                      (server->tcpStatus != CifsNeedReconnect), 10 * HZ);
++              rc = wait_event_interruptible_timeout(server->response_q,
++                                                    (server->tcpStatus != CifsNeedReconnect),
++                                                    10 * HZ);
++              if (rc < 0) {
++                      cifs_dbg(FYI, "%s: aborting reconnect due to a received"
++                               " signal by the process\n", __func__);
++                      return -ERESTARTSYS;
++              }
+               /* are we still trying to reconnect? */
+               if (server->tcpStatus != CifsNeedReconnect)
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -155,7 +155,7 @@ out:
+ static int
+ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon)
+ {
+-      int rc = 0;
++      int rc;
+       struct nls_table *nls_codepage;
+       struct cifs_ses *ses;
+       struct TCP_Server_Info *server;
+@@ -166,10 +166,10 @@ smb2_reconnect(__le16 smb2_command, stru
+        * for those three - in the calling routine.
+        */
+       if (tcon == NULL)
+-              return rc;
++              return 0;
+       if (smb2_command == SMB2_TREE_CONNECT)
+-              return rc;
++              return 0;
+       if (tcon->tidStatus == CifsExiting) {
+               /*
+@@ -212,8 +212,14 @@ smb2_reconnect(__le16 smb2_command, stru
+                       return -EAGAIN;
+               }
+-              wait_event_interruptible_timeout(server->response_q,
+-                      (server->tcpStatus != CifsNeedReconnect), 10 * HZ);
++              rc = wait_event_interruptible_timeout(server->response_q,
++                                                    (server->tcpStatus != CifsNeedReconnect),
++                                                    10 * HZ);
++              if (rc < 0) {
++                      cifs_dbg(FYI, "%s: aborting reconnect due to a received"
++                               " signal by the process\n", __func__);
++                      return -ERESTARTSYS;
++              }
+               /* are we still trying to reconnect? */
+               if (server->tcpStatus != CifsNeedReconnect)
+@@ -231,7 +237,7 @@ smb2_reconnect(__le16 smb2_command, stru
+       }
+       if (!tcon->ses->need_reconnect && !tcon->need_reconnect)
+-              return rc;
++              return 0;
+       nls_codepage = load_nls_default();
diff --git a/queue-4.9/drbd-fix-access-after-free.patch b/queue-4.9/drbd-fix-access-after-free.patch
new file mode 100644 (file)
index 0000000..e177ea3
--- /dev/null
@@ -0,0 +1,73 @@
+From 64dafbc9530c10300acffc57fae3269d95fa8f93 Mon Sep 17 00:00:00 2001
+From: Lars Ellenberg <lars.ellenberg@linbit.com>
+Date: Mon, 25 Jun 2018 11:39:52 +0200
+Subject: drbd: fix access after free
+
+From: Lars Ellenberg <lars.ellenberg@linbit.com>
+
+commit 64dafbc9530c10300acffc57fae3269d95fa8f93 upstream.
+
+We have
+  struct drbd_requests { ... struct bio *private_bio;  ... }
+to hold a bio clone for local submission.
+
+On local IO completion, we put that bio, and in case we want to use the
+result later, we overload that member to hold the ERR_PTR() of the
+completion result,
+
+Which, before v4.3, used to be the passed in "int error",
+so we could first bio_put(), then assign.
+
+v4.3-rc1~100^2~21 4246a0b63bd8 block: add a bi_error field to struct bio
+changed that:
+       bio_put(req->private_bio);
+ -     req->private_bio = ERR_PTR(error);
+ +     req->private_bio = ERR_PTR(bio->bi_error);
+
+Which introduces an access after free,
+because it was non obvious that req->private_bio == bio.
+
+Impact of that was mostly unnoticable, because we only use that value
+in a multiple-failure case, and even then map any "unexpected" error
+code to EIO, so worst case we could potentially mask a more specific
+error with EIO in a multiple failure case.
+
+Unless the pointed to memory region was unmapped, as is the case with
+CONFIG_DEBUG_PAGEALLOC, in which case this results in
+
+  BUG: unable to handle kernel paging request
+
+v4.13-rc1~70^2~75 4e4cbee93d56 block: switch bios to blk_status_t
+changes it further to
+       bio_put(req->private_bio);
+       req->private_bio = ERR_PTR(blk_status_to_errno(bio->bi_status));
+
+And blk_status_to_errno() now contains a WARN_ON_ONCE() for unexpected
+values, which catches this "sometimes", if the memory has been reused
+quickly enough for other things.
+
+Should also go into stable since 4.3, with the trivial change around 4.13.
+
+Cc: stable@vger.kernel.org
+Fixes: 4246a0b63bd8 block: add a bi_error field to struct bio
+Reported-by: Sarah Newman <srn@prgmr.com>
+Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/drbd/drbd_worker.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/block/drbd/drbd_worker.c
++++ b/drivers/block/drbd/drbd_worker.c
+@@ -269,8 +269,8 @@ void drbd_request_endio(struct bio *bio)
+               what = COMPLETED_OK;
+       }
+-      bio_put(req->private_bio);
+       req->private_bio = ERR_PTR(bio->bi_error);
++      bio_put(bio);
+       /* not req_mod(), we need irqsave here! */
+       spin_lock_irqsave(&device->resource->req_lock, flags);
diff --git a/queue-4.9/drm-udl-fix-display-corruption-of-the-last-line.patch b/queue-4.9/drm-udl-fix-display-corruption-of-the-last-line.patch
new file mode 100644 (file)
index 0000000..4377a1f
--- /dev/null
@@ -0,0 +1,76 @@
+From 99ec9e77511dea55d81729fc80b6c63a61bfa8e0 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Sun, 3 Jun 2018 16:40:54 +0200
+Subject: drm/udl: fix display corruption of the last line
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+commit 99ec9e77511dea55d81729fc80b6c63a61bfa8e0 upstream.
+
+The displaylink hardware has such a peculiarity that it doesn't render a
+command until next command is received. This produces occasional
+corruption, such as when setting 22x11 font on the console, only the first
+line of the cursor will be blinking if the cursor is located at some
+specific columns.
+
+When we end up with a repeating pixel, the driver has a bug that it leaves
+one uninitialized byte after the command (and this byte is enough to flush
+the command and render it - thus it fixes the screen corruption), however
+whe we end up with a non-repeating pixel, there is no byte appended and
+this results in temporary screen corruption.
+
+This patch fixes the screen corruption by always appending a byte 0xAF at
+the end of URB. It also removes the uninitialized byte.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/udl/udl_fb.c       |    5 ++++-
+ drivers/gpu/drm/udl/udl_transfer.c |   11 +++++++----
+ 2 files changed, 11 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/udl/udl_fb.c
++++ b/drivers/gpu/drm/udl/udl_fb.c
+@@ -136,7 +136,10 @@ int udl_handle_damage(struct udl_framebu
+       if (cmd > (char *) urb->transfer_buffer) {
+               /* Send partial buffer remaining before exiting */
+-              int len = cmd - (char *) urb->transfer_buffer;
++              int len;
++              if (cmd < (char *) urb->transfer_buffer + urb->transfer_buffer_length)
++                      *cmd++ = 0xAF;
++              len = cmd - (char *) urb->transfer_buffer;
+               ret = udl_submit_urb(dev, urb, len);
+               bytes_sent += len;
+       } else
+--- a/drivers/gpu/drm/udl/udl_transfer.c
++++ b/drivers/gpu/drm/udl/udl_transfer.c
+@@ -152,11 +152,11 @@ static void udl_compress_hline16(
+               raw_pixels_count_byte = cmd++; /*  we'll know this later */
+               raw_pixel_start = pixel;
+-              cmd_pixel_end = pixel + (min(MAX_CMD_PIXELS + 1,
+-                      min((int)(pixel_end - pixel) / bpp,
+-                          (int)(cmd_buffer_end - cmd) / 2))) * bpp;
++              cmd_pixel_end = pixel + min3(MAX_CMD_PIXELS + 1UL,
++                                      (unsigned long)(pixel_end - pixel) / bpp,
++                                      (unsigned long)(cmd_buffer_end - 1 - cmd) / 2) * bpp;
+-              prefetch_range((void *) pixel, (cmd_pixel_end - pixel) * bpp);
++              prefetch_range((void *) pixel, cmd_pixel_end - pixel);
+               pixel_val16 = get_pixel_val16(pixel, bpp);
+               while (pixel < cmd_pixel_end) {
+@@ -192,6 +192,9 @@ static void udl_compress_hline16(
+               if (pixel > raw_pixel_start) {
+                       /* finalize last RAW span */
+                       *raw_pixels_count_byte = ((pixel-raw_pixel_start) / bpp) & 0xFF;
++              } else {
++                      /* undo unused byte */
++                      cmd--;
+               }
+               *cmd_pixels_count_byte = ((pixel - cmd_pixel_start) / bpp) & 0xFF;
diff --git a/queue-4.9/drm-use-kvzalloc-for-allocating-blob-property-memory.patch b/queue-4.9/drm-use-kvzalloc-for-allocating-blob-property-memory.patch
new file mode 100644 (file)
index 0000000..46d4be1
--- /dev/null
@@ -0,0 +1,56 @@
+From 718b5406cd76f1aa6434311241b7febf0e8571ff Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com>
+Date: Fri, 29 Jun 2018 16:27:10 +0200
+Subject: drm: Use kvzalloc for allocating blob property memory
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michel Dänzer <michel.daenzer@amd.com>
+
+commit 718b5406cd76f1aa6434311241b7febf0e8571ff upstream.
+
+The property size may be controlled by userspace, can be large (I've
+seen failure with order 4, i.e. 16 pages / 64 KB) and doesn't need to be
+physically contiguous.
+
+Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20180629142710.2069-1-michel@daenzer.net
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/drm_property.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/drm_property.c
++++ b/drivers/gpu/drm/drm_property.c
+@@ -530,7 +530,7 @@ static void drm_property_free_blob(struc
+       drm_mode_object_unregister(blob->dev, &blob->base);
+-      kfree(blob);
++      kvfree(blob);
+ }
+ /**
+@@ -557,7 +557,7 @@ drm_property_create_blob(struct drm_devi
+       if (!length || length > ULONG_MAX - sizeof(struct drm_property_blob))
+               return ERR_PTR(-EINVAL);
+-      blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
++      blob = kvzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
+       if (!blob)
+               return ERR_PTR(-ENOMEM);
+@@ -573,7 +573,7 @@ drm_property_create_blob(struct drm_devi
+       ret = drm_mode_object_get_reg(dev, &blob->base, DRM_MODE_OBJECT_BLOB,
+                                     true, drm_property_free_blob);
+       if (ret) {
+-              kfree(blob);
++              kvfree(blob);
+               return ERR_PTR(-EINVAL);
+       }
diff --git a/queue-4.9/ext4-add-more-inode-number-paranoia-checks.patch b/queue-4.9/ext4-add-more-inode-number-paranoia-checks.patch
new file mode 100644 (file)
index 0000000..c6ca30d
--- /dev/null
@@ -0,0 +1,69 @@
+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>
+Cc: stable@kernel.org
+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
+@@ -1542,11 +1542,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
+@@ -4242,7 +4242,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 -EFSCORRUPTED;
+       iloc->block_group = (inode->i_ino - 1) / EXT4_INODES_PER_GROUP(sb);
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -3713,6 +3713,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-4.9/ext4-add-more-mount-time-checks-of-the-superblock.patch b/queue-4.9/ext4-add-more-mount-time-checks-of-the-superblock.patch
new file mode 100644 (file)
index 0000000..e23e211
--- /dev/null
@@ -0,0 +1,99 @@
+From bfe0a5f47ada40d7984de67e59a7d3390b9b9ecc Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sun, 17 Jun 2018 18:11:20 -0400
+Subject: ext4: add more mount time checks of the superblock
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit bfe0a5f47ada40d7984de67e59a7d3390b9b9ecc upstream.
+
+The kernel's ext4 mount-time checks were more permissive than
+e2fsprogs's libext2fs checks when opening a file system.  The
+superblock is considered too insane for debugfs or e2fsck to operate
+on it, the kernel has no business trying to mount it.
+
+This will make file system fuzzing tools work harder, but the failure
+cases that they find will be more useful and be easier to evaluate.
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/super.c |   37 ++++++++++++++++++++++++++-----------
+ 1 file changed, 26 insertions(+), 11 deletions(-)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -3656,6 +3656,13 @@ static int ext4_fill_super(struct super_
+                        le32_to_cpu(es->s_log_block_size));
+               goto failed_mount;
+       }
++      if (le32_to_cpu(es->s_log_cluster_size) >
++          (EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) {
++              ext4_msg(sb, KERN_ERR,
++                       "Invalid log cluster size: %u",
++                       le32_to_cpu(es->s_log_cluster_size));
++              goto failed_mount;
++      }
+       if (le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) > (blocksize / 4)) {
+               ext4_msg(sb, KERN_ERR,
+@@ -3794,13 +3801,6 @@ static int ext4_fill_super(struct super_
+                                "block size (%d)", clustersize, blocksize);
+                       goto failed_mount;
+               }
+-              if (le32_to_cpu(es->s_log_cluster_size) >
+-                  (EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) {
+-                      ext4_msg(sb, KERN_ERR,
+-                               "Invalid log cluster size: %u",
+-                               le32_to_cpu(es->s_log_cluster_size));
+-                      goto failed_mount;
+-              }
+               sbi->s_cluster_bits = le32_to_cpu(es->s_log_cluster_size) -
+                       le32_to_cpu(es->s_log_block_size);
+               sbi->s_clusters_per_group =
+@@ -3821,10 +3821,10 @@ static int ext4_fill_super(struct super_
+               }
+       } else {
+               if (clustersize != blocksize) {
+-                      ext4_warning(sb, "fragment/cluster size (%d) != "
+-                                   "block size (%d)", clustersize,
+-                                   blocksize);
+-                      clustersize = blocksize;
++                      ext4_msg(sb, KERN_ERR,
++                               "fragment/cluster size (%d) != "
++                               "block size (%d)", clustersize, blocksize);
++                      goto failed_mount;
+               }
+               if (sbi->s_blocks_per_group > blocksize * 8) {
+                       ext4_msg(sb, KERN_ERR,
+@@ -3878,6 +3878,13 @@ static int ext4_fill_super(struct super_
+                        ext4_blocks_count(es));
+               goto failed_mount;
+       }
++      if ((es->s_first_data_block == 0) && (es->s_log_block_size == 0) &&
++          (sbi->s_cluster_ratio == 1)) {
++              ext4_msg(sb, KERN_WARNING, "bad geometry: first data "
++                       "block is 0 with a 1k block and cluster size");
++              goto failed_mount;
++      }
++
+       blocks_count = (ext4_blocks_count(es) -
+                       le32_to_cpu(es->s_first_data_block) +
+                       EXT4_BLOCKS_PER_GROUP(sb) - 1);
+@@ -3913,6 +3920,14 @@ static int ext4_fill_super(struct super_
+               ret = -ENOMEM;
+               goto failed_mount;
+       }
++      if (((u64)sbi->s_groups_count * sbi->s_inodes_per_group) !=
++          le32_to_cpu(es->s_inodes_count)) {
++              ext4_msg(sb, KERN_ERR, "inodes count not valid: %u vs %llu",
++                       le32_to_cpu(es->s_inodes_count),
++                       ((u64)sbi->s_groups_count * sbi->s_inodes_per_group));
++              ret = -EINVAL;
++              goto failed_mount;
++      }
+       bgl_lock_init(sbi->s_blockgroup_lock);
diff --git a/queue-4.9/ext4-always-check-block-group-bounds-in-ext4_init_block_bitmap.patch b/queue-4.9/ext4-always-check-block-group-bounds-in-ext4_init_block_bitmap.patch
new file mode 100644 (file)
index 0000000..cfd355c
--- /dev/null
@@ -0,0 +1,59 @@
+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>
+Cc: stable@kernel.org
+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
+@@ -183,7 +183,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));
+@@ -216,22 +215,19 @@ static int ext4_init_block_bitmap(struct
+       start = ext4_group_first_block_no(sb, block_group);
+-      if (ext4_has_feature_flex_bg(sb))
+-              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-4.9/ext4-check-superblock-mapped-prior-to-committing.patch b/queue-4.9/ext4-check-superblock-mapped-prior-to-committing.patch
new file mode 100644 (file)
index 0000000..7c1701d
--- /dev/null
@@ -0,0 +1,55 @@
+From a17712c8e4be4fa5404d20e9cd3b2b21eae7bc56 Mon Sep 17 00:00:00 2001
+From: Jon Derrick <jonathan.derrick@intel.com>
+Date: Mon, 2 Jul 2018 18:45:18 -0400
+Subject: ext4: check superblock mapped prior to committing
+
+From: Jon Derrick <jonathan.derrick@intel.com>
+
+commit a17712c8e4be4fa5404d20e9cd3b2b21eae7bc56 upstream.
+
+This patch attempts to close a hole leading to a BUG seen with hot
+removals during writes [1].
+
+A block device (NVME namespace in this test case) is formatted to EXT4
+without partitions. It's mounted and write I/O is run to a file, then
+the device is hot removed from the slot. The superblock attempts to be
+written to the drive which is no longer present.
+
+The typical chain of events leading to the BUG:
+ext4_commit_super()
+  __sync_dirty_buffer()
+    submit_bh()
+      submit_bh_wbc()
+        BUG_ON(!buffer_mapped(bh));
+
+This fix checks for the superblock's buffer head being mapped prior to
+syncing.
+
+[1] https://www.spinics.net/lists/linux-ext4/msg56527.html
+
+Signed-off-by: Jon Derrick <jonathan.derrick@intel.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/super.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -4629,6 +4629,14 @@ static int ext4_commit_super(struct supe
+       if (!sbh || block_device_ejected(sb))
+               return error;
++
++      /*
++       * The superblock bh should be mapped, but it might not be if the
++       * device was hot-removed. Not much we can do but fail the I/O.
++       */
++      if (!buffer_mapped(sbh))
++              return error;
++
+       /*
+        * If the file system is mounted read-only, don't update the
+        * superblock write time.  This avoids updating the superblock
diff --git a/queue-4.9/ext4-clear-i_data-in-ext4_inode_info-when-removing-inline-data.patch b/queue-4.9/ext4-clear-i_data-in-ext4_inode_info-when-removing-inline-data.patch
new file mode 100644 (file)
index 0000000..4889fd2
--- /dev/null
@@ -0,0 +1,48 @@
+From 6e8ab72a812396996035a37e5ca4b3b99b5d214b Mon Sep 17 00:00:00 2001
+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
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+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>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/inline.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/ext4/inline.c
++++ b/fs/ext4/inline.c
+@@ -434,6 +434,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_feature_extents(inode->i_sb)) {
+               if (S_ISDIR(inode->i_mode) ||
diff --git a/queue-4.9/ext4-include-the-illegal-physical-block-in-the-bad-map-ext4_error-msg.patch b/queue-4.9/ext4-include-the-illegal-physical-block-in-the-bad-map-ext4_error-msg.patch
new file mode 100644 (file)
index 0000000..81d056d
--- /dev/null
@@ -0,0 +1,31 @@
+From bdbd6ce01a70f02e9373a584d0ae9538dcf0a121 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Fri, 15 Jun 2018 12:27:16 -0400
+Subject: ext4: include the illegal physical block in the bad map ext4_error msg
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit bdbd6ce01a70f02e9373a584d0ae9538dcf0a121 upstream.
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/inode.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -377,9 +377,9 @@ static int __check_block_validity(struct
+       if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), map->m_pblk,
+                                  map->m_len)) {
+               ext4_error_inode(inode, func, line, map->m_pblk,
+-                               "lblock %lu mapped to illegal pblock "
++                               "lblock %lu mapped to illegal pblock %llu "
+                                "(length %d)", (unsigned long) map->m_lblk,
+-                               map->m_len);
++                               map->m_pblk, map->m_len);
+               return -EFSCORRUPTED;
+       }
+       return 0;
diff --git a/queue-4.9/ext4-make-sure-bitmaps-and-the-inode-table-don-t-overlap-with-bg-descriptors.patch b/queue-4.9/ext4-make-sure-bitmaps-and-the-inode-table-don-t-overlap-with-bg-descriptors.patch
new file mode 100644 (file)
index 0000000..dd4c7f8
--- /dev/null
@@ -0,0 +1,79 @@
+From 77260807d1170a8cf35dbb06e07461a655f67eee Mon Sep 17 00:00:00 2001
+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
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+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>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/super.c |   25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -2231,6 +2231,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;
+@@ -2263,6 +2264,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 "
+@@ -2277,6 +2286,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 "
+@@ -2291,6 +2308,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-4.9/ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch b/queue-4.9/ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch
new file mode 100644 (file)
index 0000000..0dafeaf
--- /dev/null
@@ -0,0 +1,131 @@
+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
+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
+@@ -450,7 +450,16 @@ 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))) {
++              if (block_group == 0) {
++                      ext4_unlock_group(sb, block_group);
++                      unlock_buffer(bh);
++                      ext4_error(sb, "Block bitmap for bg 0 marked "
++                                 "uninitialized");
++                      err = -EFSCORRUPTED;
++                      goto out;
++              }
+               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
+@@ -152,7 +152,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");
++                      err = -EFSCORRUPTED;
++                      goto out;
++              }
+               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);
+@@ -926,7 +935,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
+@@ -2444,7 +2444,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 {
+@@ -2969,7 +2970,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
+@@ -3023,13 +3023,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-4.9/ext4-verify-the-depth-of-extent-tree-in-ext4_find_extent.patch b/queue-4.9/ext4-verify-the-depth-of-extent-tree-in-ext4_find_extent.patch
new file mode 100644 (file)
index 0000000..57dba77
--- /dev/null
@@ -0,0 +1,51 @@
+From bc890a60247171294acc0bd67d211fa4b88d40ba Mon Sep 17 00:00:00 2001
+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()
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+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>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -881,6 +881,12 @@ ext4_find_extent(struct inode *inode, ex
+       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 = -EFSCORRUPTED;
++              goto err;
++      }
+       if (path) {
+               ext4_ext_drop_refs(path);
diff --git a/queue-4.9/jbd2-don-t-mark-block-as-modified-if-the-handle-is-out-of-credits.patch b/queue-4.9/jbd2-don-t-mark-block-as-modified-if-the-handle-is-out-of-credits.patch
new file mode 100644 (file)
index 0000000..65bfeb2
--- /dev/null
@@ -0,0 +1,58 @@
+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>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/jbd2/transaction.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -1353,6 +1353,13 @@ int jbd2_journal_dirty_metadata(handle_t
+               if (jh->b_transaction == transaction &&
+                   jh->b_jlist != BJ_Metadata) {
+                       jbd_lock_bh_state(bh);
++                      if (jh->b_transaction == transaction &&
++                          jh->b_jlist != BJ_Metadata)
++                              pr_err("JBD2: assertion failure: h_type=%u "
++                                     "h_line_no=%u block_no=%llu jlist=%u\n",
++                                     handle->h_type, handle->h_line_no,
++                                     (unsigned long long) bh->b_blocknr,
++                                     jh->b_jlist);
+                       J_ASSERT_JH(jh, jh->b_transaction != transaction ||
+                                       jh->b_jlist == BJ_Metadata);
+                       jbd_unlock_bh_state(bh);
+@@ -1372,11 +1379,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-4.9/s390-correct-register-corruption-in-critical-section-cleanup.patch b/queue-4.9/s390-correct-register-corruption-in-critical-section-cleanup.patch
new file mode 100644 (file)
index 0000000..82c83ca
--- /dev/null
@@ -0,0 +1,51 @@
+From 891f6a726cacbb87e5b06076693ffab53bd378d7 Mon Sep 17 00:00:00 2001
+From: Christian Borntraeger <borntraeger@de.ibm.com>
+Date: Thu, 21 Jun 2018 14:49:38 +0200
+Subject: s390: Correct register corruption in critical section cleanup
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christian Borntraeger <borntraeger@de.ibm.com>
+
+commit 891f6a726cacbb87e5b06076693ffab53bd378d7 upstream.
+
+In the critical section cleanup we must not mess with r1.  For march=z9
+or older, larl + ex (instead of exrl) are used with r1 as a temporary
+register. This can clobber r1 in several interrupt handlers. Fix this by
+using r11 as a temp register.  r11 is being saved by all callers of
+cleanup_critical.
+
+Fixes: 6dd85fbb87 ("s390: move expoline assembler macros to a header")
+Cc: stable@vger.kernel.org #v4.16
+Reported-by: Oliver Kurz <okurz@suse.com>
+Reported-by: Petr Tesařík <ptesarik@suse.com>
+Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
+Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/s390/kernel/entry.S |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/s390/kernel/entry.S
++++ b/arch/s390/kernel/entry.S
+@@ -1187,7 +1187,7 @@ cleanup_critical:
+       jl      0f
+       clg     %r9,BASED(.Lcleanup_table+104)  # .Lload_fpu_regs_end
+       jl      .Lcleanup_load_fpu_regs
+-0:    BR_EX   %r14
++0:    BR_EX   %r14,%r11
+       .align  8
+ .Lcleanup_table:
+@@ -1217,7 +1217,7 @@ cleanup_critical:
+       ni      __SIE_PROG0C+3(%r9),0xfe        # no longer in SIE
+       lctlg   %c1,%c1,__LC_USER_ASCE          # load primary asce
+       larl    %r9,sie_exit                    # skip forward to sie_exit
+-      BR_EX   %r14
++      BR_EX   %r14,%r11
+ #endif
+ .Lcleanup_system_call:
index 6481782e674dac204da97481a056cab816d6358c..bedf7c2bec9ede7bc0b055877d6e2e90c57511e7 100644 (file)
@@ -19,3 +19,18 @@ x86-cpu-re-apply-forced-caps-every-time-cpu-caps-are-re-read.patch
 mm-hugetlb-yield-when-prepping-struct-pages.patch
 tracing-fix-missing-return-symbol-in-function_graph-output.patch
 scsi-sg-mitigate-read-write-abuse.patch
+s390-correct-register-corruption-in-critical-section-cleanup.patch
+drbd-fix-access-after-free.patch
+cifs-fix-infinite-loop-when-using-hard-mount-option.patch
+drm-use-kvzalloc-for-allocating-blob-property-memory.patch
+drm-udl-fix-display-corruption-of-the-last-line.patch
+jbd2-don-t-mark-block-as-modified-if-the-handle-is-out-of-credits.patch
+ext4-make-sure-bitmaps-and-the-inode-table-don-t-overlap-with-bg-descriptors.patch
+ext4-always-check-block-group-bounds-in-ext4_init_block_bitmap.patch
+ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch
+ext4-verify-the-depth-of-extent-tree-in-ext4_find_extent.patch
+ext4-include-the-illegal-physical-block-in-the-bad-map-ext4_error-msg.patch
+ext4-clear-i_data-in-ext4_inode_info-when-removing-inline-data.patch
+ext4-add-more-inode-number-paranoia-checks.patch
+ext4-add-more-mount-time-checks-of-the-superblock.patch
+ext4-check-superblock-mapped-prior-to-committing.patch