lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20251209071248.3575845-1-zzzccc427@gmail.com>
Date: Tue,  9 Dec 2025 15:12:48 +0800
From: Cen Zhang <zzzccc427@...il.com>
To: luiz.dentz@...il.com,
	marcel@...tmann.org
Cc: linux-kernel@...r.kernel.org,
	linux-bluetooth@...r.kernel.org,
	pav@....fi,
	baijiaju1990@...il.com,
	r33s3n6@...il.com,
	gality369@...il.com,
	zhenghaoran154@...il.com,
	Cen Zhang <zzzccc427@...il.com>
Subject: [PATCH] Bluetooth: btintel: serialize hw error recovery with req_lock

btintel_hw_error() issues two __hci_cmd_sync() calls to reset the
controller and fetch the Intel exception report. Unlike the shutdown
path, this helper ran without hci_req_sync_lock(), so it could race
against hci_dev_do_close() and both sides would manipulate
hdev->req_status/req_rsp concurrently.When the close path freed the
shared response buffer first, the still running hw_error path hit a
slab-use-after-free inside kfree_skb() (skb_unref → atomic_read) and
KASAN reported the crash in the trace.

Acquire hci_req_sync_lock() around the hw_error recovery sequence and
make sure all error/cleanup paths release it. This serializes the Intel
handler with every other synchronous command issuer and prevents the
req_* bookkeeping from being double-touched.

Below is the data race report and the kasan report:

BUG: data-race in __hci_cmd_sync_sk / btintel_shutdown_combined

read of hdev->req_rsp at net/bluetooth/hci_sync.c:199 by task kworker/u17:1/83
write/free of same SKB at drivers/bluetooth/btintel.c:3660 by task ioctl/22580

Call Trace (reader):
  __hci_cmd_sync_sk+0x12f2/0x1c30 net/bluetooth/hci_sync.c:200
  __hci_cmd_sync+0x55/0x80 net/bluetooth/hci_sync.c:223
  btintel_hw_error+0x114/0x670 drivers/bluetooth/btintel.c:254
  hci_error_reset+0x348/0xa30 net/bluetooth/hci_core.c:1030
  ...

Call Trace (writer):
  btintel_shutdown_combined+0xd0/0x360 drivers/bluetooth/btintel.c:3648
  hci_dev_close_sync+0x9ae/0x2c10 net/bluetooth/hci_sync.c:5246
  hci_dev_do_close+0x232/0x460 net/bluetooth/hci_core.c:526
  ...

BUG: KASAN: slab-use-after-free in sk_skb_reason_drop+0x43/0x380 net/core/skbuff.c:1202
Read of size 4 at addr ffff888144a738dc by task kworker/u17:1/83

Call Trace:
  __hci_cmd_sync_sk+0x12f2/0x1c30 net/bluetooth/hci_sync.c:200
  __hci_cmd_sync+0x55/0x80 net/bluetooth/hci_sync.c:223
  btintel_hw_error+0x186/0x670 drivers/bluetooth/btintel.c:260
  ...

Allocated by task 84:
  skb_clone+0x212/0x3a0 net/core/skbuff.c:2049
  hci_event_packet+0x66c/0x2da0 net/bluetooth/hci_event.c:7614
  ...

Freed by task 22580:
  btintel_shutdown_combined+0xd0/0x360 drivers/bluetooth/btintel.c:3648
  hci_dev_close_sync+0x9ae/0x2c10 net/bluetooth/hci_sync.c:5246
  hci_dev_do_close+0x232/0x460 net/bluetooth/hci_core.c:526
  ...

Signed-off-by: Cen Zhang <zzzccc427@...il.com>
---
 drivers/bluetooth/btintel.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
index 9d29ab811..baa3ee510 100644
--- a/drivers/bluetooth/btintel.c
+++ b/drivers/bluetooth/btintel.c
@@ -251,10 +251,12 @@ void btintel_hw_error(struct hci_dev *hdev, u8 code)
 
 	bt_dev_err(hdev, "Hardware error 0x%2.2x", code);
 
+	hci_req_sync_lock(hdev);
 	skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
 	if (IS_ERR(skb)) {
 		bt_dev_err(hdev, "Reset after hardware error failed (%ld)",
 			   PTR_ERR(skb));
+		hci_req_sync_unlock(hdev);
 		return;
 	}
 	kfree_skb(skb);
@@ -263,18 +265,22 @@ void btintel_hw_error(struct hci_dev *hdev, u8 code)
 	if (IS_ERR(skb)) {
 		bt_dev_err(hdev, "Retrieving Intel exception info failed (%ld)",
 			   PTR_ERR(skb));
+		hci_req_sync_unlock(hdev);
 		return;
 	}
 
 	if (skb->len != 13) {
 		bt_dev_err(hdev, "Exception info size mismatch");
 		kfree_skb(skb);
+		hci_req_sync_unlock(hdev);
 		return;
 	}
 
 	bt_dev_err(hdev, "Exception info %s", (char *)(skb->data + 1));
 
 	kfree_skb(skb);
+
+	hci_req_sync_unlock(hdev);
 }
 EXPORT_SYMBOL_GPL(btintel_hw_error);
 
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