diff options
author | Zefan Li <lizefan@huawei.com> | 2015-04-09 16:13:11 +0800 |
---|---|---|
committer | Zefan Li <lizefan@huawei.com> | 2015-04-09 16:13:11 +0800 |
commit | 9f19bf656c391d26a6d7c3704f8dbcbf81b0c8e6 (patch) | |
tree | 9f23d31d642ae0761e6248b0615cfc4ec8e8699a | |
parent | e321756c07a148cb4472bd525789e13557b891b0 (diff) | |
download | linux-3.4.y-queue-9f19bf656c391d26a6d7c3704f8dbcbf81b0c8e6.tar.gz |
Add a few patches to fix bugs introduced by previous backports
6 files changed, 334 insertions, 0 deletions
diff --git a/patches/mm-fix-anon_vma-degree-underflow-in-anon_vma-endless-growing-prevention.patch b/patches/mm-fix-anon_vma-degree-underflow-in-anon_vma-endless-growing-prevention.patch new file mode 100644 index 0000000..5ca98fa --- /dev/null +++ b/patches/mm-fix-anon_vma-degree-underflow-in-anon_vma-endless-growing-prevention.patch @@ -0,0 +1,73 @@ +From 3fe89b3e2a7bbf3e97657104b9b33a9d81b950b3 Mon Sep 17 00:00:00 2001 +From: Leon Yu <chianglungyu@gmail.com> +Date: Wed, 25 Mar 2015 15:55:11 -0700 +Subject: mm: fix anon_vma->degree underflow in anon_vma endless growing + prevention + +commit 3fe89b3e2a7bbf3e97657104b9b33a9d81b950b3 upstream. + +I have constantly stumbled upon "kernel BUG at mm/rmap.c:399!" after +upgrading to 3.19 and had no luck with 4.0-rc1 neither. + +So, after looking into new logic introduced by commit 7a3ef208e662 ("mm: +prevent endless growth of anon_vma hierarchy"), I found chances are that +unlink_anon_vmas() is called without incrementing dst->anon_vma->degree +in anon_vma_clone() due to allocation failure. If dst->anon_vma is not +NULL in error path, its degree will be incorrectly decremented in +unlink_anon_vmas() and eventually underflow when exiting as a result of +another call to unlink_anon_vmas(). That's how "kernel BUG at +mm/rmap.c:399!" is triggered for me. + +This patch fixes the underflow by dropping dst->anon_vma when allocation +fails. It's safe to do so regardless of original value of dst->anon_vma +because dst->anon_vma doesn't have valid meaning if anon_vma_clone() +fails. Besides, callers don't care dst->anon_vma in such case neither. + +Also suggested by Michal Hocko, we can clean up vma_adjust() a bit as +anon_vma_clone() now does the work. + +[akpm@linux-foundation.org: tweak comment] +Fixes: 7a3ef208e662 ("mm: prevent endless growth of anon_vma hierarchy") +Signed-off-by: Leon Yu <chianglungyu@gmail.com> +Signed-off-by: Konstantin Khlebnikov <koct9i@gmail.com> +Reviewed-by: Michal Hocko <mhocko@suse.cz> +Acked-by: Rik van Riel <riel@redhat.com> +Acked-by: David Rientjes <rientjes@google.com> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Zefan Li <lizefan@huawei.com> +--- + mm/mmap.c | 4 +--- + mm/rmap.c | 7 +++++++ + 2 files changed, 8 insertions(+), 3 deletions(-) + +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -571,10 +571,8 @@ again: remove_next = 1 + (end > next-> + + importer->anon_vma = exporter->anon_vma; + error = anon_vma_clone(importer, exporter); +- if (error) { +- importer->anon_vma = NULL; ++ if (error) + return error; +- } + } + } + +--- a/mm/rmap.c ++++ b/mm/rmap.c +@@ -292,6 +292,13 @@ int anon_vma_clone(struct vm_area_struct + return 0; + + enomem_failure: ++ /* ++ * dst->anon_vma is dropped here otherwise its degree can be incorrectly ++ * decremented in unlink_anon_vmas(). ++ * We can safely do this because callers of anon_vma_clone() don't care ++ * about dst->anon_vma if anon_vma_clone() failed. ++ */ ++ dst->anon_vma = NULL; + unlink_anon_vmas(dst); + return -ENOMEM; + } diff --git a/patches/net-compat-update-get_compat_msghdr-to-match-copy_msghdr_from_user-behaviour.patch b/patches/net-compat-update-get_compat_msghdr-to-match-copy_msghdr_from_user-behaviour.patch new file mode 100644 index 0000000..05757b8 --- /dev/null +++ b/patches/net-compat-update-get_compat_msghdr-to-match-copy_msghdr_from_user-behaviour.patch @@ -0,0 +1,50 @@ +From 91edd096e224941131f896b86838b1e59553696a Mon Sep 17 00:00:00 2001 +From: Catalin Marinas <catalin.marinas@arm.com> +Date: Fri, 20 Mar 2015 16:48:13 +0000 +Subject: net: compat: Update get_compat_msghdr() to match + copy_msghdr_from_user() behaviour + +commit 91edd096e224941131f896b86838b1e59553696a upstream. + +Commit db31c55a6fb2 (net: clamp ->msg_namelen instead of returning an +error) introduced the clamping of msg_namelen when the unsigned value +was larger than sizeof(struct sockaddr_storage). This caused a +msg_namelen of -1 to be valid. The native code was subsequently fixed by +commit dbb490b96584 (net: socket: error on a negative msg_namelen). + +In addition, the native code sets msg_namelen to 0 when msg_name is +NULL. This was done in commit (6a2a2b3ae075 net:socket: set msg_namelen +to 0 if msg_name is passed as NULL in msghdr struct from userland) and +subsequently updated by 08adb7dabd48 (fold verify_iovec() into +copy_msghdr_from_user()). + +This patch brings the get_compat_msghdr() in line with +copy_msghdr_from_user(). + +Fixes: db31c55a6fb2 (net: clamp ->msg_namelen instead of returning an error) +Cc: David S. Miller <davem@davemloft.net> +Cc: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +[lizf: Backported to 3.4: s/uaddr/tmp1/] +Signed-off-by: Zefan Li <lizefan@huawei.com> +--- + net/compat.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/net/compat.c ++++ b/net/compat.c +@@ -71,6 +71,13 @@ int get_compat_msghdr(struct msghdr *kms + __get_user(kmsg->msg_controllen, &umsg->msg_controllen) || + __get_user(kmsg->msg_flags, &umsg->msg_flags)) + return -EFAULT; ++ ++ if (!tmp1) ++ kmsg->msg_namelen = 0; ++ ++ if (kmsg->msg_namelen < 0) ++ return -EINVAL; ++ + if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) + kmsg->msg_namelen = sizeof(struct sockaddr_storage); + kmsg->msg_name = compat_ptr(tmp1); diff --git a/patches/nilfs2-fix-deadlock-of-segment-constructor-during-recovery.patch b/patches/nilfs2-fix-deadlock-of-segment-constructor-during-recovery.patch new file mode 100644 index 0000000..19e069c --- /dev/null +++ b/patches/nilfs2-fix-deadlock-of-segment-constructor-during-recovery.patch @@ -0,0 +1,90 @@ +From 283ee1482f349d6c0c09dfb725db5880afc56813 Mon Sep 17 00:00:00 2001 +From: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> +Date: Thu, 12 Mar 2015 16:26:00 -0700 +Subject: nilfs2: fix deadlock of segment constructor during recovery + +commit 283ee1482f349d6c0c09dfb725db5880afc56813 upstream. + +According to a report from Yuxuan Shui, nilfs2 in kernel 3.19 got stuck +during recovery at mount time. The code path that caused the deadlock was +as follows: + + nilfs_fill_super() + load_nilfs() + nilfs_salvage_orphan_logs() + * Do roll-forwarding, attach segment constructor for recovery, + and kick it. + + nilfs_segctor_thread() + nilfs_segctor_thread_construct() + * A lock is held with nilfs_transaction_lock() + nilfs_segctor_do_construct() + nilfs_segctor_drop_written_files() + iput() + iput_final() + write_inode_now() + writeback_single_inode() + __writeback_single_inode() + do_writepages() + nilfs_writepage() + nilfs_construct_dsync_segment() + nilfs_transaction_lock() --> deadlock + +This can happen if commit 7ef3ff2fea8b ("nilfs2: fix deadlock of segment +constructor over I_SYNC flag") is applied and roll-forward recovery was +performed at mount time. The roll-forward recovery can happen if datasync +write is done and the file system crashes immediately after that. For +instance, we can reproduce the issue with the following steps: + + < nilfs2 is mounted on /nilfs (device: /dev/sdb1) > + # dd if=/dev/zero of=/nilfs/test bs=4k count=1 && sync + # dd if=/dev/zero of=/nilfs/test conv=notrunc oflag=dsync bs=4k + count=1 && reboot -nfh + < the system will immediately reboot > + # mount -t nilfs2 /dev/sdb1 /nilfs + +The deadlock occurs because iput() can run segment constructor through +writeback_single_inode() if MS_ACTIVE flag is not set on sb->s_flags. The +above commit changed segment constructor so that it calls iput() +asynchronously for inodes with i_nlink == 0, but that change was +imperfect. + +This fixes the another deadlock by deferring iput() in segment constructor +even for the case that mount is not finished, that is, for the case that +MS_ACTIVE flag is not set. + +Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> +Reported-by: Yuxuan Shui <yshuiv7@gmail.com> +Tested-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> +Cc: Al Viro <viro@zeniv.linux.org.uk> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> +Signed-off-by: Zefan Li <lizefan@huawei.com> +--- + fs/nilfs2/segment.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/fs/nilfs2/segment.c ++++ b/fs/nilfs2/segment.c +@@ -1903,6 +1903,7 @@ static void nilfs_segctor_drop_written_f + struct the_nilfs *nilfs) + { + struct nilfs_inode_info *ii, *n; ++ int during_mount = !(sci->sc_super->s_flags & MS_ACTIVE); + int defer_iput = false; + + spin_lock(&nilfs->ns_inode_lock); +@@ -1915,10 +1916,10 @@ static void nilfs_segctor_drop_written_f + brelse(ii->i_bh); + ii->i_bh = NULL; + list_del_init(&ii->i_dirty); +- if (!ii->vfs_inode.i_nlink) { ++ if (!ii->vfs_inode.i_nlink || during_mount) { + /* +- * Defer calling iput() to avoid a deadlock +- * over I_SYNC flag for inodes with i_nlink == 0 ++ * Defer calling iput() to avoid deadlocks if ++ * i_nlink == 0 or mount is not yet finished. + */ + list_add_tail(&ii->i_dirty, &sci->sc_iput_queue); + defer_iput = true; diff --git a/patches/ntp-fixup-adjtimex-freq-validation-on-32-bit-systems.patch b/patches/ntp-fixup-adjtimex-freq-validation-on-32-bit-systems.patch new file mode 100644 index 0000000..e7a16d2 --- /dev/null +++ b/patches/ntp-fixup-adjtimex-freq-validation-on-32-bit-systems.patch @@ -0,0 +1,68 @@ +From 29183a70b0b828500816bd794b3fe192fce89f73 Mon Sep 17 00:00:00 2001 +From: John Stultz <john.stultz@linaro.org> +Date: Mon, 9 Feb 2015 23:30:36 -0800 +Subject: ntp: Fixup adjtimex freq validation on 32-bit systems + +commit 29183a70b0b828500816bd794b3fe192fce89f73 upstream. + +Additional validation of adjtimex freq values to avoid +potential multiplication overflows were added in commit +5e5aeb4367b (time: adjtimex: Validate the ADJ_FREQUENCY values) + +Unfortunately the patch used LONG_MAX/MIN instead of +LLONG_MAX/MIN, which was fine on 64-bit systems, but being +much smaller on 32-bit systems caused false positives +resulting in most direct frequency adjustments to fail w/ +EINVAL. + +ntpd only does direct frequency adjustments at startup, so +the issue was not as easily observed there, but other time +sync applications like ptpd and chrony were more effected by +the bug. + +See bugs: + + https://bugzilla.kernel.org/show_bug.cgi?id=92481 + https://bugzilla.redhat.com/show_bug.cgi?id=1188074 + +This patch changes the checks to use LLONG_MAX for +clarity, and additionally the checks are disabled +on 32-bit systems since LLONG_MAX/PPM_SCALE is always +larger then the 32-bit long freq value, so multiplication +overflows aren't possible there. + +Reported-by: Josh Boyer <jwboyer@fedoraproject.org> +Reported-by: George Joseph <george.joseph@fairview5.com> +Tested-by: George Joseph <george.joseph@fairview5.com> +Signed-off-by: John Stultz <john.stultz@linaro.org> +Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Sasha Levin <sasha.levin@oracle.com> +Link: http://lkml.kernel.org/r/1423553436-29747-1-git-send-email-john.stultz@linaro.org +[ Prettified the changelog and the comments a bit. ] +Signed-off-by: Ingo Molnar <mingo@kernel.org> +Signed-off-by: Zefan Li <lizefan@huawei.com> +--- + kernel/time/ntp.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/kernel/time/ntp.c ++++ b/kernel/time/ntp.c +@@ -660,10 +660,14 @@ int do_adjtimex(struct timex *txc) + return result; + } + +- if (txc->modes & ADJ_FREQUENCY) { +- if (LONG_MIN / PPM_SCALE > txc->freq) ++ /* ++ * Check for potential multiplication overflows that can ++ * only happen on 64-bit systems: ++ */ ++ if ((txc->modes & ADJ_FREQUENCY) && (BITS_PER_LONG == 64)) { ++ if (LLONG_MIN / PPM_SCALE > txc->freq) + return -EINVAL; +- if (LONG_MAX / PPM_SCALE < txc->freq) ++ if (LLONG_MAX / PPM_SCALE < txc->freq) + return -EINVAL; + } + diff --git a/patches/series b/patches/series index 22c9eab..ef03429 100644 --- a/patches/series +++ b/patches/series @@ -169,3 +169,8 @@ net-socket-set-msg_namelen-to-0-if-msg_name-is-passed-as-null-in-msghdr-struct-f fsnotify-next_i-is-freed-during-fsnotify_unmount_inodes.patch x86-cpu-amd-add-workaround-for-family-16h-erratum-793.patch s390-3215-fix-tty-output-containing-tabs.patch +ntp-fixup-adjtimex-freq-validation-on-32-bit-systems.patch +spi-dw-revisit-fifo-size-detection-again.patch +nilfs2-fix-deadlock-of-segment-constructor-during-recovery.patch +net-compat-update-get_compat_msghdr-to-match-copy_msghdr_from_user-behaviour.patch +mm-fix-anon_vma-degree-underflow-in-anon_vma-endless-growing-prevention.patch diff --git a/patches/spi-dw-revisit-fifo-size-detection-again.patch b/patches/spi-dw-revisit-fifo-size-detection-again.patch new file mode 100644 index 0000000..6f8dcc0 --- /dev/null +++ b/patches/spi-dw-revisit-fifo-size-detection-again.patch @@ -0,0 +1,48 @@ +From 9d239d353c319f9ff884c287ce47feb7cdf60ddc Mon Sep 17 00:00:00 2001 +From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +Date: Wed, 25 Feb 2015 11:39:36 +0200 +Subject: spi: dw: revisit FIFO size detection again + +commit 9d239d353c319f9ff884c287ce47feb7cdf60ddc upstream. + +The commit d297933cc7fc (spi: dw: Fix detecting FIFO depth) tries to fix the +logic of the FIFO detection based on the description on the comments. However, +there is a slight difference between numbers in TX Level and TX FIFO size. + +So, by specification the FIFO size would be in a range 2-256 bytes. From TX +Level prospective it means we can set threshold in the range 0-(FIFO size - 1) +bytes. Hence there are currently two issues: + a) FIFO size 2 bytes is actually skipped since TX Level is 1 bit and could be + either 0 or 1 byte; + b) FIFO size is incorrectly decreased by 1 which already done by meaning of + TX Level register. + +This patch fixes it eventually right. + +Fixes: d297933cc7fc (spi: dw: Fix detecting FIFO depth) +Reviewed-by: Axel Lin <axel.lin@ingics.com> +Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +Signed-off-by: Mark Brown <broonie@kernel.org> +Signed-off-by: Zefan Li <lizefan@huawei.com> +--- + drivers/spi/spi-dw.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/spi/spi-dw.c ++++ b/drivers/spi/spi-dw.c +@@ -780,13 +780,13 @@ static void spi_hw_init(struct dw_spi *d + */ + if (!dws->fifo_len) { + u32 fifo; +- for (fifo = 2; fifo <= 256; fifo++) { ++ for (fifo = 1; fifo < 256; fifo++) { + dw_writew(dws, DW_SPI_TXFLTR, fifo); + if (fifo != dw_readw(dws, DW_SPI_TXFLTR)) + break; + } + +- dws->fifo_len = (fifo == 2) ? 0 : fifo - 1; ++ dws->fifo_len = (fifo == 1) ? 0 : fifo; + dw_writew(dws, DW_SPI_TXFLTR, 0); + } + } |