summaryrefslogtreecommitdiff
path: root/net/bluetooth
AgeCommit message (Collapse)Author
5 daysBluetooth: MGMT: Fix discovery stuck after a failed Stop DiscoveryKevin Dewald
Stop Discovery moves the discovery to DISCOVERY_STOPPING, and stop_discovery_complete() only moves it on to DISCOVERY_STOPPED when stopping succeeded. When it fails, for example because LE Set Scan Enable times out, nothing moves the discovery out of DISCOVERY_STOPPING: Stop Discovery is rejected, as the discovery is not active anymore, and the LE scan timeout was cancelled before the scan was disabled. Until the controller is powered off, every Start Discovery then fails with Busy, and hci_update_passive_scan_sync() skips background scanning, so devices set to auto-connect are not connected anymore. Move the discovery back to DISCOVERY_FINDING when stopping it failed while its inquiry or active LE scan is still running, so that it can be stopped again. Only change the state while the discovery is still stopping, as Inquiry Cancel may already have stopped it, for example when only the passive scan could not be disabled, and a new Start Discovery may have followed. Do this under hci_dev_lock(), like the command completions that change these flags, and before replying, so that a client acting on the reply sees the new state. Only cancel the LE scan timeout once the scan is disabled, so that the discovery still ends on its own, except when suspending, where it is still cancelled first. A timed out LE Set Scan Enable can still complete afterwards, which cancels the timeout as well, so also stop the discovery when its scan is disabled while the timeout is pending, or while the timeout work waits for the lock. Fixes: 0e05bba6f6f8 ("Bluetooth: Update stop_discovery to use HCI request") Assisted-by: Claude:claude-opus-5.5 Signed-off-by: Kevin Dewald <kevin@simpleble.org> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: validate retained LE Set CIG Parameters command lengthYifan Zhang
hci_cc_le_set_cig_params() validates the controller response but not the parameters of the previously sent command. A short command can claim a large num_cis without containing the corresponding cis[] array. A complete successful response then makes the handler read beyond the command skb while looking up each CIS ID. KASAN reports: BUG: KASAN: slab-out-of-bounds in hci_cc_le_set_cig_params Read of size 1 hci_cc_le_set_cig_params hci_cmd_complete_evt hci_event_packet Obtain the retained parameter length and require both the fixed header and the complete CIS array before using the command data. The reproducer no longer triggers a KASAN report with this change. Fixes: 71e9588435c3 ("Bluetooth: ISO: use correct CIS order in Set CIG Parameters event") Closes: https://lore.kernel.org/linux-bluetooth/179317463153.87610.8996555110609321376@stu.pku.edu.cn/ Signed-off-by: Yifan Zhang <yfzhang23@stu.pku.edu.cn> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: validate retained LE Create CIS command lengthYifan Zhang
hci_cs_le_create_cis() retrieves the parameters of the previously sent command without their length. It then trusts num_cis and walks the flexible cis[] array when a controller reports a failed command. A five-byte HCI command containing only num_cis can therefore make the handler read beyond the command skb. KASAN reports: BUG: KASAN: slab-out-of-bounds in hci_cs_le_create_cis Read of size 2 hci_cs_le_create_cis hci_cmd_status_evt hci_event_packet Add a length-returning saved-command helper and require the fixed header and complete CIS array before walking it. The reproducer no longer triggers a KASAN report with this change. Fixes: 26afbd826ee3 ("Bluetooth: Add initial implementation of CIS connections") Closes: https://lore.kernel.org/linux-bluetooth/179317462624.87574.6271582002629080499@stu.pku.edu.cn/ Signed-off-by: Yifan Zhang <yfzhang23@stu.pku.edu.cn> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: hci_core: Initialize advertising RPA work only onceCen Zhang
hci_add_adv_instance() also updates existing instances and calls INIT_DELAYED_WORK() on their rpa_expired_cb every time, even when the work is pending or running. cancel_delayed_work_sync() then no longer finds the work, so hci_remove_adv_instance() can free the instance under it: hdev->workqueue MGMT_OP_ADD_EXT_ADV_PARAMS adv_instance_rpa_expired() hci_dev_lock(hdev) hci_add_adv_instance() INIT_DELAYED_WORK() mgmt_pending_new() fails hci_remove_adv_instance() cancel_delayed_work_sync() returns without waiting kfree(adv) hci_dev_unlock(hdev) adv->rpa_expired = true The work has been initialized on every update since it was added. Initialize it only when the instance is allocated. KASAN report as below: BUG: KASAN: slab-use-after-free in adv_instance_rpa_expired+0x139/0x160 Write of size 1 at addr ffff888108d84b2e by task kworker/u17:0/504 Workqueue: hci0 adv_instance_rpa_expired Call Trace: adv_instance_rpa_expired+0x139/0x160 Allocated by task 560: hci_add_adv_instance+0x68d/0x9d0 add_ext_adv_params+0x4d4/0xb60 hci_sock_sendmsg+0x128b/0x22e0 Freed by task 594: kfree+0x307/0x580 hci_remove_adv_instance+0x230/0x540 add_ext_adv_params+0xa43/0xb60 hci_sock_sendmsg+0x128b/0x22e0 Last potentially related work creation: insert_work+0x37/0x210 __queue_work+0xaba/0x1270 call_timer_fn+0x171/0x500 The buggy address belongs to the object at ffff888108d84800 which belongs to the cache kmalloc-1k of size 1024 The buggy address is located 814 bytes inside of freed 1024-byte region [ffff888108d84800, ffff888108d84c00) Fixes: a73c046a2869 ("Bluetooth: Implement Set ADV set random address") Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: L2CAP: Ignore connection responses with wrong identJinwang Li
L2CAP/COS/CED/BI-28-C requires the IUT to ignore a Connection Response that carries an invalid Identifier. l2cap_connect_create_rsp() only checks that a connection request is outstanding, not that the response answers it. Add an ident check against the pending request so that a mismatched response is dropped. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Jinwang Li <jinwang.li@oss.qualcomm.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: MGMT: Clear disabled connection parameters when loading noneKevin Dewald
Load Connection Parameters only clears the disabled connection parameters when it loads more than one entry, so that loading a single entry can update the parameters of one device without dropping the others. Loading no entries does not clear them either, though, which is what bluetoothd does when it starts without stored connection parameters. Pair Device adds disabled connection parameters for the device it pairs with, so these now survive bluetoothd restarts, and new connections to the device keep using the parameters they were created with instead of the defaults set since, e.g. the connection interval from main.conf. Clear the disabled connection parameters unless a single entry is loaded, as was done for any number of entries before. Fixes: 0ece498c27d8 ("Bluetooth: MGMT: Make MGMT_OP_LOAD_CONN_PARAM update existing connection") Assisted-by: Claude:claude-opus-5.5 Signed-off-by: Kevin Dewald <kevin@simpleble.org> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: hci_sync: Copy the resolving-list IRK under RCUCen Zhang
hci_le_add_resolve_list_sync() copies the peer IRK into the LE Add Device To Resolving List command after hci_find_irk_by_addr() has returned. The finder ends its RCU read-side section before returning the borrowed entry, and neither the request worker nor interleave_scan_work() holds hdev->lock here. The resolving-list membership check between the lookup and the copy takes hdev->lock and may sleep on it, which widens the window. When LL privacy programs a peer with address resolution enabled, MGMT_OP_LOAD_IRKS can free its IRK before the copy: Request worker Management / RCU reclamation hci_le_add_resolve_list_sync() irk = hci_find_irk_by_addr() load_irks() hci_dev_lock(hdev) hci_smp_irks_clear(hdev) list_del_rcu(), kfree_rcu() hci_dev_unlock(hdev) grace period ends, irk is freed resolving-list membership check memcpy(cp.peer_irk, irk->val, 16) Copy the IRK value in an RCU read-side section right after the lookup, as hci_le_set_privacy_mode_sync() does for the identity address. The section ends before hdev->lock is taken and before the synchronous HCI command is sent. KASAN reported this on a test kernel with scheduling hooks, whose frames appear in the trace. The report predates the hdev->lock taken by the membership check. KASAN report as below: ================================================================== BUG: KASAN: slab-use-after-free in hci_le_add_resolve_list_sync+0x8d9/0x910 Read of size 16 at addr ffff88810d21452d by task kworker/u17:0/504 CPU: 2 UID: 0 PID: 504 Comm: kworker/u17:0 Not tainted 7.2.0-rc6-pmb-bt-functional-v1+ #2 PREEMPT(lazy) 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 Workqueue: hci0 interleave_scan_work Call Trace: <TASK> dump_stack_lvl+0x93/0xd0 print_report+0xce/0x630 ? hci_le_add_resolve_list_sync+0x8d9/0x910 ? srso_alias_return_thunk+0x5/0xfbef5 ? __virt_addr_valid+0x20d/0x410 ? hci_le_add_resolve_list_sync+0x8d9/0x910 kasan_report+0xe0/0x110 ? hci_le_add_resolve_list_sync+0x8d9/0x910 hci_le_add_resolve_list_sync+0x8d9/0x910 ? __pfx_hci_le_add_resolve_list_sync+0x10/0x10 ? pmbd_probe_hit_cookie+0xe7/0x1c0 ? srso_alias_return_thunk+0x5/0xfbef5 ? pmbd_probe_hit_cookie+0xee/0x1c0 ? __pfx_pmbd_probe_hit_cookie+0x10/0x10 hci_le_add_accept_list_sync+0x18e/0x820 ? conn_params_copy+0x36e/0x650 ? __pfx_hci_le_add_accept_list_sync+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? conn_params_copy+0x3a0/0x650 hci_passive_scan_sync+0x95f/0x1f10 ? __pfx_hci_passive_scan_sync+0x10/0x10 ? debug_object_deactivate+0x2f8/0x3c0 ? pwq_dec_nr_in_flight+0x880/0xdf0 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_acquire+0x17b/0x2f0 ? process_one_work+0x895/0x19c0 interleave_scan_work+0x11b/0x470 process_one_work+0x908/0x19c0 ? __pfx_process_one_work+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_is_held_type+0x8f/0x100 ? srso_alias_return_thunk+0x5/0xfbef5 worker_thread+0x65c/0xe40 ? __pfx_worker_thread+0x10/0x10 kthread+0x34f/0x460 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x659/0x940 ? __pfx_ret_from_fork+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? __switch_to+0x74f/0xf80 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK> Allocated by task 535: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 __kasan_kmalloc+0xaa/0xb0 __kmalloc_cache_noprof+0x251/0x610 hci_add_irk+0xb6/0x220 load_irks+0x5f9/0x840 hci_sock_sendmsg+0x128b/0x22e0 __sys_sendto+0x425/0x470 __x64_sys_sendto+0xe5/0x1c0 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 0: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x5f/0x80 __rcu_free_sheaf_prepare+0x65/0x2a0 rcu_free_sheaf+0x1f/0xe0 rcu_core+0x661/0x1d10 handle_softirqs+0x201/0x930 __irq_exit_rcu+0x110/0x1e0 irq_exit_rcu+0xe/0x20 sysvec_apic_timer_interrupt+0x6c/0x80 asm_sysvec_apic_timer_interrupt+0x1a/0x20 The buggy address belongs to the object at ffff88810d214500 which belongs to the cache kmalloc-64 of size 64 The buggy address is located 45 bytes inside of freed 64-byte region [ffff88810d214500, ffff88810d214540) The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10d214 flags: 0x200000000000000(node=0|zone=2) page_type: f5(slab) raw: 0200000000000000 ffff8881000428c0 dead000000000100 dead000000000122 raw: 0000000000000000 0000000000200020 00000000f5000000 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff88810d214400: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ffff88810d214480: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc >ffff88810d214500: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ^ ffff88810d214580: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ffff88810d214600: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ================================================================== Fixes: e8907f76544f ("Bluetooth: hci_sync: Make use of hci_cmd_sync_queue set 3") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: SMP: Protect LTK encryption with RCUCen Zhang
smp_ltk_encrypt() checks the security level of the LTK returned by hci_find_ltk() and then starts encryption with its EDIV, Rand, value and key size. The finder ends its RCU read-side section before returning the borrowed entry, and neither caller holds hdev->lock: the SMP Security Request handler runs from the receive path, and setsockopt(BT_SECURITY) reaches smp_conn_security() with only the socket and channel locks held. MGMT_OP_LOAD_LONG_TERM_KEYS can therefore free the LTK in between: Socket security request Management / RCU reclamation smp_ltk_encrypt() key = hci_find_ltk() load_long_term_keys() hci_dev_lock(hdev) hci_smp_ltks_clear(hdev) list_del_rcu(), kfree_rcu() hci_dev_unlock(hdev) grace period ends, key is freed smp_ltk_sec_level(key) hci_le_start_enc(hcon, key->ediv, key->rand, key->val, ...) Keep an RCU read-side section across the lookup and every use of the key. hci_le_start_enc() copies the key into the command and queues it with a GFP_ATOMIC allocation, so the whole sequence can stay inside the section. KFENCE reported this on a test kernel where the socket thread was paused after the lookup until the RCU callback had freed the key. KFENCE report as below: ================================================================== BUG: KFENCE: use-after-free read in smp_ltk_encrypt.isra.0+0xf3/0x370 Use-after-free read at 0x00000000c45332eb (in kfence-#128): smp_ltk_encrypt.isra.0+0xf3/0x370 smp_conn_security+0x489/0x9d0 l2cap_sock_setsockopt+0x1bbe/0x2300 do_sock_setsockopt+0x1fb/0x430 __sys_setsockopt+0x106/0x180 __x64_sys_setsockopt+0xc2/0x160 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f kfence-#128: 0x00000000d45af9b0-0x0000000053c1365e, size=72, cache=kmalloc-96 allocated by task 533 on cpu 0 at 50.484258s (0.449177s ago): hci_add_ltk+0x1f5/0x3a0 load_long_term_keys+0x6ea/0x930 hci_sock_sendmsg+0x128b/0x22e0 sock_write_iter+0x4c0/0x550 vfs_write+0x637/0x1010 ksys_write+0x1b7/0x200 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f freed by task 0 on cpu 0 at 50.846944s (0.093664s ago): __rcu_free_sheaf_prepare+0x261/0x2a0 rcu_free_sheaf_nobarn+0x1d/0x50 rcu_core+0x661/0x1d10 handle_softirqs+0x201/0x930 __irq_exit_rcu+0x110/0x1e0 irq_exit_rcu+0xe/0x20 sysvec_apic_timer_interrupt+0x6c/0x80 asm_sysvec_apic_timer_interrupt+0x1a/0x20 pv_native_safe_halt+0xf/0x20 default_idle+0x9/0x10 default_idle_call+0x6c/0xb0 do_idle+0x3a7/0x650 cpu_startup_entry+0x54/0x60 rest_init+0x15e/0x2b0 start_kernel+0x412/0x4b0 x86_64_start_reservations+0x18/0x30 x86_64_start_kernel+0x111/0x120 common_startup_64+0x13e/0x158 CPU: 2 UID: 0 PID: 534 Comm: l2cap-ltk-actor Not tainted 7.2.0-rc6-pmb-bt-functional-v1+ #5 PREEMPT(lazy) 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 ================================================================== Fixes: 988c5997d320 ("Bluetooth: Use the LTK after receiving a LE Security Request") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: SMP: Protect link keys during LTK derivationCen Zhang
sc_generate_ltk() reads the type and value of the peer link key after hci_find_link_key() has returned. The finder ends its RCU read-side section before returning the borrowed entry, and the SMP receive path does not hold hdev->lock: l2cap_recv_acldata() releases it before the PDU is dispatched. The L2CAP connection and channel locks held by SMP do not serialize with management link-key removal. When BR/EDR Secure Connections pairing derives an LTK from the stored link key, MGMT_OP_LOAD_LINK_KEYS can free that key mid-derivation: HCI RX worker (SMP) Management / RCU reclamation sc_generate_ltk() key = hci_find_link_key() load_link_keys() hci_dev_lock(hdev) hci_link_keys_clear(hdev) list_del_rcu(), kfree_rcu() hci_dev_unlock(hdev) grace period ends, key is freed read key->type smp_h6() or smp_h7() reads key->val Hold an RCU read-side section from the lookup until the type and value have been consumed. smp_h6() and smp_h7() only run the synchronous AES-CMAC library code, which neither sleeps nor allocates. Release the section before sc_add_ltk(), which allocates with GFP_KERNEL. KASAN reported this on a test kernel whose scheduling hook paused the receive worker after the lookup; the hook frames appear in the trace. KASAN report as below: ================================================================== BUG: KASAN: slab-use-after-free in smp_distribute_keys+0x2983/0x2b70 Read of size 1 at addr ffff88810618e9a6 by task kworker/u17:0/500 CPU: 0 UID: 0 PID: 500 Comm: kworker/u17:0 Not tainted 7.2.0-rc6-pmb-bt-functional-v1+ #1 PREEMPT(lazy) 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 Workqueue: hci1 hci_rx_work Call Trace: <TASK> dump_stack_lvl+0x93/0xd0 print_report+0xce/0x630 ? smp_distribute_keys+0x2983/0x2b70 ? srso_alias_return_thunk+0x5/0xfbef5 ? __virt_addr_valid+0x20d/0x410 ? smp_distribute_keys+0x2983/0x2b70 kasan_report+0xe0/0x110 ? smp_distribute_keys+0x2983/0x2b70 smp_distribute_keys+0x2983/0x2b70 ? __pfx_smp_distribute_keys+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? pmbd_gate_maybe+0x47/0x60 ? srso_alias_return_thunk+0x5/0xfbef5 ? pmbd_probe_hit_cookie+0xe7/0x1c0 ? srso_alias_return_thunk+0x5/0xfbef5 ? pmbd_probe_hit_cookie+0xee/0x1c0 ? __pfx_pmbd_probe_hit_cookie+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? __asan_memset+0x23/0x50 ? smp_recv_cb+0x12e2/0x8f30 ? srso_alias_return_thunk+0x5/0xfbef5 smp_recv_cb+0x12e2/0x8f30 ? __pfx_smp_recv_cb+0x10/0x10 ? __pfx___might_resched+0x10/0x10 ? __pfx_sched_balance_find_src_group+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? __mutex_lock+0x182c/0x2590 ? l2cap_recv_frame+0x9ef/0x8830 ? __pfx___mutex_lock+0x10/0x10 ? __lock_acquire+0x466/0x2260 ? __pfx_l2cap_chan_hold_unless_zero+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? l2cap_recv_frame+0x13cc/0x8830 ? __pfx_smp_recv_cb+0x10/0x10 l2cap_recv_frame+0x13cc/0x8830 ? srso_alias_return_thunk+0x5/0xfbef5 ? __mutex_lock+0x182c/0x2590 ? __pfx_l2cap_recv_frame+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? find_held_lock+0x2b/0x80 ? l2cap_recv_acldata+0x1eb/0x10e0 ? __pfx___mutex_lock+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? __mutex_unlock_slowpath+0x147/0x920 ? __pfx_l2cap_conn_hold_unless_zero+0x10/0x10 ? __pfx_hci_conn_enter_active_mode+0x10/0x10 ? l2cap_recv_acldata+0x13d/0x10e0 ? srso_alias_return_thunk+0x5/0xfbef5 l2cap_recv_acldata+0xe9f/0x10e0 ? srso_alias_return_thunk+0x5/0xfbef5 hci_rx_work+0x5a6/0xf00 ? srso_alias_return_thunk+0x5/0xfbef5 process_one_work+0x908/0x19c0 ? __pfx_process_one_work+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_is_held_type+0x8f/0x100 ? srso_alias_return_thunk+0x5/0xfbef5 worker_thread+0x65c/0xe40 ? __pfx_worker_thread+0x10/0x10 kthread+0x34f/0x460 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x659/0x940 ? __pfx_ret_from_fork+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? __switch_to+0x74f/0xf80 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK> Allocated by task 500: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 __kasan_kmalloc+0xaa/0xb0 __kmalloc_cache_noprof+0x251/0x610 hci_add_link_key+0x474/0x840 hci_link_key_notify_evt+0x492/0xce0 hci_event_packet+0x894/0xc70 hci_rx_work+0x367/0xf00 process_one_work+0x908/0x19c0 worker_thread+0x65c/0xe40 kthread+0x34f/0x460 ret_from_fork+0x659/0x940 ret_from_fork_asm+0x1a/0x30 Freed by task 0: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x5f/0x80 __rcu_free_sheaf_prepare+0x65/0x2a0 rcu_free_sheaf+0x1f/0xe0 rcu_core+0x661/0x1d10 handle_softirqs+0x201/0x930 __irq_exit_rcu+0x110/0x1e0 irq_exit_rcu+0xe/0x20 sysvec_apic_timer_interrupt+0x6c/0x80 asm_sysvec_apic_timer_interrupt+0x1a/0x20 The buggy address belongs to the object at ffff88810618e980 which belongs to the cache kmalloc-64 of size 64 The buggy address is located 38 bytes inside of freed 64-byte region [ffff88810618e980, ffff88810618e9c0) The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10618e flags: 0x200000000000000(node=0|zone=2) page_type: f5(slab) raw: 0200000000000000 ffff8881000428c0 dead000000000122 0000000000000000 raw: 0000000000000000 0000000000200020 00000000f5000000 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff88810618e880: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ffff88810618e900: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc >ffff88810618e980: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ^ ffff88810618ea00: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ffff88810618ea80: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ================================================================== Fixes: b5ae344d4c0f ("Bluetooth: Add full SMP BR/EDR support") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: hci_core: Keep link-key filtering inside RCUCen Zhang
hci_find_link_key() must keep the matching link key allocated while it checks the key against the blocked-key list. It currently leaves the key-list RCU read-side section before passing k->val to hci_is_blocked_key(). That helper's own RCU section protects the blocked-key list, but it cannot keep an unlinked link key from being reclaimed. The SMP receive path calls the finder without hdev->lock: Secure Connections key distribution over BR/EDR reaches it through smp_distribute_keys() and sc_generate_ltk(). With a stored peer link key and a link-key entry in the blocked-key list, MGMT_OP_LOAD_LINK_KEYS can free the selected key before the comparison: HCI RX worker (SMP) Management / RCU reclamation hci_find_link_key() rcu_read_lock() select k rcu_read_unlock() load_link_keys() hci_dev_lock(hdev) hci_link_keys_clear(hdev) list_del_rcu(), kfree_rcu() hci_dev_unlock(hdev) grace period ends, k is freed hci_is_blocked_key(hdev, ..., k->val) memcmp() reads the freed key Keep the RCU read-side section active through the blocked-key comparison and the warning that prints k->bdaddr, and release it before returning on both matched-key paths. hci_find_ltk() already handles its blocked-key check this way. KASAN reported this on a test kernel whose scheduling hook paused the receive worker after the lookup until the key had been freed. KASAN report as below: ================================================================== BUG: KASAN: slab-use-after-free in hci_is_blocked_key+0x2db/0x300 Read of size 1 at addr ffff88810b5f89a7 by task kworker/u17:0/502 CPU: 1 UID: 0 PID: 502 Comm: kworker/u17:0 Not tainted 7.2.0-rc6-pmb-bt-functional-v1+ #5 PREEMPT(lazy) 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 Workqueue: hci1 hci_rx_work Call Trace: <TASK> dump_stack_lvl+0x93/0xd0 print_report+0xce/0x630 ? hci_is_blocked_key+0x2db/0x300 ? srso_alias_return_thunk+0x5/0xfbef5 ? __virt_addr_valid+0x20d/0x410 ? hci_is_blocked_key+0x2db/0x300 kasan_report+0xe0/0x110 ? hci_is_blocked_key+0x2db/0x300 hci_is_blocked_key+0x2db/0x300 hci_find_link_key+0x12e/0x400 smp_distribute_keys+0x1830/0x2950 ? trace_hardirqs_on+0x18/0x160 ? srso_alias_return_thunk+0x5/0xfbef5 ? queue_delayed_work_on+0xb3/0xf0 ? __pfx_smp_distribute_keys+0x10/0x10 ? __pfx_smp_send_cmd.isra.0+0x10/0x10 ? __cancel_work+0x1b0/0x290 ? __entry_text_end+0x1020f7/0x1020f9 ? lockdep_hardirqs_on_prepare+0xea/0x1a0 ? srso_alias_return_thunk+0x5/0xfbef5 ? __asan_memset+0x23/0x50 ? smp_recv_cb+0x12c7/0x8d80 ? srso_alias_return_thunk+0x5/0xfbef5 smp_recv_cb+0x12c7/0x8d80 ? __pfx_smp_recv_cb+0x10/0x10 ? __pfx___might_resched+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? stack_depot_save_flags+0x29/0x9a0 ? srso_alias_return_thunk+0x5/0xfbef5 ? __mutex_lock+0x182c/0x2590 ? kasan_save_stack+0x42/0x60 ? l2cap_recv_frame+0x9ef/0x8830 ? __kasan_slab_free+0x5f/0x80 ? kmem_cache_free+0x242/0x580 ? kfree_skbmem+0x15e/0x1d0 ? sk_skb_reason_drop+0x12f/0x490 ? hci_event_packet+0x556/0xc70 ? hci_rx_work+0x367/0xf00 ? process_one_work+0x908/0x19c0 ? worker_thread+0x65c/0xe40 ? __pfx___mutex_lock+0x10/0x10 ? __lock_acquire+0x466/0x2260 ? __pfx_l2cap_chan_hold_unless_zero+0x10/0x10 ? l2cap_recv_frame+0x13cc/0x8830 ? __pfx_smp_recv_cb+0x10/0x10 l2cap_recv_frame+0x13cc/0x8830 ? srso_alias_return_thunk+0x5/0xfbef5 ? __mutex_lock+0x182c/0x2590 ? __pfx_l2cap_recv_frame+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? find_held_lock+0x2b/0x80 ? l2cap_recv_acldata+0x1eb/0x10e0 ? __pfx___mutex_lock+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? __mutex_unlock_slowpath+0x147/0x920 ? __pfx_l2cap_conn_hold_unless_zero+0x10/0x10 ? __pfx_hci_conn_enter_active_mode+0x10/0x10 ? l2cap_recv_acldata+0x13d/0x10e0 ? srso_alias_return_thunk+0x5/0xfbef5 l2cap_recv_acldata+0xe9f/0x10e0 ? srso_alias_return_thunk+0x5/0xfbef5 hci_rx_work+0x5a6/0xf00 ? srso_alias_return_thunk+0x5/0xfbef5 process_one_work+0x908/0x19c0 ? __pfx_process_one_work+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_is_held_type+0x8f/0x100 ? srso_alias_return_thunk+0x5/0xfbef5 worker_thread+0x65c/0xe40 ? __pfx_worker_thread+0x10/0x10 kthread+0x34f/0x460 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x659/0x940 ? __pfx_ret_from_fork+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? __switch_to+0x74f/0xf80 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK> Allocated by task 504: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 __kasan_kmalloc+0xaa/0xb0 __kmalloc_cache_noprof+0x251/0x610 hci_add_link_key+0x474/0x840 hci_link_key_notify_evt+0x492/0xce0 hci_event_packet+0x894/0xc70 hci_rx_work+0x367/0xf00 process_one_work+0x908/0x19c0 worker_thread+0x65c/0xe40 kthread+0x34f/0x460 ret_from_fork+0x659/0x940 ret_from_fork_asm+0x1a/0x30 Freed by task 29: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x5f/0x80 __rcu_free_sheaf_prepare+0x65/0x2a0 rcu_free_sheaf_nobarn+0x1d/0x50 rcu_core+0x661/0x1d10 handle_softirqs+0x201/0x930 run_ksoftirqd+0x33/0x60 smpboot_thread_fn+0x3bd/0x9a0 kthread+0x34f/0x460 ret_from_fork+0x659/0x940 ret_from_fork_asm+0x1a/0x30 The buggy address belongs to the object at ffff88810b5f8980 which belongs to the cache kmalloc-64 of size 64 The buggy address is located 39 bytes inside of freed 64-byte region [ffff88810b5f8980, ffff88810b5f89c0) The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10b5f8 flags: 0x200000000000000(node=0|zone=2) page_type: f5(slab) raw: 0200000000000000 ffff8881000428c0 dead000000000100 dead000000000122 raw: 0000000000000000 0000000000200020 00000000f5000000 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff88810b5f8880: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ffff88810b5f8900: 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc >ffff88810b5f8980: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ^ ffff88810b5f8a00: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ffff88810b5f8a80: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ================================================================== Fixes: 600a87490ff9 ("Bluetooth: Implementation of MGMT_OP_SET_BLOCKED_KEYS.") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: MGMT: Return RFKILLED for Set Powered on a blocked controllerTobias Wilken
Since MGMT_OP_SET_POWERED runs through hci_cmd_sync, powering on a controller that is blocked by rfkill fails with -ERFKILL from hci_dev_open_sync(), and mgmt_set_powered_complete() reports it with mgmt_status(err). mgmt_errno_status() has no case for -ERFKILL, so userspace gets MGMT_STATUS_FAILED instead of MGMT_STATUS_RFKILLED. Before that conversion, power on went through hci_power_on(), whose error path mgmt_set_powered_failed() still maps -ERFKILL to MGMT_STATUS_RFKILLED. bluetoothd relies on that status: for RFKILLED it sets the adapter PowerState to "off-blocked" and returns org.bluez.Error.Blocked for the Powered property, for any other status it returns org.bluez.Error.Failed. With the controller soft blocked, "bluetoothctl power on" printed "Failed to set power on: org.bluez.Error.Failed" and btmon showed "Set Powered (0x0005) Status: Failed (0x03)". With this change it prints org.bluez.Error.Blocked and btmon shows "Status: RFKilled (0x12)". Map -ERFKILL to MGMT_STATUS_RFKILLED in mgmt_errno_status(). Fixes: cf75ad8b41d2 ("Bluetooth: hci_sync: Convert MGMT_SET_POWERED") Assisted-by: LLM Signed-off-by: Tobias Wilken <tooangel@tooangel.de> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: hci_sync: Protect resolving-list lookupsCen Zhang
The host resolving list is updated under hdev->lock, and each bdaddr_list_with_irk entry must remain alive throughout a lookup. hci_le_del_resolve_list_sync() and hci_le_add_resolve_list_sync() traverse that list without taking the lock. On an LE privacy-capable controller with a programmed entry, passive scan reconciliation can reach hci_le_del_resolve_list_sync() while a privileged HCI_RAW client sends LE Clear Resolving List. The raw command does not take req_lock, and its successful completion runs on the controller workqueue independently of request work: Request work Raw HCI / event work hci_le_del_resolve_list_sync() lookup loads a list node hci_sock_sendmsg() queue LE Clear Resolving List hci_cc_le_clear_resolv_list() take hdev->lock unlink and free the node release hdev->lock read the node's address/type The clear can free the node after the lookup loads it and before its address/type read, causing a use-after-free. The report below shows this access with the delete helper on the faulting stack. The add helper uses the same unprotected lookup. Take hdev->lock around each resolving-list membership lookup and retain only a boolean result. This serializes traversal with clear completion and keeps entry pointers inside the protected section. Release the lock before issuing a synchronous HCI command, whose completion also needs the lock. KASAN report as below: ================================================================== BUG: KASAN: slab-use-after-free in hci_bdaddr_list_lookup_with_irk+0x106/0x120 Read of size 1 at addr ffff88810b036e16 by task kworker/u17:0/495 CPU: 2 UID: 0 PID: 495 Comm: kworker/u17:0 Not tainted 7.2.0-rc6-pmb-bt-functional-v1+ #3 PREEMPT(lazy) 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 Workqueue: hci0 hci_cmd_sync_work Call Trace: <TASK> dump_stack_lvl+0x93/0xd0 print_report+0xce/0x630 ? hci_bdaddr_list_lookup_with_irk+0x106/0x120 ? srso_alias_return_thunk+0x5/0xfbef5 ? __virt_addr_valid+0x20d/0x410 ? hci_bdaddr_list_lookup_with_irk+0x106/0x120 kasan_report+0xe0/0x110 ? hci_bdaddr_list_lookup_with_irk+0x106/0x120 hci_bdaddr_list_lookup_with_irk+0x106/0x120 hci_le_del_resolve_list_sync.isra.0+0xd6/0x3f0 ? __pfx_hci_le_del_resolve_list_sync.isra.0+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 hci_le_del_accept_list_sync.isra.0+0x11c/0x290 ? __pfx_hci_le_del_accept_list_sync.isra.0+0x10/0x10 ? hci_passive_scan_sync+0x551/0x1e80 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_release+0xc8/0x280 hci_passive_scan_sync+0x71c/0x1e80 ? __pfx_hci_passive_scan_sync+0x10/0x10 ? find_held_lock+0x2b/0x80 ? hci_lookup_le_connect+0xe1/0x3c0 ? srso_alias_return_thunk+0x5/0xfbef5 ? find_held_lock+0x2b/0x80 ? hci_update_passive_scan_sync+0x437/0x950 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_release+0xc8/0x280 hci_update_passive_scan_sync+0x461/0x950 hci_cmd_sync_work+0x1b3/0x450 ? srso_alias_return_thunk+0x5/0xfbef5 process_one_work+0x908/0x19c0 ? __pfx_process_one_work+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_is_held_type+0x8f/0x100 ? srso_alias_return_thunk+0x5/0xfbef5 worker_thread+0x65c/0xe40 ? __pfx_worker_thread+0x10/0x10 kthread+0x34f/0x460 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x659/0x940 ? __pfx_ret_from_fork+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? __switch_to+0x74f/0xf80 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK> Allocated by task 495: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 __kasan_kmalloc+0xaa/0xb0 __kmalloc_cache_noprof+0x251/0x610 hci_bdaddr_list_add_with_irk+0x183/0x3e0 hci_cc_le_add_to_resolv_list+0x18c/0x240 hci_cmd_complete_evt+0x373/0xab0 hci_event_packet+0x4e8/0xc70 hci_rx_work+0x367/0xf00 process_one_work+0x908/0x19c0 worker_thread+0x65c/0xe40 kthread+0x34f/0x460 ret_from_fork+0x659/0x940 ret_from_fork_asm+0x1a/0x30 Freed by task 497: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x5f/0x80 kfree+0x307/0x580 hci_bdaddr_list_clear+0x134/0x230 hci_cc_le_clear_resolv_list+0x13d/0x240 hci_cmd_complete_evt+0x373/0xab0 hci_event_packet+0x4e8/0xc70 hci_rx_work+0x367/0xf00 process_one_work+0x908/0x19c0 worker_thread+0x65c/0xe40 kthread+0x34f/0x460 ret_from_fork+0x659/0x940 ret_from_fork_asm+0x1a/0x30 The buggy address belongs to the object at ffff88810b036e00 which belongs to the cache kmalloc-64 of size 64 The buggy address is located 22 bytes inside of freed 64-byte region [ffff88810b036e00, ffff88810b036e40) The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10b036 flags: 0x200000000000000(node=0|zone=2) page_type: f5(slab) raw: 0200000000000000 ffff8881000428c0 dead000000000100 dead000000000122 raw: 0000000000000000 0000000000200020 00000000f5000000 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff88810b036d00: 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc ffff88810b036d80: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc >ffff88810b036e00: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ^ ffff88810b036e80: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ffff88810b036f00: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ================================================================== Disabling lock debugging due to kernel taint Fixes: e8907f76544f ("Bluetooth: hci_sync: Make use of hci_cmd_sync_queue set 3") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: hci_sync: Copy the LE accept list under hdev->lockCen Zhang
The LE accept-list mirror consists of bdaddr_list entries that are added, removed and freed under hdev->lock. The ordinary branch of hci_update_accept_list_sync() traverses this list without that lock. The request worker's req_lock does not serialize raw HCI completions, and the RCU sections protect connection and pending-action lookups, not the accept-list nodes. Changing connectability can reach this iterator through set_connectable_sync(), hci_update_connectable_sync(), hci_update_passive_scan_sync() and hci_passive_scan_sync(). With a populated mirror, a privileged raw HCI sender can issue HCI_OP_LE_CLEAR_ACCEPT_LIST while request work is reconciling it: Request work HCI event work select b and successor t hci_cc_le_clear_accept_list() hci_dev_lock(hdev) hci_bdaddr_list_clear() unlink nodes and kfree(b) hci_dev_unlock(hdev) read b->bdaddr_type The clear completion can therefore free the selected node before its field read, or the saved successor before the iterator advances. KASAN reported a one-byte read of bdaddr_type from the freed node. Copy each entry's address and type under hdev->lock and reconcile the private array instead. Release the mutex before issuing synchronous commands, since their completion handlers also acquire it. Free the copy after iteration and use the existing error path to disable accept-list filtering if allocation fails. This change has not been runtime-tested. KASAN report as below: ================================================================== BUG: KASAN: slab-use-after-free in hci_passive_scan_sync+0x1cc4/0x1f80 Read of size 1 at addr ffff888105ee6c56 by task kworker/u17:1/499 Workqueue: hci0 hci_cmd_sync_work Call Trace: <TASK> dump_stack_lvl+0x93/0xd0 print_report+0xce/0x630 ? hci_passive_scan_sync+0x1cc4/0x1f80 ? srso_alias_return_thunk+0x5/0xfbef5 ? __virt_addr_valid+0x20d/0x410 ? hci_passive_scan_sync+0x1cc4/0x1f80 kasan_report+0xe0/0x110 ? hci_passive_scan_sync+0x1cc4/0x1f80 hci_passive_scan_sync+0x1cc4/0x1f80 ? pmbd_gate_site_armed+0x31/0x1c0 ? __pfx_hci_passive_scan_sync+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? pmbd_probe_hit_cookie+0x10/0x1c0 ? __pfx_pmbd_probe_hit_cookie+0x10/0x10 ? hci_update_passive_scan_sync+0x43f/0x9e0 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_release+0xc8/0x280 hci_update_passive_scan_sync+0x473/0x9e0 hci_update_connectable_sync+0x13c/0x250 set_connectable_sync+0x39/0xb0 hci_cmd_sync_work+0x1b3/0x450 ? srso_alias_return_thunk+0x5/0xfbef5 process_one_work+0x908/0x19c0 ? __pfx_process_one_work+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_is_held_type+0x8f/0x100 ? srso_alias_return_thunk+0x5/0xfbef5 worker_thread+0x65c/0xe40 ? __pfx_worker_thread+0x10/0x10 kthread+0x34f/0x460 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x659/0x940 ? __pfx_ret_from_fork+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? __switch_to+0x74f/0xf80 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK> Allocated by task 511: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 __kasan_kmalloc+0xaa/0xb0 __kmalloc_cache_noprof+0x251/0x610 hci_bdaddr_list_add+0x179/0x390 hci_cc_le_add_to_accept_list+0x189/0x2d0 hci_cmd_complete_evt+0x373/0xab0 hci_event_packet+0x4e8/0xc70 hci_rx_work+0x367/0xf00 process_one_work+0x908/0x19c0 worker_thread+0x65c/0xe40 kthread+0x34f/0x460 ret_from_fork+0x659/0x940 ret_from_fork_asm+0x1a/0x30 Freed by task 511: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x5f/0x80 kfree+0x307/0x580 hci_bdaddr_list_clear+0x134/0x230 hci_cc_le_clear_accept_list+0x80/0x1f0 hci_cmd_complete_evt+0x373/0xab0 hci_event_packet+0x4e8/0xc70 hci_rx_work+0x367/0xf00 process_one_work+0x908/0x19c0 worker_thread+0x65c/0xe40 kthread+0x34f/0x460 ret_from_fork+0x659/0x940 ret_from_fork_asm+0x1a/0x30 The buggy address belongs to the object at ffff888105ee6c40 which belongs to the cache kmalloc-32 of size 32 The buggy address is located 22 bytes inside of freed 32-byte region [ffff888105ee6c40, ffff888105ee6c60) The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff888105ee69c0 pfn:0x105ee6 flags: 0x200000000000200(workingset|node=0|zone=2) page_type: f5(slab) raw: 0200000000000200 ffff888100042780 ffffea0004187150 ffffea00042534d0 raw: ffff888105ee69c0 000000000040003f 00000000f5000000 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff888105ee6b00: fa fb fb fb fc fc fc fc fa fb fb fb fc fc fc fc ffff888105ee6b80: fa fb fb fb fc fc fc fc fa fb fb fb fc fc fc fc >ffff888105ee6c00: fa fb fb fb fc fc fc fc fa fb fb fb fc fc fc fc ^ ffff888105ee6c80: fa fb fb fb fc fc fc fc fa fb fb fb fc fc fc fc ffff888105ee6d00: fa fb fb fb fc fc fc fc fa fb fb fb fc fc fc fc ================================================================== Fixes: e8907f76544f ("Bluetooth: hci_sync: Make use of hci_cmd_sync_queue set 3") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: hci_sync: Update the CIS host feature when enabling LELuiz Augusto von Dentz
The Connected Isochronous Stream (Host Support) feature bit is only set during init, based on LE being enabled at that time. If LE is enabled afterwards without the init being repeated, as happens when the controller is still auto powered on after registration, the bit stays cleared and controllers enforcing it reject LE Create CIS with Command Disallowed. Update the bit whenever LE Host Supported is written, so it follows the LE state. Fixes: 709788b154ca ("Bluetooth: hci_core: Fix using {cis,bis}_capable for current settings") Assisted-by: OpenCode:claude-opus-5.5 Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: L2CAP: Hold incoming data until encryption key size is knownLuiz Augusto von Dentz
Once encryption is enabled on an ACL link, the encryption key size is read from the controller, using hdev->min_enc_key_size in the meantime. Data received before the reply is processed with that key size, so a peer starting SMP over BR/EDR right after encryption, which it may do, gets its Pairing Request rejected with "Encryption Key Size" whenever the pending security level is FIPS, as that requires a 16 octet key: > HCI Event: Encryption Change (0x08) plen 4 > ACL Data RX: Handle 1 flags 0x02 dlen 11 BR/EDR SMP: Pairing Request (0x01) len 6 @ MGMT Event: Authentication Failed (0x0011) plen 8 Status: Authentication Failed (0x05) < HCI Command: Read Encryption Key Size (0x05|0x0008) plen 2 > HCI Event: Command Complete (0x0e) plen 7 Key size: 16 < ACL Data TX: Handle 1 flags 0x00 dlen 6 BR/EDR SMP: Pairing Failed (0x05) len 1 Reason: Encryption key size (0x06) Mark the connection with HCI_CONN_ENC_KEY_SIZE_PEND while the key size is read and hold incoming L2CAP data back in pending_rx meanwhile, processing it once the reply is handled. Found with mgmt-tester "Pairing Acceptor - SMP over BR/EDR 2" under User Mode Linux time travel, where the emulated peer always replies before the key size is read. Fixes: e3f6a257a73d ("Bluetooth: Use actual encryption key size for SMP over BR/EDR") Assisted-by: OpenCode:claude-opus-5.5 Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: hci_core: Convert hci_conn flags to a bitmapLuiz Augusto von Dentz
struct hci_conn stores its flags in a single unsigned long, but the HCI_CONN_* enum already has 33 entries (up to HCI_CONN_PA_SYNC_FAILED = 32), so on 32-bit architectures set_bit()/test_bit() on the highest flags access memory past the flags field, aliasing the adjacent conn_reason field. Fix this by declaring flags with DECLARE_BITMAP() sized by a new __HCI_CONN_NUM_FLAGS terminator so it can accommodate any number of flags. Assisted-by: OpenCode:claude-opus-5.5 Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: hci_event: Clear explicit connect state on LE connectionKevin Dewald
Since commit 6cd29ec6ae5e ("Bluetooth: hci_sync: Wait for proper events when connecting LE"), create_le_conn_complete() only runs once the LE Connection Complete event has been handled, and le_conn_complete_evt() has already removed the connection parameters from pend_le_conns by then. hci_connect_le_scan_cleanup() looks the parameters up in pend_le_conns, so after a successful connection it no longer clears explicit_connect, nor deletes the parameters that were only created for the explicit connect. The parameters of every device connected through an explicit connect, such as an L2CAP or ATT connect or MGMT Pair Device, are thus left with explicit_connect set. MGMT Remove Device for all devices then keeps them as HCI_AUTO_CONN_EXPLICIT instead of freeing them, and if the device was set to auto-connect and is disconnected, they also stay on pend_le_conns: the kernel keeps scanning for the device and connects to it as soon as it advertises, although no one asked for it any more. Do the cleanup in le_conn_complete_evt() instead, where the explicit connect request is fulfilled: clear explicit_connect, delete the parameters if they only existed for it, and put report parameters back on pend_le_reports. Auto-connect parameters are added back to pend_le_conns on disconnection, as before. Update the comment in hci_explicit_conn_params_set() that names hci_connect_le_scan_cleanup() as the only place deleting them. Fixes: 6cd29ec6ae5e ("Bluetooth: hci_sync: Wait for proper events when connecting LE") Assisted-by: Claude:claude-opus-5.5 Signed-off-by: Kevin Dewald <kevin@simpleble.org> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: hci_core: Fix queuing rx_work while workqueue is drainedAkhil Arul
hci_recv_frame() drops a frame unless HCI_UP or HCI_INIT is set, but the check is not synchronized with hci_dev_close_sync(). A driver can pass the check, then close clears HCI_UP, flushes rx_work and starts drain_workqueue(), and the late queue_work() of rx_work hits the draining workqueue: workqueue: cannot queue hci_rx_work on wq hci0 WARNING: kernel/workqueue.c:2352 at __queue_work+0x2c0/0x780 Call Trace: queue_work_on+0xb2/0xc0 hci_recv_frame+0x18f/0x330 vhci_write+0x174/0x240 vfs_write+0x271/0x680 ksys_write+0x7c/0x110 Skipping the queue_work() while HCI_CMD_DRAIN_WORKQUEUE is set, as done for tx_work, does not work for rx_work: the flag covers the whole close, and events still have to be received in that window, for the commands sent by hdev->shutdown() and for the reset done with HCI_QUIRK_RESET_ON_CLOSE. Run hci_recv_frame() under rcu_read_lock() and wait with synchronize_rcu() once HCI_UP has been cleared, so that every caller which still saw HCI_UP has queued its work before the workqueue is drained, and later callers drop the frame. HCI_INIT does not reopen that window. Apart from the HCI_QUIRK_RESET_ON_CLOSE reset, which runs after drain_workqueue() has returned, it is only set by hci_dev_init_sync() during open, and open and close are serialized by hci_req_sync_lock. So once the grace period has ended, nothing can pass the check and queue rx_work until the drain is over. Tested in qemu with the syzbot C reproducer, one run per boot: the warning showed up on 12 of 30 boots before and on none of 42 boots after. Bringing a vhci controller up and down 50 times behaves the same with and without this change. Fixes: 76727c02c1e1 ("Bluetooth: Call drain_workqueue() before resetting state") Reported-by: syzbot+2344fb8002f3ef5b1712@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=2344fb8002f3ef5b1712 Signed-off-by: Akhil Arul <akhilarul324@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: hci_sync: pause advertising for the scan address updateValentin Kindschi
hci_active_scan_sync() programs a non-resolvable private address with LE Set Random Address on every active scan start. BLUETOOTH CORE SPECIFICATION Vol 4, Part E, 7.8.4 says the controller shall return Command Disallowed (0x0C) for that command while legacy advertising or scanning is enabled. hci_pause_addr_resolution(), called just above, only stops advertising when LL privacy is in use, so on a controller without it the command is issued while advertising is still on: Bluetooth: hci0: Opcode 0x2005 failed: -16 It does not converge either. hdev->random_addr is only set on a successful command complete, so it stays BDADDR_ANY, and the deferral added by commit c2994b008492 ("Bluetooth: hci_sync: Fix not setting Random Address when required") requires it to be set. Unlike the resolvable address a few lines above, which is reused while rpa_valid(), the non-resolvable one is regenerated and rewritten on every call, so a controller that refuses the write is asked again at the scan restart period of about 10 s, for as long as discovery keeps restarting. Observed on a BCM43455, which has no LL privacy and no extended advertising, 190 rejections in one capture, every one retrying the same address: < LE Set Random Address Address: 02:16:91:90:F1:D4 (Non-Resolvable) > Command Complete LE Set Random Address, Command Disallowed < LE Set Random Address Address: 26:90:57:96:9A:3E (Non-Resolvable) > Command Complete LE Set Random Address, Command Disallowed Pause advertising for the address update, and resume it once the update is done and before the scan is started. The pause does not outlive the function: it is taken only when nothing else holds it, and every exit resumes advertising, which also releases the pause taken by hci_pause_addr_resolution(). A failed pause returns before marking anything paused, so the error path is a no-op. The resume in the error path is no longer guarded by ll_privacy_capable(). That guard matched a pause taken only under LL privacy; the pause added here is unconditional, and hci_resume_advertising_sync() returns early when nothing was paused. One caveat this widens, raised on the previous posting. When HCI_ADVERTISING is set, hci_pause_advertising_sync() also clears HCI_DISCOVERABLE and HCI_LIMITED_DISCOVERABLE and zeroes discov_timeout, and hci_resume_advertising_sync() restores only HCI_ADVERTISING, so the discoverable state is lost. It reproduces today on an LL privacy controller through hci_pause_addr_resolution(); the unconditional pause makes it reachable without LL privacy as well. hci_suspend_sync() also pauses unconditionally, so a device that suspends loses the same state on any controller today. That asymmetry is pre-existing and is left alone here rather than folded into a scan path fix. Legacy controllers have one random address register, shared by the scanner and the advertiser. Restoring the advertiser here can reprogram it when the advertiser is non-connectable, so the scan then uses that address rather than the one generated for it. Both are non-resolvable and neither is linkable to the identity address. With privacy enabled both roles already share one resolvable address the same way. With the patch, on the same hardware: < LE Set Advertising Enable Enable: 0x00 Success < LE Set Random Address Success < LE Set Advertising Parameters Success < LE Set Advertising Enable Enable: 0x01 Success < LE Set Scan Parameters Success < LE Set Scan Enable Enable: 0x01 Success The address write is accepted, and advertising is restored before the scan is started. Over 119369 btmon records and about 12 minutes of the normal workload of that device, alternating active and passive scanning with ten outgoing connection attempts, every LE Set Random Address succeeded and there were no Command Disallowed responses of any opcode, against one per scan restart before. Patch 1 is required: without it the resume added here returns -EPERM on the controllers this fixes and leaves advertising disabled. Fixes: 3c44a431d62b ("Bluetooth: hci_sync: Resume adv with no RPA when active scan") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-5.5 btmon Signed-off-by: Valentin Kindschi <valentin.kindschi@fiveco.ch> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: hci_sync: re-enable legacy advertising on resumeValentin Kindschi
hci_resume_advertising_sync() never re-enables advertising on a controller without extended advertising. It restores HCI_ADVERTISING from advertising_old_state, then calls hci_schedule_adv_instance_sync(), which starts with: if (hci_dev_test_flag(hdev, HCI_ADVERTISING) && !ext_adv_capable(hdev)) return -EPERM; The flag it tests was set a few lines earlier by the resume itself, so the call returns -EPERM without sending anything. The return value is discarded by every caller, so the failure is silent: advertising_paused is cleared, HCI_ADVERTISING is set, and the controller is not advertising. Observed on a BCM43455 (no extended advertising) after an active scan: btmon shows the pause disabling advertising and no re-enable in the ten seconds that follow, the device does not appear in another controller's scan, and btmgmt info still reports "advertising" in current settings. Enable instance 0x00 directly in that case, the way reenable_adv_sync() already does for the same situation. Instances continue to go through hci_schedule_adv_instance_sync() so the software rotation loop is rearmed. This affects every caller of hci_resume_advertising_sync(), not only the scan path: address resolution changes, accept list updates, discovery stop, suspend/resume and the end of an LE connection attempt all leave advertising disabled on such a controller today. The resume does nothing when the controller is already advertising, as it is after directed advertising was started for a peripheral connection, so it does not replace that advertising. err is initialised because the extended branch leaves it unset when adv_instances is empty and HCI_LE_ADV_0 is clear. Fixes: ad383c2c65a5 ("Bluetooth: hci_sync: Enable advertising when LL privacy is enabled") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-5.5 btmon Signed-off-by: Valentin Kindschi <valentin.kindschi@fiveco.ch> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: hci_core: Initialize LTK before publicationBinbin Deng
hci_add_ltk() publishes a newly allocated LTK on hdev->long_term_keys before initializing its address, type, value, authentication state, encryption size, EDIV, and random value. hci_find_ltk() and the debugfs long_term_keys_show() traverse this list under RCU and can therefore see a zero or partially initialized key before those stores complete. The race is reachable by racing an LTK addition with another CPU looking up or dumping long-term keys. For example, userspace can issue MGMT_OP_LOAD_LONG_TERM_KEYS while another process reads the corresponding debugfs file. Initialize all fields of a new LTK before list_add_rcu() makes it visible to RCU readers. Existing LTKs remain published and continue to be updated in place. Found during a static-analysis-assisted audit: candidate sites were surfaced by a Coccinelle rule, and the reader/writer paths were confirmed by LLM-assisted (GLM-5.3) code inspection. The issue was not observed at runtime; it is identified by code inspection only. Fixes: 970d0f1b2803 ("Bluetooth: Convert LTK list to RCU") Assisted-by: GLM-5.3 coccinelle Signed-off-by: Binbin Deng <18983559317@163.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: hci_core: Initialize link key before publicationBinbin Deng
hci_add_link_key() allocates a new link key with kzalloc(), inserts it into hdev->link_keys with list_add_rcu(), and only then initializes its address, value, type, and PIN length. RCU readers such as hci_find_link_key() and the debugfs link_keys_show() do not take hci_dev_lock, so they can traverse the new entry during that initialization window and observe a zero or partially initialized key. This can be triggered by racing a link-key update with another CPU looking up or dumping keys. In particular, userspace can issue MGMT_OP_LOAD_LINK_KEYS while another process reads the corresponding debugfs file. Complete all fields of a newly allocated key before publishing it with list_add_rcu(). Existing keys remain visible and keep their current in-place update behavior. Found during a static-analysis-assisted audit: candidate sites were surfaced by a Coccinelle rule, and the reader/writer paths were confirmed by LLM-assisted (GLM-5.3) code inspection. The issue was not observed at runtime; it is identified by code inspection only. Fixes: 0378b5977013 ("Bluetooth: Convert link keys list to use RCU") Signed-off-by: Binbin Deng <18983559317@163.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: hci_core: Initialize IRK before publicationBinbin Deng
hci_add_irk() initializes the identity address and address type of a newly allocated IRK, publishes it on hdev->identity_resolving_keys, and only then initializes its value and RPA. RCU readers such as hci_find_irk_by_rpa() and the debugfs identity_resolving_keys_show() can traverse the new entry during that window and see a zero or partially initialized IRK. The race is reachable by racing an IRK addition with another CPU resolving or dumping IRKs. In particular, userspace can issue MGMT_OP_LOAD_IRKS while another process reads the corresponding debugfs file or triggers RPA resolution. Initialize the IRK value and RPA before publishing a newly allocated IRK. Existing IRKs remain published and continue to be updated in place. Found during a static-analysis-assisted audit: candidate sites were surfaced by a Coccinelle rule, and the reader/writer paths were confirmed by LLM-assisted (GLM-5.3) code inspection. The issue was not observed at runtime; it is identified by code inspection only. Fixes: adae20cb2d20 ("Bluetooth: Convert IRK list to RCU") Assisted-by: GLM-5.3 coccinelle Signed-off-by: Binbin Deng <18983559317@163.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
5 daysBluetooth: hci_sync: Fix invalid Supervision_Timeout in LE Set Default RateLuiz Augusto von Dentz
The LE Set Default Rate Parameters command is rejected with Invalid HCI Command Parameters (0x12) because the Supervision_Timeout of 120 ms is exactly the minimum recommended by HOGP v1.2: Greater than or equal to (1 + Peripheral Latency) x Subrate max x Connection Interval max x 2 But the Core spec treats the equality as invalid: BLUETOOTH CORE SPECIFICATION Version 6.3 | Vol 4, Part E 7.8.158. LE Set Default Rate Parameters command If Connection_Interval_Max x Subrate_Max x (Max_Latency + 1) is greater than or equal to Supervision_Timeout x 40, the Controller shall return the error code Invalid HCI Command Parameters (0x12). With the current values 0x78 x 4 x 1 = 480 >= 0x0c x 40 = 480. Fix this by using 2 s as the default Supervision_Timeout, which is 10x lower than the 20 s used for non-SCI connections while still well above the minimum required, and make sure it remains above the minimum in case interval_max is raised to match the controller's minimum supported connection interval. Fixes: 2f8784cfe8a9 ("Bluetooth: Add support for Shorter Connection Interval (SCI) feature") Assisted-by: OpenCode:claude-opus-5.5 Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-22Merge tag 'net-next-7.4' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next Pull networking updates from Paolo Abeni: "This includes a significant number of low-priority fixes - especially in the NIC drivers area - that we deferred from the last few RCs in the previous cycle, which can't be easily outlined in the synopsis below. Core & protocols: - Continue the work on removing rtnl_lock dependencies: - per-netns ARP and ND neighbour tables, with the default settings now configurable per netns (inheritance from init_net is controlled by the new net.core.neigh_inherit_init_net sysctl) - RCU-protected configuration and rtnl_lock-less fill_info() for hsr, netkit, sit, vlan and vxlan devices - per-netns device unregistration for ip tunnel and gre devices - use the netdev instance lock instead of rtnl_lock when reading speed and duplex via sysfs - batch the flushing of uncached routes at device unregistration time, relieving rtnl_lock contention on netns dismantle. - Add hardware pacing offload support, admin-controlled via a new rtnetlink attribute, with sch_fq integration (implemented in idpf). - Re-segment BIG TCP GSO packets into GSO packets fitting the egress device limits instead of plain MSS-sized segments, improving throughput for mixed BIG TCP / non-BIG TCP paths by up to 70%. - Generate RSS keys that spread flows over all the RX queues; the previous random keys could leave some queues unused. - Optimize the bridge VLAN forwarding paths: cache the port-VLAN in fdb entries and consider only VLAN members when flooding, for ~10% more Mpps in the fdb forwarding path. - A few TCP/IP performance improvements aimed at efficient cache usage and reducing contention. - Add the TCP ROCCET congestion control, a CUBIC variant aimed at avoiding bufferbloat in cellular networks. - Continue the conversion of getsockopt callbacks to sockopt_t. - Add an ethtool command to list the front-facing ports of an interface, including SFP cages and modules, using the phy_port representation. - Enable BIG TCP support for bareudp tunnels. - Remove the IPV6_ADDRFORM socket option and disallow buggy TCP state transitions (listen() + shutdown() + connect() and connect() + connect(AF_UNSPEC) + listen()). - Remove most BUG_ON()s from core packet processing, replacing them with error paths. Wireless: - Latency improvements, including lockless station get/dump and beacon updates, plus RTNL reduction and locking cleanups. - Infrastructure for non-station TX/RX with MLO. - NAN (Wi-Fi Aware) Instant Communication support and other NAN improvements. - Control frame Integrity Protocol (CIP) and protected TWT support. - Improvements for AP regulatory checks. Netfilter: - Disable br_netfilter in user namespaces and schedule it for removal in 2027. - Restrict the raw table in nft_compat to the specific family, hook and priority. - Prepare the flowtable for mixed IPv4-over-IPv6 tunneling (and vice versa). - Use GFP_KERNEL_ACCOUNT for most netfilter allocations, for better integration with memcg. - Allow discovering conntrack zone filtering support in ctnetlink dumps, and fix nfnetlink_hook handling of large dumps. Deletions: - Move the LLC type 2 sockets out of tree. There are no known users and the code attracts a never-ending stream of LLM-driven fixes. Device drivers: - New drivers: - Meta Platforms NIC (mpnic), the second-generation NIC from Meta - initial skeleton of the Nebula-matrix NICs driver (nbl) - X-Powers AC200/AC300 Fast Ethernet PHYs - Ethernet high-speed NICs: - Intel: - i40e: XDP metadata support for RX hash and VLAN tag - ice: expose the E825 TSPLL state via the DPLL subsystem - nVidia/Mellanox: - move the data direct infrastructure from IB to core, in preparation for netdev support. - reduce the memory used per offloaded TC rule - Meta (fbnic): - support large io_uring zero-copy RX buffers - Microsoft vNIC (mana): - add BQL support - Ethernet NICs consumer, and embedded: - Airoha: - LRO offload support - Cadence (macb): - context swapping for ringparam and MTU changes, avoiding buffer loss under memory pressure - Mucse (rnpgbe): - TX/RX and link status support - NXP (enetc): - SR-IOV improvements and VF support for ENETC v4 - Qualcomm (ppe): - IPQ5424 support - Realtek PCI (r8169): - phylink support - RSS support for RTL8127 - Renesas (ravb): - gPTP support for R-Car Gen4 - Synopsys (stmmac): - XDP multi-buffer support on the TX side - tc mqprio hw queue priority offload - support for RK3568 SGMII, Allwinner H616 EMAC1, UltraRISC DP1000 and Qualcomm sa8255p - Ethernet switches: - Mediatek (mt7530): - fast age and change conduit support - Microchip (ksz): - support for KSZ8995XA/KS8995XA - Microchip (lan966x): - PCIe FDMA support, ~20x throughput increase in PCIe endpoint - Microchip (sparx5): - Time Aware Shaper (taprio) offload - Motorcomm (yt921x): - LED and SerDes PCS support - Realtek (rtl8365mb): - EEE support - Ethernet PHYs: - Broadcom: - enable jumbo frames on BCM54xx - Realtek: - support for RTL8261CE_CG and RTL8261D_VM - MDIO support for RTL838x and RTL839x - WiFi drivers: - Broadcom (brcmfmac): - FT/OKC roaming offload - Intel (iwlwifi): - UHR sniffer support - support for newer UEFI/BIOS tables - MediaTek (mt76): - mt7925 NAN improvements - offchannel/scan improvements and MLO fixes - Morse Micro (mm81x): - monitor mode support - Qualcomm (ath12k): - IPQ5332 platform infrastructure - Realtek (rtw88): - RTL8723BS support - SDIO TX performance improvements - Realtek (rtw89): - P2P_DEVICE support - BT-coex updates for RTL8922D - Bluetooth: - move H:4 reassembly into the Bluetooth core - add generic support for vendor packets - MGMT: add security level changed event - Bluetooth drivers: - btusb: support Bulk Serialization Mode - Intel: support Draco and Titan Lake, allow unsigned firmware - Mediatek: MT7928 support - Qualcomm: QCC2072 support - Broadcom: Synaptics 4384 support" * tag 'net-next-7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (2126 commits) Bluetooth: btusb: disable by default Qualcomm multi-subsystem tipc: fix broadcast sender hang on last acker departure tipc: fix use-after-free of broadcast reception link at node release r8169: clear TX LPI on RTL8168h at link up after phylink conversion tun: Require CAP_NET_ADMIN to attach to an ownerless device net/sched/sch_cake: drop dead nla_nest_end() error check net/sched/sch_cake: widen buffer_used to u64 net/sched/sch_cake: reduce parent backlog when clearing a tin net/sched/sch_cake: serialize reconfiguration with the datapath tg3: Add Datto SIRIS 5 1U Server to restart AER quirk table net/mlx5e: Stop asserting for RTNL when closing channels net: shrink the payload-only part of skb dataref to one bit net: wwan: iosm: validate msg_head before indexing msg_ring net: bgmac: rate limit RX error messages selftests: net: veth: test XDP_TX to a peer with GRO enabled veth: schedule the peer's NAPI after XDP_TX when only GRO is enabled pppoe: delete session hash entries by pointer match net: lan969x: don't disable hardirqs in fdma tx clear net: sparx5/lan969x: do not clobber the PSFP cycle timer update period net: lan969x: fix DSM calendar for empty taxis ...
2026-10-20net: rename skb_unshare() to skb_unclone_full()Nicolai Buchwitz
skb_unshare() only copies cloned skbs. A shared skb that is not a clone comes back unchanged, which the name doesn't suggest. The loopback selftest hooks got caught by this and hit BUG_ON(skb_shared()). Rename it to skb_unclone_full(). Like skb_unclone() it only acts on clones, but it copies the whole skb, not just the head. Suggested-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de> Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com> # dpaa2 Link: https://patch.msgid.link/20261015-nb-skb-unclone-full-v1-1-0dfbf01f60f2@tipi-net.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-14Bluetooth: hci_sync: scan unfiltered for host-resolved RPAsKyle Pepper
Restore unfiltered scanning for pending IRK peers when the controller cannot resolve private addresses. Keep accept-list filtering while suspended and when forced by periodic advertising synchronization. Fixes: e209e5ccc5ac ("Bluetooth: MGMT: Mark LL Privacy as stable") Assisted-by: OpenCode:gpt-6.1-sol Signed-off-by: Kyle Pepper <cochcoder@proton.me> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: Fix the LE Read Connection Interval response layoutLuiz Augusto von Dentz
The response to HCI_OP_LE_READ_CONN_INTERVAL carries a Minimum_Supported_Connection_Interval octet between the status and Num_Groups, which was missing from the structure. Without it the minimum interval was read as the number of groups, and every group after it from one octet off. Take the minimum interval used to clamp the default rate parameters from that field rather than the smallest group minimum, as the number of groups can be zero, which left it unset. Fixes: 2f8784cfe8a9 ("Bluetooth: Add support for Shorter Connection Interval (SCI) feature") Assisted-by: OpenCode:claude-opus-5.5 Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: L2CAP: Remove dead configuration state codeSiwei Zhang
CONF_EWS_RECV has not been set since commit e7b02296fb40 ("Bluetooth: Remove BT_HS"), which made configuration requests with an EWS option be refused. Remove the flag and the branch in l2cap_parse_conf_req() that tests it. A pending connection response no longer needs to set CONF_CONNECT_PEND, as connection responses are only accepted while it is already set. No functional change. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Siwei Zhang <oss@fourdim.xyz> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: L2CAP: Only accept connection responses to outstanding requestsSiwei Zhang
An outgoing channel waits in BT_CONNECT until security and the feature mask exchange complete, and only then sends its connection request. A peer can answer it before that with a connection response matching our source CID. The channel then moves to BT_CONFIG, completes configuration and becomes connected before security has completed. If security then fails, l2cap_security_cfm() leaves the connected channel alone, so it stays up on a link that did not reach the required security level. A connection response with a zero source CID is matched by identifier. Another channel can hold the same identifier for a response it still has to send, so the lookup can pick the wrong channel. Only accept a connection response while our request is outstanding, and only look at such channels when matching by identifier. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Siwei Zhang <oss@fourdim.xyz> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: L2CAP: Use default TxWindow for zero socket optionSiwei Zhang
L2CAP_OPTIONS accepts a txwin_size of zero and stores it in tx_win. The zero is then sent to the peer in our configuration request, and if the channel ends up in ERTM mode it is passed to l2cap_seq_list_init(). Use the default TxWindow instead, as the mode can still be changed to ERTM during configuration. Fixes: 14b5aa71ec50 ("Bluetooth: Add sockopt configuration for txWindow on L2CAP") Cc: stable@vger.kernel.org Signed-off-by: Siwei Zhang <oss@fourdim.xyz> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: L2CAP: Reject invalid TxWindow in configuration requestsSiwei Zhang
A peer can send an ERTM RFC option with a TxWindow of zero, which is out of spec. It is stored in remote_tx_win unchanged and later passed to l2cap_seq_list_init(), where roundup_pow_of_two(0) is undefined. On some architectures this results in a ZERO_SIZE_PTR list and a remote kernel oops. A TxWindow above 63 is out of spec as well. With 6-bit sequence numbers we would then send more unacknowledged frames than the sequence space can tell apart. Reply with L2CAP_CONF_UNACCEPT and propose the default TxWindow instead of accepting the value, so remote_tx_win always stays within 1 to 63. Keep the parameters of an earlier request then, and do not treat the request as done because an earlier one was. Also refuse a zero size in l2cap_seq_list_init(), so any other path that reaches it with a zero TxWindow fails the channel instead of the kernel. Fixes: f2fcfcd67025 ("Bluetooth: Add configuration support for ERTM and Streaming mode") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Siwei Zhang <oss@fourdim.xyz> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: L2CAP: Reject signalling responses in invalid statesSiwei Zhang
A peer can send configuration messages while an incoming channel is in BT_CONNECT2, before the security or deferred accept gate has completed. A configuration response can then promote the channel to BT_CONNECTED. Configuration responses can also act on channels that are closing, and a late connection response can move a disconnecting channel back to BT_CONFIG. Accept connection responses only while waiting in BT_CONNECT. Answer configuration requests in BT_CONNECT2, but defer our own request until BT_CONFIG so configuration cannot complete before the gate. Ignore configuration responses outside BT_CONFIG and BT_CONNECTED, and only complete configuration in BT_CONFIG. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Siwei Zhang <oss@fourdim.xyz> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: L2CAP: Reject mode changes on connected channelsSiwei Zhang
A peer can send a configuration response with an RFC option for another mode to a connected channel, for example to switch it from Streaming to ERTM mode. l2cap_parse_conf_rsp() then changes chan->mode, but l2cap_ertm_init() is not called again, so the ERTM sequence lists are never allocated. The next out-of-sequence I-frame makes l2cap_seq_list_clear() write through the NULL srej_list.list. Refuse the channel when a response tries to change the mode of a connected channel. Fixes: f2fcfcd67025 ("Bluetooth: Add configuration support for ERTM and Streaming mode") Cc: stable@vger.kernel.org Closes: https://sashiko.dev/#/patchset/20261007144717.3832330-1-oss%40fourdim.xyz Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Siwei Zhang <oss@fourdim.xyz> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: hci_event: Fix LE link drop on remote features command statusKevin Dewald
When the local controller supports peripheral-initiated features exchange, the LE Read Remote Features procedure also runs for incoming connections, and it fails with Unsupported Remote Feature (0x1a) if the central does not support that feature. hci_le_remote_feat_complete_evt() and hci_le_read_all_remote_features_evt() handle this and let the connection transition into connected state. A controller can also return that error in the Command Status event instead. An Intel controller does so for a central that does not support peripheral-initiated features exchange, presumably because it already has the features of the central. hci_cs_le_read_remote_features() and hci_cs_le_read_all_remote_features() then confirm the connection as failed while it is still in BT_CONFIG, and the hci_conn_drop() in le_read_features_complete() disconnects it right away: > HCI Event: LE Meta Event (0x3e) plen 31 LE Enhanced Connection Complete (0x0a) Status: Success (0x00) Role: Peripheral (0x01) < HCI Command: LE Read Remote Used Features (0x08|0x0016) plen 2 > HCI Event: Command Status (0x0f) plen 4 LE Read Remote Used Features (0x08|0x0016) ncmd 1 Status: Unsupported Remote Feature / Unsupported LMP Feature (0x1a) < HCI Command: Disconnect (0x01|0x0006) plen 3 Reason: Remote User Terminated Connection (0x13) Data the central sends afterwards is reported as: Bluetooth: hci0: ACL packet for unknown connection handle 3585 Handle Unsupported Remote Feature in the command status the same way as in the complete events. Fixes: 0fe29fd1cd77 ("Bluetooth: Read LE remote features during connection establishment") Fixes: a106e50be74b ("Bluetooth: HCI: Add support for LL Extended Feature Set") Assisted-by: Claude:claude-opus-5.5 Signed-off-by: Kevin Dewald <kevin@simpleble.org> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: MSFT: Serialize handle map cleanup with event processingCen Zhang
MSFT monitor handle mappings must remain valid while vendor events look up and use them under hdev->lock. msft_do_close() removes and frees the mappings without that lock. hci_dev_close_sync() clears HCI_UP and drains the RX workqueue before MSFT cleanup. However, a transport callback that already passed hci_recv_frame()'s state check can queue a vendor event after the drain returns, if no earlier shutdown callback has quiesced reception. The driver close callback runs after MSFT cleanup, so event processing can overlap the unlocked removal. msft_monitor_device_evt() can then traverse freed list entries or read handle_data->mgmt_handle after it is freed. Take hdev->lock while resetting monitor states and removing handle mappings in msft_do_close(), as normal monitor cancellation already does. An active event reader then finishes before its mapping is freed, and later lookups see an empty handle map. An instrumented kernel produced this KASAN report (timestamps removed and unrelated frames omitted): BUG: KASAN: slab-use-after-free in msft_vendor_evt+0x1906/0x1990 Read of size 2 at addr ffff888104df3602 by task kworker/u17:2/502 Workqueue: hci0 hci_rx_work Call Trace: [...] msft_vendor_evt+0x1906/0x1990 hci_vendor_evt+0x6f/0x90 hci_event_packet+0x894/0xc70 [...] hci_rx_work+0x3f8/0xfa0 [...] Allocated by task 499: [...] msft_add_monitor_sync+0x6a8/0x10a0 msft_add_monitor_pattern+0x7f/0xb0 hci_add_adv_monitor+0x1fa/0x2e0 [...] Freed by task 499: [...] kfree+0x307/0x580 msft_do_close+0x238/0x750 hci_dev_close_sync+0x546/0x1380 [...] The buggy address belongs to the object at ffff888104df3600 which belongs to the cache kmalloc-32 of size 32 The buggy address is located 2 bytes inside of freed 32-byte region [ffff888104df3600, ffff888104df3620) [...] Fixes: 145373cb1b1f ("Bluetooth: Add framework for Microsoft vendor extension") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: MGMT: Allow connection rate request as peripheralLuiz Augusto von Dentz
Load Connection Subrate only issues the LE Connection Rate Request when connected as central, but either role can initiate the Connection Rate Update procedure, e.g. a HID device, which is the peripheral, does it once the HID host requests a HID SCI mode with the HID Control Point. Issue it regardless of the role. Fixes: 19129d7037be ("Bluetooth: Add MGMT Load Connection Subrate command") Assisted-by: OpenCode:claude-opus-5.5 Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: selftest: Pin module for selftest debugfs file operationsBui Viet Dung
An open debugfs file retains its file_operations pointer in the debugfs proxy state. However, test_smp_fops in net/bluetooth/smp.c and test_ecdh_fops in net/bluetooth/selftest.c have no .owner set to THIS_MODULE. As a result, full_proxy_open_regular() calls fops_get() which succeeds without taking a reference to the bluetooth module. When CONFIG_BT=m and selftests are enabled, a userspace process can open either /sys/kernel/debug/bluetooth/selftest_smp or /sys/kernel/debug/bluetooth/selftest_ecdh and keep the file descriptor open while the module is unloaded (rmmod bluetooth). When the userspace process subsequently closes the descriptor, full_proxy_release() accesses the already unmapped file_operations structure, triggering a kernel oops in full_proxy_release(): BUG: unable to handle page fault for address: fffffbfff8056f03 #PF: supervisor read access in kernel mode Oops: 0000 [#1] SMP KASAN NOPTI RIP: 0010:full_proxy_release+0x8e/0x140 Call Trace: <TASK> __fput+0x39f/0xa60 fput_close_sync+0xff/0x200 __x64_sys_close+0x8c/0xf0 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f </TASK> The issue was discovered via manual code audit of net/bluetooth/smp.c and net/bluetooth/selftest.c. Set .owner = THIS_MODULE on test_smp_fops and test_ecdh_fops so that debugfs keeps the module pinned until the file descriptors are closed. Fixes: 64dd374eac15 ("Bluetooth: Export SMP selftest result in debugfs") Fixes: 6de50f9fdb60 ("Bluetooth: Export ECDH selftest result in debugfs") Cc: stable@vger.kernel.org Signed-off-by: Bui Viet Dung <dungvn2345@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: L2CAP: Hold the listener while notifying child teardownCen Zhang
A pending child's listener must remain alive until the child's teardown callback finishes notifying it. l2cap_sock_teardown_cb() saves the raw bt_sk(sk)->parent pointer, calls bt_accept_unlink(), then invokes parent->sk_data_ready(). The accept queue holds a reference to the child, but the callback takes no reference to the listener across unlink. When an incoming child has not been accepted, HCI disconnection can reach l2cap_conn_del() and the child's teardown callback while another task closes the listener. The listener channel has no connection, so the child's connection and channel locks do not serialize listener release. The following ordering is possible: HCI child teardown Listener release lock the child socket save parent bt_accept_unlink(sk) drain the empty accept queue bt_sock_unlink() shut down the listener channel sock_orphan() l2cap_sock_kill() parent->sk_data_ready(parent) If no other reference delays freeing the listener, the final notification reads sk_data_ready through freed socket storage. The child lock cannot stop listener release once the child is no longer on the accept queue. Take a listener socket reference before unlinking the child and release it after sk_data_ready() returns. While the child remains queued, its socket lock prevents listener cleanup from completing the dequeue, so the listener is still alive when the reference is acquired. The reference then protects the notification after unlink without changing lock order or the ordering of queue removal and wakeup. KASAN report as below: ================================================================== BUG: KASAN: slab-use-after-free in l2cap_sock_teardown_cb+0x467/0x490 Read of size 8 at addr ffff88810b99b188 by task kworker/u17:3/516 Workqueue: hci1 hci_rx_work Call Trace: <TASK> dump_stack_lvl+0x93/0xd0 print_report+0xce/0x630 ? l2cap_sock_teardown_cb+0x467/0x490 ? srso_alias_return_thunk+0x5/0xfbef5 ? __virt_addr_valid+0x20d/0x410 ? l2cap_sock_teardown_cb+0x467/0x490 kasan_report+0xe0/0x110 ? l2cap_sock_teardown_cb+0x467/0x490 l2cap_sock_teardown_cb+0x467/0x490 l2cap_chan_del+0x123/0x8f0 l2cap_conn_del+0x31b/0x740 ? hci_cmd_sync_submit+0x264/0x320 ? __pfx_l2cap_disconn_cfm+0x10/0x10 l2cap_disconn_cfm+0x87/0xd0 hci_disconn_complete_evt+0x30f/0x990 ? srso_alias_return_thunk+0x5/0xfbef5 hci_event_packet+0x894/0xc70 ? __pfx_hci_disconn_complete_evt+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_hci_event_packet+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? free_zapped_rcu+0xd0/0x1e0 ? srso_alias_return_thunk+0x5/0xfbef5 ? lockdep_hardirqs_on_prepare+0xea/0x1a0 ? __pfx_hci_cmd_sync_complete+0x10/0x10 ? trace_hardirqs_on+0x18/0x160 ? srso_alias_return_thunk+0x5/0xfbef5 hci_rx_work+0x367/0xf00 ? srso_alias_return_thunk+0x5/0xfbef5 process_one_work+0x908/0x19c0 ? __pfx_process_one_work+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_is_held_type+0x8f/0x100 ? srso_alias_return_thunk+0x5/0xfbef5 worker_thread+0x65c/0xe40 ? __pfx_worker_thread+0x10/0x10 kthread+0x34f/0x460 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x659/0x940 ? __pfx_ret_from_fork+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? __switch_to+0x74f/0xf80 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK> Allocated by task 502: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 __kasan_kmalloc+0xaa/0xb0 __kmalloc_noprof+0x2d7/0x770 sk_prot_alloc+0x13e/0x260 sk_alloc+0x37/0xb40 bt_sock_alloc+0x40/0x3b0 l2cap_sock_create+0x116/0x310 bt_sock_create+0x171/0x330 __sock_create+0x2c4/0x730 __sys_socket+0x141/0x210 __x64_sys_socket+0x77/0xc0 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 502: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x5f/0x80 kfree+0x307/0x580 __sk_destruct+0x64f/0x790 sk_destruct+0xb3/0xd0 __sk_free+0xdd/0x370 sk_free+0x51/0x80 l2cap_sock_kill+0x17a/0x2a0 l2cap_sock_release+0x1d0/0x310 __sock_release+0xb8/0x270 sock_close+0x21/0x30 __fput+0x39f/0xa60 fput_close_sync+0xff/0x200 __x64_sys_close+0x8c/0xf0 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f The buggy address belongs to the object at ffff88810b99b000 which belongs to the cache kmalloc-2k of size 2048 The buggy address is located 392 bytes inside of freed 2048-byte region [ffff88810b99b000, ffff88810b99b800) The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10b998 head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 flags: 0x200000000000040(head|node=0|zone=2) page_type: f5(slab) raw: 0200000000000040 ffff888100042f00 dead000000000100 dead000000000122 raw: 0000000000000000 0000000000080008 00000000f5000000 0000000000000000 head: 0200000000000040 ffff888100042f00 dead000000000100 dead000000000122 head: 0000000000000000 0000000000080008 00000000f5000000 0000000000000000 head: 0200000000000003 fffffffffffffe01 00000000ffffffff 00000000ffffffff head: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff88810b99b080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff88810b99b100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb >ffff88810b99b180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ^ ffff88810b99b200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff88810b99b280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ================================================================== Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: hci_sync: Protect IRK identity reads with RCUCen Zhang
hci_le_set_privacy_mode_sync() needs the IRK returned by hci_find_irk_by_addr() to remain allocated until its identity address and type have been copied into the command. The finder drops its RCU read lock before returning this borrowed pointer, leaving the later field reads unprotected. When a privacy-capable controller has a pending peer with address resolution and device privacy enabled, accept-list programming can reach this helper while management reloads the IRKs. The request worker holds hdev->req_lock, whereas load_irks() takes hdev->lock, allowing the following ordering: Request worker Management / RCU reclaim hci_le_set_privacy_mode_sync() hci_find_irk_by_addr() rcu_read_lock() find matching IRK rcu_read_unlock() return borrowed IRK load_irks() hci_dev_lock(hdev) hci_smp_irks_clear() list_del_rcu() kfree_rcu() hci_dev_unlock(hdev) RCU grace period and IRK free read irk->addr_type copy irk->bdaddr The request then accesses a freed IRK. KASAN reports a one-byte use-after-free read of addr_type on this path. Keep an outer RCU read-side critical section across the lookup and both identity-field copies. The finder's nested unlock then leaves the IRK protected until the caller finishes copying it. Release RCU on a lookup miss and after copying the fields, before the synchronous HCI command can sleep. KASAN report as below: ================================================================== BUG: KASAN: slab-use-after-free in hci_le_add_accept_list_sync+0x90f/0x940 Read of size 1 at addr ffff88810aa6072c by task kworker/u17:0/493 Workqueue: hci0 hci_cmd_sync_work Call Trace: <TASK> dump_stack_lvl+0x93/0xd0 print_report+0xce/0x630 ? hci_le_add_accept_list_sync+0x90f/0x940 ? srso_alias_return_thunk+0x5/0xfbef5 ? __virt_addr_valid+0x20d/0x410 ? hci_le_add_accept_list_sync+0x90f/0x940 kasan_report+0xe0/0x110 ? hci_le_add_accept_list_sync+0x90f/0x940 hci_le_add_accept_list_sync+0x90f/0x940 ? __pfx_hci_le_add_accept_list_sync+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? conn_params_copy+0x3a0/0x650 hci_passive_scan_sync+0x8c9/0x1e80 ? __pfx_hci_passive_scan_sync+0x10/0x10 ? find_held_lock+0x2b/0x80 ? hci_lookup_le_connect+0x181/0x3c0 ? srso_alias_return_thunk+0x5/0xfbef5 ? find_held_lock+0x2b/0x80 ? hci_update_passive_scan_sync+0x437/0x950 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_release+0xc8/0x280 hci_update_passive_scan_sync+0x461/0x950 hci_cmd_sync_work+0x1b3/0x450 ? srso_alias_return_thunk+0x5/0xfbef5 process_one_work+0x908/0x19c0 ? __pfx_process_one_work+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_is_held_type+0x8f/0x100 ? srso_alias_return_thunk+0x5/0xfbef5 worker_thread+0x65c/0xe40 ? __pfx_worker_thread+0x10/0x10 kthread+0x34f/0x460 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x659/0x940 ? __pfx_ret_from_fork+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? __switch_to+0x74f/0xf80 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK> Allocated by task 507: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 __kasan_kmalloc+0xaa/0xb0 __kmalloc_cache_noprof+0x251/0x610 hci_add_irk+0xb6/0x220 load_irks+0x5ef/0x7e0 hci_sock_sendmsg+0x128b/0x22e0 __sys_sendto+0x425/0x470 __x64_sys_sendto+0xe5/0x1c0 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 0: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x5f/0x80 __rcu_free_sheaf_prepare+0x65/0x2a0 rcu_free_sheaf+0x1f/0xe0 rcu_core+0x661/0x1d10 handle_softirqs+0x201/0x930 __irq_exit_rcu+0x110/0x1e0 irq_exit_rcu+0xe/0x20 sysvec_apic_timer_interrupt+0x6c/0x80 asm_sysvec_apic_timer_interrupt+0x1a/0x20 The buggy address belongs to the object at ffff88810aa60700 which belongs to the cache kmalloc-64 of size 64 The buggy address is located 44 bytes inside of freed 64-byte region [ffff88810aa60700, ffff88810aa60740) The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10aa60 flags: 0x200000000000000(node=0|zone=2) page_type: f5(slab) raw: 0200000000000000 ffff8881000428c0 dead000000000100 dead000000000122 raw: 0000000000000000 0000000000200020 00000000f5000000 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff88810aa60600: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ffff88810aa60680: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc >ffff88810aa60700: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ^ ffff88810aa60780: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ffff88810aa60800: fa fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc ================================================================== Disabling lock debugging due to kernel taint Fixes: adae20cb2d20 ("Bluetooth: Convert IRK list to RCU") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: hci_debugfs: Pin module for debugfs file operationsBui Viet Dung
An open debugfs file retains its file_operations pointer in the debugfs proxy state. However, the file_operations defined in hci_debugfs.c (use_debug_keys_fops, sc_only_mode_fops, ssp_debug_mode_fops, force_bredr_smp_fops, force_static_address_fops, force_no_mitm_fops, dut_mode_fops, vendor_diag_fops, and the DEFINE_QUIRK_ATTRIBUTE macro) have no .owner set to THIS_MODULE. As a result, full_proxy_open_regular() calls fops_get() which succeeds without taking a reference to the bluetooth module. When a userspace process opens any of these debugfs files, a subsequent controller removal and module unload (rmmod bluetooth) can succeed while the file descriptor remains open. When the userspace process subsequently closes the descriptor, full_proxy_release() accesses the already unmapped file_operations structure, triggering a kernel oops in full_proxy_release(): BUG: unable to handle page fault for address: fffffbfff8056f03 #PF: supervisor read access in kernel mode Oops: 0000 [#1] SMP KASAN NOPTI RIP: 0010:full_proxy_release+0x8e/0x140 Call Trace: <TASK> __fput+0x39f/0xa60 fput_close_sync+0xff/0x200 __x64_sys_close+0x8c/0xf0 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f </TASK> The issue was discovered via manual code audit of net/bluetooth/hci_debugfs.c and verified on a Linux 7.3-rc6 test VM with CONFIG_BT=m. Set .owner = THIS_MODULE on all debugfs file_operations tables in hci_debugfs.c so that debugfs keeps the module loaded until close has finished. Fixes: 0886aea6acd2 ("Bluetooth: Expose debug keys usage setting via debugfs") Cc: stable@vger.kernel.org Signed-off-by: Bui Viet Dung <dungvn2345@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: 6lowpan: Pin module for 6lowpan_control debugfs fileBui Viet Dung
An open debugfs file retains lowpan_control_fops in the debugfs proxy state. However, lowpan_control_fops has no .owner set to THIS_MODULE. As a result, full_proxy_open_regular() calls fops_get() which succeeds without taking a reference to the bluetooth_6lowpan module. With CONFIG_BT_6LOWPAN=m, a userspace process can keep the debugfs file descriptor for 6lowpan_control open across module unload (delete_module / rmmod bluetooth_6lowpan). When the process subsequently closes the file descriptor, full_proxy_release() accesses the already freed and unmapped lowpan_control_fops table, causing a kernel page fault or oops. The issue was discovered via manual code audit of net/bluetooth/6lowpan.c. Set .owner = THIS_MODULE on lowpan_control_fops so that debugfs pins the module until all open file descriptors have finished. Fixes: 6b8d4a6a0314 ("Bluetooth: 6LoWPAN: Use connected oriented channel instead of fixed one") Cc: stable@vger.kernel.org Signed-off-by: Bui Viet Dung <dungvn2345@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: 6lowpan: Drain RCU readers on registration failureCen Zhang
A lowpan_btle_dev is embedded in its net_device allocation and must remain alive until readers of bt_6lowpan_devices have left their RCU sections. setup_netdev() publishes it before registration, but its error path only unlinks it before calling free_netdev(). If a second controller's registration fails while multicast is sent on an existing 6LoWPAN interface, send_mcast_pkt() can already have selected the new entry. It reads entry->netdev before checking which interface owns it. An early failure, such as allocating the device's name node, leaves NETREG_UNINITIALIZED, so free_netdev() releases the storage immediately. The following ordering frees the selected entry before the reader loads its netdev field: Adapter creation (controller B) Multicast on controller A setup_netdev() list_add_rcu() rcu_read_lock() select B's entry lowpan_register_netdev() fails list_del_rcu() free_netdev() read entry->netdev rcu_read_unlock() Removing the list node does not wait for that reader, and devices_lock does not serialize the multicast reader. The subsequent field load is a use-after-free, reported by KASAN in bt_xmit(). Wait for an RCU grace period after dropping devices_lock and before free_netdev(). This keeps the failed adapter allocated until traversals that could have selected it complete. The callback is already sleepable, and the wait happens outside the list spinlock. KASAN report as below: ================================================================== BUG: KASAN: slab-use-after-free in bt_xmit+0x1d06/0x21e0 Read of size 8 at addr ffff88810ef45030 by task python3/556 Call Trace: <TASK> dump_stack_lvl+0x93/0xd0 print_report+0xce/0x630 ? bt_xmit+0x1d06/0x21e0 ? srso_alias_return_thunk+0x5/0xfbef5 ? __virt_addr_valid+0x20d/0x410 ? bt_xmit+0x1d06/0x21e0 kasan_report+0xe0/0x110 ? bt_xmit+0x1d06/0x21e0 bt_xmit+0x1d06/0x21e0 ? __pfx_bt_xmit+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_acquire+0x17b/0x2f0 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_is_held_type+0x8f/0x100 ? dev_hard_start_xmit+0x187/0x660 ? __pfx_bt_xmit+0x10/0x10 dev_hard_start_xmit+0x187/0x660 sch_direct_xmit+0x153/0x850 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_sch_direct_xmit+0x10/0x10 ? do_raw_spin_lock+0x130/0x270 ? __pfx_do_raw_spin_lock+0x10/0x10 ? lock_is_held_type+0x8f/0x100 __dev_queue_xmit+0x3111/0x3aa0 ? srso_alias_return_thunk+0x5/0xfbef5 ? look_up_lock_class+0x59/0x130 ? register_lock_class+0x41/0x790 ? __pfx___dev_queue_xmit+0x10/0x10 ? __lock_acquire+0x466/0x2260 ? find_held_lock+0x2b/0x80 ? ___neigh_create+0x1690/0x2540 ? __local_bh_enable_ip+0xa6/0x120 ? srso_alias_return_thunk+0x5/0xfbef5 ? lockdep_hardirqs_on_prepare+0xea/0x1a0 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_acquire+0x17b/0x2f0 ? srso_alias_return_thunk+0x5/0xfbef5 ? find_held_lock+0x2b/0x80 ? ip6_finish_output2+0x8be/0x1840 ? srso_alias_return_thunk+0x5/0xfbef5 ? neigh_connected_output+0x39f/0x4e0 ? srso_alias_return_thunk+0x5/0xfbef5 neigh_connected_output+0x33f/0x4e0 ip6_finish_output2+0x8be/0x1840 ip6_finish_output+0x424/0xd50 ip6_output+0x210/0x640 ? __pfx_ip6_mr_output+0x10/0x10 ip6_local_out+0x193/0x1c0 ip6_send_skb+0xfb/0x3e0 udp_v6_send_skb+0x6e1/0x1180 udpv6_sendmsg+0x1f9b/0x2a00 ? get_random_u32+0xaf/0x640 ? __pfx_udpv6_sendmsg+0x10/0x10 ? lock_release+0xc8/0x280 ? srso_alias_return_thunk+0x5/0xfbef5 ? lockdep_hardirqs_on_prepare+0xea/0x1a0 ? srso_alias_return_thunk+0x5/0xfbef5 ? trace_hardirqs_on+0x18/0x160 ? srso_alias_return_thunk+0x5/0xfbef5 ? __local_bh_enable_ip+0xa6/0x120 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_udpv6_sendmsg+0x10/0x10 ? inet6_sendmsg+0xff/0x140 inet6_sendmsg+0xff/0x140 __sys_sendto+0x320/0x470 ? __pfx___sys_sendto+0x10/0x10 ? exc_page_fault+0x5c/0xc0 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_release+0xc8/0x280 ? handle_mm_fault+0x12e/0x580 __x64_sys_sendto+0xe5/0x1c0 ? lockdep_hardirqs_on_prepare+0xea/0x1a0 ? srso_alias_return_thunk+0x5/0xfbef5 ? trace_hardirqs_on+0x18/0x160 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f Allocated by task 502: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 __kasan_kmalloc+0xaa/0xb0 __kvmalloc_node_noprof+0x353/0x930 alloc_netdev_mqs+0xa0/0x1250 chan_ready_cb+0x198/0x1110 l2cap_recv_frame+0x6dc0/0x8830 l2cap_recv_acldata+0xe9f/0x10e0 hci_rx_work+0x5a6/0xf00 process_one_work+0x908/0x19c0 worker_thread+0x65c/0xe40 kthread+0x34f/0x460 ret_from_fork+0x659/0x940 ret_from_fork_asm+0x1a/0x30 Freed by task 502: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x5f/0x80 kfree+0x307/0x580 free_netdev+0x6ca/0x8f0 chan_ready_cb+0xd91/0x1110 l2cap_recv_frame+0x6dc0/0x8830 l2cap_recv_acldata+0xe9f/0x10e0 hci_rx_work+0x5a6/0xf00 process_one_work+0x908/0x19c0 worker_thread+0x65c/0xe40 kthread+0x34f/0x460 ret_from_fork+0x659/0x940 ret_from_fork_asm+0x1a/0x30 The buggy address belongs to the object at ffff88810ef44000 which belongs to the cache kmalloc-8k of size 8192 The buggy address is located 4144 bytes inside of freed 8192-byte region [ffff88810ef44000, ffff88810ef46000) The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10ef40 head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 flags: 0x200000000000040(head|node=0|zone=2) page_type: f5(slab) raw: 0200000000000040 ffff888100043180 dead000000000100 dead000000000122 raw: 0000000000000000 0000000000020002 00000000f5000000 0000000000000000 head: 0200000000000040 ffff888100043180 dead000000000100 dead000000000122 head: 0000000000000000 0000000000020002 00000000f5000000 0000000000000000 head: 0200000000000003 fffffffffffffe01 00000000ffffffff 00000000ffffffff head: ffff88810ef41a80 0000000000000000 00000000ffffffff 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff88810ef44f00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff88810ef44f80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb >ffff88810ef45000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ^ ffff88810ef45080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff88810ef45100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ================================================================== Disabling lock debugging due to kernel taint Fixes: 5857d1dbae7d ("Bluetooth: 6lowpan: Fix possible race") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: msft: Lock failed probe cleanup against feature readersCen Zhang
The MSFT data must remain allocated while msft_get_features() reads its features. read_adv_mon_features() protects that access with hdev->lock, but msft_do_open() clears hdev->msft_data and frees the object without that lock when read_supported_features() fails. After a successful probe, the data survives a normal close. A later open can fail the probe while a management feature request is running. hci_mgmt_cmd() permits requests during HCI_INIT, and the opener's hdev->req_lock does not serialize the management reader: Management feature request HCI open hold hdev->req_lock msft_do_open() hold hdev->lock msft_get_features(): save msft read_supported_features() fails hdev->msft_data = NULL kfree(msft) read msft->features release hdev->lock release hdev->req_lock The saved pointer then refers to freed memory, causing a use-after-free read. Advertisement reporting through mgmt_device_found() also reads the features with hdev->lock held. Take hdev->lock around clearing and freeing msft_data in the failure branch. An existing feature reader finishes before the free, while a reader starting after cleanup sees NULL. Keep the synchronous probe outside this critical section, following the existing req_lock to hdev->lock ordering. KASAN report as below: ================================================================== BUG: KASAN: slab-use-after-free in msft_monitor_supported+0xa9/0xb0 Read of size 8 at addr ffff88811573ee00 by task mgmt-read-adv-m/532 CPU: 2 UID: 0 PID: 532 Comm: mgmt-read-adv-m Not tainted 7.2.0-rc6-pmb-bt-functional-v1+ #1 PREEMPT(lazy) 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 Call Trace: <TASK> dump_stack_lvl+0x93/0xd0 print_report+0xce/0x630 ? msft_monitor_supported+0xa9/0xb0 ? srso_alias_return_thunk+0x5/0xfbef5 ? __virt_addr_valid+0x20d/0x410 ? msft_monitor_supported+0xa9/0xb0 kasan_report+0xe0/0x110 ? msft_monitor_supported+0xa9/0xb0 msft_monitor_supported+0xa9/0xb0 read_adv_mon_features+0xdf/0x640 ? trace_hardirqs_on+0x18/0x160 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_read_adv_mon_features+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? srso_alias_return_thunk+0x5/0xfbef5 ? do_raw_read_unlock+0x49/0xe0 ? srso_alias_return_thunk+0x5/0xfbef5 ? _raw_read_unlock+0x23/0x40 hci_sock_sendmsg+0x12b5/0x2270 ? __pfx_hci_sock_sendmsg+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? selinux_socket_sendmsg+0x160/0x280 __sys_sendto+0x425/0x470 ? __pfx_hci_sock_sendmsg+0x10/0x10 ? __pfx___sys_sendto+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? srso_alias_return_thunk+0x5/0xfbef5 ? srso_alias_return_thunk+0x5/0xfbef5 ? __sys_setsockopt+0x119/0x180 __x64_sys_sendto+0xe5/0x1c0 ? lockdep_hardirqs_on_prepare+0xea/0x1a0 ? srso_alias_return_thunk+0x5/0xfbef5 ? trace_hardirqs_on+0x18/0x160 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f9ceb04a687 Code: 48 89 fa 4c 89 df e8 58 b3 00 00 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> c3 0f 1f 80 00 00 00 00 83 e2 39 83 fa 08 75 de e8 23 ff ff ff RSP: 002b:00007ffe6ab96a70 EFLAGS: 00000202 ORIG_RAX: 000000000000002c RAX: ffffffffffffffda RBX: 00007f9ceafb8780 RCX: 00007f9ceb04a687 RDX: 0000000000000006 RSI: 00007ffe6ab96aea RDI: 0000000000000003 RBP: 0000000000000002 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000003 R13: 00007ffe6ab96d50 R14: 00007f9ceb1f6000 R15: 00005625e427dd68 </TASK> Allocated by task 506: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 __kasan_kmalloc+0xaa/0xb0 __kmalloc_cache_noprof+0x251/0x610 msft_register+0x54/0x260 hci_register_dev+0x6b7/0xc80 __vhci_create_device+0x330/0x840 vhci_write+0x287/0x440 vfs_write+0x637/0x1010 ksys_write+0x111/0x200 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 529: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x5f/0x80 kfree+0x307/0x580 msft_do_open+0x604/0x9e0 hci_dev_open_sync+0x94a/0x2110 hci_dev_do_open+0x2f/0xb0 hci_dev_open+0x17d/0x300 hci_sock_ioctl+0x3c6/0x710 sock_do_ioctl+0x120/0x2b0 sock_ioctl+0x41b/0x670 __x64_sys_ioctl+0x163/0x1d0 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f The buggy address belongs to the object at ffff88811573ee00 which belongs to the cache kmalloc-256 of size 256 The buggy address is located 0 bytes inside of freed 256-byte region [ffff88811573ee00, ffff88811573ef00) The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x11573e head: order:1 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 flags: 0x200000000000040(head|node=0|zone=2) page_type: f5(slab) raw: 0200000000000040 ffff888100042b40 dead000000000100 dead000000000122 raw: 0000000000000000 0000000000100010 00000000f5000000 0000000000000000 head: 0200000000000040 ffff888100042b40 dead000000000100 dead000000000122 head: 0000000000000000 0000000000100010 00000000f5000000 0000000000000000 head: 0200000000000001 ffffffffffffff81 00000000ffffffff 00000000ffffffff head: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff88811573ed00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff88811573ed80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc >ffff88811573ee00: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ^ ffff88811573ee80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff88811573ef00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ================================================================== Fixes: 5031ffcc79b8 ("Bluetooth: Keep MSFT ext info throughout a hci_dev's life cycle") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: MGMT: Reject quality report requests during unregisterCen Zhang
A quality report request must not call a driver callback after its module text has been released. hci_mgmt_cmd() holds an hci_dev reference through set_exp_feature(), but that reference only preserves the device allocation. set_quality_report_func() takes req_lock and invokes hdev->set_quality_report without checking HCI_UNREGISTER. This is unsafe when a SET_EXP_FEATURE request for an Intel controller would change HCI_QUALITY_REPORT and is delayed before taking req_lock while the controller is removed. With btintel_pcie and btintel built as modules and no other btintel dependents, the following order is possible: Management request Removal and module unload ------------------ ------------------------- hci_mgmt_cmd(): retain hdev hci_unregister_dev(): set HCI_UNREGISTER remove hdev from lookup close under req_lock release req_lock btintel_pcie_remove(): return unload btintel_pcie, then btintel set_quality_report_func(): take req_lock call hdev->set_quality_report When the request resumes after btintel unload, the indirect call targets released module text and can cause an instruction-fetch page fault. The close operation serializes with a running callback but does not prevent a delayed management handler from invoking it afterwards. Check HCI_UNREGISTER immediately after acquiring the existing req_lock and return MGMT_STATUS_INVALID_INDEX via the common unlock path. If unregister passed its close section first, the request now rejects the removed controller before accessing the callback. If the request passes the check first, hci_dev_do_close() must wait for req_lock until the callback has returned, so unregister cannot finish before the use. Oops report as below: BUG: unable to handle page fault for address: ffffffffc0408e10 #PF: supervisor instruction fetch in kernel mode #PF: error_code(0x0010) - not-present page PGD 80a9067 P4D 80a9067 PUD 80ab067 PMD 0 Oops: Oops: 0010 [#1] SMP KASAN NOPTI CPU: 1 UID: 0 PID: 439 Comm: btmgmt Tainted: G O 7.2.0-rc6-pmb-bt-functional-v1+ #1 PREEMPT(lazy) Tainted: [O]=OOT_MODULE 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 RIP: 0010:0xffffffffc0408e10 Code: Unable to access opcode bytes at 0xffffffffc0408de6. RSP: 0018:ffff888110927838 EFLAGS: 00010293 RAX: 0000000000000000 RBX: 1ffff11022124f0c RCX: ffffffff85b1a1b6 RDX: ffff888117511d00 RSI: 0000000000000001 RDI: ffff888117598000 RBP: ffff888110927950 R08: 0000000000000001 R09: 0000000000000001 R10: ffffffff893d3057 R11: ffff888117511d00 R12: ffff888117598000 R13: 0000000000000001 R14: ffffffffc0408e10 R15: ffff888117599970 FS: 00007f15453f2040(0000) GS:ffff8881fd852000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffffffc0408de6 CR3: 000000010b832005 CR4: 0000000000770ef0 PKRU: 55555554 Call Trace: <TASK> ? set_quality_report_func+0x232/0x660 ? __pfx_set_quality_report_func+0x10/0x10 ? pmbd_gate_maybe+0x47/0x60 ? srso_alias_return_thunk+0x5/0xfbef5 ? pmbd_probe_hit_cookie+0xe7/0x1c0 ? srso_alias_return_thunk+0x5/0xfbef5 ? pmbd_probe_hit_cookie+0xee/0x1c0 set_exp_feature+0xf7/0x260 ? set_exp_feature+0xf7/0x260 ? hci_sock_sendmsg+0x12b2/0x2400 ? __pfx_hci_sock_sendmsg+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? selinux_socket_sendmsg+0x160/0x280 ? sock_write_iter+0x4c0/0x550 ? __pfx_hci_sock_sendmsg+0x10/0x10 ? __pfx_sock_write_iter+0x10/0x10 ? __file_has_perm+0x25e/0x420 ? __pfx___file_has_perm+0x10/0x10 ? do_iter_readv_writev+0x59c/0x860 ? __pfx_do_iter_readv_writev+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? security_file_permission+0x26/0x80 ? vfs_writev+0x30e/0xc10 ? __pfx_vfs_writev+0x10/0x10 ? __pfx_do_epoll_wait+0x10/0x10 ? __pfx_do_epoll_ctl+0x10/0x10 ? do_writev+0x241/0x2f0 ? srso_alias_return_thunk+0x5/0xfbef5 ? do_writev+0x241/0x2f0 ? __pfx_do_writev+0x10/0x10 ? irqentry_exit+0xbe/0x820 ? do_syscall_64+0x115/0x6a0 ? entry_SYSCALL_64_after_hwframe+0x77/0x7f </TASK> Modules linked in: [last unloaded: btintel(O)] CR2: ffffffffc0408e10 ---[ end trace 0000000000000000 ]--- RIP: 0010:0xffffffffc0408e10 Code: Unable to access opcode bytes at 0xffffffffc0408de6. RSP: 0018:ffff888110927838 EFLAGS: 00010293 RAX: 0000000000000000 RBX: 1ffff11022124f0c RCX: ffffffff85b1a1b6 RDX: ffff888117511d00 RSI: 0000000000000001 RDI: ffff888117598000 RBP: ffff888110927950 R08: 0000000000000001 R09: 0000000000000001 R10: ffffffff893d3057 R11: ffff888117511d00 R12: ffff888117598000 R13: 0000000000000001 R14: ffffffffc0408e10 R15: ffff888117599970 FS: 00007f15453f2040(0000) GS:ffff8881fd852000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffffffc0408de6 CR3: 000000010b832005 CR4: 0000000000770ef0 PKRU: 55555554 Kernel panic - not syncing: Fatal exception Kernel Offset: disabled Rebooting in 1 seconds.. Fixes: ae7d925b5c04 ("Bluetooth: Support the quality report events") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: ISO: Hold the listener during disconnect notificationCen Zhang
An ISO listener must remain alive until a queued child's disconnect notification completes. bt_accept_enqueue() retains only the child and stores a raw parent pointer; iso_conn_ready() drops its temporary listener reference after setup. iso_chan_del() saves that pointer, unlinks the child and then calls parent->sk_data_ready() without holding a listener reference. With an incoming CIS child still queued, disconnect and listener release can proceed in this order: HCI disconnect Listener release iso_conn_del(): lock child iso_chan_del(): save parent bt_accept_unlink(child) iso_sock_cleanup_listen(): drain empty accept queue iso_sock_release(): orphan and kill listener final sock_put(listener) parent->sk_data_ready(parent) After unlink, listener cleanup no longer has to take the child socket lock. The listener can therefore be freed before iso_chan_del() reads sk_data_ready, causing a use-after-free. Take a temporary parent reference before bt_accept_unlink() and drop it after the notification. The child lock excludes accept dequeue while the child is still queued, so listener cleanup cannot complete before sock_hold(). The reference then keeps the listener alive across unlink and through the callback without changing lock order. KASAN report as below: ================================================================== BUG: KASAN: slab-use-after-free in iso_chan_del+0x302/0x320 Read of size 8 at addr ffff888105ca2188 by task kworker/2:1/50 CPU: 2 UID: 0 PID: 50 Comm: kworker/2:1 Not tainted 7.2.0-rc6-pmb-bt-functional-v1+ #1 PREEMPT(lazy) 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 Workqueue: events iso_fixture_disconnect_work Call Trace: <TASK> dump_stack_lvl+0x93/0xd0 print_report+0xce/0x630 ? iso_chan_del+0x302/0x320 ? srso_alias_return_thunk+0x5/0xfbef5 ? __virt_addr_valid+0x20d/0x410 ? iso_chan_del+0x302/0x320 kasan_report+0xe0/0x110 ? iso_chan_del+0x302/0x320 iso_chan_del+0x302/0x320 iso_conn_del+0x19d/0x3c0 ? __pfx_iso_disconn_cfm+0x10/0x10 iso_disconn_cfm+0x78/0x120 hci_disconn_complete_evt+0x319/0xa30 ? find_held_lock+0x2b/0x80 hci_test_iso_disconn_event+0x85/0xb0 ? __pfx_hci_test_iso_disconn_event+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? srso_alias_return_thunk+0x5/0xfbef5 ? _raw_read_unlock+0x23/0x40 ? srso_alias_return_thunk+0x5/0xfbef5 ? __hci_dev_get+0x15d/0x280 iso_fixture_disconnect_work+0x67/0x290 process_one_work+0x908/0x19c0 ? __pfx_process_one_work+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_is_held_type+0x8f/0x100 ? srso_alias_return_thunk+0x5/0xfbef5 worker_thread+0x65c/0xe40 ? srso_alias_return_thunk+0x5/0xfbef5 ? __kthread_parkme+0x175/0x220 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_worker_thread+0x10/0x10 kthread+0x34f/0x460 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x659/0x940 ? __pfx_ret_from_fork+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? __switch_to+0x74f/0xf80 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK> Allocated by task 521: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 __kasan_kmalloc+0xaa/0xb0 __kmalloc_noprof+0x2d7/0x770 sk_prot_alloc+0x13e/0x260 sk_alloc+0x37/0xb40 bt_sock_alloc+0x40/0x3b0 iso_sock_alloc.constprop.0+0x3a/0x360 iso_sock_create+0xc7/0x160 bt_sock_create+0x171/0x330 __sock_create+0x2c4/0x730 __sys_socket+0x141/0x210 __x64_sys_socket+0x77/0xc0 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f Freed by task 521: kasan_save_stack+0x33/0x60 kasan_save_track+0x14/0x30 kasan_save_free_info+0x3b/0x60 __kasan_slab_free+0x5f/0x80 kfree+0x307/0x580 __sk_destruct+0x64f/0x790 sk_destruct+0xb3/0xd0 __sk_free+0xdd/0x370 sk_free+0x51/0x80 iso_sock_release+0x46d/0x5b0 __sock_release+0xb8/0x270 sock_close+0x21/0x30 __fput+0x39f/0xa60 task_work_run+0x144/0x230 do_exit+0x834/0x2830 do_group_exit+0xc7/0x280 get_signal+0x20a9/0x2400 arch_do_signal_or_restart+0x94/0x6f0 exit_to_user_mode_loop+0xcf/0x570 do_syscall_64+0x4f0/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f The buggy address belongs to the object at ffff888105ca2000 which belongs to the cache kmalloc-2k of size 2048 The buggy address is located 392 bytes inside of freed 2048-byte region [ffff888105ca2000, ffff888105ca2800) The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff888105ca5000 pfn:0x105ca0 head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 flags: 0x200000000000240(workingset|head|node=0|zone=2) page_type: f5(slab) raw: 0200000000000240 ffff888100042f00 ffffea00042cd010 ffffea00042c9210 raw: ffff888105ca5000 0000000000080005 00000000f5000000 0000000000000000 head: 0200000000000240 ffff888100042f00 ffffea00042cd010 ffffea00042c9210 head: ffff888105ca5000 0000000000080005 00000000f5000000 0000000000000000 head: 0200000000000003 fffffffffffffe01 00000000ffffffff 00000000ffffffff head: ffff888105ca1000 0000000000000000 00000000ffffffff 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: ffff888105ca2080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff888105ca2100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb >ffff888105ca2180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ^ ffff888105ca2200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ffff888105ca2280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb ================================================================== Fixes: f764a6c2c1e4 ("Bluetooth: ISO: Add broadcast support") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: hci_sync: Serialize devcoredump reset during device openCen Zhang
An ACTIVE devcoredump's buffer cursors must remain valid from the packet handler's state check through its copy. hci_devcd_rx() holds hdev->lock across that interval, and hci_devcd_reset() requires the same lock. However, hci_dev_open_sync() invokes reset without taking it. A registered VHCI controller can collect a dump through its debugfs interface while the controller is down. If a successful open overlaps with handling a nonempty dump packet, reset can run after the receiver's ACTIVE check and before its copy: hci_devcd_rx() hci_dev_open_sync() dequeue nonempty skb hci_dev_lock(hdev) handler observes ACTIVE hdev->open(hdev) succeeds hci_devcd_reset(hdev) dump.tail = NULL dump.state = IDLE hci_devcd_copy() compare against old dump.end memcpy(NULL, ..., skb->len) hci_dev_unlock(hdev) Reset leaves dump.end pointing at the old buffer and purges only queued packets, so it cannot discard the skb already dequeued by the receiver. The bounds check can pass with a NULL tail, leading to a nonempty copy to address zero. KASAN reported a 24-byte NULL write in hci_devcd_rx(). Take hdev->lock around the open-time reset. The receiver then finishes its state check and copy using valid cursors before reset, or observes IDLE after reset and skips the copy. KASAN report as below: BUG: KASAN: null-ptr-deref in hci_devcd_rx+0x5d5/0x1a80 Write of size 24 at addr 0000000000000000 by task kworker/u17:0/496 CPU: 0 UID: 0 PID: 496 Comm: kworker/u17:0 Not tainted 7.2.0-rc6-pmb-bt-functional-v1+ #1 PREEMPT(lazy) 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 Workqueue: hci0 hci_devcd_rx Call Trace: <TASK> dump_stack_lvl+0x93/0xd0 kasan_report+0xe0/0x110 ? hci_devcd_rx+0x5d5/0x1a80 kasan_check_range+0x105/0x1b0 __asan_memcpy+0x3c/0x60 hci_devcd_rx+0x5d5/0x1a80 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_hci_devcd_rx+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_release+0xc8/0x280 ? srso_alias_return_thunk+0x5/0xfbef5 process_one_work+0x908/0x19c0 ? __pfx_process_one_work+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? lock_is_held_type+0x8f/0x100 ? srso_alias_return_thunk+0x5/0xfbef5 worker_thread+0x65c/0xe40 ? __pfx_worker_thread+0x10/0x10 kthread+0x34f/0x460 ? srso_alias_return_thunk+0x5/0xfbef5 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x659/0x940 ? __pfx_ret_from_fork+0x10/0x10 ? srso_alias_return_thunk+0x5/0xfbef5 ? __switch_to+0x74f/0xf80 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1a/0x30 </TASK> ================================================================== Disabling lock debugging due to kernel taint Fixes: 9695ef876fd1 ("Bluetooth: Add support for hci devcoredump") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: hci_core: Keep RCU protection through LTK filteringCen Zhang
The LTK selected by hci_find_ltk() must remain allocated while its value is checked against the blocked-key list. The finder releases RCU before passing k->val to hci_is_blocked_key(). The helper's own RCU section protects the blocked-key list, but the selected LTK may already have been reclaimed before that section starts. An LE ATT socket security request can reach smp_ltk_encrypt() without holding hdev->lock. With a matching stored LTK and an LTK-type blocked-key entry present, a concurrent MGMT_OP_LOAD_LONG_TERM_KEYS can remove the selected LTK in the following order: Socket security Management / RCU reclamation hci_find_ltk() rcu_read_lock() select k rcu_read_unlock() load_long_term_keys() hci_dev_lock(hdev) hci_smp_ltks_clear(hdev) list_del_rcu(&k->list) kfree_rcu(k, rcu) grace period ends; k is freed hci_is_blocked_key(..., k->val) memcmp(b->val, val, ...) The final comparison reads freed LTK bytes. Entering a new RCU section in hci_is_blocked_key() cannot protect a pointer obtained before the completed grace period. Keep the finder's RCU read-side section active through the blocked-key comparison and the warning that reads k->bdaddr. Release it before returning on either matched-key path. This delays reclamation until the finder has finished using the selected record, following the existing IRK lookup pattern. KFENCE report as below: ================================================================== BUG: KFENCE: use-after-free read in hci_is_blocked_key+0xdf/0x240 Use-after-free read at 0x00000000b9ee38e4 (in kfence-#249): hci_is_blocked_key+0xdf/0x240 blocked_key_wrapper+0xc5/0x140 [pmbd_ltk_probe] hci_find_ltk+0x1aa/0x3e0 smp_ltk_encrypt.isra.0+0xad/0x340 smp_conn_security+0x3b8/0x8c0 l2cap_sock_setsockopt+0x1c4b/0x2270 do_sock_setsockopt+0x1fb/0x430 __sys_setsockopt+0x106/0x180 __x64_sys_setsockopt+0xc2/0x160 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f kfence-#249: 0x00000000121f2ad9-0x000000005b5bfb3d, size=72, cache=kmalloc-96 allocated by task 495 on cpu 0 at 36.722380s (2.603973s ago): hci_add_ltk+0x1f5/0x3a0 load_long_term_keys+0x6d0/0x860 hci_sock_sendmsg+0x128b/0x22e0 __sys_sendto+0x425/0x470 __x64_sys_sendto+0xe5/0x1c0 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f freed by task 533 on cpu 0 at 36.993097s (2.339769s ago): __rcu_free_sheaf_prepare+0x261/0x2a0 rcu_free_sheaf+0x1f/0xe0 rcu_core+0x661/0x1d10 handle_softirqs+0x201/0x930 __irq_exit_rcu+0x110/0x1e0 irq_exit_rcu+0xe/0x20 sysvec_apic_timer_interrupt+0x6c/0x80 asm_sysvec_apic_timer_interrupt+0x1a/0x20 srso_alias_return_thunk+0x0/0xfbef5 __asan_memcpy+0x23/0x60 create_monitor_ctrl_event+0x1a2/0x460 mgmt_cmd_complete+0x2da/0x580 load_long_term_keys+0x741/0x860 hci_sock_sendmsg+0x128b/0x22e0 __sys_sendto+0x425/0x470 __x64_sys_sendto+0xe5/0x1c0 do_syscall_64+0x115/0x6a0 entry_SYSCALL_64_after_hwframe+0x77/0x7f CPU: 1 UID: 0 PID: 495 Comm: python3 Tainted: G O 7.2.0-rc6-pmb-bt-functional-v1+ #1 PREEMPT(lazy) Tainted: [O]=OOT_MODULE 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 ================================================================== Fixes: 600a87490ff9 ("Bluetooth: Implementation of MGMT_OP_SET_BLOCKED_KEYS.") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: 6LoWPAN: Use RCU-safe device list removalCen Zhang
RCU readers of bt_6lowpan_devices must be able to follow an adapter's forward link until their read-side critical section ends. The entries are published with list_add_rcu(), but device_event() removes an entry on NETDEV_UNREGISTER with list_del(), poisoning that link. When an adapter is being unregistered and 6LoWPAN is enabled, a 6lowpan_control debugfs write with an existing LE L2CAP connection can enter lookup_peer() after unregister's first synchronize_net(). If the connection has no peer on that adapter, the reader must advance to the next list entry. Neither RTNL nor devices_lock excludes this RCU reader. The last peer's chan_close_cb() schedules delete_netdev(), which reaches unregister_netdevice_many_notify() through unregister_dev() and lowpan_unregister_netdev(). The following ordering is possible: Unregister worker Control writer ----------------- -------------- synchronize_net() returns lowpan_control_write() lookup_peer(): rcu_read_lock() reach adapter; no matching peer device_event(): devices_lock list_del(&entry->list) spin_unlock(&devices_lock) follow poisoned next link read invalid adapter address post-notifier synchronize_net() waits for the reader This invalid pointer access can fault in lookup_peer(). The first grace period drains existing readers but permits new ones to start, and the later grace period cannot prevent the intervening poisoned-link access. Use list_del_rcu() under the existing devices_lock to preserve the forward link for readers that already reached the adapter. The existing post-notifier synchronize_net() waits for those readers before netdevice teardown frees the private storage containing lowpan_btle_dev. KASAN report as below: [...] [ 45.867526] Oops: general protection fault, probably for non-canonical address 0xfbd59c0000000023: 0000 [#1] SMP KASAN NOPTI [ 45.869489] KASAN: maybe wild-memory-access in range [0xdead000000000118-0xdead00000000011f] [ 45.870981] CPU: 1 UID: 0 PID: 646 Comm: sh Not tainted 7.2.0-rc6-pmb-bt-functional-v1+ #4 PREEMPT(lazy) [ 45.872609] 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 [ 45.874380] RIP: 0010:lookup_peer+0x1ba/0x320 [ 45.875067] Code: 48 89 d9 ba 04 00 00 00 4c 89 fe bf a0 06 00 00 e8 2b e8 ad fb e9 56 ff ff ff e8 01 1e c3 fb 49 8d 7f 18 48 89 f8 48 c1 e8 03 <80> 3c 28 00 0f 85 4a 01 00 00 4d 8b 47 18 4c 89 f1 ba 04 00 00 00 [ 45.878206] RSP: 0018:ffff888114d67b90 EFLAGS: 00010212 [ 45.879106] RAX: 1bd5a00000000023 RBX: 0000000000000000 RCX: ffffffff85c1d19f [ 45.880334] RDX: ffff88810dc35700 RSI: 0000000000000000 RDI: dead000000000118 [ 45.881455] RBP: dffffc0000000000 R08: 0000000000000001 R09: 0000000000000001 [ 45.882546] R10: ffffffff893d3057 R11: ffff88810dc35700 R12: ffff88810a690000 [ 45.883839] R13: ffff888115451038 R14: ffff88810a690000 R15: dead000000000100 [ 45.885186] FS: 00007fa889bac780(0000) GS:ffff8881fd852000(0000) knlGS:0000000000000000 [ 45.886539] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 45.887527] CR2: 00007ffe304f2f80 CR3: 0000000104f64005 CR4: 0000000000770ef0 [ 45.888687] PKRU: 55555554 [ 45.889183] Call Trace: [ 45.889666] <TASK> [ 45.890061] lowpan_control_write+0x445/0x9e0 [ 45.890854] ? __pfx_lowpan_control_write+0x10/0x10 [ 45.891738] ? srso_alias_return_thunk+0x5/0xfbef5 [ 45.892603] ? srso_alias_return_thunk+0x5/0xfbef5 [ 45.893383] ? __debugfs_file_get+0x1bd/0x7f0 [ 45.894057] ? srso_alias_return_thunk+0x5/0xfbef5 [ 45.894902] ? lock_acquire+0x17b/0x2f0 [ 45.895593] ? ksys_write+0x111/0x200 [ 45.896290] full_proxy_write+0x11f/0x180 [ 45.896991] vfs_write+0x25a/0x1010 [ 45.897642] ? __pfx_full_proxy_write+0x10/0x10 [ 45.898440] ? __pfx_vfs_write+0x10/0x10 [ 45.899178] ? lock_release+0x11f/0x280 [ 45.899855] ksys_write+0x111/0x200 [ 45.900435] ? __pfx_ksys_write+0x10/0x10 [ 45.901074] ? irqentry_exit+0xbe/0x820 [ 45.901722] ? srso_alias_return_thunk+0x5/0xfbef5 [ 45.902489] do_syscall_64+0x115/0x6a0 [ 45.903064] entry_SYSCALL_64_after_hwframe+0x77/0x7f [ 45.903813] RIP: 0033:0x7fa889c3e687 [ 45.904359] Code: 48 89 fa 4c 89 df e8 58 b3 00 00 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> c3 0f 1f 80 00 00 00 00 83 e2 39 83 fa 08 75 de e8 23 ff ff ff [ 45.906981] RSP: 002b:00007ffd7651b960 EFLAGS: 00000202 ORIG_RAX: 0000000000000001 [ 45.908070] RAX: ffffffffffffffda RBX: 00007fa889bac780 RCX: 00007fa889c3e687 [ 45.909102] RDX: 000000000000001c RSI: 00005570f25e8d10 RDI: 0000000000000001 [ 45.910133] RBP: 00005570f25e8d10 R08: 0000000000000000 R09: 0000000000000000 [ 45.911162] R10: 0000000000000000 R11: 0000000000000202 R12: 0000000000000001 [ 45.912190] R13: 000000000000001c R14: 0000000000000000 R15: 00005570f25e8a78 [ 45.913208] </TASK> [ 45.913530] Modules linked in: [ 45.914022] ---[ end trace 0000000000000000 ]--- [ 45.914709] RIP: 0010:lookup_peer+0x1ba/0x320 [ 45.915436] Code: 48 89 d9 ba 04 00 00 00 4c 89 fe bf a0 06 00 00 e8 2b e8 ad fb e9 56 ff ff ff e8 01 1e c3 fb 49 8d 7f 18 48 89 f8 48 c1 e8 03 <80> 3c 28 00 0f 85 4a 01 00 00 4d 8b 47 18 4c 89 f1 ba 04 00 00 00 [ 45.919191] RSP: 0018:ffff888114d67b90 EFLAGS: 00010212 [ 45.920046] RAX: 1bd5a00000000023 RBX: 0000000000000000 RCX: ffffffff85c1d19f [ 45.921129] RDX: ffff88810dc35700 RSI: 0000000000000000 RDI: dead000000000118 [ 45.922553] RBP: dffffc0000000000 R08: 0000000000000001 R09: 0000000000000001 [ 45.923653] R10: ffffffff893d3057 R11: ffff88810dc35700 R12: ffff88810a690000 [ 45.925119] R13: ffff888115451038 R14: ffff88810a690000 R15: dead000000000100 [ 45.926180] FS: 00007fa889bac780(0000) GS:ffff8881fd852000(0000) knlGS:0000000000000000 [ 45.927817] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 45.928726] CR2: 00007ffe304f2f80 CR3: 0000000104f64005 CR4: 0000000000770ef0 [ 45.930069] PKRU: 55555554 [ 45.930456] Kernel panic - not syncing: Fatal exception [ 45.931542] Kernel Offset: disabled [ 45.932040] Rebooting in 1 seconds.. Fixes: 90305829635d ("Bluetooth: 6lowpan: Converting rwlocks to use RCU") Assisted-by: LLM Signed-off-by: Cen Zhang <zzzccc427@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
2026-10-14Bluetooth: MGMT: Fix leaking instance on Add Extended Advertising ParametersLuiz Augusto von Dentz
If queueing the command fails the instance is never removed, despite it having already been added or modified by hci_add_adv_instance, so remove it as it is done by add_ext_adv_params_complete on failure, signaling it has been removed if it was previously added. Fixes: cba6b758711c ("Bluetooth: hci_sync: Make use of hci_cmd_sync_queue set 2") Assisted-by: OpenCode:claude-opus-5.5 Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>