From: Chengfeng Ye <nicoyip.dev@gmail.com>
To: Marcel Holtmann <marcel@holtmann.org>,
Luiz Augusto von Dentz <luiz.dentz@gmail.com>
Cc: linux-bluetooth@vger.kernel.org, linux-kernel@vger.kernel.org,
Chengfeng Ye <nicoyip.dev@gmail.com>,
stable@vger.kernel.org
Subject: [PATCH] Bluetooth: hci_sync: Fix scan response data UAF
Date: Tue, 21 Jul 2026 00:47:38 +0800 [thread overview]
Message-ID: <20260720164738.2921802-1-nicoyip.dev@gmail.com> (raw)
eir_create_scan_rsp() calls hci_find_adv_instance(), whose return value is
valid only while hdev->lock is held. After advertising setup was moved to
hci_cmd_sync_work, neither scan response data builder held that lock.
hci_set_ext_scan_rsp_data_sync() also kept the returned pointer while
waiting for the controller and wrote scan_rsp_changed through it afterward.
An advertising termination event can therefore interleave as follows:
hci_cmd_sync_work hci_rx_work
hci_find_adv_instance()
__hci_cmd_sync_status()
wait for controller reply hci_dev_lock()
hci_remove_adv_instance()
kfree(adv)
adv->scan_rsp_changed = false
KASAN reported:
BUG: KASAN: slab-use-after-free in hci_set_ext_scan_rsp_data_sync+0x2e1/0x300
Write of size 1 at addr ffff88810a45d21d by task kworker/u17:0/88
Workqueue: hci0 hci_cmd_sync_work
Call Trace:
hci_set_ext_scan_rsp_data_sync+0x2e1/0x300
hci_schedule_adv_instance_sync+0x390/0x4c0
hci_cmd_sync_work+0x173/0x300
Allocated by task 87:
hci_add_adv_instance+0x538/0xac0
add_advertising+0x885/0x1160
Freed by task 89:
kfree+0x131/0x3c0
hci_remove_adv_instance+0x1d8/0x3b0
hci_le_ext_adv_term_evt+0x17b/0x730
Hold hdev->lock while looking up the instance, building the scan
response, and clearing its dirty bit. Clear the bit before waiting for
the controller so no adv_info pointer survives the wait, and restore it
under the lock if the command fails. This also preserves an update that
races with a successful command because that update sets the bit again.
Protect the legacy scan response builder with the same lock.
Fixes: cba6b758711c ("Bluetooth: hci_sync: Make use of hci_cmd_sync_queue set 2")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
---
net/bluetooth/hci_sync.c | 32 +++++++++++++++++++++++++++-----
1 file changed, 27 insertions(+), 5 deletions(-)
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index 532534bc601c..8c69a98c71e8 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -1490,9 +1490,13 @@ static int hci_set_ext_scan_rsp_data_sync(struct hci_dev *hdev, u8 instance)
int err;
if (instance) {
+ hci_dev_lock(hdev);
+
adv = hci_find_adv_instance(hdev, instance);
- if (!adv || !adv->scan_rsp_changed)
+ if (!adv || !adv->scan_rsp_changed) {
+ hci_dev_unlock(hdev);
return 0;
+ }
}
len = eir_create_scan_rsp(hdev, instance, pdu->data);
@@ -1502,15 +1506,27 @@ static int hci_set_ext_scan_rsp_data_sync(struct hci_dev *hdev, u8 instance)
pdu->operation = LE_SET_ADV_DATA_OP_COMPLETE;
pdu->frag_pref = LE_SET_ADV_DATA_NO_FRAG;
+ if (adv) {
+ adv->scan_rsp_changed = false;
+ hci_dev_unlock(hdev);
+ }
+
err = __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_SCAN_RSP_DATA,
struct_size(pdu, data, len), pdu,
HCI_CMD_TIMEOUT);
- if (err)
+ if (err) {
+ if (instance) {
+ hci_dev_lock(hdev);
+ adv = hci_find_adv_instance(hdev, instance);
+ if (adv)
+ adv->scan_rsp_changed = true;
+ hci_dev_unlock(hdev);
+ }
+
return err;
+ }
- if (adv) {
- adv->scan_rsp_changed = false;
- } else {
+ if (!instance) {
memcpy(hdev->scan_rsp_data, pdu->data, len);
hdev->scan_rsp_data_len = len;
}
@@ -1525,8 +1541,14 @@ static int __hci_set_scan_rsp_data_sync(struct hci_dev *hdev, u8 instance)
memset(&cp, 0, sizeof(cp));
+ if (instance)
+ hci_dev_lock(hdev);
+
len = eir_create_scan_rsp(hdev, instance, cp.data);
+ if (instance)
+ hci_dev_unlock(hdev);
+
if (hdev->scan_rsp_data_len == len &&
!memcmp(cp.data, hdev->scan_rsp_data, len))
return 0;
--
2.43.0
next reply other threads:[~2026-07-20 16:47 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-20 16:47 Chengfeng Ye [this message]
2026-07-20 18:55 ` Bluetooth: hci_sync: Fix scan response data UAF bluez.test.bot
2026-07-20 19:54 ` [PATCH] " Luiz Augusto von Dentz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260720164738.2921802-1-nicoyip.dev@gmail.com \
--to=nicoyip.dev@gmail.com \
--cc=linux-bluetooth@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luiz.dentz@gmail.com \
--cc=marcel@holtmann.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.