From a7c5c18b7cc30dcd2a9ae5a0fb38378d3998417e Mon Sep 17 00:00:00 2001 From: Cen Zhang Date: Fri, 30 Oct 2026 22:27:45 +0800 Subject: [PATCH] Bluetooth: hci_core: Initialize advertising RPA work only once hci_add_adv_instance() also updates existing instances and calls INIT_DELAYED_WORK() on their rpa_expired_cb every time, even when the work is pending or running. cancel_delayed_work_sync() then no longer finds the work, so hci_remove_adv_instance() can free the instance under it: hdev->workqueue MGMT_OP_ADD_EXT_ADV_PARAMS adv_instance_rpa_expired() hci_dev_lock(hdev) hci_add_adv_instance() INIT_DELAYED_WORK() mgmt_pending_new() fails hci_remove_adv_instance() cancel_delayed_work_sync() returns without waiting kfree(adv) hci_dev_unlock(hdev) adv->rpa_expired = true The work has been initialized on every update since it was added. Initialize it only when the instance is allocated. KASAN report as below: BUG: KASAN: slab-use-after-free in adv_instance_rpa_expired+0x139/0x160 Write of size 1 at addr ffff888108d84b2e by task kworker/u17:0/504 Workqueue: hci0 adv_instance_rpa_expired Call Trace: adv_instance_rpa_expired+0x139/0x160 Allocated by task 560: hci_add_adv_instance+0x68d/0x9d0 add_ext_adv_params+0x4d4/0xb60 hci_sock_sendmsg+0x128b/0x22e0 Freed by task 594: kfree+0x307/0x580 hci_remove_adv_instance+0x230/0x540 add_ext_adv_params+0xa43/0xb60 hci_sock_sendmsg+0x128b/0x22e0 Last potentially related work creation: insert_work+0x37/0x210 __queue_work+0xaba/0x1270 call_timer_fn+0x171/0x500 The buggy address belongs to the object at ffff888108d84800 which belongs to the cache kmalloc-1k of size 1024 The buggy address is located 814 bytes inside of freed 1024-byte region [ffff888108d84800, ffff888108d84c00) Fixes: a73c046a2869 ("Bluetooth: Implement Set ADV set random address") Signed-off-by: Cen Zhang Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/hci_core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index a299aea1dd09..bc77db53b195 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1700,6 +1700,9 @@ struct adv_info *hci_add_adv_instance(struct hci_dev *hdev, u8 instance, if (!adv) return ERR_PTR(-ENOMEM); + INIT_DELAYED_WORK(&adv->rpa_expired_cb, + adv_instance_rpa_expired); + adv->pending = true; adv->instance = instance; @@ -1736,8 +1739,6 @@ struct adv_info *hci_add_adv_instance(struct hci_dev *hdev, u8 instance, else adv->duration = duration; - INIT_DELAYED_WORK(&adv->rpa_expired_cb, adv_instance_rpa_expired); - BT_DBG("%s for %dMR", hdev->name, instance); return adv;