]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 11 Feb 2013 19:42:57 +0000 (11:42 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 11 Feb 2013 19:42:57 +0000 (11:42 -0800)
added patches:
bluetooth-fix-handling-of-unexpected-smp-pdus.patch
kernel-resource.c-fix-stack-overflow-in-__reserve_region_with_split.patch
virtio_console-don-t-access-uninitialized-data.patch

queue-3.4/bluetooth-fix-handling-of-unexpected-smp-pdus.patch [new file with mode: 0644]
queue-3.4/kernel-resource.c-fix-stack-overflow-in-__reserve_region_with_split.patch [new file with mode: 0644]
queue-3.4/series
queue-3.4/virtio_console-don-t-access-uninitialized-data.patch [new file with mode: 0644]

diff --git a/queue-3.4/bluetooth-fix-handling-of-unexpected-smp-pdus.patch b/queue-3.4/bluetooth-fix-handling-of-unexpected-smp-pdus.patch
new file mode 100644 (file)
index 0000000..5127389
--- /dev/null
@@ -0,0 +1,47 @@
+From 8cf9fa1240229cbdd888236c0c43fcbad680cf00 Mon Sep 17 00:00:00 2001
+From: Johan Hedberg <johan.hedberg@intel.com>
+Date: Tue, 29 Jan 2013 10:44:23 -0600
+Subject: Bluetooth: Fix handling of unexpected SMP PDUs
+
+From: Johan Hedberg <johan.hedberg@intel.com>
+
+commit 8cf9fa1240229cbdd888236c0c43fcbad680cf00 upstream.
+
+The conn->smp_chan pointer can be NULL if SMP PDUs arrive at unexpected
+moments. To avoid NULL pointer dereferences the code should be checking
+for this and disconnect if an unexpected SMP PDU arrives. This patch
+fixes the issue by adding a check for conn->smp_chan for all other PDUs
+except pairing request and security request (which are are the first
+PDUs to come to initialize the SMP context).
+
+Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
+Acked-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/bluetooth/smp.c |   13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/net/bluetooth/smp.c
++++ b/net/bluetooth/smp.c
+@@ -852,6 +852,19 @@ int smp_sig_channel(struct l2cap_conn *c
+       skb_pull(skb, sizeof(code));
++      /*
++       * The SMP context must be initialized for all other PDUs except
++       * pairing and security requests. If we get any other PDU when
++       * not initialized simply disconnect (done if this function
++       * returns an error).
++       */
++      if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
++          !conn->smp_chan) {
++              BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
++              kfree_skb(skb);
++              return -ENOTSUPP;
++      }
++
+       switch (code) {
+       case SMP_CMD_PAIRING_REQ:
+               reason = smp_cmd_pairing_req(conn, skb);
diff --git a/queue-3.4/kernel-resource.c-fix-stack-overflow-in-__reserve_region_with_split.patch b/queue-3.4/kernel-resource.c-fix-stack-overflow-in-__reserve_region_with_split.patch
new file mode 100644 (file)
index 0000000..07d4373
--- /dev/null
@@ -0,0 +1,104 @@
+From 4965f5667f36a95b41cda6638875bc992bd7d18b Mon Sep 17 00:00:00 2001
+From: T Makphaibulchoke <tmac@hp.com>
+Date: Thu, 4 Oct 2012 17:16:55 -0700
+Subject: kernel/resource.c: fix stack overflow in __reserve_region_with_split()
+
+From: T Makphaibulchoke <tmac@hp.com>
+
+commit 4965f5667f36a95b41cda6638875bc992bd7d18b upstream.
+
+Using a recursive call add a non-conflicting region in
+__reserve_region_with_split() could result in a stack overflow in the case
+that the recursive calls are too deep.  Convert the recursive calls to an
+iterative loop to avoid the problem.
+
+Tested on a machine containing 135 regions.  The kernel no longer panicked
+with stack overflow.
+
+Also tested with code arbitrarily adding regions with no conflict,
+embedding two consecutive conflicts and embedding two non-consecutive
+conflicts.
+
+Signed-off-by: T Makphaibulchoke <tmac@hp.com>
+Reviewed-by: Ram Pai <linuxram@us.ibm.com>
+Cc: Paul Gortmaker <paul.gortmaker@gmail.com>
+Cc: Wei Yang <weiyang@linux.vnet.ibm.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Jiri Slaby <jslaby@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/resource.c |   52 +++++++++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 39 insertions(+), 13 deletions(-)
+
+--- a/kernel/resource.c
++++ b/kernel/resource.c
+@@ -758,6 +758,7 @@ static void __init __reserve_region_with
+       struct resource *parent = root;
+       struct resource *conflict;
+       struct resource *res = kzalloc(sizeof(*res), GFP_ATOMIC);
++      struct resource *next_res = NULL;
+       if (!res)
+               return;
+@@ -767,21 +768,46 @@ static void __init __reserve_region_with
+       res->end = end;
+       res->flags = IORESOURCE_BUSY;
+-      conflict = __request_resource(parent, res);
+-      if (!conflict)
+-              return;
+-
+-      /* failed, split and try again */
+-      kfree(res);
++      while (1) {
+-      /* conflict covered whole area */
+-      if (conflict->start <= start && conflict->end >= end)
+-              return;
++              conflict = __request_resource(parent, res);
++              if (!conflict) {
++                      if (!next_res)
++                              break;
++                      res = next_res;
++                      next_res = NULL;
++                      continue;
++              }
++
++              /* conflict covered whole area */
++              if (conflict->start <= res->start &&
++                              conflict->end >= res->end) {
++                      kfree(res);
++                      WARN_ON(next_res);
++                      break;
++              }
++
++              /* failed, split and try again */
++              if (conflict->start > res->start) {
++                      end = res->end;
++                      res->end = conflict->start - 1;
++                      if (conflict->end < end) {
++                              next_res = kzalloc(sizeof(*next_res),
++                                              GFP_ATOMIC);
++                              if (!next_res) {
++                                      kfree(res);
++                                      break;
++                              }
++                              next_res->name = name;
++                              next_res->start = conflict->end + 1;
++                              next_res->end = end;
++                              next_res->flags = IORESOURCE_BUSY;
++                      }
++              } else {
++                      res->start = conflict->end + 1;
++              }
++      }
+-      if (conflict->start > start)
+-              __reserve_region_with_split(root, start, conflict->start-1, name);
+-      if (conflict->end < end)
+-              __reserve_region_with_split(root, conflict->end+1, end, name);
+ }
+ void __init reserve_region_with_split(struct resource *root,
index 980c122805e46cb9826d49f70d109e0e99a5edb8..60ceb9d4c8c58bfbf6955e1ac445e22d2450d198 100644 (file)
@@ -1,2 +1,5 @@
 rtlwifi-fix-the-usage-of-the-wrong-variable-in-usb.c.patch
 rtlwifi-fix-scheduling-while-atomic-bug.patch
+virtio_console-don-t-access-uninitialized-data.patch
+kernel-resource.c-fix-stack-overflow-in-__reserve_region_with_split.patch
+bluetooth-fix-handling-of-unexpected-smp-pdus.patch
diff --git a/queue-3.4/virtio_console-don-t-access-uninitialized-data.patch b/queue-3.4/virtio_console-don-t-access-uninitialized-data.patch
new file mode 100644 (file)
index 0000000..3a550c4
--- /dev/null
@@ -0,0 +1,68 @@
+From aded024a12b32fc1ed9a80639681daae2d07ec25 Mon Sep 17 00:00:00 2001
+From: Sjur Brændeland <sjur.brandeland@stericsson.com>
+Date: Tue, 22 Jan 2013 09:50:26 +1030
+Subject: virtio_console: Don't access uninitialized data.
+
+From: Sjur Brændeland <sjur.brandeland@stericsson.com>
+
+commit aded024a12b32fc1ed9a80639681daae2d07ec25 upstream.
+
+Don't access uninitialized work-queue when removing device.
+The work queue is initialized only if the device multi-queue.
+So don't call cancel_work unless this is a multi-queue device.
+
+This fixes the following panic:
+
+Kernel panic - not syncing: BUG!
+Call Trace:
+62031b28:  [<6026085d>] panic+0x16b/0x2d3
+62031b30:  [<6004ef5e>] flush_work+0x0/0x1d7
+62031b60:  [<602606f2>] panic+0x0/0x2d3
+62031b68:  [<600333b0>] memcpy+0x0/0x140
+62031b80:  [<6002d58a>] unblock_signals+0x0/0x84
+62031ba0:  [<602609c5>] printk+0x0/0xa0
+62031bd8:  [<60264e51>] __mutex_unlock_slowpath+0x13d/0x148
+62031c10:  [<6004ef5e>] flush_work+0x0/0x1d7
+62031c18:  [<60050234>] try_to_grab_pending+0x0/0x17e
+62031c38:  [<6004e984>] get_work_gcwq+0x71/0x8f
+62031c48:  [<60050539>] __cancel_work_timer+0x5b/0x115
+62031c78:  [<628acc85>] unplug_port+0x0/0x191 [virtio_console]
+62031c98:  [<6005061c>] cancel_work_sync+0x12/0x14
+62031ca8:  [<628ace96>] virtcons_remove+0x80/0x15c [virtio_console]
+62031ce8:  [<628191de>] virtio_dev_remove+0x1e/0x7e [virtio]
+62031d08:  [<601cf242>] __device_release_driver+0x75/0xe4
+62031d28:  [<601cf2dd>] device_release_driver+0x2c/0x40
+62031d48:  [<601ce0dd>] driver_unbind+0x7d/0xc6
+62031d88:  [<601cd5d9>] drv_attr_store+0x27/0x29
+62031d98:  [<60115f61>] sysfs_write_file+0x100/0x14d
+62031df8:  [<600b737d>] vfs_write+0xcb/0x184
+62031e08:  [<600b58b8>] filp_close+0x88/0x94
+62031e38:  [<600b7686>] sys_write+0x59/0x88
+62031e88:  [<6001ced1>] handle_syscall+0x5d/0x80
+62031ea8:  [<60030a74>] userspace+0x405/0x531
+62031f08:  [<600d32cc>] sys_dup+0x0/0x5e
+62031f28:  [<601b11d6>] strcpy+0x0/0x18
+62031f38:  [<600be46c>] do_execve+0x10/0x12
+62031f48:  [<600184c7>] run_init_process+0x43/0x45
+62031fd8:  [<60019a91>] new_thread_handler+0xba/0xbc
+
+Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
+Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/virtio_console.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/char/virtio_console.c
++++ b/drivers/char/virtio_console.c
+@@ -1808,7 +1808,8 @@ static void virtcons_remove(struct virti
+       /* Disable interrupts for vqs */
+       vdev->config->reset(vdev);
+       /* Finish up work that's lined up */
+-      cancel_work_sync(&portdev->control_work);
++      if (use_multiport(portdev))
++              cancel_work_sync(&portdev->control_work);
+       list_for_each_entry_safe(port, port2, &portdev->ports, list)
+               unplug_port(port);