| Age | Commit message (Collapse) | Author |
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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
...
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|