From: Greg Kroah-Hartman Date: Tue, 10 Oct 2017 18:15:34 +0000 (+0200) Subject: 3.18-stable patches X-Git-Tag: v3.18.75~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7b51d13aa4c673c9b0755189acbbfc5a141912c2;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: drm-i915-bios-ignore-hdmi-on-port-a.patch ext4-don-t-clear-sgid-when-inheriting-acls.patch ext4-fix-data-corruption-for-mmap-writes.patch ext4-only-call-ext4_truncate-when-size-isize.patch ext4-validate-s_first_meta_bg-at-mount-time.patch fs-super.c-fix-race-between-freeze_super-and-thaw_super.patch --- diff --git a/queue-3.18/drm-i915-bios-ignore-hdmi-on-port-a.patch b/queue-3.18/drm-i915-bios-ignore-hdmi-on-port-a.patch new file mode 100644 index 00000000000..4e8eff159cf --- /dev/null +++ b/queue-3.18/drm-i915-bios-ignore-hdmi-on-port-a.patch @@ -0,0 +1,48 @@ +From 2ba7d7e0437127314864238f8bfcb8369d81075c Mon Sep 17 00:00:00 2001 +From: Jani Nikula +Date: Thu, 21 Sep 2017 17:19:20 +0300 +Subject: drm/i915/bios: ignore HDMI on port A +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jani Nikula + +commit 2ba7d7e0437127314864238f8bfcb8369d81075c upstream. + +The hardware state readout oopses after several warnings when trying to +use HDMI on port A, if such a combination is configured in VBT. Filter +the combo out already at the VBT parsing phase. + +v2: also ignore DVI (Ville) + +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102889 +Cc: Imre Deak +Reviewed-by: Ville Syrjälä +Tested-by: Daniel Drake +Signed-off-by: Jani Nikula +Link: https://patchwork.freedesktop.org/patch/msgid/20170921141920.18172-1-jani.nikula@intel.com +(cherry picked from commit d27ffc1d00327c29b3aa97f941b42f0949f9e99f) +Signed-off-by: Rodrigo Vivi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_bios.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/gpu/drm/i915/intel_bios.c ++++ b/drivers/gpu/drm/i915/intel_bios.c +@@ -940,6 +940,13 @@ static void parse_ddi_port(struct drm_i9 + is_hdmi = is_dvi && (child->common.device_type & DEVICE_TYPE_NOT_HDMI_OUTPUT) == 0; + is_edp = is_dp && (child->common.device_type & DEVICE_TYPE_INTERNAL_CONNECTOR); + ++ if (port == PORT_A && is_dvi) { ++ DRM_DEBUG_KMS("VBT claims port A supports DVI%s, ignoring\n", ++ is_hdmi ? "/HDMI" : ""); ++ is_dvi = false; ++ is_hdmi = false; ++ } ++ + info->supports_dvi = is_dvi; + info->supports_hdmi = is_hdmi; + info->supports_dp = is_dp; diff --git a/queue-3.18/ext4-don-t-clear-sgid-when-inheriting-acls.patch b/queue-3.18/ext4-don-t-clear-sgid-when-inheriting-acls.patch new file mode 100644 index 00000000000..2a5a94cf785 --- /dev/null +++ b/queue-3.18/ext4-don-t-clear-sgid-when-inheriting-acls.patch @@ -0,0 +1,77 @@ +From a3bb2d5587521eea6dab2d05326abb0afb460abd Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Sun, 30 Jul 2017 23:33:01 -0400 +Subject: ext4: Don't clear SGID when inheriting ACLs + +From: Jan Kara + +commit a3bb2d5587521eea6dab2d05326abb0afb460abd upstream. + +When new directory 'DIR1' is created in a directory 'DIR0' with SGID bit +set, DIR1 is expected to have SGID bit set (and owning group equal to +the owning group of 'DIR0'). However when 'DIR0' also has some default +ACLs that 'DIR1' inherits, setting these ACLs will result in SGID bit on +'DIR1' to get cleared if user is not member of the owning group. + +Fix the problem by moving posix_acl_update_mode() out of +__ext4_set_acl() into ext4_set_acl(). That way the function will not be +called when inheriting ACLs which is what we want as it prevents SGID +bit clearing and the mode has been properly set by posix_acl_create() +anyway. + +Fixes: 073931017b49d9458aa351605b43a7e34598caef +Signed-off-by: Theodore Ts'o +Signed-off-by: Jan Kara +Reviewed-by: Andreas Gruenbacher +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/acl.c | 22 +++++++++++++++------- + 1 file changed, 15 insertions(+), 7 deletions(-) + +--- a/fs/ext4/acl.c ++++ b/fs/ext4/acl.c +@@ -200,13 +200,6 @@ __ext4_set_acl(handle_t *handle, struct + switch (type) { + case ACL_TYPE_ACCESS: + name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS; +- if (acl) { +- error = posix_acl_update_mode(inode, &inode->i_mode, &acl); +- if (error) +- return error; +- inode->i_ctime = ext4_current_time(inode); +- ext4_mark_inode_dirty(handle, inode); +- } + break; + + case ACL_TYPE_DEFAULT: +@@ -239,6 +232,8 @@ ext4_set_acl(struct inode *inode, struct + { + handle_t *handle; + int error, retries = 0; ++ umode_t mode = inode->i_mode; ++ int update_mode = 0; + + retry: + handle = ext4_journal_start(inode, EXT4_HT_XATTR, +@@ -246,7 +241,20 @@ retry: + if (IS_ERR(handle)) + return PTR_ERR(handle); + ++ if ((type == ACL_TYPE_ACCESS) && acl) { ++ error = posix_acl_update_mode(inode, &mode, &acl); ++ if (error) ++ goto out_stop; ++ update_mode = 1; ++ } ++ + error = __ext4_set_acl(handle, inode, type, acl); ++ if (!error && update_mode) { ++ inode->i_mode = mode; ++ inode->i_ctime = ext4_current_time(inode); ++ ext4_mark_inode_dirty(handle, inode); ++ } ++out_stop: + ext4_journal_stop(handle); + if (error == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) + goto retry; diff --git a/queue-3.18/ext4-fix-data-corruption-for-mmap-writes.patch b/queue-3.18/ext4-fix-data-corruption-for-mmap-writes.patch new file mode 100644 index 00000000000..2adeb94e41e --- /dev/null +++ b/queue-3.18/ext4-fix-data-corruption-for-mmap-writes.patch @@ -0,0 +1,65 @@ +From a056bdaae7a181f7dcc876cfab2f94538e508709 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Fri, 26 May 2017 17:45:45 -0400 +Subject: ext4: fix data corruption for mmap writes + +From: Jan Kara + +commit a056bdaae7a181f7dcc876cfab2f94538e508709 upstream. + +mpage_submit_page() can race with another process growing i_size and +writing data via mmap to the written-back page. As mpage_submit_page() +samples i_size too early, it may happen that ext4_bio_write_page() +zeroes out too large tail of the page and thus corrupts user data. + +Fix the problem by sampling i_size only after the page has been +write-protected in page tables by clear_page_dirty_for_io() call. + +Reported-by: Michael Zimmer +CC: stable@vger.kernel.org +Fixes: cb20d5188366f04d96d2e07b1240cc92170ade40 +Signed-off-by: Jan Kara +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/inode.c | 24 +++++++++++++++++++----- + 1 file changed, 19 insertions(+), 5 deletions(-) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -1780,15 +1780,29 @@ static int ext4_writepage(struct page *p + static int mpage_submit_page(struct mpage_da_data *mpd, struct page *page) + { + int len; +- loff_t size = i_size_read(mpd->inode); ++ loff_t size; + int err; + + BUG_ON(page->index != mpd->first_page); +- if (page->index == size >> PAGE_CACHE_SHIFT) +- len = size & ~PAGE_CACHE_MASK; +- else +- len = PAGE_CACHE_SIZE; + clear_page_dirty_for_io(page); ++ /* ++ * We have to be very careful here! Nothing protects writeback path ++ * against i_size changes and the page can be writeably mapped into ++ * page tables. So an application can be growing i_size and writing ++ * data through mmap while writeback runs. clear_page_dirty_for_io() ++ * write-protects our page in page tables and the page cannot get ++ * written to again until we release page lock. So only after ++ * clear_page_dirty_for_io() we are safe to sample i_size for ++ * ext4_bio_write_page() to zero-out tail of the written page. We rely ++ * on the barrier provided by TestClearPageDirty in ++ * clear_page_dirty_for_io() to make sure i_size is really sampled only ++ * after page tables are updated. ++ */ ++ size = i_size_read(mpd->inode); ++ if (page->index == size >> PAGE_SHIFT) ++ len = size & ~PAGE_MASK; ++ else ++ len = PAGE_SIZE; + err = ext4_bio_write_page(&mpd->io_submit, page, len, mpd->wbc, false); + if (!err) + mpd->wbc->nr_to_write--; diff --git a/queue-3.18/ext4-only-call-ext4_truncate-when-size-isize.patch b/queue-3.18/ext4-only-call-ext4_truncate-when-size-isize.patch new file mode 100644 index 00000000000..b5e2c545a49 --- /dev/null +++ b/queue-3.18/ext4-only-call-ext4_truncate-when-size-isize.patch @@ -0,0 +1,112 @@ +From 3da40c7b089810ac9cf2bb1e59633f619f3a7312 Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Mon, 22 Jun 2015 00:31:26 -0400 +Subject: ext4: only call ext4_truncate when size <= isize + +From: Josef Bacik + +commit 3da40c7b089810ac9cf2bb1e59633f619f3a7312 upstream. + +At LSF we decided that if we truncate up from isize we shouldn't trim +fallocated blocks that were fallocated with KEEP_SIZE and are past the +new i_size. This patch fixes ext4 to do this. + +[ Completely reworked patch so that i_disksize would actually get set + when truncating up. Also reworked the code for handling truncate so + that it's easier to handle. -- tytso ] + +Signed-off-by: Josef Bacik +Signed-off-by: Theodore Ts'o +Reviewed-by: Lukas Czerner +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/inode.c | 40 +++++++++++++++++++--------------------- + 1 file changed, 19 insertions(+), 21 deletions(-) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -4534,8 +4534,10 @@ int ext4_setattr(struct dentry *dentry, + ext4_journal_stop(handle); + } + +- if (attr->ia_valid & ATTR_SIZE && attr->ia_size != inode->i_size) { ++ if (attr->ia_valid & ATTR_SIZE) { + handle_t *handle; ++ loff_t oldsize = inode->i_size; ++ int shrink = (attr->ia_size <= inode->i_size); + + if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) { + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); +@@ -4543,24 +4545,26 @@ int ext4_setattr(struct dentry *dentry, + if (attr->ia_size > sbi->s_bitmap_maxbytes) + return -EFBIG; + } ++ if (!S_ISREG(inode->i_mode)) ++ return -EINVAL; + + if (IS_I_VERSION(inode) && attr->ia_size != inode->i_size) + inode_inc_iversion(inode); + +- if (S_ISREG(inode->i_mode) && ++ if (ext4_should_order_data(inode) && + (attr->ia_size < inode->i_size)) { +- if (ext4_should_order_data(inode)) { +- error = ext4_begin_ordered_truncate(inode, ++ error = ext4_begin_ordered_truncate(inode, + attr->ia_size); +- if (error) +- goto err_out; +- } ++ if (error) ++ goto err_out; ++ } ++ if (attr->ia_size != inode->i_size) { + handle = ext4_journal_start(inode, EXT4_HT_INODE, 3); + if (IS_ERR(handle)) { + error = PTR_ERR(handle); + goto err_out; + } +- if (ext4_handle_valid(handle)) { ++ if (ext4_handle_valid(handle) && shrink) { + error = ext4_orphan_add(handle, inode); + orphan = 1; + } +@@ -4579,15 +4583,13 @@ int ext4_setattr(struct dentry *dentry, + up_write(&EXT4_I(inode)->i_data_sem); + ext4_journal_stop(handle); + if (error) { +- ext4_orphan_del(NULL, inode); ++ if (orphan) ++ ext4_orphan_del(NULL, inode); + goto err_out; + } +- } else { +- loff_t oldsize = inode->i_size; +- +- i_size_write(inode, attr->ia_size); +- pagecache_isize_extended(inode, oldsize, inode->i_size); + } ++ if (!shrink) ++ pagecache_isize_extended(inode, oldsize, inode->i_size); + + /* + * Blocks are going to be removed from the inode. Wait +@@ -4606,14 +4608,10 @@ int ext4_setattr(struct dentry *dentry, + * Truncate pagecache after we've waited for commit + * in data=journal mode to make pages freeable. + */ +- truncate_pagecache(inode, inode->i_size); ++ truncate_pagecache(inode, inode->i_size); ++ if (shrink) ++ ext4_truncate(inode); + } +- /* +- * We want to call ext4_truncate() even if attr->ia_size == +- * inode->i_size for cases like truncation of fallocated space +- */ +- if (attr->ia_valid & ATTR_SIZE) +- ext4_truncate(inode); + + if (!rc) { + setattr_copy(inode, attr); diff --git a/queue-3.18/ext4-validate-s_first_meta_bg-at-mount-time.patch b/queue-3.18/ext4-validate-s_first_meta_bg-at-mount-time.patch new file mode 100644 index 00000000000..af66ee1501a --- /dev/null +++ b/queue-3.18/ext4-validate-s_first_meta_bg-at-mount-time.patch @@ -0,0 +1,69 @@ +From 3a4b77cd47bb837b8557595ec7425f281f2ca1fe Mon Sep 17 00:00:00 2001 +From: Eryu Guan +Date: Thu, 1 Dec 2016 15:08:37 -0500 +Subject: ext4: validate s_first_meta_bg at mount time + +From: Eryu Guan + +commit 3a4b77cd47bb837b8557595ec7425f281f2ca1fe upstream. + +Ralf Spenneberg reported that he hit a kernel crash when mounting a +modified ext4 image. And it turns out that kernel crashed when +calculating fs overhead (ext4_calculate_overhead()), this is because +the image has very large s_first_meta_bg (debug code shows it's +842150400), and ext4 overruns the memory in count_overhead() when +setting bitmap buffer, which is PAGE_SIZE. + +ext4_calculate_overhead(): + buf = get_zeroed_page(GFP_NOFS); <=== PAGE_SIZE buffer + blks = count_overhead(sb, i, buf); + +count_overhead(): + for (j = ext4_bg_num_gdb(sb, grp); j > 0; j--) { <=== j = 842150400 + ext4_set_bit(EXT4_B2C(sbi, s++), buf); <=== buffer overrun + count++; + } + +This can be reproduced easily for me by this script: + + #!/bin/bash + rm -f fs.img + mkdir -p /mnt/ext4 + fallocate -l 16M fs.img + mke2fs -t ext4 -O bigalloc,meta_bg,^resize_inode -F fs.img + debugfs -w -R "ssv first_meta_bg 842150400" fs.img + mount -o loop fs.img /mnt/ext4 + +Fix it by validating s_first_meta_bg first at mount time, and +refusing to mount if its value exceeds the largest possible meta_bg +number. + +Reported-by: Ralf Spenneberg +Signed-off-by: Eryu Guan +Signed-off-by: Theodore Ts'o +Reviewed-by: Andreas Dilger +Signed-off-by: Greg Kroah-Hartman + + +--- + fs/ext4/super.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -3931,6 +3931,15 @@ static int ext4_fill_super(struct super_ + (EXT4_MAX_BLOCK_FILE_PHYS / EXT4_BLOCKS_PER_GROUP(sb))); + db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) / + EXT4_DESC_PER_BLOCK(sb); ++ if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG)) { ++ if (le32_to_cpu(es->s_first_meta_bg) >= db_count) { ++ ext4_msg(sb, KERN_WARNING, ++ "first meta block group too large: %u " ++ "(group descriptor block count %u)", ++ le32_to_cpu(es->s_first_meta_bg), db_count); ++ goto failed_mount; ++ } ++ } + sbi->s_group_desc = ext4_kvmalloc(db_count * + sizeof(struct buffer_head *), + GFP_KERNEL); diff --git a/queue-3.18/fs-super.c-fix-race-between-freeze_super-and-thaw_super.patch b/queue-3.18/fs-super.c-fix-race-between-freeze_super-and-thaw_super.patch new file mode 100644 index 00000000000..4fbec284fd8 --- /dev/null +++ b/queue-3.18/fs-super.c-fix-race-between-freeze_super-and-thaw_super.patch @@ -0,0 +1,49 @@ +From 89f39af129382a40d7cd1f6914617282cfeee28e Mon Sep 17 00:00:00 2001 +From: Oleg Nesterov +Date: Mon, 26 Sep 2016 18:07:48 +0200 +Subject: fs/super.c: fix race between freeze_super() and thaw_super() + +From: Oleg Nesterov + +commit 89f39af129382a40d7cd1f6914617282cfeee28e upstream. + +Change thaw_super() to check frozen != SB_FREEZE_COMPLETE rather than +frozen == SB_UNFROZEN, otherwise it can race with freeze_super() which +drops sb->s_umount after SB_FREEZE_WRITE to preserve the lock ordering. + +In this case thaw_super() will wrongly call s_op->unfreeze_fs() before +it was actually frozen, and call sb_freeze_unlock() which leads to the +unbalanced percpu_up_write(). Unfortunately lockdep can't detect this, +so this triggers misc BUG_ON()'s in kernel/rcu/sync.c. + +Reported-and-tested-by: Nikolay Borisov +Signed-off-by: Oleg Nesterov +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/super.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/fs/super.c ++++ b/fs/super.c +@@ -1346,8 +1346,8 @@ int freeze_super(struct super_block *sb) + } + } + /* +- * This is just for debugging purposes so that fs can warn if it +- * sees write activity when frozen is set to SB_FREEZE_COMPLETE. ++ * For debugging purposes so that fs can warn if it sees write activity ++ * when frozen is set to SB_FREEZE_COMPLETE, and for thaw_super(). + */ + sb->s_writers.frozen = SB_FREEZE_COMPLETE; + up_write(&sb->s_umount); +@@ -1366,7 +1366,7 @@ int thaw_super(struct super_block *sb) + int error; + + down_write(&sb->s_umount); +- if (sb->s_writers.frozen == SB_UNFROZEN) { ++ if (sb->s_writers.frozen != SB_FREEZE_COMPLETE) { + up_write(&sb->s_umount); + return -EINVAL; + } diff --git a/queue-3.18/series b/queue-3.18/series index dadd2be3203..c12495f08ca 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -24,3 +24,9 @@ lsm-fix-smack_inode_removexattr-and-xattr_getsecurity-memleak.patch alsa-usx2y-suppress-kernel-warning-at-page-allocation-failures.patch driver-core-platform-don-t-read-past-the-end-of-driver_override-buffer.patch hid-i2c-hid-allocate-hid-buffers-for-real-worst-case.patch +drm-i915-bios-ignore-hdmi-on-port-a.patch +ext4-only-call-ext4_truncate-when-size-isize.patch +fs-super.c-fix-race-between-freeze_super-and-thaw_super.patch +ext4-fix-data-corruption-for-mmap-writes.patch +ext4-don-t-clear-sgid-when-inheriting-acls.patch +ext4-validate-s_first_meta_bg-at-mount-time.patch