mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 02:21:39 -04:00
Bluetooth: hci_sync: free the advertising instance on the failure and cancel paths
adv_timeout_expire() hands a kmalloc()ed instance byte to
hci_cmd_sync_queue() with a NULL destroy callback, and only
adv_timeout_expire_sync() frees it. That leaks on two paths:
- the return value is not checked, and hci_cmd_sync_queue() does not
take ownership when it fails (-ENETDOWN, -ENODEV, -ENOMEM);
- a cancelled entry is not released, as _hci_cmd_sync_cancel_entry()
does not free entry->data when there is no destroy callback.
hci_cmd_sync_clear() cancels every pending entry when the controller
is unregistered.
Free the buffer from a destroy callback, and in the caller when the entry
could not be queued at all.
Fixes: c249ea9b43 ("Bluetooth: Move Adv Instance timer to hci_sync")
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
committed by
Luiz Augusto von Dentz
parent
42de40abe2
commit
120d8dc042
@@ -540,8 +540,6 @@ static int adv_timeout_expire_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
u8 instance = *(u8 *)data;
|
||||
|
||||
kfree(data);
|
||||
|
||||
hci_clear_adv_instance_sync(hdev, NULL, instance, false);
|
||||
|
||||
if (list_empty(&hdev->adv_instances))
|
||||
@@ -550,6 +548,12 @@ static int adv_timeout_expire_sync(struct hci_dev *hdev, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void adv_timeout_expire_destroy(struct hci_dev *hdev, void *data,
|
||||
int err)
|
||||
{
|
||||
kfree(data);
|
||||
}
|
||||
|
||||
static void adv_timeout_expire(struct work_struct *work)
|
||||
{
|
||||
u8 *inst_ptr;
|
||||
@@ -570,7 +574,9 @@ static void adv_timeout_expire(struct work_struct *work)
|
||||
goto unlock;
|
||||
|
||||
*inst_ptr = hdev->cur_adv_instance;
|
||||
hci_cmd_sync_queue(hdev, adv_timeout_expire_sync, inst_ptr, NULL);
|
||||
if (hci_cmd_sync_queue(hdev, adv_timeout_expire_sync, inst_ptr,
|
||||
adv_timeout_expire_destroy) < 0)
|
||||
kfree(inst_ptr);
|
||||
|
||||
unlock:
|
||||
hci_dev_unlock(hdev);
|
||||
|
||||
Reference in New Issue
Block a user