* [PATCH v1] Bluetooth: HIDP: Fix possible UAF
@ 2026-03-06 2:31 Luiz Augusto von Dentz
2026-03-06 4:27 ` [v1] " bluez.test.bot
` (3 more replies)
0 siblings, 4 replies; 14+ messages in thread
From: Luiz Augusto von Dentz @ 2026-03-06 2:31 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This fixes the following trace caused by not dropping l2cap_conn
reference when user->remove callback is called:
[ 97.809249] l2cap_conn_free: freeing conn ffff88810a171c00
[ 97.809907] CPU: 1 UID: 0 PID: 1419 Comm: repro_standalon Not tainted 7.0.0-rc1-dirty #14 PREEMPT(lazy)
[ 97.809935] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
[ 97.809947] Call Trace:
[ 97.809954] <TASK>
[ 97.809961] dump_stack_lvl (lib/dump_stack.c:122)
[ 97.809990] l2cap_conn_free (net/bluetooth/l2cap_core.c:1808)
[ 97.810017] l2cap_conn_del (./include/linux/kref.h:66 net/bluetooth/l2cap_core.c:1821 net/bluetooth/l2cap_core.c:1798)
[ 97.810055] l2cap_disconn_cfm (net/bluetooth/l2cap_core.c:7347 (discriminator 1) net/bluetooth/l2cap_core.c:7340 (discriminator 1))
[ 97.810086] ? __pfx_l2cap_disconn_cfm (net/bluetooth/l2cap_core.c:7341)
[ 97.810117] hci_conn_hash_flush (./include/net/bluetooth/hci_core.h:2152 (discriminator 2) net/bluetooth/hci_conn.c:2644 (discriminator 2))
[ 97.810148] hci_dev_close_sync (net/bluetooth/hci_sync.c:5360)
[ 97.810180] ? __pfx_hci_dev_close_sync (net/bluetooth/hci_sync.c:5285)
[ 97.810212] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 97.810242] ? up_write (./arch/x86/include/asm/atomic64_64.h:87 (discriminator 5) ./include/linux/atomic/atomic-arch-fallback.h:2852 (discriminator 5) ./include/linux/atomic/atomic-long.h:268 (discriminator 5) ./include/linux/atomic/atomic-instrumented.h:3391 (discriminator 5) kernel/locking/rwsem.c:1385 (discriminator 5) kernel/locking/rwsem.c:1643 (discriminator 5))
[ 97.810267] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 97.810290] ? rcu_is_watching (./arch/x86/include/asm/atomic.h:23 ./include/linux/atomic/atomic-arch-fallback.h:457 ./include/linux/context_tracking.h:128 kernel/rcu/tree.c:752)
[ 97.810320] hci_unregister_dev (net/bluetooth/hci_core.c:504 net/bluetooth/hci_core.c:2716)
[ 97.810346] vhci_release (drivers/bluetooth/hci_vhci.c:691)
[ 97.810375] ? __pfx_vhci_release (drivers/bluetooth/hci_vhci.c:678)
[ 97.810404] __fput (fs/file_table.c:470)
[ 97.810430] task_work_run (kernel/task_work.c:235)
[ 97.810451] ? __pfx_task_work_run (kernel/task_work.c:201)
[ 97.810472] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 97.810495] ? do_raw_spin_unlock (./include/asm-generic/qspinlock.h:128 (discriminator 5) kernel/locking/spinlock_debug.c:142 (discriminator 5))
[ 97.810527] do_exit (kernel/exit.c:972)
[ 97.810547] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 97.810574] ? __pfx_do_exit (kernel/exit.c:897)
[ 97.810594] ? lock_acquire (kernel/locking/lockdep.c:470 (discriminator 6) kernel/locking/lockdep.c:5870 (discriminator 6) kernel/locking/lockdep.c:5825 (discriminator 6))
[ 97.810616] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 97.810639] ? do_raw_spin_lock (kernel/locking/spinlock_debug.c:95 (discriminator 4) kernel/locking/spinlock_debug.c:118 (discriminator 4))
[ 97.810664] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 97.810688] ? find_held_lock (kernel/locking/lockdep.c:5350 (discriminator 1))
[ 97.810721] do_group_exit (kernel/exit.c:1093)
[ 97.810745] get_signal (kernel/signal.c:3007 (discriminator 1))
[ 97.810772] ? security_file_permission (./arch/x86/include/asm/jump_label.h:37 security/security.c:2366)
[ 97.810803] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 97.810826] ? vfs_read (fs/read_write.c:555)
[ 97.810854] ? __pfx_get_signal (kernel/signal.c:2800)
[ 97.810880] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 97.810905] ? __pfx_vfs_read (fs/read_write.c:555)
[ 97.810932] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 97.810960] arch_do_signal_or_restart (arch/x86/kernel/signal.c:337 (discriminator 1))
[ 97.810990] ? __pfx_arch_do_signal_or_restart (arch/x86/kernel/signal.c:334)
[ 97.811021] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 97.811055] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 97.811078] ? ksys_read (fs/read_write.c:707)
[ 97.811106] ? __pfx_ksys_read (fs/read_write.c:707)
[ 97.811137] exit_to_user_mode_loop (kernel/entry/common.c:66 kernel/entry/common.c:98)
[ 97.811169] ? rcu_is_watching (./arch/x86/include/asm/atomic.h:23 ./include/linux/atomic/atomic-arch-fallback.h:457 ./include/linux/context_tracking.h:128 kernel/rcu/tree.c:752)
[ 97.811192] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 97.811215] ? trace_hardirqs_off (./include/trace/events/preemptirq.h:36 (discriminator 33) kernel/trace/trace_preemptirq.c:95 (discriminator 33) kernel/trace/trace_preemptirq.c:90 (discriminator 33))
[ 97.811240] do_syscall_64 (./include/linux/irq-entry-common.h:226 ./include/linux/irq-entry-common.h:256 ./include/linux/entry-common.h:325 arch/x86/entry/syscall_64.c:100)
[ 97.811268] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 97.811292] ? exc_page_fault (arch/x86/mm/fault.c:1480 (discriminator 3) arch/x86/mm/fault.c:1527 (discriminator 3))
[ 97.811318] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
[ 97.811338] RIP: 0033:0x445cfe
[ 97.811352] Code: Unable to access opcode bytes at 0x445cd4.
Code starting with the faulting instruction
===========================================
[ 97.811360] RSP: 002b:00007f65c41c6dc8 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
[ 97.811378] RAX: fffffffffffffe00 RBX: 00007f65c41c76c0 RCX: 0000000000445cfe
[ 97.811391] RDX: 0000000000000400 RSI: 00007f65c41c6e40 RDI: 0000000000000004
[ 97.811403] RBP: 00007f65c41c7250 R08: 0000000000000000 R09: 0000000000000000
[ 97.811415] R10: 0000000000000000 R11: 0000000000000246 R12: ffffffffffffffe8
[ 97.811428] R13: 0000000000000000 R14: 00007fff780a8c00 R15: 00007f65c41c76c0
[ 97.811453] </TASK>
[ 98.402453] ==================================================================
[ 98.403560] BUG: KASAN: use-after-free in __mutex_lock (kernel/locking/mutex.c:199 kernel/locking/mutex.c:694 kernel/locking/mutex.c:776)
[ 98.404541] Read of size 8 at addr ffff888113ee40a8 by task khidpd_00050004/1430
[ 98.405361]
[ 98.405563] CPU: 1 UID: 0 PID: 1430 Comm: khidpd_00050004 Not tainted 7.0.0-rc1-dirty #14 PREEMPT(lazy)
[ 98.405588] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
[ 98.405600] Call Trace:
[ 98.405607] <TASK>
[ 98.405614] dump_stack_lvl (lib/dump_stack.c:122)
[ 98.405641] print_report (mm/kasan/report.c:379 mm/kasan/report.c:482)
[ 98.405667] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 98.405691] ? __virt_addr_valid (arch/x86/mm/physaddr.c:55)
[ 98.405724] ? __mutex_lock (kernel/locking/mutex.c:199 kernel/locking/mutex.c:694 kernel/locking/mutex.c:776)
[ 98.405748] kasan_report (mm/kasan/report.c:221 mm/kasan/report.c:597)
[ 98.405778] ? __mutex_lock (kernel/locking/mutex.c:199 kernel/locking/mutex.c:694 kernel/locking/mutex.c:776)
[ 98.405807] __mutex_lock (kernel/locking/mutex.c:199 kernel/locking/mutex.c:694 kernel/locking/mutex.c:776)
[ 98.405832] ? do_raw_spin_lock (kernel/locking/spinlock_debug.c:95 (discriminator 4) kernel/locking/spinlock_debug.c:118 (discriminator 4))
[ 98.405859] ? l2cap_unregister_user (./include/linux/list.h:381 (discriminator 2) net/bluetooth/l2cap_core.c:1723 (discriminator 2))
[ 98.405888] ? __pfx_do_raw_spin_lock (kernel/locking/spinlock_debug.c:114)
[ 98.405915] ? __pfx___mutex_lock (kernel/locking/mutex.c:775)
[ 98.405939] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 98.405963] ? lock_acquire (kernel/locking/lockdep.c:470 (discriminator 6) kernel/locking/lockdep.c:5870 (discriminator 6) kernel/locking/lockdep.c:5825 (discriminator 6))
[ 98.405984] ? find_held_lock (kernel/locking/lockdep.c:5350 (discriminator 1))
[ 98.406015] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 98.406038] ? lock_release (kernel/locking/lockdep.c:5536 kernel/locking/lockdep.c:5889 kernel/locking/lockdep.c:5875)
[ 98.406061] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 98.406085] ? _raw_spin_unlock_irqrestore (./arch/x86/include/asm/irqflags.h:42 ./arch/x86/include/asm/irqflags.h:119 ./arch/x86/include/asm/irqflags.h:159 ./include/linux/spinlock_api_smp.h:178 kernel/locking/spinlock.c:194)
[ 98.406107] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 98.406130] ? __timer_delete_sync (kernel/time/timer.c:1592)
[ 98.406158] ? l2cap_unregister_user (./include/linux/list.h:381 (discriminator 2) net/bluetooth/l2cap_core.c:1723 (discriminator 2))
[ 98.406186] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 98.406210] l2cap_unregister_user (./include/linux/list.h:381 (discriminator 2) net/bluetooth/l2cap_core.c:1723 (discriminator 2))
[ 98.406263] hidp_session_thread (./include/linux/instrumented.h:112 ./include/linux/atomic/atomic-instrumented.h:400 ./include/linux/refcount.h:389 ./include/linux/refcount.h:432 ./include/linux/refcount.h:450 ./include/linux/kref.h:64 net/bluetooth/hidp/core.c:996 net/bluetooth/hidp/core.c:1305)
[ 98.406293] ? __pfx_hidp_session_thread (net/bluetooth/hidp/core.c:1264)
[ 98.406323] ? kthread (kernel/kthread.c:433)
[ 98.406340] ? __pfx_hidp_session_wake_function (net/bluetooth/hidp/core.c:1251)
[ 98.406370] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 98.406393] ? find_held_lock (kernel/locking/lockdep.c:5350 (discriminator 1))
[ 98.406424] ? __pfx_hidp_session_wake_function (net/bluetooth/hidp/core.c:1251)
[ 98.406453] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 98.406476] ? trace_hardirqs_on (kernel/trace/trace_preemptirq.c:79 (discriminator 1))
[ 98.406499] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 98.406523] ? kthread (kernel/kthread.c:433)
[ 98.406539] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 98.406565] ? kthread (kernel/kthread.c:433)
[ 98.406581] ? __pfx_hidp_session_thread (net/bluetooth/hidp/core.c:1264)
[ 98.406610] kthread (kernel/kthread.c:467)
[ 98.406627] ? __pfx_kthread (kernel/kthread.c:412)
[ 98.406645] ret_from_fork (arch/x86/kernel/process.c:164)
[ 98.406674] ? __pfx_ret_from_fork (arch/x86/kernel/process.c:153)
[ 98.406704] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 98.406728] ? __pfx_kthread (kernel/kthread.c:412)
[ 98.406747] ret_from_fork_asm (arch/x86/entry/entry_64.S:258)
[ 98.406774] </TASK>
[ 98.406780]
[ 98.433693] The buggy address belongs to the physical page:
[ 98.434405] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff888113ee7c40 pfn:0x113ee4
[ 98.435557] flags: 0x200000000000000(node=0|zone=2)
[ 98.436198] raw: 0200000000000000 ffffea0004244308 ffff8881f6f3ebc0 0000000000000000
[ 98.437195] raw: ffff888113ee7c40 0000000000000000 00000000ffffffff 0000000000000000
[ 98.438115] page dumped because: kasan: bad access detected
[ 98.438951]
[ 98.439211] Memory state around the buggy address:
[ 98.439871] ffff888113ee3f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 98.440714] ffff888113ee4000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 98.441580] >ffff888113ee4080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 98.442458] ^
[ 98.443011] ffff888113ee4100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 98.443889] ffff888113ee4180: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
[ 98.444768] ==================================================================
[ 98.445719] Disabling lock debugging due to kernel taint
[ 98.448074] l2cap_conn_free: freeing conn ffff88810c22b400
[ 98.450012] CPU: 1 UID: 0 PID: 1430 Comm: khidpd_00050004 Tainted: G B 7.0.0-rc1-dirty #14 PREEMPT(lazy)
[ 98.450040] Tainted: [B]=BAD_PAGE
[ 98.450047] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
[ 98.450059] Call Trace:
[ 98.450065] <TASK>
[ 98.450071] dump_stack_lvl (lib/dump_stack.c:122)
[ 98.450099] l2cap_conn_free (net/bluetooth/l2cap_core.c:1808)
[ 98.450125] l2cap_conn_put (net/bluetooth/l2cap_core.c:1822)
[ 98.450154] session_free (net/bluetooth/hidp/core.c:990)
[ 98.450181] hidp_session_thread (net/bluetooth/hidp/core.c:1307)
[ 98.450213] ? __pfx_hidp_session_thread (net/bluetooth/hidp/core.c:1264)
[ 98.450271] ? kthread (kernel/kthread.c:433)
[ 98.450293] ? __pfx_hidp_session_wake_function (net/bluetooth/hidp/core.c:1251)
[ 98.450339] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 98.450368] ? find_held_lock (kernel/locking/lockdep.c:5350 (discriminator 1))
[ 98.450406] ? __pfx_hidp_session_wake_function (net/bluetooth/hidp/core.c:1251)
[ 98.450442] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 98.450471] ? trace_hardirqs_on (kernel/trace/trace_preemptirq.c:79 (discriminator 1))
[ 98.450499] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 98.450528] ? kthread (kernel/kthread.c:433)
[ 98.450547] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 98.450578] ? kthread (kernel/kthread.c:433)
[ 98.450598] ? __pfx_hidp_session_thread (net/bluetooth/hidp/core.c:1264)
[ 98.450637] kthread (kernel/kthread.c:467)
[ 98.450657] ? __pfx_kthread (kernel/kthread.c:412)
[ 98.450680] ret_from_fork (arch/x86/kernel/process.c:164)
[ 98.450715] ? __pfx_ret_from_fork (arch/x86/kernel/process.c:153)
[ 98.450752] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221)
[ 98.450782] ? __pfx_kthread (kernel/kthread.c:412)
[ 98.450804] ret_from_fork_asm (arch/x86/entry/entry_64.S:258)
[ 98.450836] </TASK>
Fixes: b4f34d8d9d26 ("Bluetooth: hidp: add new session-management helpers")
Reported-by: soufiane el hachmi <kilwa10@gmail.com>
Tested-by: soufiane el hachmi <kilwa10@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
net/bluetooth/hidp/core.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 6724adce615b..e0e400381550 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -986,7 +986,8 @@ static void session_free(struct kref *ref)
skb_queue_purge(&session->intr_transmit);
fput(session->intr_sock->file);
fput(session->ctrl_sock->file);
- l2cap_conn_put(session->conn);
+ if (session->conn)
+ l2cap_conn_put(session->conn);
kfree(session);
}
@@ -1164,6 +1165,15 @@ static void hidp_session_remove(struct l2cap_conn *conn,
down_write(&hidp_session_sem);
+ /* Drop L2CAP reference immediately to indicate that
+ * l2cap_unregister_user() shall not be called as it is already
+ * considered removed.
+ */
+ if (session->conn) {
+ l2cap_conn_put(session->conn);
+ session->conn = NULL;
+ }
+
hidp_session_terminate(session);
cancel_work_sync(&session->dev_init);
@@ -1301,7 +1311,9 @@ static int hidp_session_thread(void *arg)
* Instead, this call has the same semantics as if user-space tried to
* delete the session.
*/
- l2cap_unregister_user(session->conn, &session->user);
+ if (session->conn)
+ l2cap_unregister_user(session->conn, &session->user);
+
hidp_session_put(session);
module_put_and_kthread_exit(0);
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread* RE: [v1] Bluetooth: HIDP: Fix possible UAF 2026-03-06 2:31 [PATCH v1] Bluetooth: HIDP: Fix possible UAF Luiz Augusto von Dentz @ 2026-03-06 4:27 ` bluez.test.bot 2026-03-06 18:40 ` [PATCH v1] " patchwork-bot+bluetooth ` (2 subsequent siblings) 3 siblings, 0 replies; 14+ messages in thread From: bluez.test.bot @ 2026-03-06 4:27 UTC (permalink / raw) To: linux-bluetooth, luiz.dentz [-- Attachment #1: Type: text/plain, Size: 3149 bytes --] This is automated email and please do not reply to this email! Dear submitter, Thank you for submitting the patches to the linux bluetooth mailing list. This is a CI test results with your patch series: PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1062284 ---Test result--- Test Summary: CheckPatch PENDING 0.33 seconds GitLint PENDING 0.26 seconds SubjectPrefix PASS 0.12 seconds BuildKernel PASS 26.03 seconds CheckAllWarning PASS 28.99 seconds CheckSparse WARNING 32.97 seconds BuildKernel32 PASS 25.60 seconds TestRunnerSetup PASS 566.00 seconds TestRunner_l2cap-tester PASS 28.89 seconds TestRunner_iso-tester PASS 94.23 seconds TestRunner_bnep-tester PASS 6.47 seconds TestRunner_mgmt-tester FAIL 118.14 seconds TestRunner_rfcomm-tester PASS 9.63 seconds TestRunner_sco-tester FAIL 14.71 seconds TestRunner_ioctl-tester PASS 10.26 seconds TestRunner_mesh-tester FAIL 12.43 seconds TestRunner_smp-tester PASS 8.67 seconds TestRunner_userchan-tester PASS 6.76 seconds IncrementalBuild PENDING 0.79 seconds Details ############################## Test: CheckPatch - PENDING Desc: Run checkpatch.pl script Output: ############################## Test: GitLint - PENDING Desc: Run gitlint Output: ############################## Test: CheckSparse - WARNING Desc: Run sparse tool with linux kernel Output: net/bluetooth/hidp/core.c:1486:1: error: bad constant expressionnet/bluetooth/hidp/core.c:1487:1: error: bad constant expressionnet/bluetooth/hidp/core.c:1488:1: error: bad constant expressionnet/bluetooth/hidp/core.c:1489:1: error: bad constant expressionnet/bluetooth/hidp/core.c:1490:1: error: bad constant expressionnet/bluetooth/hidp/core.c:1490:1: error: bad constant expressionnet/bluetooth/hidp/core.c:1491:1: error: bad constant expression ############################## Test: TestRunner_mgmt-tester - FAIL Desc: Run mgmt-tester with test-runner Output: Total: 494, Passed: 489 (99.0%), Failed: 1, Not Run: 4 Failed Test Cases Read Exp Feature - Success Failed 0.112 seconds ############################## Test: TestRunner_sco-tester - FAIL Desc: Run sco-tester with test-runner Output: WARNING: possible circular locking dependency detected BUG: sleeping function called from invalid context at net/core/sock.c:3782 Total: 30, Passed: 30 (100.0%), Failed: 0, Not Run: 0 ############################## Test: TestRunner_mesh-tester - FAIL Desc: Run mesh-tester with test-runner Output: Total: 10, Passed: 8 (80.0%), Failed: 2, Not Run: 0 Failed Test Cases Mesh - Send cancel - 1 Timed out 2.607 seconds Mesh - Send cancel - 2 Timed out 1.998 seconds ############################## Test: IncrementalBuild - PENDING Desc: Incremental build with the patches in the series Output: --- Regards, Linux Bluetooth ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v1] Bluetooth: HIDP: Fix possible UAF 2026-03-06 2:31 [PATCH v1] Bluetooth: HIDP: Fix possible UAF Luiz Augusto von Dentz 2026-03-06 4:27 ` [v1] " bluez.test.bot @ 2026-03-06 18:40 ` patchwork-bot+bluetooth 2026-03-06 18:49 ` Pauli Virtanen 2026-04-22 1:14 ` [PATCH] Bluetooth: HIDP: guard session->conn in hidp_connection_del Michael Bommarito 3 siblings, 0 replies; 14+ messages in thread From: patchwork-bot+bluetooth @ 2026-03-06 18:40 UTC (permalink / raw) To: Luiz Augusto von Dentz; +Cc: linux-bluetooth Hello: This patch was applied to bluetooth/bluetooth-next.git (master) by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>: On Thu, 5 Mar 2026 21:31:55 -0500 you wrote: > From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> > > This fixes the following trace caused by not dropping l2cap_conn > reference when user->remove callback is called: > > [ 97.809249] l2cap_conn_free: freeing conn ffff88810a171c00 > [ 97.809907] CPU: 1 UID: 0 PID: 1419 Comm: repro_standalon Not tainted 7.0.0-rc1-dirty #14 PREEMPT(lazy) > [ 97.809935] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014 > [ 97.809947] Call Trace: > [ 97.809954] <TASK> > [ 97.809961] dump_stack_lvl (lib/dump_stack.c:122) > [ 97.809990] l2cap_conn_free (net/bluetooth/l2cap_core.c:1808) > [ 97.810017] l2cap_conn_del (./include/linux/kref.h:66 net/bluetooth/l2cap_core.c:1821 net/bluetooth/l2cap_core.c:1798) > [ 97.810055] l2cap_disconn_cfm (net/bluetooth/l2cap_core.c:7347 (discriminator 1) net/bluetooth/l2cap_core.c:7340 (discriminator 1)) > [ 97.810086] ? __pfx_l2cap_disconn_cfm (net/bluetooth/l2cap_core.c:7341) > [ 97.810117] hci_conn_hash_flush (./include/net/bluetooth/hci_core.h:2152 (discriminator 2) net/bluetooth/hci_conn.c:2644 (discriminator 2)) > [ 97.810148] hci_dev_close_sync (net/bluetooth/hci_sync.c:5360) > [ 97.810180] ? __pfx_hci_dev_close_sync (net/bluetooth/hci_sync.c:5285) > [ 97.810212] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.810242] ? up_write (./arch/x86/include/asm/atomic64_64.h:87 (discriminator 5) ./include/linux/atomic/atomic-arch-fallback.h:2852 (discriminator 5) ./include/linux/atomic/atomic-long.h:268 (discriminator 5) ./include/linux/atomic/atomic-instrumented.h:3391 (discriminator 5) kernel/locking/rwsem.c:1385 (discriminator 5) kernel/locking/rwsem.c:1643 (discriminator 5)) > [ 97.810267] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.810290] ? rcu_is_watching (./arch/x86/include/asm/atomic.h:23 ./include/linux/atomic/atomic-arch-fallback.h:457 ./include/linux/context_tracking.h:128 kernel/rcu/tree.c:752) > [ 97.810320] hci_unregister_dev (net/bluetooth/hci_core.c:504 net/bluetooth/hci_core.c:2716) > [ 97.810346] vhci_release (drivers/bluetooth/hci_vhci.c:691) > [ 97.810375] ? __pfx_vhci_release (drivers/bluetooth/hci_vhci.c:678) > [ 97.810404] __fput (fs/file_table.c:470) > [ 97.810430] task_work_run (kernel/task_work.c:235) > [ 97.810451] ? __pfx_task_work_run (kernel/task_work.c:201) > [ 97.810472] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.810495] ? do_raw_spin_unlock (./include/asm-generic/qspinlock.h:128 (discriminator 5) kernel/locking/spinlock_debug.c:142 (discriminator 5)) > [ 97.810527] do_exit (kernel/exit.c:972) > [ 97.810547] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.810574] ? __pfx_do_exit (kernel/exit.c:897) > [ 97.810594] ? lock_acquire (kernel/locking/lockdep.c:470 (discriminator 6) kernel/locking/lockdep.c:5870 (discriminator 6) kernel/locking/lockdep.c:5825 (discriminator 6)) > [ 97.810616] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.810639] ? do_raw_spin_lock (kernel/locking/spinlock_debug.c:95 (discriminator 4) kernel/locking/spinlock_debug.c:118 (discriminator 4)) > [ 97.810664] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.810688] ? find_held_lock (kernel/locking/lockdep.c:5350 (discriminator 1)) > [ 97.810721] do_group_exit (kernel/exit.c:1093) > [ 97.810745] get_signal (kernel/signal.c:3007 (discriminator 1)) > [ 97.810772] ? security_file_permission (./arch/x86/include/asm/jump_label.h:37 security/security.c:2366) > [ 97.810803] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.810826] ? vfs_read (fs/read_write.c:555) > [ 97.810854] ? __pfx_get_signal (kernel/signal.c:2800) > [ 97.810880] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.810905] ? __pfx_vfs_read (fs/read_write.c:555) > [ 97.810932] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.810960] arch_do_signal_or_restart (arch/x86/kernel/signal.c:337 (discriminator 1)) > [ 97.810990] ? __pfx_arch_do_signal_or_restart (arch/x86/kernel/signal.c:334) > [ 97.811021] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.811055] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.811078] ? ksys_read (fs/read_write.c:707) > [ 97.811106] ? __pfx_ksys_read (fs/read_write.c:707) > [ 97.811137] exit_to_user_mode_loop (kernel/entry/common.c:66 kernel/entry/common.c:98) > [ 97.811169] ? rcu_is_watching (./arch/x86/include/asm/atomic.h:23 ./include/linux/atomic/atomic-arch-fallback.h:457 ./include/linux/context_tracking.h:128 kernel/rcu/tree.c:752) > [ 97.811192] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.811215] ? trace_hardirqs_off (./include/trace/events/preemptirq.h:36 (discriminator 33) kernel/trace/trace_preemptirq.c:95 (discriminator 33) kernel/trace/trace_preemptirq.c:90 (discriminator 33)) > [ 97.811240] do_syscall_64 (./include/linux/irq-entry-common.h:226 ./include/linux/irq-entry-common.h:256 ./include/linux/entry-common.h:325 arch/x86/entry/syscall_64.c:100) > [ 97.811268] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.811292] ? exc_page_fault (arch/x86/mm/fault.c:1480 (discriminator 3) arch/x86/mm/fault.c:1527 (discriminator 3)) > [ 97.811318] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130) > [ 97.811338] RIP: 0033:0x445cfe > [ 97.811352] Code: Unable to access opcode bytes at 0x445cd4. > > [...] Here is the summary with links: - [v1] Bluetooth: HIDP: Fix possible UAF https://git.kernel.org/bluetooth/bluetooth-next/c/708efc5f2338 You are awesome, thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v1] Bluetooth: HIDP: Fix possible UAF 2026-03-06 2:31 [PATCH v1] Bluetooth: HIDP: Fix possible UAF Luiz Augusto von Dentz 2026-03-06 4:27 ` [v1] " bluez.test.bot 2026-03-06 18:40 ` [PATCH v1] " patchwork-bot+bluetooth @ 2026-03-06 18:49 ` Pauli Virtanen 2026-03-06 19:23 ` Luiz Augusto von Dentz 2026-04-22 1:14 ` [PATCH] Bluetooth: HIDP: guard session->conn in hidp_connection_del Michael Bommarito 3 siblings, 1 reply; 14+ messages in thread From: Pauli Virtanen @ 2026-03-06 18:49 UTC (permalink / raw) To: Luiz Augusto von Dentz, linux-bluetooth Hi, to, 2026-03-05 kello 21:31 -0500, Luiz Augusto von Dentz kirjoitti: > From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> > > This fixes the following trace caused by not dropping l2cap_conn > reference when user->remove callback is called: > > [ 97.809249] l2cap_conn_free: freeing conn ffff88810a171c00 > [ 97.809907] CPU: 1 UID: 0 PID: 1419 Comm: repro_standalon Not tainted 7.0.0-rc1-dirty #14 PREEMPT(lazy) > [ 97.809935] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014 > [ 97.809947] Call Trace: > [ 97.809954] <TASK> > [ 97.809961] dump_stack_lvl (lib/dump_stack.c:122) > [ 97.809990] l2cap_conn_free (net/bluetooth/l2cap_core.c:1808) > [ 97.810017] l2cap_conn_del (./include/linux/kref.h:66 net/bluetooth/l2cap_core.c:1821 net/bluetooth/l2cap_core.c:1798) > [ 97.810055] l2cap_disconn_cfm (net/bluetooth/l2cap_core.c:7347 (discriminator 1) net/bluetooth/l2cap_core.c:7340 (discriminator 1)) > [ 97.810086] ? __pfx_l2cap_disconn_cfm (net/bluetooth/l2cap_core.c:7341) > [ 97.810117] hci_conn_hash_flush (./include/net/bluetooth/hci_core.h:2152 (discriminator 2) net/bluetooth/hci_conn.c:2644 (discriminator 2)) > [ 97.810148] hci_dev_close_sync (net/bluetooth/hci_sync.c:5360) > [ 97.810180] ? __pfx_hci_dev_close_sync (net/bluetooth/hci_sync.c:5285) > [ 97.810212] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.810242] ? up_write (./arch/x86/include/asm/atomic64_64.h:87 (discriminator 5) ./include/linux/atomic/atomic-arch-fallback.h:2852 (discriminator 5) ./include/linux/atomic/atomic-long.h:268 (discriminator 5) ./include/linux/atomic/atomic-instrumented.h:3391 (discriminator 5) kernel/locking/rwsem.c:1385 (discriminator 5) kernel/locking/rwsem.c:1643 (discriminator 5)) > [ 97.810267] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.810290] ? rcu_is_watching (./arch/x86/include/asm/atomic.h:23 ./include/linux/atomic/atomic-arch-fallback.h:457 ./include/linux/context_tracking.h:128 kernel/rcu/tree.c:752) > [ 97.810320] hci_unregister_dev (net/bluetooth/hci_core.c:504 net/bluetooth/hci_core.c:2716) > [ 97.810346] vhci_release (drivers/bluetooth/hci_vhci.c:691) > [ 97.810375] ? __pfx_vhci_release (drivers/bluetooth/hci_vhci.c:678) > [ 97.810404] __fput (fs/file_table.c:470) > [ 97.810430] task_work_run (kernel/task_work.c:235) > [ 97.810451] ? __pfx_task_work_run (kernel/task_work.c:201) > [ 97.810472] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.810495] ? do_raw_spin_unlock (./include/asm-generic/qspinlock.h:128 (discriminator 5) kernel/locking/spinlock_debug.c:142 (discriminator 5)) > [ 97.810527] do_exit (kernel/exit.c:972) > [ 97.810547] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.810574] ? __pfx_do_exit (kernel/exit.c:897) > [ 97.810594] ? lock_acquire (kernel/locking/lockdep.c:470 (discriminator 6) kernel/locking/lockdep.c:5870 (discriminator 6) kernel/locking/lockdep.c:5825 (discriminator 6)) > [ 97.810616] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.810639] ? do_raw_spin_lock (kernel/locking/spinlock_debug.c:95 (discriminator 4) kernel/locking/spinlock_debug.c:118 (discriminator 4)) > [ 97.810664] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.810688] ? find_held_lock (kernel/locking/lockdep.c:5350 (discriminator 1)) > [ 97.810721] do_group_exit (kernel/exit.c:1093) > [ 97.810745] get_signal (kernel/signal.c:3007 (discriminator 1)) > [ 97.810772] ? security_file_permission (./arch/x86/include/asm/jump_label.h:37 security/security.c:2366) > [ 97.810803] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.810826] ? vfs_read (fs/read_write.c:555) > [ 97.810854] ? __pfx_get_signal (kernel/signal.c:2800) > [ 97.810880] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.810905] ? __pfx_vfs_read (fs/read_write.c:555) > [ 97.810932] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.810960] arch_do_signal_or_restart (arch/x86/kernel/signal.c:337 (discriminator 1)) > [ 97.810990] ? __pfx_arch_do_signal_or_restart (arch/x86/kernel/signal.c:334) > [ 97.811021] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.811055] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.811078] ? ksys_read (fs/read_write.c:707) > [ 97.811106] ? __pfx_ksys_read (fs/read_write.c:707) > [ 97.811137] exit_to_user_mode_loop (kernel/entry/common.c:66 kernel/entry/common.c:98) > [ 97.811169] ? rcu_is_watching (./arch/x86/include/asm/atomic.h:23 ./include/linux/atomic/atomic-arch-fallback.h:457 ./include/linux/context_tracking.h:128 kernel/rcu/tree.c:752) > [ 97.811192] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.811215] ? trace_hardirqs_off (./include/trace/events/preemptirq.h:36 (discriminator 33) kernel/trace/trace_preemptirq.c:95 (discriminator 33) kernel/trace/trace_preemptirq.c:90 (discriminator 33)) > [ 97.811240] do_syscall_64 (./include/linux/irq-entry-common.h:226 ./include/linux/irq-entry-common.h:256 ./include/linux/entry-common.h:325 arch/x86/entry/syscall_64.c:100) > [ 97.811268] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 97.811292] ? exc_page_fault (arch/x86/mm/fault.c:1480 (discriminator 3) arch/x86/mm/fault.c:1527 (discriminator 3)) > [ 97.811318] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130) > [ 97.811338] RIP: 0033:0x445cfe > [ 97.811352] Code: Unable to access opcode bytes at 0x445cd4. > > Code starting with the faulting instruction > =========================================== > [ 97.811360] RSP: 002b:00007f65c41c6dc8 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 > [ 97.811378] RAX: fffffffffffffe00 RBX: 00007f65c41c76c0 RCX: 0000000000445cfe > [ 97.811391] RDX: 0000000000000400 RSI: 00007f65c41c6e40 RDI: 0000000000000004 > [ 97.811403] RBP: 00007f65c41c7250 R08: 0000000000000000 R09: 0000000000000000 > [ 97.811415] R10: 0000000000000000 R11: 0000000000000246 R12: ffffffffffffffe8 > [ 97.811428] R13: 0000000000000000 R14: 00007fff780a8c00 R15: 00007f65c41c76c0 > [ 97.811453] </TASK> > [ 98.402453] ================================================================== > [ 98.403560] BUG: KASAN: use-after-free in __mutex_lock (kernel/locking/mutex.c:199 kernel/locking/mutex.c:694 kernel/locking/mutex.c:776) > [ 98.404541] Read of size 8 at addr ffff888113ee40a8 by task khidpd_00050004/1430 > [ 98.405361] > [ 98.405563] CPU: 1 UID: 0 PID: 1430 Comm: khidpd_00050004 Not tainted 7.0.0-rc1-dirty #14 PREEMPT(lazy) > [ 98.405588] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014 > [ 98.405600] Call Trace: > [ 98.405607] <TASK> > [ 98.405614] dump_stack_lvl (lib/dump_stack.c:122) > [ 98.405641] print_report (mm/kasan/report.c:379 mm/kasan/report.c:482) > [ 98.405667] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 98.405691] ? __virt_addr_valid (arch/x86/mm/physaddr.c:55) > [ 98.405724] ? __mutex_lock (kernel/locking/mutex.c:199 kernel/locking/mutex.c:694 kernel/locking/mutex.c:776) > [ 98.405748] kasan_report (mm/kasan/report.c:221 mm/kasan/report.c:597) > [ 98.405778] ? __mutex_lock (kernel/locking/mutex.c:199 kernel/locking/mutex.c:694 kernel/locking/mutex.c:776) > [ 98.405807] __mutex_lock (kernel/locking/mutex.c:199 kernel/locking/mutex.c:694 kernel/locking/mutex.c:776) > [ 98.405832] ? do_raw_spin_lock (kernel/locking/spinlock_debug.c:95 (discriminator 4) kernel/locking/spinlock_debug.c:118 (discriminator 4)) > [ 98.405859] ? l2cap_unregister_user (./include/linux/list.h:381 (discriminator 2) net/bluetooth/l2cap_core.c:1723 (discriminator 2)) > [ 98.405888] ? __pfx_do_raw_spin_lock (kernel/locking/spinlock_debug.c:114) > [ 98.405915] ? __pfx___mutex_lock (kernel/locking/mutex.c:775) > [ 98.405939] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 98.405963] ? lock_acquire (kernel/locking/lockdep.c:470 (discriminator 6) kernel/locking/lockdep.c:5870 (discriminator 6) kernel/locking/lockdep.c:5825 (discriminator 6)) > [ 98.405984] ? find_held_lock (kernel/locking/lockdep.c:5350 (discriminator 1)) > [ 98.406015] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 98.406038] ? lock_release (kernel/locking/lockdep.c:5536 kernel/locking/lockdep.c:5889 kernel/locking/lockdep.c:5875) > [ 98.406061] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 98.406085] ? _raw_spin_unlock_irqrestore (./arch/x86/include/asm/irqflags.h:42 ./arch/x86/include/asm/irqflags.h:119 ./arch/x86/include/asm/irqflags.h:159 ./include/linux/spinlock_api_smp.h:178 kernel/locking/spinlock.c:194) > [ 98.406107] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 98.406130] ? __timer_delete_sync (kernel/time/timer.c:1592) > [ 98.406158] ? l2cap_unregister_user (./include/linux/list.h:381 (discriminator 2) net/bluetooth/l2cap_core.c:1723 (discriminator 2)) > [ 98.406186] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 98.406210] l2cap_unregister_user (./include/linux/list.h:381 (discriminator 2) net/bluetooth/l2cap_core.c:1723 (discriminator 2)) > [ 98.406263] hidp_session_thread (./include/linux/instrumented.h:112 ./include/linux/atomic/atomic-instrumented.h:400 ./include/linux/refcount.h:389 ./include/linux/refcount.h:432 ./include/linux/refcount.h:450 ./include/linux/kref.h:64 net/bluetooth/hidp/core.c:996 net/bluetooth/hidp/core.c:1305) > [ 98.406293] ? __pfx_hidp_session_thread (net/bluetooth/hidp/core.c:1264) > [ 98.406323] ? kthread (kernel/kthread.c:433) > [ 98.406340] ? __pfx_hidp_session_wake_function (net/bluetooth/hidp/core.c:1251) > [ 98.406370] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 98.406393] ? find_held_lock (kernel/locking/lockdep.c:5350 (discriminator 1)) > [ 98.406424] ? __pfx_hidp_session_wake_function (net/bluetooth/hidp/core.c:1251) > [ 98.406453] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 98.406476] ? trace_hardirqs_on (kernel/trace/trace_preemptirq.c:79 (discriminator 1)) > [ 98.406499] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 98.406523] ? kthread (kernel/kthread.c:433) > [ 98.406539] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 98.406565] ? kthread (kernel/kthread.c:433) > [ 98.406581] ? __pfx_hidp_session_thread (net/bluetooth/hidp/core.c:1264) > [ 98.406610] kthread (kernel/kthread.c:467) > [ 98.406627] ? __pfx_kthread (kernel/kthread.c:412) > [ 98.406645] ret_from_fork (arch/x86/kernel/process.c:164) > [ 98.406674] ? __pfx_ret_from_fork (arch/x86/kernel/process.c:153) > [ 98.406704] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 98.406728] ? __pfx_kthread (kernel/kthread.c:412) > [ 98.406747] ret_from_fork_asm (arch/x86/entry/entry_64.S:258) > [ 98.406774] </TASK> > [ 98.406780] > [ 98.433693] The buggy address belongs to the physical page: > [ 98.434405] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff888113ee7c40 pfn:0x113ee4 > [ 98.435557] flags: 0x200000000000000(node=0|zone=2) > [ 98.436198] raw: 0200000000000000 ffffea0004244308 ffff8881f6f3ebc0 0000000000000000 > [ 98.437195] raw: ffff888113ee7c40 0000000000000000 00000000ffffffff 0000000000000000 > [ 98.438115] page dumped because: kasan: bad access detected > [ 98.438951] > [ 98.439211] Memory state around the buggy address: > [ 98.439871] ffff888113ee3f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc > [ 98.440714] ffff888113ee4000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff > [ 98.441580] >ffff888113ee4080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff > [ 98.442458] ^ > [ 98.443011] ffff888113ee4100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff > [ 98.443889] ffff888113ee4180: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff > [ 98.444768] ================================================================== > [ 98.445719] Disabling lock debugging due to kernel taint > [ 98.448074] l2cap_conn_free: freeing conn ffff88810c22b400 > [ 98.450012] CPU: 1 UID: 0 PID: 1430 Comm: khidpd_00050004 Tainted: G B 7.0.0-rc1-dirty #14 PREEMPT(lazy) > [ 98.450040] Tainted: [B]=BAD_PAGE > [ 98.450047] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014 > [ 98.450059] Call Trace: > [ 98.450065] <TASK> > [ 98.450071] dump_stack_lvl (lib/dump_stack.c:122) > [ 98.450099] l2cap_conn_free (net/bluetooth/l2cap_core.c:1808) > [ 98.450125] l2cap_conn_put (net/bluetooth/l2cap_core.c:1822) > [ 98.450154] session_free (net/bluetooth/hidp/core.c:990) > [ 98.450181] hidp_session_thread (net/bluetooth/hidp/core.c:1307) > [ 98.450213] ? __pfx_hidp_session_thread (net/bluetooth/hidp/core.c:1264) > [ 98.450271] ? kthread (kernel/kthread.c:433) > [ 98.450293] ? __pfx_hidp_session_wake_function (net/bluetooth/hidp/core.c:1251) > [ 98.450339] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 98.450368] ? find_held_lock (kernel/locking/lockdep.c:5350 (discriminator 1)) > [ 98.450406] ? __pfx_hidp_session_wake_function (net/bluetooth/hidp/core.c:1251) > [ 98.450442] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 98.450471] ? trace_hardirqs_on (kernel/trace/trace_preemptirq.c:79 (discriminator 1)) > [ 98.450499] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 98.450528] ? kthread (kernel/kthread.c:433) > [ 98.450547] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 98.450578] ? kthread (kernel/kthread.c:433) > [ 98.450598] ? __pfx_hidp_session_thread (net/bluetooth/hidp/core.c:1264) > [ 98.450637] kthread (kernel/kthread.c:467) > [ 98.450657] ? __pfx_kthread (kernel/kthread.c:412) > [ 98.450680] ret_from_fork (arch/x86/kernel/process.c:164) > [ 98.450715] ? __pfx_ret_from_fork (arch/x86/kernel/process.c:153) > [ 98.450752] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > [ 98.450782] ? __pfx_kthread (kernel/kthread.c:412) > [ 98.450804] ret_from_fork_asm (arch/x86/entry/entry_64.S:258) > [ 98.450836] </TASK> > > Fixes: b4f34d8d9d26 ("Bluetooth: hidp: add new session-management helpers") > Reported-by: soufiane el hachmi <kilwa10@gmail.com> > Tested-by: soufiane el hachmi <kilwa10@gmail.com> > Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> > --- > net/bluetooth/hidp/core.c | 16 ++++++++++++++-- > 1 file changed, 14 insertions(+), 2 deletions(-) > > diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c > index 6724adce615b..e0e400381550 100644 > --- a/net/bluetooth/hidp/core.c > +++ b/net/bluetooth/hidp/core.c > @@ -986,7 +986,8 @@ static void session_free(struct kref *ref) > skb_queue_purge(&session->intr_transmit); > fput(session->intr_sock->file); > fput(session->ctrl_sock->file); > - l2cap_conn_put(session->conn); > + if (session->conn) > + l2cap_conn_put(session->conn); > kfree(session); > } > > @@ -1164,6 +1165,15 @@ static void hidp_session_remove(struct l2cap_conn *conn, > > down_write(&hidp_session_sem); > > + /* Drop L2CAP reference immediately to indicate that > + * l2cap_unregister_user() shall not be called as it is already > + * considered removed. > + */ > + if (session->conn) { > + l2cap_conn_put(session->conn); > + session->conn = NULL; > + } > + > hidp_session_terminate(session); > > cancel_work_sync(&session->dev_init); > @@ -1301,7 +1311,9 @@ static int hidp_session_thread(void *arg) > * Instead, this call has the same semantics as if user-space tried to > * delete the session. > */ > - l2cap_unregister_user(session->conn, &session->user); > + if (session->conn) > + l2cap_unregister_user(session->conn, &session->user); Does this TOCTOU on session->conn: [Task 1] [Task 2] hci_dev_lock() l2cap_disconn_cfm() l2cap_conn_del() if (session->conn) hidp_session_remove() l2cap_conn_free() l2cap_unregister_user() hdev = conn->hcon->hdev <UAF> I wonder if it is same issue as https://syzkaller.appspot.com/bug?extid=14b6d57fb728e27ce23c and I remember the earlier patch that tries to address the race via changing the locking: https://lore.kernel.org/all/20251106182016.26508-1-ssranevjti@gmail.com/ AFAICS, done that way the call to l2cap_unregister_user() in hidp_session_thread() should be noop via the !list_empty(&user->list) branch, as the hidp_session_remove() already ran. session->conn would remain until it is put when session->ref refcount goes to zero. > + > hidp_session_put(session); > > module_put_and_kthread_exit(0); -- Pauli Virtanen ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v1] Bluetooth: HIDP: Fix possible UAF 2026-03-06 18:49 ` Pauli Virtanen @ 2026-03-06 19:23 ` Luiz Augusto von Dentz 0 siblings, 0 replies; 14+ messages in thread From: Luiz Augusto von Dentz @ 2026-03-06 19:23 UTC (permalink / raw) To: Pauli Virtanen; +Cc: linux-bluetooth Hi Pauli, On Fri, Mar 6, 2026 at 1:49 PM Pauli Virtanen <pav@iki.fi> wrote: > > Hi, > > to, 2026-03-05 kello 21:31 -0500, Luiz Augusto von Dentz kirjoitti: > > From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> > > > > This fixes the following trace caused by not dropping l2cap_conn > > reference when user->remove callback is called: > > > > [ 97.809249] l2cap_conn_free: freeing conn ffff88810a171c00 > > [ 97.809907] CPU: 1 UID: 0 PID: 1419 Comm: repro_standalon Not tainted 7.0.0-rc1-dirty #14 PREEMPT(lazy) > > [ 97.809935] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014 > > [ 97.809947] Call Trace: > > [ 97.809954] <TASK> > > [ 97.809961] dump_stack_lvl (lib/dump_stack.c:122) > > [ 97.809990] l2cap_conn_free (net/bluetooth/l2cap_core.c:1808) > > [ 97.810017] l2cap_conn_del (./include/linux/kref.h:66 net/bluetooth/l2cap_core.c:1821 net/bluetooth/l2cap_core.c:1798) > > [ 97.810055] l2cap_disconn_cfm (net/bluetooth/l2cap_core.c:7347 (discriminator 1) net/bluetooth/l2cap_core.c:7340 (discriminator 1)) > > [ 97.810086] ? __pfx_l2cap_disconn_cfm (net/bluetooth/l2cap_core.c:7341) > > [ 97.810117] hci_conn_hash_flush (./include/net/bluetooth/hci_core.h:2152 (discriminator 2) net/bluetooth/hci_conn.c:2644 (discriminator 2)) > > [ 97.810148] hci_dev_close_sync (net/bluetooth/hci_sync.c:5360) > > [ 97.810180] ? __pfx_hci_dev_close_sync (net/bluetooth/hci_sync.c:5285) > > [ 97.810212] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 97.810242] ? up_write (./arch/x86/include/asm/atomic64_64.h:87 (discriminator 5) ./include/linux/atomic/atomic-arch-fallback.h:2852 (discriminator 5) ./include/linux/atomic/atomic-long.h:268 (discriminator 5) ./include/linux/atomic/atomic-instrumented.h:3391 (discriminator 5) kernel/locking/rwsem.c:1385 (discriminator 5) kernel/locking/rwsem.c:1643 (discriminator 5)) > > [ 97.810267] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 97.810290] ? rcu_is_watching (./arch/x86/include/asm/atomic.h:23 ./include/linux/atomic/atomic-arch-fallback.h:457 ./include/linux/context_tracking.h:128 kernel/rcu/tree.c:752) > > [ 97.810320] hci_unregister_dev (net/bluetooth/hci_core.c:504 net/bluetooth/hci_core.c:2716) > > [ 97.810346] vhci_release (drivers/bluetooth/hci_vhci.c:691) > > [ 97.810375] ? __pfx_vhci_release (drivers/bluetooth/hci_vhci.c:678) > > [ 97.810404] __fput (fs/file_table.c:470) > > [ 97.810430] task_work_run (kernel/task_work.c:235) > > [ 97.810451] ? __pfx_task_work_run (kernel/task_work.c:201) > > [ 97.810472] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 97.810495] ? do_raw_spin_unlock (./include/asm-generic/qspinlock.h:128 (discriminator 5) kernel/locking/spinlock_debug.c:142 (discriminator 5)) > > [ 97.810527] do_exit (kernel/exit.c:972) > > [ 97.810547] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 97.810574] ? __pfx_do_exit (kernel/exit.c:897) > > [ 97.810594] ? lock_acquire (kernel/locking/lockdep.c:470 (discriminator 6) kernel/locking/lockdep.c:5870 (discriminator 6) kernel/locking/lockdep.c:5825 (discriminator 6)) > > [ 97.810616] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 97.810639] ? do_raw_spin_lock (kernel/locking/spinlock_debug.c:95 (discriminator 4) kernel/locking/spinlock_debug.c:118 (discriminator 4)) > > [ 97.810664] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 97.810688] ? find_held_lock (kernel/locking/lockdep.c:5350 (discriminator 1)) > > [ 97.810721] do_group_exit (kernel/exit.c:1093) > > [ 97.810745] get_signal (kernel/signal.c:3007 (discriminator 1)) > > [ 97.810772] ? security_file_permission (./arch/x86/include/asm/jump_label.h:37 security/security.c:2366) > > [ 97.810803] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 97.810826] ? vfs_read (fs/read_write.c:555) > > [ 97.810854] ? __pfx_get_signal (kernel/signal.c:2800) > > [ 97.810880] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 97.810905] ? __pfx_vfs_read (fs/read_write.c:555) > > [ 97.810932] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 97.810960] arch_do_signal_or_restart (arch/x86/kernel/signal.c:337 (discriminator 1)) > > [ 97.810990] ? __pfx_arch_do_signal_or_restart (arch/x86/kernel/signal.c:334) > > [ 97.811021] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 97.811055] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 97.811078] ? ksys_read (fs/read_write.c:707) > > [ 97.811106] ? __pfx_ksys_read (fs/read_write.c:707) > > [ 97.811137] exit_to_user_mode_loop (kernel/entry/common.c:66 kernel/entry/common.c:98) > > [ 97.811169] ? rcu_is_watching (./arch/x86/include/asm/atomic.h:23 ./include/linux/atomic/atomic-arch-fallback.h:457 ./include/linux/context_tracking.h:128 kernel/rcu/tree.c:752) > > [ 97.811192] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 97.811215] ? trace_hardirqs_off (./include/trace/events/preemptirq.h:36 (discriminator 33) kernel/trace/trace_preemptirq.c:95 (discriminator 33) kernel/trace/trace_preemptirq.c:90 (discriminator 33)) > > [ 97.811240] do_syscall_64 (./include/linux/irq-entry-common.h:226 ./include/linux/irq-entry-common.h:256 ./include/linux/entry-common.h:325 arch/x86/entry/syscall_64.c:100) > > [ 97.811268] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 97.811292] ? exc_page_fault (arch/x86/mm/fault.c:1480 (discriminator 3) arch/x86/mm/fault.c:1527 (discriminator 3)) > > [ 97.811318] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130) > > [ 97.811338] RIP: 0033:0x445cfe > > [ 97.811352] Code: Unable to access opcode bytes at 0x445cd4. > > > > Code starting with the faulting instruction > > =========================================== > > [ 97.811360] RSP: 002b:00007f65c41c6dc8 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 > > [ 97.811378] RAX: fffffffffffffe00 RBX: 00007f65c41c76c0 RCX: 0000000000445cfe > > [ 97.811391] RDX: 0000000000000400 RSI: 00007f65c41c6e40 RDI: 0000000000000004 > > [ 97.811403] RBP: 00007f65c41c7250 R08: 0000000000000000 R09: 0000000000000000 > > [ 97.811415] R10: 0000000000000000 R11: 0000000000000246 R12: ffffffffffffffe8 > > [ 97.811428] R13: 0000000000000000 R14: 00007fff780a8c00 R15: 00007f65c41c76c0 > > [ 97.811453] </TASK> > > [ 98.402453] ================================================================== > > [ 98.403560] BUG: KASAN: use-after-free in __mutex_lock (kernel/locking/mutex.c:199 kernel/locking/mutex.c:694 kernel/locking/mutex.c:776) > > [ 98.404541] Read of size 8 at addr ffff888113ee40a8 by task khidpd_00050004/1430 > > [ 98.405361] > > [ 98.405563] CPU: 1 UID: 0 PID: 1430 Comm: khidpd_00050004 Not tainted 7.0.0-rc1-dirty #14 PREEMPT(lazy) > > [ 98.405588] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014 > > [ 98.405600] Call Trace: > > [ 98.405607] <TASK> > > [ 98.405614] dump_stack_lvl (lib/dump_stack.c:122) > > [ 98.405641] print_report (mm/kasan/report.c:379 mm/kasan/report.c:482) > > [ 98.405667] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 98.405691] ? __virt_addr_valid (arch/x86/mm/physaddr.c:55) > > [ 98.405724] ? __mutex_lock (kernel/locking/mutex.c:199 kernel/locking/mutex.c:694 kernel/locking/mutex.c:776) > > [ 98.405748] kasan_report (mm/kasan/report.c:221 mm/kasan/report.c:597) > > [ 98.405778] ? __mutex_lock (kernel/locking/mutex.c:199 kernel/locking/mutex.c:694 kernel/locking/mutex.c:776) > > [ 98.405807] __mutex_lock (kernel/locking/mutex.c:199 kernel/locking/mutex.c:694 kernel/locking/mutex.c:776) > > [ 98.405832] ? do_raw_spin_lock (kernel/locking/spinlock_debug.c:95 (discriminator 4) kernel/locking/spinlock_debug.c:118 (discriminator 4)) > > [ 98.405859] ? l2cap_unregister_user (./include/linux/list.h:381 (discriminator 2) net/bluetooth/l2cap_core.c:1723 (discriminator 2)) > > [ 98.405888] ? __pfx_do_raw_spin_lock (kernel/locking/spinlock_debug.c:114) > > [ 98.405915] ? __pfx___mutex_lock (kernel/locking/mutex.c:775) > > [ 98.405939] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 98.405963] ? lock_acquire (kernel/locking/lockdep.c:470 (discriminator 6) kernel/locking/lockdep.c:5870 (discriminator 6) kernel/locking/lockdep.c:5825 (discriminator 6)) > > [ 98.405984] ? find_held_lock (kernel/locking/lockdep.c:5350 (discriminator 1)) > > [ 98.406015] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 98.406038] ? lock_release (kernel/locking/lockdep.c:5536 kernel/locking/lockdep.c:5889 kernel/locking/lockdep.c:5875) > > [ 98.406061] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 98.406085] ? _raw_spin_unlock_irqrestore (./arch/x86/include/asm/irqflags.h:42 ./arch/x86/include/asm/irqflags.h:119 ./arch/x86/include/asm/irqflags.h:159 ./include/linux/spinlock_api_smp.h:178 kernel/locking/spinlock.c:194) > > [ 98.406107] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 98.406130] ? __timer_delete_sync (kernel/time/timer.c:1592) > > [ 98.406158] ? l2cap_unregister_user (./include/linux/list.h:381 (discriminator 2) net/bluetooth/l2cap_core.c:1723 (discriminator 2)) > > [ 98.406186] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 98.406210] l2cap_unregister_user (./include/linux/list.h:381 (discriminator 2) net/bluetooth/l2cap_core.c:1723 (discriminator 2)) > > [ 98.406263] hidp_session_thread (./include/linux/instrumented.h:112 ./include/linux/atomic/atomic-instrumented.h:400 ./include/linux/refcount.h:389 ./include/linux/refcount.h:432 ./include/linux/refcount.h:450 ./include/linux/kref.h:64 net/bluetooth/hidp/core.c:996 net/bluetooth/hidp/core.c:1305) > > [ 98.406293] ? __pfx_hidp_session_thread (net/bluetooth/hidp/core.c:1264) > > [ 98.406323] ? kthread (kernel/kthread.c:433) > > [ 98.406340] ? __pfx_hidp_session_wake_function (net/bluetooth/hidp/core.c:1251) > > [ 98.406370] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 98.406393] ? find_held_lock (kernel/locking/lockdep.c:5350 (discriminator 1)) > > [ 98.406424] ? __pfx_hidp_session_wake_function (net/bluetooth/hidp/core.c:1251) > > [ 98.406453] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 98.406476] ? trace_hardirqs_on (kernel/trace/trace_preemptirq.c:79 (discriminator 1)) > > [ 98.406499] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 98.406523] ? kthread (kernel/kthread.c:433) > > [ 98.406539] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 98.406565] ? kthread (kernel/kthread.c:433) > > [ 98.406581] ? __pfx_hidp_session_thread (net/bluetooth/hidp/core.c:1264) > > [ 98.406610] kthread (kernel/kthread.c:467) > > [ 98.406627] ? __pfx_kthread (kernel/kthread.c:412) > > [ 98.406645] ret_from_fork (arch/x86/kernel/process.c:164) > > [ 98.406674] ? __pfx_ret_from_fork (arch/x86/kernel/process.c:153) > > [ 98.406704] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 98.406728] ? __pfx_kthread (kernel/kthread.c:412) > > [ 98.406747] ret_from_fork_asm (arch/x86/entry/entry_64.S:258) > > [ 98.406774] </TASK> > > [ 98.406780] > > [ 98.433693] The buggy address belongs to the physical page: > > [ 98.434405] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff888113ee7c40 pfn:0x113ee4 > > [ 98.435557] flags: 0x200000000000000(node=0|zone=2) > > [ 98.436198] raw: 0200000000000000 ffffea0004244308 ffff8881f6f3ebc0 0000000000000000 > > [ 98.437195] raw: ffff888113ee7c40 0000000000000000 00000000ffffffff 0000000000000000 > > [ 98.438115] page dumped because: kasan: bad access detected > > [ 98.438951] > > [ 98.439211] Memory state around the buggy address: > > [ 98.439871] ffff888113ee3f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc > > [ 98.440714] ffff888113ee4000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff > > [ 98.441580] >ffff888113ee4080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff > > [ 98.442458] ^ > > [ 98.443011] ffff888113ee4100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff > > [ 98.443889] ffff888113ee4180: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff > > [ 98.444768] ================================================================== > > [ 98.445719] Disabling lock debugging due to kernel taint > > [ 98.448074] l2cap_conn_free: freeing conn ffff88810c22b400 > > [ 98.450012] CPU: 1 UID: 0 PID: 1430 Comm: khidpd_00050004 Tainted: G B 7.0.0-rc1-dirty #14 PREEMPT(lazy) > > [ 98.450040] Tainted: [B]=BAD_PAGE > > [ 98.450047] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014 > > [ 98.450059] Call Trace: > > [ 98.450065] <TASK> > > [ 98.450071] dump_stack_lvl (lib/dump_stack.c:122) > > [ 98.450099] l2cap_conn_free (net/bluetooth/l2cap_core.c:1808) > > [ 98.450125] l2cap_conn_put (net/bluetooth/l2cap_core.c:1822) > > [ 98.450154] session_free (net/bluetooth/hidp/core.c:990) > > [ 98.450181] hidp_session_thread (net/bluetooth/hidp/core.c:1307) > > [ 98.450213] ? __pfx_hidp_session_thread (net/bluetooth/hidp/core.c:1264) > > [ 98.450271] ? kthread (kernel/kthread.c:433) > > [ 98.450293] ? __pfx_hidp_session_wake_function (net/bluetooth/hidp/core.c:1251) > > [ 98.450339] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 98.450368] ? find_held_lock (kernel/locking/lockdep.c:5350 (discriminator 1)) > > [ 98.450406] ? __pfx_hidp_session_wake_function (net/bluetooth/hidp/core.c:1251) > > [ 98.450442] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 98.450471] ? trace_hardirqs_on (kernel/trace/trace_preemptirq.c:79 (discriminator 1)) > > [ 98.450499] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 98.450528] ? kthread (kernel/kthread.c:433) > > [ 98.450547] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 98.450578] ? kthread (kernel/kthread.c:433) > > [ 98.450598] ? __pfx_hidp_session_thread (net/bluetooth/hidp/core.c:1264) > > [ 98.450637] kthread (kernel/kthread.c:467) > > [ 98.450657] ? __pfx_kthread (kernel/kthread.c:412) > > [ 98.450680] ret_from_fork (arch/x86/kernel/process.c:164) > > [ 98.450715] ? __pfx_ret_from_fork (arch/x86/kernel/process.c:153) > > [ 98.450752] ? srso_alias_return_thunk (arch/x86/lib/retpoline.S:221) > > [ 98.450782] ? __pfx_kthread (kernel/kthread.c:412) > > [ 98.450804] ret_from_fork_asm (arch/x86/entry/entry_64.S:258) > > [ 98.450836] </TASK> > > > > Fixes: b4f34d8d9d26 ("Bluetooth: hidp: add new session-management helpers") > > Reported-by: soufiane el hachmi <kilwa10@gmail.com> > > Tested-by: soufiane el hachmi <kilwa10@gmail.com> > > Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> > > --- > > net/bluetooth/hidp/core.c | 16 ++++++++++++++-- > > 1 file changed, 14 insertions(+), 2 deletions(-) > > > > diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c > > index 6724adce615b..e0e400381550 100644 > > --- a/net/bluetooth/hidp/core.c > > +++ b/net/bluetooth/hidp/core.c > > @@ -986,7 +986,8 @@ static void session_free(struct kref *ref) > > skb_queue_purge(&session->intr_transmit); > > fput(session->intr_sock->file); > > fput(session->ctrl_sock->file); > > - l2cap_conn_put(session->conn); > > + if (session->conn) > > + l2cap_conn_put(session->conn); > > kfree(session); > > } > > > > @@ -1164,6 +1165,15 @@ static void hidp_session_remove(struct l2cap_conn *conn, > > > > down_write(&hidp_session_sem); > > > > + /* Drop L2CAP reference immediately to indicate that > > + * l2cap_unregister_user() shall not be called as it is already > > + * considered removed. > > + */ > > + if (session->conn) { > > + l2cap_conn_put(session->conn); > > + session->conn = NULL; > > + } > > + > > hidp_session_terminate(session); > > > > cancel_work_sync(&session->dev_init); > > @@ -1301,7 +1311,9 @@ static int hidp_session_thread(void *arg) > > * Instead, this call has the same semantics as if user-space tried to > > * delete the session. > > */ > > - l2cap_unregister_user(session->conn, &session->user); > > + if (session->conn) > > + l2cap_unregister_user(session->conn, &session->user); > > Does this TOCTOU on session->conn: > > [Task 1] [Task 2] > hci_dev_lock() > l2cap_disconn_cfm() > l2cap_conn_del() > if (session->conn) > hidp_session_remove() > l2cap_conn_free() > l2cap_unregister_user() > hdev = conn->hcon->hdev <UAF> > > I wonder if it is same issue as > https://syzkaller.appspot.com/bug?extid=14b6d57fb728e27ce23c > > and I remember the earlier patch that tries to address the race via > changing the locking: > > https://lore.kernel.org/all/20251106182016.26508-1-ssranevjti@gmail.com/ Interesting, this one might have slipped through. It seems valid and looks like it would address the TOCTOU, let me check with the reporter if the above fix the problem as well then we migh just drop the change setting the l2cap_conn to NULL. > > AFAICS, done that way the call to l2cap_unregister_user() in > hidp_session_thread() should be noop via the !list_empty(&user->list) > branch, as the hidp_session_remove() already ran. session->conn would > remain until it is put when session->ref refcount goes to zero. > > > > + > > hidp_session_put(session); > > > > module_put_and_kthread_exit(0); > > -- > Pauli Virtanen -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH] Bluetooth: HIDP: guard session->conn in hidp_connection_del 2026-03-06 2:31 [PATCH v1] Bluetooth: HIDP: Fix possible UAF Luiz Augusto von Dentz ` (2 preceding siblings ...) 2026-03-06 18:49 ` Pauli Virtanen @ 2026-04-22 1:14 ` Michael Bommarito 2026-04-22 4:13 ` bluez.test.bot ` (2 more replies) 3 siblings, 3 replies; 14+ messages in thread From: Michael Bommarito @ 2026-04-22 1:14 UTC (permalink / raw) To: Marcel Holtmann; +Cc: Luiz Augusto von Dentz, linux-bluetooth, linux-kernel commit dbf666e4fc9b ("Bluetooth: HIDP: Fix possible UAF") changed hidp_session_remove() to drop the L2CAP reference and set session->conn = NULL once the session is considered removed, and added an if (session->conn) guard around the l2cap_unregister_user() call at the kthread-exit site in hidp_session_thread(). The sibling call site in hidp_connection_del() still invokes l2cap_unregister_user(session->conn, &session->user) unconditionally. hidp_session_find() takes the session refcount under down_read(&hidp_session_sem) and returns; between the find() and the call at :1421, hidp_session_remove() can run on another thread (driven by the remote peer disconnecting or local teardown), take down_write(&hidp_session_sem), set session->conn to NULL, and return. The HIDPCONNDEL ioctl path then dereferences a NULL l2cap_conn inside l2cap_unregister_user(), which acquires conn->lock without a NULL check. Result: kernel NULL-pointer dereference. Apply the same if (session->conn) guard used at the twin site. No functional change when session->conn is non-NULL. Discovery and verification: - Found via static audit of every session->conn read in hidp/core.c after the referenced commit landed. The other reads are safe (creation-time in hidp_session_dev_init, already-guarded in session_free / hidp_session_thread / hidp_session_remove; the other hidp_session_find callers do not touch session->conn at all), so :1421 is the only remaining unguarded site. - Runtime A/B confirmed in UML with CONFIG_BT_HIDP=y + CONFIG_KASAN=y: a late_initcall stub that injects a fake hidp_session with conn=NULL into hidp_session_list and invokes hidp_connection_del() panics on the pre-fix tree at __mutex_lock from l2cap_unregister_user+0x2d, and returns cleanly on the post-fix tree with the new guard short-circuiting before the deref. Fixes: dbf666e4fc9b ("Bluetooth: HIDP: Fix possible UAF") Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> Assisted-by: Claude:claude-opus-4-7 --- net/bluetooth/hidp/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 7bcf8c5ceaee..9192efd1b156 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -1417,7 +1417,7 @@ int hidp_connection_del(struct hidp_conndel_req *req) HIDP_TRANS_HID_CONTROL | HIDP_CTRL_VIRTUAL_CABLE_UNPLUG, NULL, 0); - else + else if (session->conn) l2cap_unregister_user(session->conn, &session->user); hidp_session_put(session); -- 2.53.0 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* RE: Bluetooth: HIDP: guard session->conn in hidp_connection_del 2026-04-22 1:14 ` [PATCH] Bluetooth: HIDP: guard session->conn in hidp_connection_del Michael Bommarito @ 2026-04-22 4:13 ` bluez.test.bot 2026-04-22 14:55 ` [PATCH] " Luiz Augusto von Dentz 2026-05-02 16:43 ` [PATCH v2] Bluetooth: HIDP: serialise l2cap_unregister_user via hidp_session_sem Michael Bommarito 2 siblings, 0 replies; 14+ messages in thread From: bluez.test.bot @ 2026-04-22 4:13 UTC (permalink / raw) To: linux-bluetooth, michael.bommarito [-- Attachment #1: Type: text/plain, Size: 4405 bytes --] This is automated email and please do not reply to this email! Dear submitter, Thank you for submitting the patches to the linux bluetooth mailing list. This is a CI test results with your patch series: PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1084091 ---Test result--- Test Summary: CheckPatch FAIL 0.55 seconds GitLint PASS 0.20 seconds SubjectPrefix PASS 0.08 seconds BuildKernel PASS 26.22 seconds CheckAllWarning PASS 28.58 seconds CheckSparse PASS 27.49 seconds BuildKernel32 PASS 25.59 seconds TestRunnerSetup PASS 574.90 seconds TestRunner_l2cap-tester PASS 27.87 seconds TestRunner_iso-tester PASS 42.34 seconds TestRunner_bnep-tester PASS 6.48 seconds TestRunner_mgmt-tester FAIL 114.28 seconds TestRunner_rfcomm-tester PASS 9.83 seconds TestRunner_sco-tester PASS 14.50 seconds TestRunner_ioctl-tester PASS 10.22 seconds TestRunner_mesh-tester FAIL 12.18 seconds TestRunner_smp-tester PASS 8.81 seconds TestRunner_userchan-tester PASS 6.92 seconds TestRunner_6lowpan-tester FAIL 8.68 seconds IncrementalBuild PASS 25.52 seconds Details ############################## Test: CheckPatch - FAIL Desc: Run checkpatch.pl script Output: Bluetooth: HIDP: guard session->conn in hidp_connection_del WARNING: Non-standard signature: Assisted-by: #140: Assisted-by: Claude:claude-opus-4-7 ERROR: Unrecognized email address: 'Claude:claude-opus-4-7' #140: Assisted-by: Claude:claude-opus-4-7 total: 1 errors, 1 warnings, 0 checks, 8 lines checked NOTE: For some of the reported defects, checkpatch may be able to mechanically convert to the typical style using --fix or --fix-inplace. /github/workspace/src/patch/14533271.patch has style problems, please review. NOTE: Ignored message types: UNKNOWN_COMMIT_ID NOTE: If any of the errors are false positives, please report them to the maintainer, see CHECKPATCH in MAINTAINERS. ############################## Test: TestRunner_mgmt-tester - FAIL Desc: Run mgmt-tester with test-runner Output: Total: 494, Passed: 489 (99.0%), Failed: 1, Not Run: 4 Failed Test Cases Read Exp Feature - Success Failed 0.112 seconds ############################## Test: TestRunner_mesh-tester - FAIL Desc: Run mesh-tester with test-runner Output: Total: 10, Passed: 8 (80.0%), Failed: 2, Not Run: 0 Failed Test Cases Mesh - Send cancel - 1 Timed out 2.627 seconds Mesh - Send cancel - 2 Timed out 1.994 seconds ############################## Test: TestRunner_6lowpan-tester - FAIL Desc: Run 6lowpan-tester with test-runner Output: WARNING: possible circular locking dependency detected 7.0.0-rc7-gcdeca5510265 #1 Not tainted ------------------------------------------------------ kworker/0:1/11 is trying to acquire lock: ffff888002735940 ((wq_completion)hci0#2){+.+.}-{0:0}, at: touch_wq_lockdep_map+0x75/0x180 but task is already holding lock: ffffffff9d84f9e0 (rtnl_mutex){+.+.}-{4:4}, at: lowpan_unregister_netdev+0xd/0x30 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #4 (rtnl_mutex){+.+.}-{4:4}: lock_acquire+0xf7/0x2c0 __mutex_lock+0x16b/0x1fc0 lowpan_register_netdev+0x11/0x30 chan_ready_cb+0x836/0xd00 l2cap_recv_frame+0x61bb/0x88e0 l2cap_recv_acldata+0x790/0xdf0 hci_rx_work+0x500/0xd00 process_scheduled_works+0xba7/0x1a90 worker_thread+0x514/0xbb0 kthread+0x368/0x490 ret_from_fork+0x498/0x7e0 ret_from_fork_asm+0x19/0x30 -> #3 (&chan->lock#3/1){+.+.}-{4:4}: lock_acquire+0xf7/0x2c0 __mutex_lock+0x16b/0x1fc0 l2cap_chan_connect+0x74e/0x1980 lowpan_control_write+0x523/0x660 full_proxy_write+0x10b/0x190 vfs_write+0x1c0/0xf60 ksys_write+0xf1/0x1d0 do_syscall_64+0xa0/0x570 entry_SYSCALL_64_after_hwframe+0x74/0x7c -> #2 (&conn->lock){+.+.}-{4:4}: ... Total: 8, Passed: 8 (100.0%), Failed: 0, Not Run: 0 https://github.com/bluez/bluetooth-next/pull/115 --- Regards, Linux Bluetooth ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] Bluetooth: HIDP: guard session->conn in hidp_connection_del 2026-04-22 1:14 ` [PATCH] Bluetooth: HIDP: guard session->conn in hidp_connection_del Michael Bommarito 2026-04-22 4:13 ` bluez.test.bot @ 2026-04-22 14:55 ` Luiz Augusto von Dentz 2026-04-22 15:09 ` Michael Bommarito 2026-05-02 16:43 ` [PATCH v2] Bluetooth: HIDP: serialise l2cap_unregister_user via hidp_session_sem Michael Bommarito 2 siblings, 1 reply; 14+ messages in thread From: Luiz Augusto von Dentz @ 2026-04-22 14:55 UTC (permalink / raw) To: Michael Bommarito; +Cc: Marcel Holtmann, linux-bluetooth, linux-kernel Hi Michael, On Tue, Apr 21, 2026 at 9:14 PM Michael Bommarito <michael.bommarito@gmail.com> wrote: > > commit dbf666e4fc9b ("Bluetooth: HIDP: Fix possible UAF") changed > hidp_session_remove() to drop the L2CAP reference and set > session->conn = NULL once the session is considered removed, and > added an if (session->conn) guard around the l2cap_unregister_user() > call at the kthread-exit site in hidp_session_thread(). > > The sibling call site in hidp_connection_del() still invokes > l2cap_unregister_user(session->conn, &session->user) unconditionally. > hidp_session_find() takes the session refcount under > down_read(&hidp_session_sem) and returns; between the find() and the > call at :1421, hidp_session_remove() can run on another thread > (driven by the remote peer disconnecting or local teardown), take > down_write(&hidp_session_sem), set session->conn to NULL, and return. > The HIDPCONNDEL ioctl path then dereferences a NULL l2cap_conn inside > l2cap_unregister_user(), which acquires conn->lock without a NULL > check. Result: kernel NULL-pointer dereference. > > Apply the same if (session->conn) guard used at the twin site. No > functional change when session->conn is non-NULL. > > Discovery and verification: > > - Found via static audit of every session->conn read in hidp/core.c > after the referenced commit landed. The other reads are safe > (creation-time in hidp_session_dev_init, already-guarded in > session_free / hidp_session_thread / hidp_session_remove; the other > hidp_session_find callers do not touch session->conn at all), so > :1421 is the only remaining unguarded site. > - Runtime A/B confirmed in UML with CONFIG_BT_HIDP=y + CONFIG_KASAN=y: > a late_initcall stub that injects a fake hidp_session with > conn=NULL into hidp_session_list and invokes hidp_connection_del() > panics on the pre-fix tree at __mutex_lock from > l2cap_unregister_user+0x2d, and returns cleanly on the post-fix > tree with the new guard short-circuiting before the deref. > > Fixes: dbf666e4fc9b ("Bluetooth: HIDP: Fix possible UAF") > Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> > Assisted-by: Claude:claude-opus-4-7 > --- > net/bluetooth/hidp/core.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c > index 7bcf8c5ceaee..9192efd1b156 100644 > --- a/net/bluetooth/hidp/core.c > +++ b/net/bluetooth/hidp/core.c > @@ -1417,7 +1417,7 @@ int hidp_connection_del(struct hidp_conndel_req *req) > HIDP_TRANS_HID_CONTROL | > HIDP_CTRL_VIRTUAL_CABLE_UNPLUG, > NULL, 0); > - else > + else if (session->conn) > l2cap_unregister_user(session->conn, &session->user); > > hidp_session_put(session); > -- > 2.53.0 We might need a lock in order to access the session->conn: https://sashiko.dev/#/patchset/20260422011437.176643-1-michael.bommarito%40gmail.com -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] Bluetooth: HIDP: guard session->conn in hidp_connection_del 2026-04-22 14:55 ` [PATCH] " Luiz Augusto von Dentz @ 2026-04-22 15:09 ` Michael Bommarito 2026-04-22 15:48 ` Pauli Virtanen 2026-04-22 15:49 ` Luiz Augusto von Dentz 0 siblings, 2 replies; 14+ messages in thread From: Michael Bommarito @ 2026-04-22 15:09 UTC (permalink / raw) To: Luiz Augusto von Dentz; +Cc: Marcel Holtmann, linux-bluetooth, linux-kernel On Wed, Apr 22, 2026 at 10:55 AM Luiz Augusto von Dentz <luiz.dentz@gmail.com> wrote: > We might need a lock in order to access the session->conn: This one is a little easier than the other txwin_size issue in terms of blast radius. What pattern would you prefer here? Option 1, smaller but ordering questions: hold the semaphore across check and use like this: down_read(&hidp_session_sem); if (session->conn) l2cap_unregister_user(session->conn, &session->user); up_read(&hidp_session_sem) Option 2, more correct but more cycles: snapshot the conn and use outside down_read(&hidp_session_sem); conn = session->conn; if (conn) l2cap_conn_get(conn); up_read(&hidp_session_sem); if (conn) { l2cap_unregister_user(conn, &session->user); l2cap_conn_put(conn); } Thanks, Mike Bommarito ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] Bluetooth: HIDP: guard session->conn in hidp_connection_del 2026-04-22 15:09 ` Michael Bommarito @ 2026-04-22 15:48 ` Pauli Virtanen 2026-04-22 15:49 ` Luiz Augusto von Dentz 1 sibling, 0 replies; 14+ messages in thread From: Pauli Virtanen @ 2026-04-22 15:48 UTC (permalink / raw) To: Michael Bommarito, Luiz Augusto von Dentz Cc: Marcel Holtmann, linux-bluetooth, linux-kernel Hi, ke, 2026-04-22 kello 11:09 -0400, Michael Bommarito kirjoitti: > On Wed, Apr 22, 2026 at 10:55 AM Luiz Augusto von Dentz > <luiz.dentz@gmail.com> wrote: > > We might need a lock in order to access the session->conn: > > This one is a little easier than the other txwin_size issue in terms > of blast radius. > > What pattern would you prefer here? > > Option 1, smaller but ordering questions: hold the semaphore across > check and use like this: > > down_read(&hidp_session_sem); > if (session->conn) > l2cap_unregister_user(session->conn, &session->user); > up_read(&hidp_session_sem) > > > Option 2, more correct but more cycles: snapshot the conn and use outside > > down_read(&hidp_session_sem); > conn = session->conn; > if (conn) > l2cap_conn_get(conn); > up_read(&hidp_session_sem); > if (conn) { > l2cap_unregister_user(conn, &session->user); > l2cap_conn_put(conn); > } I'm not sure now (would need to rethink it through), but one probably should check if dbf666e4fc9b is needed or whether 752a6c9596d alone would be enough to address the original issue. -- Pauli Virtanen ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] Bluetooth: HIDP: guard session->conn in hidp_connection_del 2026-04-22 15:09 ` Michael Bommarito 2026-04-22 15:48 ` Pauli Virtanen @ 2026-04-22 15:49 ` Luiz Augusto von Dentz 1 sibling, 0 replies; 14+ messages in thread From: Luiz Augusto von Dentz @ 2026-04-22 15:49 UTC (permalink / raw) To: Michael Bommarito; +Cc: Marcel Holtmann, linux-bluetooth, linux-kernel Hi Michael, On Wed, Apr 22, 2026 at 11:09 AM Michael Bommarito <michael.bommarito@gmail.com> wrote: > > On Wed, Apr 22, 2026 at 10:55 AM Luiz Augusto von Dentz > <luiz.dentz@gmail.com> wrote: > > We might need a lock in order to access the session->conn: > > This one is a little easier than the other txwin_size issue in terms > of blast radius. > > What pattern would you prefer here? > > Option 1, smaller but ordering questions: hold the semaphore across > check and use like this: > > down_read(&hidp_session_sem); > if (session->conn) > l2cap_unregister_user(session->conn, &session->user); > up_read(&hidp_session_sem) > > > Option 2, more correct but more cycles: snapshot the conn and use outside > > down_read(&hidp_session_sem); > conn = session->conn; > if (conn) > l2cap_conn_get(conn); > up_read(&hidp_session_sem); > if (conn) { > l2cap_unregister_user(conn, &session->user); > l2cap_conn_put(conn); > } Neither seems completely correct, in my opinion. I guess we want to use option 2 but set the session->conn to NULL since it will call l2cap_unregister_user. > Thanks, > Mike Bommarito -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v2] Bluetooth: HIDP: serialise l2cap_unregister_user via hidp_session_sem 2026-04-22 1:14 ` [PATCH] Bluetooth: HIDP: guard session->conn in hidp_connection_del Michael Bommarito 2026-04-22 4:13 ` bluez.test.bot 2026-04-22 14:55 ` [PATCH] " Luiz Augusto von Dentz @ 2026-05-02 16:43 ` Michael Bommarito 2026-05-02 17:44 ` [v2] " bluez.test.bot 2026-05-04 17:10 ` [PATCH v2] " patchwork-bot+bluetooth 2 siblings, 2 replies; 14+ messages in thread From: Michael Bommarito @ 2026-05-02 16:43 UTC (permalink / raw) To: Marcel Holtmann Cc: Luiz Augusto von Dentz, Pauli Virtanen, linux-bluetooth, linux-kernel Commit dbf666e4fc9b ("Bluetooth: HIDP: Fix possible UAF") made hidp_session_remove() drop the L2CAP reference and set session->conn = NULL once the session is considered removed, and added a bare if (session->conn) guard around the kthread-exit l2cap_unregister_user() call in hidp_session_thread(). The sibling ioctl site in hidp_connection_del() still reads session->conn unlocked and unguarded, and the kthread-exit guard itself is a lockless double-read. hidp_session_find() drops hidp_session_sem before returning, so hidp_session_remove() can null session->conn between the lookup and the call in hidp_connection_del(). Worse, since commit 752a6c9596dd ("Bluetooth: L2CAP: Fix use-after-free in l2cap_unregister_user") takes mutex_lock(&conn->lock) inside l2cap_unregister_user(), a stale non-NULL snapshot also UAFs on conn->lock. v1 only added an if (session->conn) guard at the ioctl site, which doesn't address either race; Luiz suggested snapshotting session->conn under the sem and clearing it before the call. Taking hidp_session_sem across l2cap_unregister_user() would be wrong: l2cap_conn_del() already establishes the lock order conn->lock -> hidp_session_sem via l2cap_unregister_all_users() -> user->remove == hidp_session_remove(), so taking hidp_session_sem before conn->lock would AB/BA deadlock. Factor a helper hidp_session_unregister_conn() that under down_write(&hidp_session_sem) snapshots session->conn and clears the member, then outside the sem calls l2cap_unregister_user() and l2cap_conn_put() on the snapshot. Call it from both hidp_connection_del() and hidp_session_thread()'s exit path. At most one consumer wins the write-sem; later callers observe session->conn == NULL and skip the unregister and put, so the reference hidp_session_new() took via l2cap_conn_get() is consumed exactly once. session_free() already tolerates a NULL session->conn. Fixes: dbf666e4fc9b ("Bluetooth: HIDP: Fix possible UAF") Suggested-by: Luiz Augusto von Dentz <luiz.dentz@gmail.com> Link: https://lore.kernel.org/all/20260422011437.176643-1-michael.bommarito@gmail.com/ Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> Assisted-by: Claude:claude-opus-4-7 --- Tested under UML with CONFIG_BT_HIDP=y, CONFIG_KASAN=y, and CONFIG_PROVE_LOCKING=y. W=1 build of net/bluetooth/hidp/ clean; boot clean. A KCFLAGS-gated test stub (not part of this patch) drove hidp_session_unregister_conn() twice in a row against a fake session with conn = NULL: the helper short-circuited both times and lockdep stayed silent. net/bluetooth/hidp/core.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 7bcf8c5ceaee..976f91eeb745 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -1035,6 +1035,28 @@ static struct hidp_session *hidp_session_find(const bdaddr_t *bdaddr) return session; } +/* + * Consume session->conn: clear the member under hidp_session_sem, then + * l2cap_unregister_user() and l2cap_conn_put() the snapshot outside the + * sem. At most one caller wins; later callers see NULL and skip. The + * reference is the one hidp_session_new() took via l2cap_conn_get(). + */ +static void hidp_session_unregister_conn(struct hidp_session *session) +{ + struct l2cap_conn *conn; + + down_write(&hidp_session_sem); + conn = session->conn; + if (conn) + session->conn = NULL; + up_write(&hidp_session_sem); + + if (conn) { + l2cap_unregister_user(conn, &session->user); + l2cap_conn_put(conn); + } +} + /* * Start session synchronously * This starts a session thread and waits until initialization @@ -1311,8 +1333,7 @@ static int hidp_session_thread(void *arg) * Instead, this call has the same semantics as if user-space tried to * delete the session. */ - if (session->conn) - l2cap_unregister_user(session->conn, &session->user); + hidp_session_unregister_conn(session); hidp_session_put(session); @@ -1418,7 +1439,7 @@ int hidp_connection_del(struct hidp_conndel_req *req) HIDP_CTRL_VIRTUAL_CABLE_UNPLUG, NULL, 0); else - l2cap_unregister_user(session->conn, &session->user); + hidp_session_unregister_conn(session); hidp_session_put(session); -- 2.53.0 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* RE: [v2] Bluetooth: HIDP: serialise l2cap_unregister_user via hidp_session_sem 2026-05-02 16:43 ` [PATCH v2] Bluetooth: HIDP: serialise l2cap_unregister_user via hidp_session_sem Michael Bommarito @ 2026-05-02 17:44 ` bluez.test.bot 2026-05-04 17:10 ` [PATCH v2] " patchwork-bot+bluetooth 1 sibling, 0 replies; 14+ messages in thread From: bluez.test.bot @ 2026-05-02 17:44 UTC (permalink / raw) To: linux-bluetooth, michael.bommarito [-- Attachment #1: Type: text/plain, Size: 3741 bytes --] This is automated email and please do not reply to this email! Dear submitter, Thank you for submitting the patches to the linux bluetooth mailing list. This is a CI test results with your patch series: PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1088829 ---Test result--- Test Summary: CheckPatch PASS 0.64 seconds GitLint FAIL 0.24 seconds SubjectPrefix PASS 0.09 seconds BuildKernel PASS 28.18 seconds CheckAllWarning PASS 30.05 seconds CheckSparse PASS 28.76 seconds BuildKernel32 PASS 26.27 seconds TestRunnerSetup PASS 579.48 seconds TestRunner_l2cap-tester FAIL 6.77 seconds TestRunner_iso-tester PASS 295.82 seconds TestRunner_bnep-tester FAIL 6.75 seconds TestRunner_mgmt-tester FAIL 8.99 seconds TestRunner_rfcomm-tester PASS 29.07 seconds TestRunner_sco-tester PASS 68.13 seconds TestRunner_ioctl-tester FAIL 37.43 seconds TestRunner_mesh-tester PASS 27.11 seconds TestRunner_smp-tester PASS 6.58 seconds TestRunner_userchan-tester FAIL 6.68 seconds TestRunner_6lowpan-tester PASS 22.83 seconds IncrementalBuild PASS 25.14 seconds Details ############################## Test: GitLint - FAIL Desc: Run gitlint Output: [v2] Bluetooth: HIDP: serialise l2cap_unregister_user via hidp_session_sem WARNING: I3 - ignore-body-lines: gitlint will be switching from using Python regex 'match' (match beginning) to 'search' (match anywhere) semantics. Please review your ignore-body-lines.regex option accordingly. To remove this warning, set general.regex-style-search=True. More details: https://jorisroovers.github.io/gitlint/configuration/#regex-style-search 42: B1 Line exceeds max length (86>80): "Link: https://lore.kernel.org/all/20260422011437.176643-1-michael.bommarito@gmail.com/" ############################## Test: TestRunner_l2cap-tester - FAIL Desc: Run l2cap-tester with test-runner Output: No test result found ############################## Test: TestRunner_bnep-tester - FAIL Desc: Run bnep-tester with test-runner Output: No test result found ############################## Test: TestRunner_mgmt-tester - FAIL Desc: Run mgmt-tester with test-runner Output: No test result found ############################## Test: TestRunner_ioctl-tester - FAIL Desc: Run ioctl-tester with test-runner Output: Total: 28, Passed: 0 (0.0%), Failed: 11, Not Run: 17 Failed Test Cases Device List Timed out -30.849 seconds Device Info Timed out -6.201 seconds Reset Stat Timed out -6.204 seconds Set Link Mode - ACCEPT Timed out -6.207 seconds Set Pkt Type - DM Timed out -14.394 seconds Set Pkt Type - DH Timed out -14.397 seconds Set Pkt Type - HV Timed out -14.400 seconds Set Pkt Type - 2-DH Timed out -14.403 seconds Set Pkt Type - 2-DH Timed out -14.406 seconds Set Pkt Type - ALL Timed out -14.409 seconds Set ACL MTU - 1 Timed out -14.411 seconds ############################## Test: TestRunner_userchan-tester - FAIL Desc: Run userchan-tester with test-runner Output: No test result found https://github.com/bluez/bluetooth-next/pull/140 --- Regards, Linux Bluetooth ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2] Bluetooth: HIDP: serialise l2cap_unregister_user via hidp_session_sem 2026-05-02 16:43 ` [PATCH v2] Bluetooth: HIDP: serialise l2cap_unregister_user via hidp_session_sem Michael Bommarito 2026-05-02 17:44 ` [v2] " bluez.test.bot @ 2026-05-04 17:10 ` patchwork-bot+bluetooth 1 sibling, 0 replies; 14+ messages in thread From: patchwork-bot+bluetooth @ 2026-05-04 17:10 UTC (permalink / raw) To: Michael Bommarito; +Cc: marcel, luiz.dentz, pav, linux-bluetooth, linux-kernel Hello: This patch was applied to bluetooth/bluetooth-next.git (master) by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>: On Sat, 2 May 2026 12:43:03 -0400 you wrote: > Commit dbf666e4fc9b ("Bluetooth: HIDP: Fix possible UAF") made > hidp_session_remove() drop the L2CAP reference and set > session->conn = NULL once the session is considered removed, and > added a bare if (session->conn) guard around the kthread-exit > l2cap_unregister_user() call in hidp_session_thread(). The sibling > ioctl site in hidp_connection_del() still reads session->conn > unlocked and unguarded, and the kthread-exit guard itself is a > lockless double-read. > > [...] Here is the summary with links: - [v2] Bluetooth: HIDP: serialise l2cap_unregister_user via hidp_session_sem https://git.kernel.org/bluetooth/bluetooth-next/c/fd572908d364 You are awesome, thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2026-05-04 17:10 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-03-06 2:31 [PATCH v1] Bluetooth: HIDP: Fix possible UAF Luiz Augusto von Dentz 2026-03-06 4:27 ` [v1] " bluez.test.bot 2026-03-06 18:40 ` [PATCH v1] " patchwork-bot+bluetooth 2026-03-06 18:49 ` Pauli Virtanen 2026-03-06 19:23 ` Luiz Augusto von Dentz 2026-04-22 1:14 ` [PATCH] Bluetooth: HIDP: guard session->conn in hidp_connection_del Michael Bommarito 2026-04-22 4:13 ` bluez.test.bot 2026-04-22 14:55 ` [PATCH] " Luiz Augusto von Dentz 2026-04-22 15:09 ` Michael Bommarito 2026-04-22 15:48 ` Pauli Virtanen 2026-04-22 15:49 ` Luiz Augusto von Dentz 2026-05-02 16:43 ` [PATCH v2] Bluetooth: HIDP: serialise l2cap_unregister_user via hidp_session_sem Michael Bommarito 2026-05-02 17:44 ` [v2] " bluez.test.bot 2026-05-04 17:10 ` [PATCH v2] " patchwork-bot+bluetooth
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox