The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH] Bluetooth: hci_event: Synchronously cancel timers in hci_cmd_complete_evt()
@ 2026-06-19  0:42 Sungwoo Kim
  2026-08-17  8:28 ` kernel test robot
  0 siblings, 1 reply; 2+ messages in thread
From: Sungwoo Kim @ 2026-06-19  0:42 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz, Chethan T N,
	Srivatsa Ravishankar, Kiran K, Manish Mandlik
  Cc: Sungwoo Kim, Dave Tian, linux-bluetooth, linux-kernel

RFC only.

hci_cmd_complete_evt() and hci_cmd_timeout can interleave, leading to
user-after-free access.

CPU1                  CPU2
hci_cmd_timeout()
                      hci_event_packet()
                      [snip]
                        hci_cmd_complete_evt()
                          handle_cmd_cnt_and_timer()
                            // this is asynchronous
                            cancel_delayed_work(&hdev->cmd_timer)
                        hci_cmd_sync_complete()
                          kfree_skb(hdev->req_skb); // free
  hci_skb_opcode(hdev->req_skb); // use-after-free

To fix this, make cancel_delayed_work() synchronous so it can wait for
the timeout handler.
However, this is not a complete fix because hci_cmd_timeout() resets the
device and queue a new command.
I would like to request for comments the better way to fix this issue.

KASAN splat:
BUG: KASAN: slab-use-after-free in hci_cmd_timeout+0x216/0x260 net/bluetooth/hci_core.c:1432
Read of size 2 at addr ffff88811605a7b8 by task syz.2.21760/74233

Call Trace:
 <TASK>
 __dump_stack lib/dump_stack.c:94 [inline]
 dump_stack_lvl+0xba/0x110 lib/dump_stack.c:120
 print_address_description mm/kasan/report.c:378 [inline]
 print_report+0x157/0x4c9 mm/kasan/report.c:482
 kasan_report+0xdf/0x1b0 mm/kasan/report.c:595
 hci_cmd_timeout+0x216/0x260 net/bluetooth/hci_core.c:1432
[snip]

Freed by task 4563:
[snip]
 kfree_skb include/linux/skbuff.h:1333 [inline]
 hci_cmd_sync_complete net/bluetooth/hci_sync.c:36 [inline]
 hci_cmd_sync_complete+0x152/0x370 net/bluetooth/hci_sync.c:24
 hci_event_packet+0x8fd/0xd20 net/bluetooth/hci_event.c:7863
 hci_rx_work+0x5c5/0xfa0 net/bluetooth/hci_core.c:4041
 process_one_work+0x93f/0x1810 kernel/workqueue.c:3316
[snip]

Fixes: ecb71f256667 ("Bluetooth: Fix race condition in handling NOP command")
Acked-by: Dave Tian <daveti@purdue.edu>
Signed-off-by: Sungwoo Kim <iam@sung-woo.kim>
---
 net/bluetooth/hci_event.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index eea2f810aafa..3639aa896bc3 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3765,14 +3765,14 @@ static void hci_remote_features_evt(struct hci_dev *hdev, void *data,
 	hci_dev_unlock(hdev);
 }
 
-static inline void handle_cmd_cnt_and_timer(struct hci_dev *hdev, u8 ncmd)
+static inline void handle_cmd_cnt_and_timer_sync(struct hci_dev *hdev, u8 ncmd)
 {
-	cancel_delayed_work(&hdev->cmd_timer);
+	cancel_delayed_work_sync(&hdev->cmd_timer);
 
 	rcu_read_lock();
 	if (!test_bit(HCI_RESET, &hdev->flags)) {
 		if (ncmd) {
-			cancel_delayed_work(&hdev->ncmd_timer);
+			cancel_delayed_work_sync(&hdev->ncmd_timer);
 			atomic_set(&hdev->cmd_cnt, 1);
 		} else {
 			if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
@@ -4304,7 +4304,7 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, void *data,
 		*status = skb->data[0];
 	}
 
-	handle_cmd_cnt_and_timer(hdev, ev->ncmd);
+	handle_cmd_cnt_and_timer_sync(hdev, ev->ncmd);
 
 	hci_req_cmd_complete(hdev, *opcode, *status, req_complete,
 			     req_complete_skb);
@@ -4418,7 +4418,7 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, void *data,
 		}
 	}
 
-	handle_cmd_cnt_and_timer(hdev, ev->ncmd);
+	handle_cmd_cnt_and_timer_sync(hdev, ev->ncmd);
 
 	/* Indicate request completion if the command failed. Also, if
 	 * we're not waiting for a special event and we get a success
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] Bluetooth: hci_event: Synchronously cancel timers in hci_cmd_complete_evt()
  2026-06-19  0:42 [PATCH] Bluetooth: hci_event: Synchronously cancel timers in hci_cmd_complete_evt() Sungwoo Kim
@ 2026-08-17  8:28 ` kernel test robot
  0 siblings, 0 replies; 2+ messages in thread
From: kernel test robot @ 2026-08-17  8:28 UTC (permalink / raw)
  To: Sungwoo Kim
  Cc: oe-lkp, lkp, Dave Tian, linux-bluetooth, Marcel Holtmann,
	Luiz Augusto von Dentz, Chethan T N, Srivatsa Ravishankar,
	Kiran K, Manish Mandlik, Sungwoo Kim, linux-kernel, yi1.lai


Hello,

kernel test robot noticed "BUG:sleeping_function_called_from_invalid_context_at_kernel/workqueue.c" on:

commit: 4e57c39dee9e03022145302358f459ed5a2d4676 ("[PATCH] Bluetooth: hci_event: Synchronously cancel timers in hci_cmd_complete_evt()")
url: https://github.com/intel-lab-lkp/linux/commits/Sungwoo-Kim/Bluetooth-hci_event-Synchronously-cancel-timers-in-hci_cmd_complete_evt/20260807-040337
base: https://git.kernel.org/cgit/linux/kernel/git/bluetooth/bluetooth.git master 
patch link: https://lore.kernel.org/all/20260619004222.3764523-2-iam@sung-woo.kim/
patch subject: [PATCH] Bluetooth: hci_event: Synchronously cancel timers in hci_cmd_complete_evt()

in testcase: perf-fuzzer
version: perf-fuzzer-x86_64-3cf46b1-1_20260807
with following parameters:

	runtime: 1h



config: x86_64-rhel-9.4-bpf
compiler: gcc-14
test machine: 16 threads Intel(R) Core(TM) i7-13620H (Raptor Lake) with 32G memory


If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <yi1.lai@intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202608171032.be018232-lkp@intel.com



