1. 08 9月, 2021 8 次提交
  2. 04 9月, 2021 2 次提交
  3. 01 9月, 2021 1 次提交
    • W
      Bluetooth: fix use-after-free error in lock_sock_nested() · 1bff51ea
      Wang ShaoBo 提交于
      use-after-free error in lock_sock_nested is reported:
      
      [  179.140137][ T3731] =====================================================
      [  179.142675][ T3731] BUG: KMSAN: use-after-free in lock_sock_nested+0x280/0x2c0
      [  179.145494][ T3731] CPU: 4 PID: 3731 Comm: kworker/4:2 Not tainted 5.12.0-rc6+ #54
      [  179.148432][ T3731] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
      [  179.151806][ T3731] Workqueue: events l2cap_chan_timeout
      [  179.152730][ T3731] Call Trace:
      [  179.153301][ T3731]  dump_stack+0x24c/0x2e0
      [  179.154063][ T3731]  kmsan_report+0xfb/0x1e0
      [  179.154855][ T3731]  __msan_warning+0x5c/0xa0
      [  179.155579][ T3731]  lock_sock_nested+0x280/0x2c0
      [  179.156436][ T3731]  ? kmsan_get_metadata+0x116/0x180
      [  179.157257][ T3731]  l2cap_sock_teardown_cb+0xb8/0x890
      [  179.158154][ T3731]  ? __msan_metadata_ptr_for_load_8+0x10/0x20
      [  179.159141][ T3731]  ? kmsan_get_metadata+0x116/0x180
      [  179.159994][ T3731]  ? kmsan_get_shadow_origin_ptr+0x84/0xb0
      [  179.160959][ T3731]  ? l2cap_sock_recv_cb+0x420/0x420
      [  179.161834][ T3731]  l2cap_chan_del+0x3e1/0x1d50
      [  179.162608][ T3731]  ? kmsan_get_metadata+0x116/0x180
      [  179.163435][ T3731]  ? kmsan_get_shadow_origin_ptr+0x84/0xb0
      [  179.164406][ T3731]  l2cap_chan_close+0xeea/0x1050
      [  179.165189][ T3731]  ? kmsan_internal_unpoison_shadow+0x42/0x70
      [  179.166180][ T3731]  l2cap_chan_timeout+0x1da/0x590
      [  179.167066][ T3731]  ? __msan_metadata_ptr_for_load_8+0x10/0x20
      [  179.168023][ T3731]  ? l2cap_chan_create+0x560/0x560
      [  179.168818][ T3731]  process_one_work+0x121d/0x1ff0
      [  179.169598][ T3731]  worker_thread+0x121b/0x2370
      [  179.170346][ T3731]  kthread+0x4ef/0x610
      [  179.171010][ T3731]  ? process_one_work+0x1ff0/0x1ff0
      [  179.171828][ T3731]  ? kthread_blkcg+0x110/0x110
      [  179.172587][ T3731]  ret_from_fork+0x1f/0x30
      [  179.173348][ T3731]
      [  179.173752][ T3731] Uninit was created at:
      [  179.174409][ T3731]  kmsan_internal_poison_shadow+0x5c/0xf0
      [  179.175373][ T3731]  kmsan_slab_free+0x76/0xc0
      [  179.176060][ T3731]  kfree+0x3a5/0x1180
      [  179.176664][ T3731]  __sk_destruct+0x8af/0xb80
      [  179.177375][ T3731]  __sk_free+0x812/0x8c0
      [  179.178032][ T3731]  sk_free+0x97/0x130
      [  179.178686][ T3731]  l2cap_sock_release+0x3d5/0x4d0
      [  179.179457][ T3731]  sock_close+0x150/0x450
      [  179.180117][ T3731]  __fput+0x6bd/0xf00
      [  179.180787][ T3731]  ____fput+0x37/0x40
      [  179.181481][ T3731]  task_work_run+0x140/0x280
      [  179.182219][ T3731]  do_exit+0xe51/0x3e60
      [  179.182930][ T3731]  do_group_exit+0x20e/0x450
      [  179.183656][ T3731]  get_signal+0x2dfb/0x38f0
      [  179.184344][ T3731]  arch_do_signal_or_restart+0xaa/0xe10
      [  179.185266][ T3731]  exit_to_user_mode_prepare+0x2d2/0x560
      [  179.186136][ T3731]  syscall_exit_to_user_mode+0x35/0x60
      [  179.186984][ T3731]  do_syscall_64+0xc5/0x140
      [  179.187681][ T3731]  entry_SYSCALL_64_after_hwframe+0x44/0xae
      [  179.188604][ T3731] =====================================================
      
      In our case, there are two Thread A and B:
      
      Context: Thread A:              Context: Thread B:
      
      l2cap_chan_timeout()            __se_sys_shutdown()
        l2cap_chan_close()              l2cap_sock_shutdown()
          l2cap_chan_del()                l2cap_chan_close()
            l2cap_sock_teardown_cb()        l2cap_sock_teardown_cb()
      
      Once l2cap_sock_teardown_cb() excuted, this sock will be marked as SOCK_ZAPPED,
      and can be treated as killable in l2cap_sock_kill() if sock_orphan() has
      excuted, at this time we close sock through sock_close() which end to call
      l2cap_sock_kill() like Thread C:
      
      Context: Thread C:
      
      sock_close()
        l2cap_sock_release()
          sock_orphan()
          l2cap_sock_kill()  #free sock if refcnt is 1
      
      If C completed, Once A or B reaches l2cap_sock_teardown_cb() again,
      use-after-free happened.
      
      We should set chan->data to NULL if sock is destructed, for telling teardown
      operation is not allowed in l2cap_sock_teardown_cb(), and also we should
      avoid killing an already killed socket in l2cap_sock_close_cb().
      Signed-off-by: NWang ShaoBo <bobo.shaobowang@huawei.com>
      Signed-off-by: NLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
      Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
      1bff51ea
  4. 31 8月, 2021 2 次提交
  5. 30 8月, 2021 6 次提交
  6. 19 8月, 2021 3 次提交
    • K
      Bluetooth: Fix return value in hci_dev_do_close() · 61969ef8
      Kangmin Park 提交于
      hci_error_reset() return without calling hci_dev_do_open() when
      hci_dev_do_close() return error value which is not 0.
      
      Also, hci_dev_close() return hci_dev_do_close() function's return
      value.
      
      But, hci_dev_do_close() return always 0 even if hdev->shutdown
      return error value. So, fix hci_dev_do_close() to save and return
      the return value of the hdev->shutdown when it is called.
      Signed-off-by: NKangmin Park <l4stpr0gr4m@gmail.com>
      Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
      61969ef8
    • P
      Bluetooth: add timeout sanity check to hci_inquiry · f41a4b2b
      Pavel Skripkin 提交于
      Syzbot hit "task hung" bug in hci_req_sync(). The problem was in
      unreasonable huge inquiry timeout passed from userspace.
      Fix it by adding sanity check for timeout value to hci_inquiry().
      
      Since hci_inquiry() is the only user of hci_req_sync() with user
      controlled timeout value, it makes sense to check timeout value in
      hci_inquiry() and don't touch hci_req_sync().
      
      Fixes: 1da177e4 ("Linux-2.6.12-rc2")
      Reported-and-tested-by: syzbot+be2baed593ea56c6a84c@syzkaller.appspotmail.com
      Signed-off-by: NPavel Skripkin <paskripkin@gmail.com>
      Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
      f41a4b2b
    • K
      Bluetooth: mgmt: Pessimize compile-time bounds-check · a31e5a41
      Kees Cook 提交于
      After gaining __alloc_size hints, GCC thinks it can reach a memcpy()
      with eir_len == 0 (since it can't see into the rewrite of status).
      Instead, check eir_len == 0, avoiding this future warning:
      
      In function 'eir_append_data',
          inlined from 'read_local_oob_ext_data_complete' at net/bluetooth/mgmt.c:7210:12:
      ./include/linux/fortify-string.h:54:29: warning: '__builtin_memcpy' offset 5 is out of the bounds [0, 3] [-Warray-bounds]
      ...
      net/bluetooth/hci_request.h:133:2: note: in expansion of macro 'memcpy'
        133 |  memcpy(&eir[eir_len], data, data_len);
            |  ^~~~~~
      
      Cc: Marcel Holtmann <marcel@holtmann.org>
      Cc: Johan Hedberg <johan.hedberg@gmail.com>
      Cc: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
      Cc: "David S. Miller" <davem@davemloft.net>
      Cc: Jakub Kicinski <kuba@kernel.org>
      Cc: linux-bluetooth@vger.kernel.org
      Cc: netdev@vger.kernel.org
      Signed-off-by: NKees Cook <keescook@chromium.org>
      Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
      a31e5a41
  7. 17 8月, 2021 1 次提交
    • K
      Bluetooth: Fix race condition in handling NOP command · ecb71f25
      Kiran K 提交于
      For NOP command, need to cancel work scheduled on cmd_timer,
      on receiving command status or commmand complete event.
      
      Below use case might lead to race condition multiple when NOP
      commands are queued sequentially:
      
      hci_cmd_work() {
         if (atomic_read(&hdev->cmd_cnt) {
                  .
                  .
                  .
            atomic_dec(&hdev->cmd_cnt);
            hci_send_frame(hdev,...);
            schedule_delayed_work(&hdev->cmd_timer,...);
         }
      }
      
      On receiving event for first NOP, the work scheduled on hdev->cmd_timer
      is not cancelled and second NOP is dequeued and sent to controller.
      
      While waiting for an event for second NOP command, work scheduled on
      cmd_timer for the first NOP can get scheduled, resulting in sending third
      NOP command (sending back to back NOP commands). This might
      cause issues at controller side (like memory overrun, controller going
      unresponsive) resulting in hci tx timeouts, hardware errors etc.
      
      The fix to this issue is to cancel the delayed work scheduled on
      cmd_timer on receiving command status or command complete event for
      NOP command (this patch handles NOP command same as any other SIG
      command).
      Signed-off-by: NKiran K <kiran.k@intel.com>
      Reviewed-by: NChethan T N <chethan.tumkur.narayan@intel.com>
      Reviewed-by: NSrivatsa Ravishankar <ravishankar.srivatsa@intel.com>
      Acked-by: NManish Mandlik <mmandlik@google.com>
      Signed-off-by: NMarcel Holtmann <marcel@holtmann.org>
      ecb71f25
  8. 16 8月, 2021 3 次提交
  9. 11 8月, 2021 6 次提交
    • D
      Bluetooth: fix repeated calls to sco_sock_kill · e1dee2c1
      Desmond Cheong Zhi Xi 提交于
      In commit 4e1a720d ("Bluetooth: avoid killing an already killed
      socket"), a check was added to sco_sock_kill to skip killing a socket
      if the SOCK_DEAD flag was set.
      
      This was done after a trace for a use-after-free bug showed that the
      same sock pointer was being killed twice.
      
      Unfortunately, this check prevents sco_sock_kill from running on any
      socket. sco_sock_kill kills a socket only if it's zapped and orphaned,
      however sock_orphan announces that the socket is dead before detaching
      it. i.e., orphaned sockets have the SOCK_DEAD flag set.
      
      To fix this, we remove the check for SOCK_DEAD, and avoid repeated
      calls to sco_sock_kill by removing incorrect calls in:
      
      1. sco_sock_timeout. The socket should not be killed on timeout as
      further processing is expected to be done. For example,
      sco_sock_connect sets the timer then waits for the socket to be
      connected or for an error to be returned.
      
      2. sco_conn_del. This function should clean up resources for the
      connection, but the socket itself should be cleaned up in
      sco_sock_release.
      
      3. sco_sock_close. Calls to sco_sock_close in sco_sock_cleanup_listen
      and sco_sock_release are followed by sco_sock_kill. Hence the
      duplicated call should be removed.
      
      Fixes: 4e1a720d ("Bluetooth: avoid killing an already killed socket")
      Signed-off-by: NDesmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
      Signed-off-by: NLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
      e1dee2c1
    • D
      Bluetooth: switch to lock_sock in RFCOMM · b7ce436a
      Desmond Cheong Zhi Xi 提交于
      Other than rfcomm_sk_state_change and rfcomm_connect_ind, functions in
      RFCOMM use lock_sock to lock the socket.
      
      Since bh_lock_sock and spin_lock_bh do not provide synchronization
      with lock_sock, these calls should be changed to lock_sock.
      
      This is now safe to do because packet processing is now done in a
      workqueue instead of a tasklet, so bh_lock_sock/spin_lock_bh are no
      longer necessary to synchronise between user contexts and SOFTIRQ
      processing.
      Signed-off-by: NDesmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
      Signed-off-by: NLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
      b7ce436a
    • D
      Bluetooth: serialize calls to sco_sock_{set,clear}_timer · 3f2c89fb
      Desmond Cheong Zhi Xi 提交于
      Currently, calls to sco_sock_set_timer are made under the locked
      socket, but this does not apply to all calls to sco_sock_clear_timer.
      
      Both sco_sock_{set,clear}_timer should be serialized by lock_sock to
      prevent unexpected concurrent clearing/setting of timers.
      
      Additionally, since sco_pi(sk)->conn is only cleared under the locked
      socket, this change allows us to avoid races between
      sco_sock_clear_timer and the call to kfree(conn) in sco_conn_del.
      Signed-off-by: NDesmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
      Signed-off-by: NLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
      3f2c89fb
    • D
      Bluetooth: switch to lock_sock in SCO · 27c24fda
      Desmond Cheong Zhi Xi 提交于
      Since sco_sock_timeout is now scheduled using delayed work, it is no
      longer run in SOFTIRQ context. Hence bh_lock_sock is no longer
      necessary in SCO to synchronise between user contexts and SOFTIRQ
      processing.
      
      As such, calls to bh_lock_sock should be replaced with lock_sock to
      synchronize with other concurrent processes that use lock_sock.
      Signed-off-by: NDesmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
      Signed-off-by: NLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
      27c24fda
    • D
      Bluetooth: avoid circular locks in sco_sock_connect · 734bc5ff
      Desmond Cheong Zhi Xi 提交于
      In a future patch, calls to bh_lock_sock in sco.c should be replaced
      by lock_sock now that none of the functions are run in IRQ context.
      
      However, doing so results in a circular locking dependency:
      
      ======================================================
      WARNING: possible circular locking dependency detected
      5.14.0-rc4-syzkaller #0 Not tainted
      ------------------------------------------------------
      syz-executor.2/14867 is trying to acquire lock:
      ffff88803e3c1120 (sk_lock-AF_BLUETOOTH-BTPROTO_SCO){+.+.}-{0:0}, at:
      lock_sock include/net/sock.h:1613 [inline]
      ffff88803e3c1120 (sk_lock-AF_BLUETOOTH-BTPROTO_SCO){+.+.}-{0:0}, at:
      sco_conn_del+0x12a/0x2a0 net/bluetooth/sco.c:191
      
      but task is already holding lock:
      ffffffff8d2dc7c8 (hci_cb_list_lock){+.+.}-{3:3}, at:
      hci_disconn_cfm include/net/bluetooth/hci_core.h:1497 [inline]
      ffffffff8d2dc7c8 (hci_cb_list_lock){+.+.}-{3:3}, at:
      hci_conn_hash_flush+0xda/0x260 net/bluetooth/hci_conn.c:1608
      
      which lock already depends on the new lock.
      
      the existing dependency chain (in reverse order) is:
      
      -> #2 (hci_cb_list_lock){+.+.}-{3:3}:
             __mutex_lock_common kernel/locking/mutex.c:959 [inline]
             __mutex_lock+0x12a/0x10a0 kernel/locking/mutex.c:1104
             hci_connect_cfm include/net/bluetooth/hci_core.h:1482 [inline]
             hci_remote_features_evt net/bluetooth/hci_event.c:3263 [inline]
             hci_event_packet+0x2f4d/0x7c50 net/bluetooth/hci_event.c:6240
             hci_rx_work+0x4f8/0xd30 net/bluetooth/hci_core.c:5122
             process_one_work+0x98d/0x1630 kernel/workqueue.c:2276
             worker_thread+0x658/0x11f0 kernel/workqueue.c:2422
             kthread+0x3e5/0x4d0 kernel/kthread.c:319
             ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:295
      
      -> #1 (&hdev->lock){+.+.}-{3:3}:
             __mutex_lock_common kernel/locking/mutex.c:959 [inline]
             __mutex_lock+0x12a/0x10a0 kernel/locking/mutex.c:1104
             sco_connect net/bluetooth/sco.c:245 [inline]
             sco_sock_connect+0x227/0xa10 net/bluetooth/sco.c:601
             __sys_connect_file+0x155/0x1a0 net/socket.c:1879
             __sys_connect+0x161/0x190 net/socket.c:1896
             __do_sys_connect net/socket.c:1906 [inline]
             __se_sys_connect net/socket.c:1903 [inline]
             __x64_sys_connect+0x6f/0xb0 net/socket.c:1903
             do_syscall_x64 arch/x86/entry/common.c:50 [inline]
             do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
             entry_SYSCALL_64_after_hwframe+0x44/0xae
      
      -> #0 (sk_lock-AF_BLUETOOTH-BTPROTO_SCO){+.+.}-{0:0}:
             check_prev_add kernel/locking/lockdep.c:3051 [inline]
             check_prevs_add kernel/locking/lockdep.c:3174 [inline]
             validate_chain kernel/locking/lockdep.c:3789 [inline]
             __lock_acquire+0x2a07/0x54a0 kernel/locking/lockdep.c:5015
             lock_acquire kernel/locking/lockdep.c:5625 [inline]
             lock_acquire+0x1ab/0x510 kernel/locking/lockdep.c:5590
             lock_sock_nested+0xca/0x120 net/core/sock.c:3170
             lock_sock include/net/sock.h:1613 [inline]
             sco_conn_del+0x12a/0x2a0 net/bluetooth/sco.c:191
             sco_disconn_cfm+0x71/0xb0 net/bluetooth/sco.c:1202
             hci_disconn_cfm include/net/bluetooth/hci_core.h:1500 [inline]
             hci_conn_hash_flush+0x127/0x260 net/bluetooth/hci_conn.c:1608
             hci_dev_do_close+0x528/0x1130 net/bluetooth/hci_core.c:1778
             hci_unregister_dev+0x1c0/0x5a0 net/bluetooth/hci_core.c:4015
             vhci_release+0x70/0xe0 drivers/bluetooth/hci_vhci.c:340
             __fput+0x288/0x920 fs/file_table.c:280
             task_work_run+0xdd/0x1a0 kernel/task_work.c:164
             exit_task_work include/linux/task_work.h:32 [inline]
             do_exit+0xbd4/0x2a60 kernel/exit.c:825
             do_group_exit+0x125/0x310 kernel/exit.c:922
             get_signal+0x47f/0x2160 kernel/signal.c:2808
             arch_do_signal_or_restart+0x2a9/0x1c40 arch/x86/kernel/signal.c:865
             handle_signal_work kernel/entry/common.c:148 [inline]
             exit_to_user_mode_loop kernel/entry/common.c:172 [inline]
             exit_to_user_mode_prepare+0x17d/0x290 kernel/entry/common.c:209
             __syscall_exit_to_user_mode_work kernel/entry/common.c:291 [inline]
             syscall_exit_to_user_mode+0x19/0x60 kernel/entry/common.c:302
             ret_from_fork+0x15/0x30 arch/x86/entry/entry_64.S:288
      
      other info that might help us debug this:
      
      Chain exists of:
        sk_lock-AF_BLUETOOTH-BTPROTO_SCO --> &hdev->lock --> hci_cb_list_lock
      
       Possible unsafe locking scenario:
      
             CPU0                    CPU1
             ----                    ----
        lock(hci_cb_list_lock);
                                     lock(&hdev->lock);
                                     lock(hci_cb_list_lock);
        lock(sk_lock-AF_BLUETOOTH-BTPROTO_SCO);
      
       *** DEADLOCK ***
      
      The issue is that the lock hierarchy should go from &hdev->lock -->
      hci_cb_list_lock --> sk_lock-AF_BLUETOOTH-BTPROTO_SCO. For example,
      one such call trace is:
      
        hci_dev_do_close():
          hci_dev_lock();
          hci_conn_hash_flush():
            hci_disconn_cfm():
              mutex_lock(&hci_cb_list_lock);
              sco_disconn_cfm():
              sco_conn_del():
                lock_sock(sk);
      
      However, in sco_sock_connect, we call lock_sock before calling
      hci_dev_lock inside sco_connect, thus inverting the lock hierarchy.
      
      We fix this by pulling the call to hci_dev_lock out from sco_connect.
      Signed-off-by: NDesmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
      Signed-off-by: NLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
      734bc5ff
    • D
      Bluetooth: schedule SCO timeouts with delayed_work · ba316be1
      Desmond Cheong Zhi Xi 提交于
      struct sock.sk_timer should be used as a sock cleanup timer. However,
      SCO uses it to implement sock timeouts.
      
      This causes issues because struct sock.sk_timer's callback is run in
      an IRQ context, and the timer callback function sco_sock_timeout takes
      a spin lock on the socket. However, other functions such as
      sco_conn_del and sco_conn_ready take the spin lock with interrupts
      enabled.
      
      This inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} lock usage could
      lead to deadlocks as reported by Syzbot [1]:
             CPU0
             ----
        lock(slock-AF_BLUETOOTH-BTPROTO_SCO);
        <Interrupt>
          lock(slock-AF_BLUETOOTH-BTPROTO_SCO);
      
      To fix this, we use delayed work to implement SCO sock timouts
      instead. This allows us to avoid taking the spin lock on the socket in
      an IRQ context, and corrects the misuse of struct sock.sk_timer.
      
      As a note, cancel_delayed_work is used instead of
      cancel_delayed_work_sync in sco_sock_set_timer and
      sco_sock_clear_timer to avoid a deadlock. In the future, the call to
      bh_lock_sock inside sco_sock_timeout should be changed to lock_sock to
      synchronize with other functions using lock_sock. However, since
      sco_sock_set_timer and sco_sock_clear_timer are sometimes called under
      the locked socket (in sco_connect and __sco_sock_close),
      cancel_delayed_work_sync might cause them to sleep until an
      sco_sock_timeout that has started finishes running. But
      sco_sock_timeout would also sleep until it can grab the lock_sock.
      
      Using cancel_delayed_work is fine because sco_sock_timeout does not
      change from run to run, hence there is no functional difference
      between:
      1. waiting for a timeout to finish running before scheduling another
      timeout
      2. scheduling another timeout while a timeout is running.
      
      Link: https://syzkaller.appspot.com/bug?id=9089d89de0502e120f234ca0fc8a703f7368b31e [1]
      Reported-by: syzbot+2f6d7c28bb4bf7e82060@syzkaller.appspotmail.com
      Tested-by: syzbot+2f6d7c28bb4bf7e82060@syzkaller.appspotmail.com
      Signed-off-by: NDesmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
      Signed-off-by: NLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
      ba316be1
  10. 06 8月, 2021 1 次提交
    • T
      Bluetooth: defer cleanup of resources in hci_unregister_dev() · e0448092
      Tetsuo Handa 提交于
      syzbot is hitting might_sleep() warning at hci_sock_dev_event() due to
      calling lock_sock() with rw spinlock held [1].
      
      It seems that history of this locking problem is a trial and error.
      
      Commit b40df574 ("[PATCH] bluetooth: fix socket locking in
      hci_sock_dev_event()") in 2.6.21-rc4 changed bh_lock_sock() to
      lock_sock() as an attempt to fix lockdep warning.
      
      Then, commit 4ce61d1c ("[BLUETOOTH]: Fix locking in
      hci_sock_dev_event().") in 2.6.22-rc2 changed lock_sock() to
      local_bh_disable() + bh_lock_sock_nested() as an attempt to fix the
      sleep in atomic context warning.
      
      Then, commit 4b5dd696 ("Bluetooth: Remove local_bh_disable() from
      hci_sock.c") in 3.3-rc1 removed local_bh_disable().
      
      Then, commit e305509e ("Bluetooth: use correct lock to prevent UAF
      of hdev object") in 5.13-rc5 again changed bh_lock_sock_nested() to
      lock_sock() as an attempt to fix CVE-2021-3573.
      
      This difficulty comes from current implementation that
      hci_sock_dev_event(HCI_DEV_UNREG) is responsible for dropping all
      references from sockets because hci_unregister_dev() immediately
      reclaims resources as soon as returning from
      hci_sock_dev_event(HCI_DEV_UNREG).
      
      But the history suggests that hci_sock_dev_event(HCI_DEV_UNREG) was not
      doing what it should do.
      
      Therefore, instead of trying to detach sockets from device, let's accept
      not detaching sockets from device at hci_sock_dev_event(HCI_DEV_UNREG),
      by moving actual cleanup of resources from hci_unregister_dev() to
      hci_cleanup_dev() which is called by bt_host_release() when all
      references to this unregistered device (which is a kobject) are gone.
      
      Since hci_sock_dev_event(HCI_DEV_UNREG) no longer resets
      hci_pi(sk)->hdev, we need to check whether this device was unregistered
      and return an error based on HCI_UNREGISTER flag.  There might be subtle
      behavioral difference in "monitor the hdev" functionality; please report
      if you found something went wrong due to this patch.
      
      Link: https://syzkaller.appspot.com/bug?extid=a5df189917e79d5e59c9 [1]
      Reported-by: Nsyzbot <syzbot+a5df189917e79d5e59c9@syzkaller.appspotmail.com>
      Suggested-by: NLinus Torvalds <torvalds@linux-foundation.org>
      Signed-off-by: NTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
      Fixes: e305509e ("Bluetooth: use correct lock to prevent UAF of hdev object")
      Acked-by: NLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      e0448092
  11. 05 8月, 2021 2 次提交
  12. 04 8月, 2021 2 次提交
  13. 29 7月, 2021 3 次提交