)]}'
{
  "commit": "281ddc4e01ab54cab07995f2a1b72cf81bf90eb5",
  "tree": "940e4d54e1a9a7c1581b38b8499256bf529dfe3c",
  "parents": [
    "3b70dd827b27bfadd89e7b1a2d422b04da38797c"
  ],
  "author": {
    "name": "Cen Zhang",
    "email": "zzzccc427@gmail.com",
    "time": "Thu Oct 29 21:12:26 2026 +0800"
  },
  "committer": {
    "name": "Luiz Augusto von Dentz",
    "email": "luiz.von.dentz@intel.com",
    "time": "Mon Nov 02 17:09:02 2026 -0500"
  },
  "message": "Bluetooth: hci_core: Keep link-key filtering inside RCU\n\nhci_find_link_key() must keep the matching link key allocated while it\nchecks the key against the blocked-key list. It currently leaves the\nkey-list RCU read-side section before passing k-\u003eval to\nhci_is_blocked_key(). That helper\u0027s own RCU section protects the\nblocked-key list, but it cannot keep an unlinked link key from being\nreclaimed.\n\nThe SMP receive path calls the finder without hdev-\u003elock: Secure\nConnections key distribution over BR/EDR reaches it through\nsmp_distribute_keys() and sc_generate_ltk(). With a stored peer link\nkey and a link-key entry in the blocked-key list,\nMGMT_OP_LOAD_LINK_KEYS can free the selected key before the comparison:\n\n  HCI RX worker (SMP)              Management / RCU reclamation\n  hci_find_link_key()\n    rcu_read_lock()\n    select k\n    rcu_read_unlock()\n                                   load_link_keys()\n                                     hci_dev_lock(hdev)\n                                     hci_link_keys_clear(hdev)\n                                       list_del_rcu(), kfree_rcu()\n                                     hci_dev_unlock(hdev)\n                                   grace period ends, k is freed\n    hci_is_blocked_key(hdev, ..., k-\u003eval)\n      memcmp() reads the freed key\n\nKeep the RCU read-side section active through the blocked-key\ncomparison and the warning that prints k-\u003ebdaddr, and release it before\nreturning on both matched-key paths. hci_find_ltk() already handles its\nblocked-key check this way.\n\nKASAN reported this on a test kernel whose scheduling hook paused the\nreceive worker after the lookup until the key had been freed.\n\nKASAN report as below:\n\n    \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\n    BUG: KASAN: slab-use-after-free in hci_is_blocked_key+0x2db/0x300\n    Read of size 1 at addr ffff88810b5f89a7 by task kworker/u17:0/502\n\n    CPU: 1 UID: 0 PID: 502 Comm: kworker/u17:0 Not tainted 7.2.0-rc6-pmb-bt-functional-v1+ #5 PREEMPT(lazy)\n    Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014\n    Workqueue: hci1 hci_rx_work\n    Call Trace:\n     \u003cTASK\u003e\n     dump_stack_lvl+0x93/0xd0\n     print_report+0xce/0x630\n     ? hci_is_blocked_key+0x2db/0x300\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     ? __virt_addr_valid+0x20d/0x410\n     ? hci_is_blocked_key+0x2db/0x300\n     kasan_report+0xe0/0x110\n     ? hci_is_blocked_key+0x2db/0x300\n     hci_is_blocked_key+0x2db/0x300\n     hci_find_link_key+0x12e/0x400\n     smp_distribute_keys+0x1830/0x2950\n     ? trace_hardirqs_on+0x18/0x160\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     ? queue_delayed_work_on+0xb3/0xf0\n     ? __pfx_smp_distribute_keys+0x10/0x10\n     ? __pfx_smp_send_cmd.isra.0+0x10/0x10\n     ? __cancel_work+0x1b0/0x290\n     ? __entry_text_end+0x1020f7/0x1020f9\n     ? lockdep_hardirqs_on_prepare+0xea/0x1a0\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     ? __asan_memset+0x23/0x50\n     ? smp_recv_cb+0x12c7/0x8d80\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     smp_recv_cb+0x12c7/0x8d80\n     ? __pfx_smp_recv_cb+0x10/0x10\n     ? __pfx___might_resched+0x10/0x10\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     ? stack_depot_save_flags+0x29/0x9a0\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     ? __mutex_lock+0x182c/0x2590\n     ? kasan_save_stack+0x42/0x60\n     ? l2cap_recv_frame+0x9ef/0x8830\n     ? __kasan_slab_free+0x5f/0x80\n     ? kmem_cache_free+0x242/0x580\n     ? kfree_skbmem+0x15e/0x1d0\n     ? sk_skb_reason_drop+0x12f/0x490\n     ? hci_event_packet+0x556/0xc70\n     ? hci_rx_work+0x367/0xf00\n     ? process_one_work+0x908/0x19c0\n     ? worker_thread+0x65c/0xe40\n     ? __pfx___mutex_lock+0x10/0x10\n     ? __lock_acquire+0x466/0x2260\n     ? __pfx_l2cap_chan_hold_unless_zero+0x10/0x10\n     ? l2cap_recv_frame+0x13cc/0x8830\n     ? __pfx_smp_recv_cb+0x10/0x10\n     l2cap_recv_frame+0x13cc/0x8830\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     ? __mutex_lock+0x182c/0x2590\n     ? __pfx_l2cap_recv_frame+0x10/0x10\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     ? find_held_lock+0x2b/0x80\n     ? l2cap_recv_acldata+0x1eb/0x10e0\n     ? __pfx___mutex_lock+0x10/0x10\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     ? __mutex_unlock_slowpath+0x147/0x920\n     ? __pfx_l2cap_conn_hold_unless_zero+0x10/0x10\n     ? __pfx_hci_conn_enter_active_mode+0x10/0x10\n     ? l2cap_recv_acldata+0x13d/0x10e0\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     l2cap_recv_acldata+0xe9f/0x10e0\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     hci_rx_work+0x5a6/0xf00\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     process_one_work+0x908/0x19c0\n     ? __pfx_process_one_work+0x10/0x10\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     ? lock_is_held_type+0x8f/0x100\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     worker_thread+0x65c/0xe40\n     ? __pfx_worker_thread+0x10/0x10\n     kthread+0x34f/0x460\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     ? __pfx_kthread+0x10/0x10\n     ret_from_fork+0x659/0x940\n     ? __pfx_ret_from_fork+0x10/0x10\n     ? srso_alias_return_thunk+0x5/0xfbef5\n     ? __switch_to+0x74f/0xf80\n     ? __pfx_kthread+0x10/0x10\n     ret_from_fork_asm+0x1a/0x30\n     \u003c/TASK\u003e\n\n    Allocated by task 504:\n     kasan_save_stack+0x33/0x60\n     kasan_save_track+0x14/0x30\n     __kasan_kmalloc+0xaa/0xb0\n     __kmalloc_cache_noprof+0x251/0x610\n     hci_add_link_key+0x474/0x840\n     hci_link_key_notify_evt+0x492/0xce0\n     hci_event_packet+0x894/0xc70\n     hci_rx_work+0x367/0xf00\n     process_one_work+0x908/0x19c0\n     worker_thread+0x65c/0xe40\n     kthread+0x34f/0x460\n     ret_from_fork+0x659/0x940\n     ret_from_fork_asm+0x1a/0x30\n\n    Freed by task 29:\n     kasan_save_stack+0x33/0x60\n     kasan_save_track+0x14/0x30\n     kasan_save_free_info+0x3b/0x60\n     __kasan_slab_free+0x5f/0x80\n     __rcu_free_sheaf_prepare+0x65/0x2a0\n     rcu_free_sheaf_nobarn+0x1d/0x50\n     rcu_core+0x661/0x1d10\n     handle_softirqs+0x201/0x930\n     run_ksoftirqd+0x33/0x60\n     smpboot_thread_fn+0x3bd/0x9a0\n     kthread+0x34f/0x460\n     ret_from_fork+0x659/0x940\n     ret_from_fork_asm+0x1a/0x30\n\n    The buggy address belongs to the object at ffff88810b5f8980\n     which belongs to the cache kmalloc-64 of size 64\n    The buggy address is located 39 bytes inside of\n     freed 64-byte region [ffff88810b5f8980, ffff88810b5f89c0)\n\n    The buggy address belongs to the physical page:\n    page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10b5f8\n    flags: 0x200000000000000(node\u003d0|zone\u003d2)\n    page_type: f5(slab)\n    raw: 0200000000000000 ffff8881000428c0 dead000000000100 dead000000000122\n    raw: 0000000000000000 0000000000200020 00000000f5000000 0000000000000000\n    page dumped because: kasan: bad access detected\n\n    Memory state around the buggy address:\n     ffff88810b5f8880: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc\n     ffff88810b5f8900: 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc\n    \u003effff88810b5f8980: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc\n                                   ^\n     ffff88810b5f8a00: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc\n     ffff88810b5f8a80: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc\n    \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\n\nFixes: 600a87490ff9 (\"Bluetooth: Implementation of MGMT_OP_SET_BLOCKED_KEYS.\")\nAssisted-by: LLM\nSigned-off-by: Cen Zhang \u003czzzccc427@gmail.com\u003e\nSigned-off-by: Luiz Augusto von Dentz \u003cluiz.von.dentz@intel.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "55fc64db495ac6e2e55487df85398538dfb033e9",
      "old_mode": 33188,
      "old_path": "net/bluetooth/hci_core.c",
      "new_id": "a299aea1dd092f35a9919c0f1d119c98ac9fe375",
      "new_mode": 33188,
      "new_path": "net/bluetooth/hci_core.c"
    }
  ]
}
