mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-31 08:15:07 -04:00
Bluetooth: MGMT: free the mesh send cancel command when it is cancelled
mesh_send_cancel() queues the pending command with a NULL destroy
callback, so it is only freed if send_cancel() runs. A cancelled entry is
leaked, as _hci_cmd_sync_cancel_entry() does not release entry->data when
there is no destroy callback, and hci_cmd_sync_clear() cancels every
pending entry when the controller is unregistered. Nothing else reclaims
it either: mgmt_pending_new() does not put the command on
hdev->mgmt_pending.
The leak also pins the socket reference taken by mgmt_pending_new(), so
the mgmt socket is never released.
Free the command from a destroy callback.
Fixes: b338d91703 ("Bluetooth: Implement support for Mesh")
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
120d8dc042
commit
3c742feda8
@@ -2437,11 +2437,15 @@ static int send_cancel(struct hci_dev *hdev, void *data)
|
||||
|
||||
mgmt_cmd_complete(cmd->sk, hdev->id, MGMT_OP_MESH_SEND_CANCEL,
|
||||
0, NULL, 0);
|
||||
mgmt_pending_free(cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void send_cancel_destroy(struct hci_dev *hdev, void *data, int err)
|
||||
{
|
||||
mgmt_pending_free(data);
|
||||
}
|
||||
|
||||
static int mesh_send_cancel(struct sock *sk, struct hci_dev *hdev,
|
||||
void *data, u16 len)
|
||||
{
|
||||
@@ -2462,7 +2466,8 @@ static int mesh_send_cancel(struct sock *sk, struct hci_dev *hdev,
|
||||
if (!cmd)
|
||||
err = -ENOMEM;
|
||||
else
|
||||
err = hci_cmd_sync_queue(hdev, send_cancel, cmd, NULL);
|
||||
err = hci_cmd_sync_queue(hdev, send_cancel, cmd,
|
||||
send_cancel_destroy);
|
||||
|
||||
if (err < 0) {
|
||||
err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_MESH_SEND_CANCEL,
|
||||
|
||||
Reference in New Issue
Block a user