Commit f17d858e authored by Jaganath Kanakkassery's avatar Jaganath Kanakkassery Committed by Marcel Holtmann

Bluetooth: Fix potential memory leak

If command is added to req then it should be freed in case if
hdev is down or HCI_ADVERTISING flag is set.

This introduces a helper in hci_request to purge the cmd_q
to make cmd_q internal to hci_request which is used to fix
the leak.

This also replace accessing of cmd_q in hci_conn with the
new helper.
Signed-off-by: default avatarJaganath Kanakkassery <jaganathx.kanakkassery@intel.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 858ff38a
...@@ -907,7 +907,7 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, ...@@ -907,7 +907,7 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
*/ */
if (hci_dev_test_flag(hdev, HCI_LE_SCAN) && if (hci_dev_test_flag(hdev, HCI_LE_SCAN) &&
hdev->le_scan_type == LE_SCAN_ACTIVE) { hdev->le_scan_type == LE_SCAN_ACTIVE) {
skb_queue_purge(&req.cmd_q); hci_req_purge(&req);
hci_conn_del(conn); hci_conn_del(conn);
return ERR_PTR(-EBUSY); return ERR_PTR(-EBUSY);
} }
......
...@@ -41,6 +41,11 @@ void hci_req_init(struct hci_request *req, struct hci_dev *hdev) ...@@ -41,6 +41,11 @@ void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
req->err = 0; req->err = 0;
} }
void hci_req_purge(struct hci_request *req)
{
skb_queue_purge(&req->cmd_q);
}
static int req_run(struct hci_request *req, hci_req_complete_t complete, static int req_run(struct hci_request *req, hci_req_complete_t complete,
hci_req_complete_skb_t complete_skb) hci_req_complete_skb_t complete_skb)
{ {
......
...@@ -36,6 +36,7 @@ struct hci_request { ...@@ -36,6 +36,7 @@ struct hci_request {
}; };
void hci_req_init(struct hci_request *req, struct hci_dev *hdev); void hci_req_init(struct hci_request *req, struct hci_dev *hdev);
void hci_req_purge(struct hci_request *req);
int hci_req_run(struct hci_request *req, hci_req_complete_t complete); int hci_req_run(struct hci_request *req, hci_req_complete_t complete);
int hci_req_run_skb(struct hci_request *req, hci_req_complete_skb_t complete); int hci_req_run_skb(struct hci_request *req, hci_req_complete_skb_t complete);
void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
......
...@@ -6383,6 +6383,7 @@ static int remove_advertising(struct sock *sk, struct hci_dev *hdev, ...@@ -6383,6 +6383,7 @@ static int remove_advertising(struct sock *sk, struct hci_dev *hdev,
if (skb_queue_empty(&req.cmd_q) || if (skb_queue_empty(&req.cmd_q) ||
!hdev_is_powered(hdev) || !hdev_is_powered(hdev) ||
hci_dev_test_flag(hdev, HCI_ADVERTISING)) { hci_dev_test_flag(hdev, HCI_ADVERTISING)) {
hci_req_purge(&req);
rp.instance = cp->instance; rp.instance = cp->instance;
err = mgmt_cmd_complete(sk, hdev->id, err = mgmt_cmd_complete(sk, hdev->id,
MGMT_OP_REMOVE_ADVERTISING, MGMT_OP_REMOVE_ADVERTISING,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment