From 66b3eb133fe9bee4e963aa67bf659fe4fdb18da4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 11 Feb 2013 11:42:57 -0800 Subject: [PATCH] 3.4-stable patches 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 --- ...-fix-handling-of-unexpected-smp-pdus.patch | 47 ++++++++ ...rflow-in-__reserve_region_with_split.patch | 104 ++++++++++++++++++ queue-3.4/series | 3 + ...sole-don-t-access-uninitialized-data.patch | 68 ++++++++++++ 4 files changed, 222 insertions(+) create mode 100644 queue-3.4/bluetooth-fix-handling-of-unexpected-smp-pdus.patch create mode 100644 queue-3.4/kernel-resource.c-fix-stack-overflow-in-__reserve_region_with_split.patch create mode 100644 queue-3.4/virtio_console-don-t-access-uninitialized-data.patch 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 index 00000000000..5127389fb8e --- /dev/null +++ b/queue-3.4/bluetooth-fix-handling-of-unexpected-smp-pdus.patch @@ -0,0 +1,47 @@ +From 8cf9fa1240229cbdd888236c0c43fcbad680cf00 Mon Sep 17 00:00:00 2001 +From: Johan Hedberg +Date: Tue, 29 Jan 2013 10:44:23 -0600 +Subject: Bluetooth: Fix handling of unexpected SMP PDUs + +From: Johan Hedberg + +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 +Acked-by: Marcel Holtmann +Signed-off-by: Gustavo Padovan +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..07d4373fa56 --- /dev/null +++ b/queue-3.4/kernel-resource.c-fix-stack-overflow-in-__reserve_region_with_split.patch @@ -0,0 +1,104 @@ +From 4965f5667f36a95b41cda6638875bc992bd7d18b Mon Sep 17 00:00:00 2001 +From: T Makphaibulchoke +Date: Thu, 4 Oct 2012 17:16:55 -0700 +Subject: kernel/resource.c: fix stack overflow in __reserve_region_with_split() + +From: T Makphaibulchoke + +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 +Reviewed-by: Ram Pai +Cc: Paul Gortmaker +Cc: Wei Yang +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Cc: Jiri Slaby +Signed-off-by: Greg Kroah-Hartman + +--- + 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, diff --git a/queue-3.4/series b/queue-3.4/series index 980c122805e..60ceb9d4c8c 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -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 index 00000000000..3a550c49eef --- /dev/null +++ b/queue-3.4/virtio_console-don-t-access-uninitialized-data.patch @@ -0,0 +1,68 @@ +From aded024a12b32fc1ed9a80639681daae2d07ec25 Mon Sep 17 00:00:00 2001 +From: Sjur Brændeland +Date: Tue, 22 Jan 2013 09:50:26 +1030 +Subject: virtio_console: Don't access uninitialized data. + +From: Sjur Brændeland + +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 +Signed-off-by: Rusty Russell +Signed-off-by: Greg Kroah-Hartman + +--- + 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); -- 2.47.3