Re: [PATCH] Bluetooth: hci_sync: Fix scan response data UAF
Luiz Augusto von Dentz <[email protected]>
| Newsgroups | org.kernel.vger.linux-bluetooth,org.kernel.vger.linux-kernel,org.kernel.vger.stable |
|---|---|
| Message-ID | <CABBYNZ+G3jD3A6-k1fEm2sSRa27o8s0PNN_arzVa8de-eJK8oQ@mail.gmail.com> |
Hi, On Mon, Jul 20, 2026 at 12:47 PM Chengfeng Ye <[email protected]> wrote: > > 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: [email protected] > Signed-off-by: Chengfeng Ye <[email protected]> > --- > 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 It looks like Sashiko found some other places where this could be a problem: https://sashiko.dev/#/patchset/20260720164738.2921802-1-nicoyip.dev%40gmail.com -- Luiz Augusto von Dentz