Skip to content
  • Johan Hedberg's avatar
    Bluetooth: Fix crash in SMP when unpairing · c81d555a
    Johan Hedberg authored
    
    
    When unpairing the keys stored in hci_dev are removed. If SMP is
    ongoing the SMP context will also have references to these keys, so
    removing them from the hci_dev lists will make the pointers invalid.
    This can result in the following type of crashes:
    
     BUG: unable to handle kernel paging request at 6b6b6b6b
     IP: [<c11f26be>] __list_del_entry+0x44/0x71
     *pde = 00000000
     Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
     Modules linked in: hci_uart btqca btusb btintel btbcm btrtl hci_vhci rfcomm bluetooth_6lowpan bluetooth
     CPU: 0 PID: 723 Comm: kworker/u5:0 Not tainted 4.3.0-rc3+ #1379
     Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.8.1-20150318_183358- 04/01/2014
     Workqueue: hci0 hci_rx_work [bluetooth]
     task: f19da940 ti: f1a94000 task.ti: f1a94000
     EIP: 0060:[<c11f26be>] EFLAGS: 00010202 CPU: 0
     EIP is at __list_del_entry+0x44/0x71
     EAX: c0088d20 EBX: f30fcac0 ECX: 6b6b6b6b EDX: 6b6b6b6b
     ESI: f4b60000 EDI: c0088d20 EBP: f1a95d90 ESP: f1a95d8c
      DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
     CR0: 8005003b CR2: 6b6b6b6b CR3: 319e5000 CR4: 00000690
     Stack:
      f30fcac0 f1a95db0 f82dc3e1 f1bfc000 00000000 c106524f f1bfc000 f30fd020
      f1a95dc0 f1a95dd0 f82dcbdb f1a95de0 f82dcbdb 00000067 f1bfc000 f30fd020
      f1a95de0 f1a95df0 f82d1126 00000067 f82d1126 00000006 f30fd020 f1bfc000
     Call Trace:
      [<f82dc3e1>] smp_chan_destroy+0x192/0x240 [bluetooth]
      [<c106524f>] ? trace_hardirqs_on_caller+0x14e/0x169
      [<f82dcbdb>] smp_teardown_cb+0x47/0x64 [bluetooth]
      [<f82dcbdb>] ? smp_teardown_cb+0x47/0x64 [bluetooth]
      [<f82d1126>] l2cap_chan_del+0x5d/0x14d [bluetooth]
      [<f82d1126>] ? l2cap_chan_del+0x5d/0x14d [bluetooth]
      [<f82d40ef>] l2cap_conn_del+0x109/0x17b [bluetooth]
      [<f82d40ef>] ? l2cap_conn_del+0x109/0x17b [bluetooth]
      [<f82c0205>] ? hci_event_packet+0x5b1/0x2092 [bluetooth]
      [<f82d41aa>] l2cap_disconn_cfm+0x49/0x50 [bluetooth]
      [<f82d41aa>] ? l2cap_disconn_cfm+0x49/0x50 [bluetooth]
      [<f82c0228>] hci_event_packet+0x5d4/0x2092 [bluetooth]
      [<c1332c16>] ? skb_release_data+0x6a/0x95
      [<f82ce5d4>] ? hci_send_to_monitor+0xe7/0xf4 [bluetooth]
      [<c1409708>] ? _raw_spin_unlock_irqrestore+0x44/0x57
      [<f82b3bb0>] hci_rx_work+0xf1/0x28b [bluetooth]
      [<f82b3bb0>] ? hci_rx_work+0xf1/0x28b [bluetooth]
      [<c10635a0>] ? __lock_is_held+0x2e/0x44
      [<c104772e>] process_one_work+0x232/0x432
      [<c1071ddc>] ? rcu_read_lock_sched_held+0x50/0x5a
      [<c104772e>] ? process_one_work+0x232/0x432
      [<c1047d48>] worker_thread+0x1b8/0x255
      [<c1047b90>] ? rescuer_thread+0x23c/0x23c
      [<c104bb71>] kthread+0x91/0x96
      [<c14096a7>] ? _raw_spin_unlock_irq+0x27/0x44
      [<c1409d61>] ret_from_kernel_thread+0x21/0x30
      [<c104bae0>] ? kthread_parkme+0x1e/0x1e
    
    To solve the issue, introduce a new smp_cancel_pairing() API that can
    be used to clean up the SMP state before touching the hci_dev lists.
    
    Signed-off-by: default avatarJohan Hedberg <johan.hedberg@intel.com>
    Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
    c81d555a