kern  :err   : [   86.152673] [    T369] BUG: sleeping function called from invalid context at kernel/workqueue.c:4487
kern  :err   : [   86.152761] [    T369] in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 369, name: kworker/u65:1
kern  :err   : [   86.152792] [    T369] preempt_count: 0, expected: 0
kern  :err   : [   86.152812] [    T369] RCU nest depth: 1, expected: 0
kern  :warn  : [   86.152831] [    T369] 3 locks held by kworker/u65:1/369:
kern  :warn  : [   86.152852] [    T369]  #0: ffff888886372940 ((wq_completion)hci0#2){+.+.}-{0:0}, at: process_one_work (workqueue.c:3297)
kern  :warn  : [   86.152907] [    T369]  #1: ffff88888350fd40 ((work_completion)(&hdev->rx_work)){+.+.}-{0:0}, at: process_one_work (workqueue.c:3298)
kern  :warn  : [   86.152956] [    T369]  #2: ffffffff8542d780 (rcu_read_lock){....}-{1:3}, at: handle_cmd_cnt_and_timer_sync (linux/rcupdate.h:300 linux/rcupdate.h:840 bluetooth/hci_event.c:3760) bluetooth
kern  :warn  : [   86.153170] [    T369] CPU: 12 UID: 0 PID: 369 Comm: kworker/u65:1 Tainted: G S                  7.2.0-rc4+ #1 PREEMPT(full)
kern  :warn  : [   86.153177] [    T369] Tainted: [S]=CPU_OUT_OF_SPEC
kern  :warn  : [   86.153179] [    T369] Hardware name: LENOVO 90XW004HPL/336B, BIOS M5LKT1CA 01/06/2025
kern  :warn  : [   86.153181] [    T369] Workqueue: hci0 hci_rx_work [bluetooth]
kern  :warn  : [   86.153342] [    T369] Call Trace:
kern  :warn  : [   86.153344] [    T369]  <TASK>
kern  :warn  : [   86.153347] [    T369]  dump_stack_lvl (dump_stack.c:94 dump_stack.c:120)
kern  :warn  : [   86.153356] [    T369]  __might_resched.cold (sched/core.c:9197)
kern  :warn  : [   86.153365] [    T369]  cancel_delayed_work_sync (workqueue.c:4487 workqueue.c:4568)
kern  :warn  : [   86.153371] [    T369] handle_cmd_cnt_and_timer_sync (bluetooth/hci_event.c:3763) bluetooth
kern  :warn  : [   86.153537] [    T369] hci_cmd_complete_evt (bluetooth/hci_event.c:4295) bluetooth
kern  :warn  : [   86.153704] [    T369]  ? __skb_clone (core/skbuff.c:1634)
kern  :warn  : [   86.153713] [    T369] hci_event_packet (bluetooth/hci_event.c:7781 bluetooth/hci_event.c:7835) bluetooth
kern  :warn  : [   86.153881] [    T369]  ? __pfx_hci_cmd_complete_evt (bluetooth/hci_event.c:4421 (discriminator 4)) bluetooth
kern  :warn  : [   86.154048] [    T369]  ? __pfx_hci_event_packet (net/bluetooth/hci_core.h:1688 (discriminator 2)) bluetooth
kern  :warn  : [   86.154217] [    T369]  ? __call_rcu_common+0x535/0x570
kern  :warn  : [   86.154225] [    T369]  ? preempt_count_sub (sched/core.c:6000 (discriminator 2) sched/core.c:5997 (discriminator 2) sched/core.c:6019 (discriminator 2))
kern  :warn  : [   86.154237] [    T369] hci_rx_work (bluetooth/hci_core.c:4039) bluetooth
kern  :warn  : [   86.154402] [    T369]  process_one_work (workqueue.c:3322)
kern  :warn  : [   86.154417] [    T369]  ? __pfx_process_one_work (workqueue.c:1978 (discriminator 7))
kern  :warn  : [   86.154423] [    T369]  ? __list_add_valid_or_report (list_debug.c:32)
kern  :warn  : [   86.154435] [    T369]  ? __pfx_hci_rx_work (linux/skbuff.h:1323) bluetooth
kern  :warn  : [   86.154595] [    T369]  worker_thread (workqueue.c:3405 workqueue.c:3486)
kern  :warn  : [   86.154605] [    T369]  ? __kthread_parkme (kthread.c:285 (discriminator 1))
kern  :warn  : [   86.154611] [    T369]  ? __pfx_worker_thread (workqueue.c:3380)
kern  :warn  : [   86.154616] [    T369]  kthread (kthread.c:436)
kern  :warn  : [   86.154621] [    T369]  ? kthread (kthread.c:412 (discriminator 1))
kern  :warn  : [   86.154625] [    T369]  ? __pfx_kthread (kthread.c:378)
kern  :warn  : [   86.154632] [    T369]  ret_from_fork (x86/kernel/process.c:158)
kern  :warn  : [   86.154638] [    T369]  ? __pfx_ret_from_fork (x86/include/asm/entry-common.h:54)
kern  :warn  : [   86.154646] [    T369]  ? __switch_to (linux/thread_info.h:142 (discriminator 2) x86/kernel/process.h:17 (discriminator 2) x86/kernel/process_64.c:676 (discriminator 2))
kern  :warn  : [   86.154651] [    T369]  ? __pfx_kthread (kthread.c:378)
kern  :warn  : [   86.154657] [    T369]  ret_from_fork_asm (x86/entry/entry_64.S:245)
kern  :warn  : [   86.154674] [    T369]  </TASK>
kern  :info  : [   86.156790] [    T172] Bluetooth: hci0: Firmware timestamp 2022.51 buildtype 1 build 56683
kern  :info  : [   86.156888] [    T172] Bluetooth: hci0: Firmware SHA1: 0xe2305c5c
kern  :info  : [   86.164030] [    T371] xor: automatically using best checksumming function   avx
kern  :info  : [   86.178626] [    T172] Bluetooth: hci0: DSM reset method type: 0x00
kern  :info  : [   86.202655] [    T328] think_lmi: ThinkCenter modified support being used
kern  :err   : [   86.311812] [    T312] ACPI BIOS Error (bug): Could not resolve symbol [^^RP28.PXSX.WIST], AE_NOT_FOUND (20260408/psargs-365)
kern  :err   : [   86.311950] [    T312] ACPI Error: Aborting method _SB.PC00.CNVW.IFUN due to previous error (AE_NOT_FOUND) (20260408/psparse-543)
kern  :err   : [   86.315878] [    T312] ACPI Error: Aborting method _SB.PC00.CNVW._DSM due to previous error (AE_NOT_FOUND) (20260408/psparse-543)
kern  :info  : [   86.318661] [    T312] iwlwifi 0000:00:14.3: Detected crf-id 0x1300504, cnv-id 0x80400 wfpm id 0x80000030
kern  :info  : [   86.318776] [    T312] iwlwifi 0000:00:14.3: PCI dev 51f1/0274, rev=0x370, rfid=0x10a100
kern  :info  : [   86.318810] [    T312] iwlwifi 0000:00:14.3: Detected Intel(R) Wi-Fi 6 AX203


The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20260817/202608171032.be018232-lkp@intel.com



--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-08-17  8:28 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-19  0:42 [PATCH] Bluetooth: hci_event: Synchronously cancel timers in hci_cmd_complete_evt() Sungwoo Kim
2026-08-17  8:28 ` kernel test robot

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