mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
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: a73c046a28 ("Bluetooth: Implement Set ADV set random address")
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
a9f9eeb534
commit
a7c5c18b7c
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user