From: Greg Kroah-Hartman Date: Thu, 19 Apr 2012 16:27:40 +0000 (-0700) Subject: 3.2-stable patches X-Git-Tag: v3.2.16~21 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e30d2cdd010d53cfacb551539952cb409d1d5012;p=thirdparty%2Fkernel%2Fstable-queue.git 3.2-stable patches added patches: bluetooth-hci_core-fix-null-pointer-dereference-at.patch bluetooth-uart-ldisc-fix-memory-leak.patch xhci-fix-register-save-restore-order.patch --- diff --git a/queue-3.2/bluetooth-hci_core-fix-null-pointer-dereference-at.patch b/queue-3.2/bluetooth-hci_core-fix-null-pointer-dereference-at.patch new file mode 100644 index 00000000000..3d592b3c902 --- /dev/null +++ b/queue-3.2/bluetooth-hci_core-fix-null-pointer-dereference-at.patch @@ -0,0 +1,129 @@ +From 94324962066231a938564bebad0f941cd2d06bb2 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Thu, 15 Mar 2012 14:48:41 +0100 +Subject: Bluetooth: hci_core: fix NULL-pointer dereference at + unregister + +From: Johan Hovold + +commit 94324962066231a938564bebad0f941cd2d06bb2 upstream. + +Make sure hci_dev_open returns immediately if hci_dev_unregister has +been called. + +This fixes a race between hci_dev_open and hci_dev_unregister which can +lead to a NULL-pointer dereference. + +Bug is 100% reproducible using hciattach and a disconnected serial port: + +0. # hciattach -n /dev/ttyO1 any noflow + +1. hci_dev_open called from hci_power_on grabs req lock +2. hci_init_req executes but device fails to initialise (times out + eventually) +3. hci_dev_open is called from hci_sock_ioctl and sleeps on req lock +4. hci_uart_tty_close calls hci_dev_unregister and sleeps on req lock in + hci_dev_do_close +5. hci_dev_open (1) releases req lock +6. hci_dev_do_close grabs req lock and returns as device is not up +7. hci_dev_unregister sleeps in destroy_workqueue +8. hci_dev_open (3) grabs req lock, calls hci_init_req and eventually sleeps +9. hci_dev_unregister finishes, while hci_dev_open is still running... + +[ 79.627136] INFO: trying to register non-static key. +[ 79.632354] the code is fine but needs lockdep annotation. +[ 79.638122] turning off the locking correctness validator. +[ 79.643920] [] (unwind_backtrace+0x0/0xf8) from [] (__lock_acquire+0x1590/0x1ab0) +[ 79.653594] [] (__lock_acquire+0x1590/0x1ab0) from [] (lock_acquire+0x9c/0x128) +[ 79.663085] [] (lock_acquire+0x9c/0x128) from [] (run_timer_softirq+0x150/0x3ac) +[ 79.672668] [] (run_timer_softirq+0x150/0x3ac) from [] (__do_softirq+0xd4/0x22c) +[ 79.682281] [] (__do_softirq+0xd4/0x22c) from [] (irq_exit+0x8c/0x94) +[ 79.690856] [] (irq_exit+0x8c/0x94) from [] (handle_IRQ+0x34/0x84) +[ 79.699157] [] (handle_IRQ+0x34/0x84) from [] (omap3_intc_handle_irq+0x48/0x4c) +[ 79.708648] [] (omap3_intc_handle_irq+0x48/0x4c) from [] (__irq_usr+0x3c/0x60) +[ 79.718048] Exception stack(0xcf281fb0 to 0xcf281ff8) +[ 79.723358] 1fa0: 0001e6a0 be8dab00 0001e698 00036698 +[ 79.731933] 1fc0: 0002df98 0002df38 0000001f 00000000 b6f234d0 00000000 00000004 00000000 +[ 79.740509] 1fe0: 0001e6f8 be8d6aa0 be8dac50 0000aab8 80000010 ffffffff +[ 79.747497] Unable to handle kernel NULL pointer dereference at virtual address 00000000 +[ 79.756011] pgd = cf3b4000 +[ 79.758850] [00000000] *pgd=8f0c7831, *pte=00000000, *ppte=00000000 +[ 79.765502] Internal error: Oops: 80000007 [#1] +[ 79.770294] Modules linked in: +[ 79.773529] CPU: 0 Tainted: G W (3.3.0-rc6-00002-gb5d5c87 #421) +[ 79.781066] PC is at 0x0 +[ 79.783721] LR is at run_timer_softirq+0x16c/0x3ac +[ 79.788787] pc : [<00000000>] lr : [] psr: 60000113 +[ 79.788787] sp : cf281ee0 ip : 00000000 fp : cf280000 +[ 79.800903] r10: 00000004 r9 : 00000100 r8 : b6f234d0 +[ 79.806427] r7 : c0519c28 r6 : cf093488 r5 : c0561a00 r4 : 00000000 +[ 79.813323] r3 : 00000000 r2 : c054eee0 r1 : 00000001 r0 : 00000000 +[ 79.820190] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user +[ 79.827728] Control: 10c5387d Table: 8f3b4019 DAC: 00000015 +[ 79.833801] Process gpsd (pid: 1265, stack limit = 0xcf2802e8) +[ 79.839965] Stack: (0xcf281ee0 to 0xcf282000) +[ 79.844573] 1ee0: 00000002 00000000 c0040a24 00000000 00000002 cf281f08 00200200 00000000 +[ 79.853210] 1f00: 00000000 cf281f18 cf281f08 00000000 00000000 00000000 cf281f18 cf281f18 +[ 79.861816] 1f20: 00000000 00000001 c056184c 00000000 00000001 b6f234d0 c0561848 00000004 +[ 79.870452] 1f40: cf280000 c003a3b8 c051e79c 00000001 00000000 00000100 3fa9e7b8 0000000a +[ 79.879089] 1f60: 00000025 cf280000 00000025 00000000 00000000 b6f234d0 00000000 00000004 +[ 79.887756] 1f80: 00000000 c003a924 c053ad38 c0013a50 fa200000 cf281fb0 ffffffff c0008530 +[ 79.896362] 1fa0: 0001e6a0 0000aab8 80000010 c037499c 0001e6a0 be8dab00 0001e698 00036698 +[ 79.904998] 1fc0: 0002df98 0002df38 0000001f 00000000 b6f234d0 00000000 00000004 00000000 +[ 79.913665] 1fe0: 0001e6f8 be8d6aa0 be8dac50 0000aab8 80000010 ffffffff 00fbf700 04ffff00 +[ 79.922302] [] (run_timer_softirq+0x16c/0x3ac) from [] (__do_softirq+0xd4/0x22c) +[ 79.931945] [] (__do_softirq+0xd4/0x22c) from [] (irq_exit+0x8c/0x94) +[ 79.940582] [] (irq_exit+0x8c/0x94) from [] (handle_IRQ+0x34/0x84) +[ 79.948913] [] (handle_IRQ+0x34/0x84) from [] (omap3_intc_handle_irq+0x48/0x4c) +[ 79.958404] [] (omap3_intc_handle_irq+0x48/0x4c) from [] (__irq_usr+0x3c/0x60) +[ 79.967773] Exception stack(0xcf281fb0 to 0xcf281ff8) +[ 79.973083] 1fa0: 0001e6a0 be8dab00 0001e698 00036698 +[ 79.981658] 1fc0: 0002df98 0002df38 0000001f 00000000 b6f234d0 00000000 00000004 00000000 +[ 79.990234] 1fe0: 0001e6f8 be8d6aa0 be8dac50 0000aab8 80000010 ffffffff +[ 79.997161] Code: bad PC value +[ 80.000396] ---[ end trace 6f6739840475f9ee ]--- +[ 80.005279] Kernel panic - not syncing: Fatal exception in interrupt + +Signed-off-by: Johan Hovold +Acked-by: Marcel Holtmann +Signed-off-by: Johan Hedberg +Signed-off-by: Greg Kroah-Hartman + +--- + include/net/bluetooth/hci.h | 1 + + net/bluetooth/hci_core.c | 7 +++++++ + 2 files changed, 8 insertions(+) + +--- a/include/net/bluetooth/hci.h ++++ b/include/net/bluetooth/hci.h +@@ -84,6 +84,7 @@ enum { + HCI_SERVICE_CACHE, + HCI_LINK_KEYS, + HCI_DEBUG_KEYS, ++ HCI_UNREGISTER, + + HCI_RESET, + }; +--- a/net/bluetooth/hci_core.c ++++ b/net/bluetooth/hci_core.c +@@ -510,6 +510,11 @@ int hci_dev_open(__u16 dev) + + hci_req_lock(hdev); + ++ if (test_bit(HCI_UNREGISTER, &hdev->flags)) { ++ ret = -ENODEV; ++ goto done; ++ } ++ + if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) { + ret = -ERFKILL; + goto done; +@@ -1540,6 +1545,8 @@ int hci_unregister_dev(struct hci_dev *h + + BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); + ++ set_bit(HCI_UNREGISTER, &hdev->flags); ++ + write_lock_bh(&hci_dev_list_lock); + list_del(&hdev->list); + write_unlock_bh(&hci_dev_list_lock); diff --git a/queue-3.2/bluetooth-hci_ldisc-fix-null-pointer-dereference-on-tty_close.patch b/queue-3.2/bluetooth-hci_ldisc-fix-null-pointer-dereference-on-tty_close.patch index af60ad4f5b8..02308ba0f99 100644 --- a/queue-3.2/bluetooth-hci_ldisc-fix-null-pointer-dereference-on-tty_close.patch +++ b/queue-3.2/bluetooth-hci_ldisc-fix-null-pointer-dereference-on-tty_close.patch @@ -89,7 +89,7 @@ Signed-off-by: Greg Kroah-Hartman --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c -@@ -310,11 +310,11 @@ static void hci_uart_tty_close(struct tt +@@ -309,11 +309,11 @@ static void hci_uart_tty_close(struct tt hci_uart_close(hdev); if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) { @@ -100,5 +100,5 @@ Signed-off-by: Greg Kroah-Hartman } + hu->proto->close(hu); } + kfree(hu); } - } diff --git a/queue-3.2/bluetooth-uart-ldisc-fix-memory-leak.patch b/queue-3.2/bluetooth-uart-ldisc-fix-memory-leak.patch new file mode 100644 index 00000000000..e92cc72342c --- /dev/null +++ b/queue-3.2/bluetooth-uart-ldisc-fix-memory-leak.patch @@ -0,0 +1,48 @@ +From 501dac2851c5bf1edf158adc4deb15e10c59bb04 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Wed, 11 Apr 2012 11:24:35 +0200 +Subject: [PATCH] Bluetooth: uart-ldisc: Fix memory leak + +From: Johan Hovold + +This is a partial, self-contained, minimal backport of commit +797fe796c4335b35d95d5326824513befdb5d1e9 upstream which fixes the memory +leak: + +Bluetooth: uart-ldisc: Fix memory leak and remove destruct cb + +We currently leak the hci_uart object if HCI_UART_PROTO_SET is never set +because the hci-destruct callback will then never be called. This fix +removes the hci-destruct callback and frees the driver internal private +hci_uart object directly on tty-close. We call hci_unregister_dev() here +so the hci-core will never call our callbacks again (except destruct). +Therefore, we can safely free the driver internal data right away and +set the destruct callback to NULL. + +Signed-off-by: David Herrmann +Acked-by: Marcel Holtmann +Signed-off-by: Johan Hedberg +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman +--- + drivers/bluetooth/hci_ldisc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/bluetooth/hci_ldisc.c ++++ b/drivers/bluetooth/hci_ldisc.c +@@ -237,7 +237,6 @@ static void hci_uart_destruct(struct hci + return; + + BT_DBG("%s", hdev->name); +- kfree(hdev->driver_data); + } + + /* ------ LDISC part ------ */ +@@ -316,6 +315,7 @@ static void hci_uart_tty_close(struct tt + hci_free_dev(hdev); + } + } ++ kfree(hu); + } + } + diff --git a/queue-3.2/series b/queue-3.2/series index 2d9a136da6c..f9df942876a 100644 --- a/queue-3.2/series +++ b/queue-3.2/series @@ -8,6 +8,7 @@ rtlwifi-add-missing-dma-buffer-unmapping-for-pci-drivers.patch arm-7379-1-dt-fix-atags_to_fdt-second-call-site.patch arm-7384-1-thumbee-disable-userspace-teehbr-access-for-config_arm_thumbee.patch md-bitmap-prevent-bitmap_daemon_work-running-while-initialising-bitmap.patch +bluetooth-uart-ldisc-fix-memory-leak.patch bluetooth-hci_ldisc-fix-null-pointer-dereference-on-tty_close.patch ext4-address-scalability-issue-by-removing-extent-cache-statistics.patch ia64-fix-futex_atomic_cmpxchg_inatomic.patch @@ -42,3 +43,5 @@ serial-pl011-clear-pending-interrupts.patch serial-pl011-move-interrupt-clearing.patch fcaps-clear-the-same-personality-flags-as-suid-when-fcaps-are-used.patch ath9k-fix-max-noise-floor-threshold.patch +xhci-fix-register-save-restore-order.patch +bluetooth-hci_core-fix-null-pointer-dereference-at.patch diff --git a/queue-3.2/xhci-fix-register-save-restore-order.patch b/queue-3.2/xhci-fix-register-save-restore-order.patch new file mode 100644 index 00000000000..d4a6ac4b160 --- /dev/null +++ b/queue-3.2/xhci-fix-register-save-restore-order.patch @@ -0,0 +1,60 @@ +From c7713e736526d8c9f6f87716fb90562a8ffaff2c Mon Sep 17 00:00:00 2001 +From: Sarah Sharp +Date: Fri, 16 Mar 2012 13:19:35 -0700 +Subject: xhci: Fix register save/restore order. + +From: Sarah Sharp + +commit c7713e736526d8c9f6f87716fb90562a8ffaff2c upstream. + +The xHCI 1.0 spec errata released on June 13, 2011, changes the ordering +that the xHCI registers are saved and restored in. It moves the +interrupt pending (IMAN) and interrupt control (IMOD) registers to be +saved and restored last. I believe that's because the host controller +may attempt to fetch the event ring table when interrupts are +re-enabled. Therefore we need to restore the event ring registers +before we re-enable interrupts. + +This should be backported to kernels as old as 2.6.37, that contain the +commit 5535b1d5f8885695c6ded783c692e3c0d0eda8ca "USB: xHCI: PCI power +management implementation" + +Signed-off-by: Sarah Sharp +Tested-by: Elric Fu +Cc: Andiry Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -664,11 +664,11 @@ static void xhci_save_registers(struct x + xhci->s3.dev_nt = xhci_readl(xhci, &xhci->op_regs->dev_notification); + xhci->s3.dcbaa_ptr = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); + xhci->s3.config_reg = xhci_readl(xhci, &xhci->op_regs->config_reg); +- xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); +- xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control); + xhci->s3.erst_size = xhci_readl(xhci, &xhci->ir_set->erst_size); + xhci->s3.erst_base = xhci_read_64(xhci, &xhci->ir_set->erst_base); + xhci->s3.erst_dequeue = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); ++ xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); ++ xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control); + } + + static void xhci_restore_registers(struct xhci_hcd *xhci) +@@ -677,11 +677,11 @@ static void xhci_restore_registers(struc + xhci_writel(xhci, xhci->s3.dev_nt, &xhci->op_regs->dev_notification); + xhci_write_64(xhci, xhci->s3.dcbaa_ptr, &xhci->op_regs->dcbaa_ptr); + xhci_writel(xhci, xhci->s3.config_reg, &xhci->op_regs->config_reg); +- xhci_writel(xhci, xhci->s3.irq_pending, &xhci->ir_set->irq_pending); +- xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control); + xhci_writel(xhci, xhci->s3.erst_size, &xhci->ir_set->erst_size); + xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base); + xhci_write_64(xhci, xhci->s3.erst_dequeue, &xhci->ir_set->erst_dequeue); ++ xhci_writel(xhci, xhci->s3.irq_pending, &xhci->ir_set->irq_pending); ++ xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control); + } + + static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci)