]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 30 Apr 2017 12:26:53 +0000 (14:26 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 30 Apr 2017 12:26:53 +0000 (14:26 +0200)
added patches:
ext4-check-if-in-inode-xattr-is-corrupted-in-ext4_expand_extra_isize_ea.patch
md-raid1-fix-a-dead-loop-when-read-from-a-writemostly-disk.patch
mips-fix-crash-registers-on-non-crashing-cpus.patch
rds-fix-the-atomicity-for-congestion-map-update.patch
usb-gadget-f_midi-fixed-a-bug-when-buflen-was-smaller-than-wmaxpacketsize.patch
xen-x86-don-t-lose-event-interrupts.patch

queue-3.18/ext4-check-if-in-inode-xattr-is-corrupted-in-ext4_expand_extra_isize_ea.patch [new file with mode: 0644]
queue-3.18/md-raid1-fix-a-dead-loop-when-read-from-a-writemostly-disk.patch [new file with mode: 0644]
queue-3.18/mips-fix-crash-registers-on-non-crashing-cpus.patch [new file with mode: 0644]
queue-3.18/rds-fix-the-atomicity-for-congestion-map-update.patch [new file with mode: 0644]
queue-3.18/series
queue-3.18/usb-gadget-f_midi-fixed-a-bug-when-buflen-was-smaller-than-wmaxpacketsize.patch [new file with mode: 0644]
queue-3.18/xen-x86-don-t-lose-event-interrupts.patch [new file with mode: 0644]

diff --git a/queue-3.18/ext4-check-if-in-inode-xattr-is-corrupted-in-ext4_expand_extra_isize_ea.patch b/queue-3.18/ext4-check-if-in-inode-xattr-is-corrupted-in-ext4_expand_extra_isize_ea.patch
new file mode 100644 (file)
index 0000000..027336f
--- /dev/null
@@ -0,0 +1,92 @@
+From 9e92f48c34eb2b9af9d12f892e2fe1fce5e8ce35 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Tue, 22 Mar 2016 16:13:15 -0400
+Subject: ext4: check if in-inode xattr is corrupted in ext4_expand_extra_isize_ea()
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 9e92f48c34eb2b9af9d12f892e2fe1fce5e8ce35 upstream.
+
+We aren't checking to see if the in-inode extended attribute is
+corrupted before we try to expand the inode's extra isize fields.
+
+This can lead to potential crashes caused by the BUG_ON() check in
+ext4_xattr_shift_entries().
+
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: Julia Lawall <julia.lawall@lip6.fr>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ext4/xattr.c |   32 ++++++++++++++++++++++++++++----
+ 1 file changed, 28 insertions(+), 4 deletions(-)
+
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -233,6 +233,27 @@ ext4_xattr_check_block(struct inode *ino
+       return error;
+ }
++static int
++__xattr_check_inode(struct inode *inode, struct ext4_xattr_ibody_header *header,
++                       void *end, const char *function, unsigned int line)
++{
++      struct ext4_xattr_entry *entry = IFIRST(header);
++      int error = -EFSCORRUPTED;
++
++      if (((void *) header >= end) ||
++          (header->h_magic != le32_to_cpu(EXT4_XATTR_MAGIC)))
++              goto errout;
++      error = ext4_xattr_check_names(entry, end, entry);
++errout:
++      if (error)
++              __ext4_error_inode(inode, function, line, 0,
++                                 "corrupted in-inode xattr");
++      return error;
++}
++
++#define xattr_check_inode(inode, header, end) \
++      __xattr_check_inode((inode), (header), (end), __func__, __LINE__)
++
+ static inline int
+ ext4_xattr_check_entry(struct ext4_xattr_entry *entry, size_t size)
+ {
+@@ -344,7 +365,7 @@ ext4_xattr_ibody_get(struct inode *inode
+       header = IHDR(inode, raw_inode);
+       entry = IFIRST(header);
+       end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
+-      error = ext4_xattr_check_names(entry, end, entry);
++      error = xattr_check_inode(inode, header, end);
+       if (error)
+               goto cleanup;
+       error = ext4_xattr_find_entry(&entry, name_index, name,
+@@ -476,7 +497,7 @@ ext4_xattr_ibody_list(struct dentry *den
+       raw_inode = ext4_raw_inode(&iloc);
+       header = IHDR(inode, raw_inode);
+       end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
+-      error = ext4_xattr_check_names(IFIRST(header), end, IFIRST(header));
++      error = xattr_check_inode(inode, header, end);
+       if (error)
+               goto cleanup;
+       error = ext4_xattr_list_entries(dentry, IFIRST(header),
+@@ -993,8 +1014,7 @@ int ext4_xattr_ibody_find(struct inode *
+       is->s.here = is->s.first;
+       is->s.end = (void *)raw_inode + EXT4_SB(inode->i_sb)->s_inode_size;
+       if (ext4_test_inode_state(inode, EXT4_STATE_XATTR)) {
+-              error = ext4_xattr_check_names(IFIRST(header), is->s.end,
+-                                             IFIRST(header));
++              error = xattr_check_inode(inode, header, is->s.end);
+               if (error)
+                       return error;
+               /* Find the named attribute. */
+@@ -1291,6 +1311,10 @@ retry:
+       last = entry;
+       total_ino = sizeof(struct ext4_xattr_ibody_header);
++      error = xattr_check_inode(inode, header, end);
++      if (error)
++              goto cleanup;
++
+       free = ext4_xattr_free_space(last, &min_offs, base, &total_ino);
+       if (free >= new_extra_isize) {
+               entry = IFIRST(header);
diff --git a/queue-3.18/md-raid1-fix-a-dead-loop-when-read-from-a-writemostly-disk.patch b/queue-3.18/md-raid1-fix-a-dead-loop-when-read-from-a-writemostly-disk.patch
new file mode 100644 (file)
index 0000000..d4d21da
--- /dev/null
@@ -0,0 +1,37 @@
+From 816b0acf3deb6d6be5d0519b286fdd4bafade905 Mon Sep 17 00:00:00 2001
+From: Wei Fang <fangwei1@huawei.com>
+Date: Mon, 21 Mar 2016 19:18:32 +0800
+Subject: md:raid1: fix a dead loop when read from a WriteMostly disk
+
+From: Wei Fang <fangwei1@huawei.com>
+
+commit 816b0acf3deb6d6be5d0519b286fdd4bafade905 upstream.
+
+If first_bad == this_sector when we get the WriteMostly disk
+in read_balance(), valid disk will be returned with zero
+max_sectors. It'll lead to a dead loop in make_request(), and
+OOM will happen because of endless allocation of struct bio.
+
+Since we can't get data from this disk in this case, so
+continue for another disk.
+
+Signed-off-by: Wei Fang <fangwei1@huawei.com>
+Signed-off-by: Shaohua Li <shli@fb.com>
+Cc: Julia Lawall <julia.lawall@lip6.fr>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/raid1.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -563,7 +563,7 @@ static int read_balance(struct r1conf *c
+                       if (best_dist_disk < 0) {
+                               if (is_badblock(rdev, this_sector, sectors,
+                                               &first_bad, &bad_sectors)) {
+-                                      if (first_bad < this_sector)
++                                      if (first_bad <= this_sector)
+                                               /* Cannot use this */
+                                               continue;
+                                       best_good_sectors = first_bad - this_sector;
diff --git a/queue-3.18/mips-fix-crash-registers-on-non-crashing-cpus.patch b/queue-3.18/mips-fix-crash-registers-on-non-crashing-cpus.patch
new file mode 100644 (file)
index 0000000..2db0aff
--- /dev/null
@@ -0,0 +1,58 @@
+From c80e1b62ffca52e2d1d865ee58bc79c4c0c55005 Mon Sep 17 00:00:00 2001
+From: Corey Minyard <cminyard@mvista.com>
+Date: Mon, 11 Apr 2016 09:10:19 -0500
+Subject: MIPS: Fix crash registers on non-crashing CPUs
+
+From: Corey Minyard <cminyard@mvista.com>
+
+commit c80e1b62ffca52e2d1d865ee58bc79c4c0c55005 upstream.
+
+As part of handling a crash on an SMP system, an IPI is send to
+all other CPUs to save their current registers and stop.  It was
+using task_pt_regs(current) to get the registers, but that will
+only be accurate if the CPU was interrupted running in userland.
+Instead allow the architecture to pass in the registers (all
+pass NULL now, but allow for the future) and then use get_irq_regs()
+which should be accurate as we are in an interrupt.  Fall back to
+task_pt_regs(current) if nothing else is available.
+
+Signed-off-by: Corey Minyard <cminyard@mvista.com>
+Cc: David Daney <ddaney@caviumnetworks.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/13050/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Cc: Julia Lawall <julia.lawall@lip6.fr>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/crash.c |   16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+--- a/arch/mips/kernel/crash.c
++++ b/arch/mips/kernel/crash.c
+@@ -14,12 +14,22 @@ static int crashing_cpu = -1;
+ static cpumask_t cpus_in_crash = CPU_MASK_NONE;
+ #ifdef CONFIG_SMP
+-static void crash_shutdown_secondary(void *ignore)
++static void crash_shutdown_secondary(void *passed_regs)
+ {
+-      struct pt_regs *regs;
++      struct pt_regs *regs = passed_regs;
+       int cpu = smp_processor_id();
+-      regs = task_pt_regs(current);
++      /*
++       * If we are passed registers, use those.  Otherwise get the
++       * regs from the last interrupt, which should be correct, as
++       * we are in an interrupt.  But if the regs are not there,
++       * pull them from the top of the stack.  They are probably
++       * wrong, but we need something to keep from crashing again.
++       */
++      if (!regs)
++              regs = get_irq_regs();
++      if (!regs)
++              regs = task_pt_regs(current);
+       if (!cpu_online(cpu))
+               return;
diff --git a/queue-3.18/rds-fix-the-atomicity-for-congestion-map-update.patch b/queue-3.18/rds-fix-the-atomicity-for-congestion-map-update.patch
new file mode 100644 (file)
index 0000000..f0d8676
--- /dev/null
@@ -0,0 +1,50 @@
+From e47db94e10447fc467777a40302f2b393e9af2fa Mon Sep 17 00:00:00 2001
+From: "santosh.shilimkar@oracle.com" <santosh.shilimkar@oracle.com>
+Date: Thu, 14 Apr 2016 10:43:27 -0700
+Subject: RDS: Fix the atomicity for congestion map update
+
+From: santosh.shilimkar@oracle.com <santosh.shilimkar@oracle.com>
+
+commit e47db94e10447fc467777a40302f2b393e9af2fa upstream.
+
+Two different threads with different rds sockets may be in
+rds_recv_rcvbuf_delta() via receive path. If their ports
+both map to the same word in the congestion map, then
+using non-atomic ops to update it could cause the map to
+be incorrect. Lets use atomics to avoid such an issue.
+
+Full credit to Wengang <wen.gang.wang@oracle.com> for
+finding the issue, analysing it and also pointing out
+to offending code with spin lock based fix.
+
+Reviewed-by: Leon Romanovsky <leon@leon.nu>
+Signed-off-by: Wengang Wang <wen.gang.wang@oracle.com>
+Signed-off-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Cc: Julia Lawall <julia.lawall@lip6.fr>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/rds/cong.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/rds/cong.c
++++ b/net/rds/cong.c
+@@ -285,7 +285,7 @@ void rds_cong_set_bit(struct rds_cong_ma
+       i = be16_to_cpu(port) / RDS_CONG_MAP_PAGE_BITS;
+       off = be16_to_cpu(port) % RDS_CONG_MAP_PAGE_BITS;
+-      __set_bit_le(off, (void *)map->m_page_addrs[i]);
++      set_bit_le(off, (void *)map->m_page_addrs[i]);
+ }
+ void rds_cong_clear_bit(struct rds_cong_map *map, __be16 port)
+@@ -299,7 +299,7 @@ void rds_cong_clear_bit(struct rds_cong_
+       i = be16_to_cpu(port) / RDS_CONG_MAP_PAGE_BITS;
+       off = be16_to_cpu(port) % RDS_CONG_MAP_PAGE_BITS;
+-      __clear_bit_le(off, (void *)map->m_page_addrs[i]);
++      clear_bit_le(off, (void *)map->m_page_addrs[i]);
+ }
+ static int rds_cong_test_bit(struct rds_cong_map *map, __be16 port)
index d5dd8c2d4777c31db7b5555d4d25a0bc6d706d75..eef098e68fbcf26f966c200bdd7c24237033792c 100644 (file)
@@ -1,2 +1,8 @@
 f2fs-do-more-integrity-verification-for-superblock.patch
 xc2028-unlock-on-error-in-xc2028_set_config.patch
+ext4-check-if-in-inode-xattr-is-corrupted-in-ext4_expand_extra_isize_ea.patch
+md-raid1-fix-a-dead-loop-when-read-from-a-writemostly-disk.patch
+mips-fix-crash-registers-on-non-crashing-cpus.patch
+rds-fix-the-atomicity-for-congestion-map-update.patch
+usb-gadget-f_midi-fixed-a-bug-when-buflen-was-smaller-than-wmaxpacketsize.patch
+xen-x86-don-t-lose-event-interrupts.patch
diff --git a/queue-3.18/usb-gadget-f_midi-fixed-a-bug-when-buflen-was-smaller-than-wmaxpacketsize.patch b/queue-3.18/usb-gadget-f_midi-fixed-a-bug-when-buflen-was-smaller-than-wmaxpacketsize.patch
new file mode 100644 (file)
index 0000000..c79d93a
--- /dev/null
@@ -0,0 +1,52 @@
+From 03d27ade4941076b34c823d63d91dc895731a595 Mon Sep 17 00:00:00 2001
+From: "Felipe F. Tonello" <eu@felipetonello.com>
+Date: Wed, 9 Mar 2016 19:39:30 +0000
+Subject: usb: gadget: f_midi: Fixed a bug when buflen was smaller than wMaxPacketSize
+
+From: Felipe F. Tonello <eu@felipetonello.com>
+
+commit 03d27ade4941076b34c823d63d91dc895731a595 upstream.
+
+buflen by default (256) is smaller than wMaxPacketSize (512) in high-speed
+devices.
+
+That caused the OUT endpoint to freeze if the host send any data packet of
+length greater than 256 bytes.
+
+This is an example dump of what happended on that enpoint:
+HOST:   [DATA][Length=260][...]
+DEVICE: [NAK]
+HOST:   [PING]
+DEVICE: [NAK]
+HOST:   [PING]
+DEVICE: [NAK]
+...
+HOST:   [PING]
+DEVICE: [NAK]
+
+This patch fixes this problem by setting the minimum usb_request's buffer size
+for the OUT endpoint as its wMaxPacketSize.
+
+Acked-by: Michal Nazarewicz <mina86@mina86.com>
+Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Cc: Julia Lawall <julia.lawall@lip6.fr>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/function/f_midi.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/function/f_midi.c
++++ b/drivers/usb/gadget/function/f_midi.c
+@@ -357,7 +357,9 @@ static int f_midi_set_alt(struct usb_fun
+       /* allocate a bunch of read buffers and queue them all at once. */
+       for (i = 0; i < midi->qlen && err == 0; i++) {
+               struct usb_request *req =
+-                      midi_alloc_ep_req(midi->out_ep, midi->buflen);
++                      midi_alloc_ep_req(midi->out_ep,
++                              max_t(unsigned, midi->buflen,
++                                      bulk_out_desc.wMaxPacketSize));
+               if (req == NULL)
+                       return -ENOMEM;
diff --git a/queue-3.18/xen-x86-don-t-lose-event-interrupts.patch b/queue-3.18/xen-x86-don-t-lose-event-interrupts.patch
new file mode 100644 (file)
index 0000000..d954211
--- /dev/null
@@ -0,0 +1,47 @@
+From c06b6d70feb32d28f04ba37aa3df17973fd37b6b Mon Sep 17 00:00:00 2001
+From: Stefano Stabellini <sstabellini@kernel.org>
+Date: Fri, 15 Apr 2016 18:23:00 -0700
+Subject: xen/x86: don't lose event interrupts
+
+From: Stefano Stabellini <sstabellini@kernel.org>
+
+commit c06b6d70feb32d28f04ba37aa3df17973fd37b6b upstream.
+
+On slow platforms with unreliable TSC, such as QEMU emulated machines,
+it is possible for the kernel to request the next event in the past. In
+that case, in the current implementation of xen_vcpuop_clockevent, we
+simply return -ETIME. To be precise the Xen returns -ETIME and we pass
+it on. However the result of this is a missed event, which simply causes
+the kernel to hang.
+
+Instead it is better to always ask the hypervisor for a timer event,
+even if the timeout is in the past. That way there are no lost
+interrupts and the kernel survives. To do that, remove the
+VCPU_SSHOTTMR_future flag.
+
+Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
+Acked-by: Juergen Gross <jgross@suse.com>
+Cc: Julia Lawall <julia.lawall@lip6.fr>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/xen/time.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/arch/x86/xen/time.c
++++ b/arch/x86/xen/time.c
+@@ -362,11 +362,11 @@ static int xen_vcpuop_set_next_event(uns
+       WARN_ON(evt->mode != CLOCK_EVT_MODE_ONESHOT);
+       single.timeout_abs_ns = get_abs_timeout(delta);
+-      single.flags = VCPU_SSHOTTMR_future;
++      /* Get an event anyway, even if the timeout is already expired */
++      single.flags = 0;
+       ret = HYPERVISOR_vcpu_op(VCPUOP_set_singleshot_timer, cpu, &single);
+-
+-      BUG_ON(ret != 0 && ret != -ETIME);
++      BUG_ON(ret != 0);
+       return ret;
+ }