summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZefan Li <lizefan@huawei.com>2015-04-09 16:13:11 +0800
committerZefan Li <lizefan@huawei.com>2015-04-09 16:13:11 +0800
commit9f19bf656c391d26a6d7c3704f8dbcbf81b0c8e6 (patch)
tree9f23d31d642ae0761e6248b0615cfc4ec8e8699a
parente321756c07a148cb4472bd525789e13557b891b0 (diff)
downloadlinux-3.4.y-queue-9f19bf656c391d26a6d7c3704f8dbcbf81b0c8e6.tar.gz
Add a few patches to fix bugs introduced by previous backports
-rw-r--r--patches/mm-fix-anon_vma-degree-underflow-in-anon_vma-endless-growing-prevention.patch73
-rw-r--r--patches/net-compat-update-get_compat_msghdr-to-match-copy_msghdr_from_user-behaviour.patch50
-rw-r--r--patches/nilfs2-fix-deadlock-of-segment-constructor-during-recovery.patch90
-rw-r--r--patches/ntp-fixup-adjtimex-freq-validation-on-32-bit-systems.patch68
-rw-r--r--patches/series5
-rw-r--r--patches/spi-dw-revisit-fifo-size-detection-again.patch48
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);
+ }
+ }