From 888a1dd28a9abdc30a09ea85d3382daeabbb3d69 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 10 Jul 2018 14:52:07 +0200 Subject: [PATCH] 4.9-stable patches 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 --- ...te-loop-when-using-hard-mount-option.patch | 129 +++++++++++++++++ queue-4.9/drbd-fix-access-after-free.patch | 73 ++++++++++ ...-display-corruption-of-the-last-line.patch | 76 ++++++++++ ...-for-allocating-blob-property-memory.patch | 56 ++++++++ ...dd-more-inode-number-paranoia-checks.patch | 69 +++++++++ ...-mount-time-checks-of-the-superblock.patch | 99 +++++++++++++ ...oup-bounds-in-ext4_init_block_bitmap.patch | 59 ++++++++ ...uperblock-mapped-prior-to-committing.patch | 55 ++++++++ ...inode_info-when-removing-inline-data.patch | 48 +++++++ ...-block-in-the-bad-map-ext4_error-msg.patch | 31 +++++ ...le-don-t-overlap-with-bg-descriptors.patch | 79 +++++++++++ ...at-the-bg_flags-field-if-it-is-valid.patch | 131 ++++++++++++++++++ ...h-of-extent-tree-in-ext4_find_extent.patch | 51 +++++++ ...fied-if-the-handle-is-out-of-credits.patch | 58 ++++++++ ...rruption-in-critical-section-cleanup.patch | 51 +++++++ queue-4.9/series | 15 ++ 16 files changed, 1080 insertions(+) create mode 100644 queue-4.9/cifs-fix-infinite-loop-when-using-hard-mount-option.patch create mode 100644 queue-4.9/drbd-fix-access-after-free.patch create mode 100644 queue-4.9/drm-udl-fix-display-corruption-of-the-last-line.patch create mode 100644 queue-4.9/drm-use-kvzalloc-for-allocating-blob-property-memory.patch create mode 100644 queue-4.9/ext4-add-more-inode-number-paranoia-checks.patch create mode 100644 queue-4.9/ext4-add-more-mount-time-checks-of-the-superblock.patch create mode 100644 queue-4.9/ext4-always-check-block-group-bounds-in-ext4_init_block_bitmap.patch create mode 100644 queue-4.9/ext4-check-superblock-mapped-prior-to-committing.patch create mode 100644 queue-4.9/ext4-clear-i_data-in-ext4_inode_info-when-removing-inline-data.patch create mode 100644 queue-4.9/ext4-include-the-illegal-physical-block-in-the-bad-map-ext4_error-msg.patch create mode 100644 queue-4.9/ext4-make-sure-bitmaps-and-the-inode-table-don-t-overlap-with-bg-descriptors.patch create mode 100644 queue-4.9/ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch create mode 100644 queue-4.9/ext4-verify-the-depth-of-extent-tree-in-ext4_find_extent.patch create mode 100644 queue-4.9/jbd2-don-t-mark-block-as-modified-if-the-handle-is-out-of-credits.patch create mode 100644 queue-4.9/s390-correct-register-corruption-in-critical-section-cleanup.patch 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 index 00000000000..8cae963e60c --- /dev/null +++ b/queue-4.9/cifs-fix-infinite-loop-when-using-hard-mount-option.patch @@ -0,0 +1,129 @@ +From 7ffbe65578b44fafdef577a360eb0583929f7c6e Mon Sep 17 00:00:00 2001 +From: Paulo Alcantara +Date: Thu, 5 Jul 2018 13:46:34 -0300 +Subject: cifs: Fix infinite loop when using hard mount option + +From: Paulo Alcantara + +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 +Cc: stable@vger.kernel.org +Reviewed-by: Aurelien Aptel +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e177ea3e52c --- /dev/null +++ b/queue-4.9/drbd-fix-access-after-free.patch @@ -0,0 +1,73 @@ +From 64dafbc9530c10300acffc57fae3269d95fa8f93 Mon Sep 17 00:00:00 2001 +From: Lars Ellenberg +Date: Mon, 25 Jun 2018 11:39:52 +0200 +Subject: drbd: fix access after free + +From: Lars Ellenberg + +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 +Signed-off-by: Lars Ellenberg +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..4377a1ff153 --- /dev/null +++ b/queue-4.9/drm-udl-fix-display-corruption-of-the-last-line.patch @@ -0,0 +1,76 @@ +From 99ec9e77511dea55d81729fc80b6c63a61bfa8e0 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Sun, 3 Jun 2018 16:40:54 +0200 +Subject: drm/udl: fix display corruption of the last line + +From: Mikulas Patocka + +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 +Cc: stable@vger.kernel.org +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..46d4be1b433 --- /dev/null +++ b/queue-4.9/drm-use-kvzalloc-for-allocating-blob-property-memory.patch @@ -0,0 +1,56 @@ +From 718b5406cd76f1aa6434311241b7febf0e8571ff Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michel=20D=C3=A4nzer?= +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 + +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 +Reviewed-by: Alex Deucher +Signed-off-by: Alex Deucher +Link: https://patchwork.freedesktop.org/patch/msgid/20180629142710.2069-1-michel@daenzer.net +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..c6ca30dd209 --- /dev/null +++ b/queue-4.9/ext4-add-more-inode-number-paranoia-checks.patch @@ -0,0 +1,69 @@ +From c37e9e013469521d9adb932d17a1795c139b36db Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Sun, 17 Jun 2018 00:41:14 -0400 +Subject: ext4: add more inode number paranoia checks + +From: Theodore Ts'o + +commit c37e9e013469521d9adb932d17a1795c139b36db upstream. + +If there is a directory entry pointing to a system inode (such as a +journal inode), complain and declare the file system to be corrupted. + +Also, if the superblock's first inode number field is too small, +refuse to mount the file system. + +This addresses CVE-2018-10882. + +https://bugzilla.kernel.org/show_bug.cgi?id=200069 + +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/ext4.h | 5 ----- + fs/ext4/inode.c | 3 ++- + fs/ext4/super.c | 5 +++++ + 3 files changed, 7 insertions(+), 6 deletions(-) + +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -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 index 00000000000..e23e2116c15 --- /dev/null +++ b/queue-4.9/ext4-add-more-mount-time-checks-of-the-superblock.patch @@ -0,0 +1,99 @@ +From bfe0a5f47ada40d7984de67e59a7d3390b9b9ecc Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Sun, 17 Jun 2018 18:11:20 -0400 +Subject: ext4: add more mount time checks of the superblock + +From: Theodore Ts'o + +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 +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..cfd355cf275 --- /dev/null +++ b/queue-4.9/ext4-always-check-block-group-bounds-in-ext4_init_block_bitmap.patch @@ -0,0 +1,59 @@ +From 819b23f1c501b17b9694325471789e6b5cc2d0d2 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Wed, 13 Jun 2018 23:00:48 -0400 +Subject: ext4: always check block group bounds in ext4_init_block_bitmap() + +From: Theodore Ts'o + +commit 819b23f1c501b17b9694325471789e6b5cc2d0d2 upstream. + +Regardless of whether the flex_bg feature is set, we should always +check to make sure the bits we are setting in the block bitmap are +within the block group bounds. + +https://bugzilla.kernel.org/show_bug.cgi?id=199865 + +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/balloc.c | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +--- a/fs/ext4/balloc.c ++++ b/fs/ext4/balloc.c +@@ -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 index 00000000000..7c1701dc5eb --- /dev/null +++ b/queue-4.9/ext4-check-superblock-mapped-prior-to-committing.patch @@ -0,0 +1,55 @@ +From a17712c8e4be4fa5404d20e9cd3b2b21eae7bc56 Mon Sep 17 00:00:00 2001 +From: Jon Derrick +Date: Mon, 2 Jul 2018 18:45:18 -0400 +Subject: ext4: check superblock mapped prior to committing + +From: Jon Derrick + +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 +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..4889fd224bc --- /dev/null +++ b/queue-4.9/ext4-clear-i_data-in-ext4_inode_info-when-removing-inline-data.patch @@ -0,0 +1,48 @@ +From 6e8ab72a812396996035a37e5ca4b3b99b5d214b Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +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 + +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 +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..81d056dcd13 --- /dev/null +++ b/queue-4.9/ext4-include-the-illegal-physical-block-in-the-bad-map-ext4_error-msg.patch @@ -0,0 +1,31 @@ +From bdbd6ce01a70f02e9373a584d0ae9538dcf0a121 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +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 + +commit bdbd6ce01a70f02e9373a584d0ae9538dcf0a121 upstream. + +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..dd4c7f86ca4 --- /dev/null +++ b/queue-4.9/ext4-make-sure-bitmaps-and-the-inode-table-don-t-overlap-with-bg-descriptors.patch @@ -0,0 +1,79 @@ +From 77260807d1170a8cf35dbb06e07461a655f67eee Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +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 + +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 +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..0dafeaf0832 --- /dev/null +++ b/queue-4.9/ext4-only-look-at-the-bg_flags-field-if-it-is-valid.patch @@ -0,0 +1,131 @@ +From 8844618d8aa7a9973e7b527d038a2a589665002c Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Thu, 14 Jun 2018 00:58:00 -0400 +Subject: ext4: only look at the bg_flags field if it is valid + +From: Theodore Ts'o + +commit 8844618d8aa7a9973e7b527d038a2a589665002c upstream. + +The bg_flags field in the block group descripts is only valid if the +uninit_bg or metadata_csum feature is enabled. We were not +consistently looking at this field; fix this. + +Also block group #0 must never have uninitialized allocation bitmaps, +or need to be zeroed, since that's where the root inode, and other +special inodes are set up. Check for these conditions and mark the +file system as corrupted if they are detected. + +This addresses CVE-2018-10876. + +https://bugzilla.kernel.org/show_bug.cgi?id=199403 + +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/balloc.c | 11 ++++++++++- + fs/ext4/ialloc.c | 14 ++++++++++++-- + fs/ext4/mballoc.c | 6 ++++-- + fs/ext4/super.c | 11 ++++++++++- + 4 files changed, 36 insertions(+), 6 deletions(-) + +--- a/fs/ext4/balloc.c ++++ b/fs/ext4/balloc.c +@@ -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 index 00000000000..57dba77de00 --- /dev/null +++ b/queue-4.9/ext4-verify-the-depth-of-extent-tree-in-ext4_find_extent.patch @@ -0,0 +1,51 @@ +From bc890a60247171294acc0bd67d211fa4b88d40ba Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +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 + +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 +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..65bfeb20260 --- /dev/null +++ b/queue-4.9/jbd2-don-t-mark-block-as-modified-if-the-handle-is-out-of-credits.patch @@ -0,0 +1,58 @@ +From e09463f220ca9a1a1ecfda84fcda658f99a1f12a Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Sat, 16 Jun 2018 20:21:45 -0400 +Subject: jbd2: don't mark block as modified if the handle is out of credits + +From: Theodore Ts'o + +commit e09463f220ca9a1a1ecfda84fcda658f99a1f12a upstream. + +Do not set the b_modified flag in block's journal head should not +until after we're sure that jbd2_journal_dirty_metadat() will not +abort with an error due to there not being enough space reserved in +the jbd2 handle. + +Otherwise, future attempts to modify the buffer may lead a large +number of spurious errors and warnings. + +This addresses CVE-2018-10883. + +https://bugzilla.kernel.org/show_bug.cgi?id=200071 + +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..82c83ca9203 --- /dev/null +++ b/queue-4.9/s390-correct-register-corruption-in-critical-section-cleanup.patch @@ -0,0 +1,51 @@ +From 891f6a726cacbb87e5b06076693ffab53bd378d7 Mon Sep 17 00:00:00 2001 +From: Christian Borntraeger +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 + +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 +Reported-by: Petr Tesařík +Signed-off-by: Christian Borntraeger +Reviewed-by: Hendrik Brueckner +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman + +--- + 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: diff --git a/queue-4.9/series b/queue-4.9/series index 6481782e674..bedf7c2bec9 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -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 -- 2.47.3