public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
* [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; 7+ 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] 7+ 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; 7+ 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] 7+ 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; 7+ 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] 7+ 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; 7+ 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] 7+ 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; 7+ 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] 7+ 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
  3 siblings, 1 reply; 7+ 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] 7+ 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
  0 siblings, 0 replies; 7+ 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] 7+ messages in thread

end of thread, other threads:[~2026-04-22  4:13 UTC | newest]

Thread overview: 7+ 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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox