| From 755ebc0327e6fb5457e39b1d69580a6f1751c16b Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 22 Sep 2021 21:49:45 +0800 |
| Subject: Bluetooth: btmtkuart: fix a memleak in mtk_hci_wmt_sync |
| |
| From: Dinghao Liu <dinghao.liu@zju.edu.cn> |
| |
| [ Upstream commit 3e5f2d90c28f9454e421108554707620bc23269d ] |
| |
| bdev->evt_skb will get freed in the normal path and one error path |
| of mtk_hci_wmt_sync, while the other error paths do not free it, |
| which may cause a memleak. This bug is suggested by a static analysis |
| tool, please advise. |
| |
| Fixes: e0b67035a90b ("Bluetooth: mediatek: update the common setup between MT7622 and other devices") |
| Signed-off-by: Dinghao Liu <dinghao.liu@zju.edu.cn> |
| Signed-off-by: Marcel Holtmann <marcel@holtmann.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/bluetooth/btmtkuart.c | 13 ++++++++----- |
| 1 file changed, 8 insertions(+), 5 deletions(-) |
| |
| diff --git a/drivers/bluetooth/btmtkuart.c b/drivers/bluetooth/btmtkuart.c |
| index 8a81fbca5c9d8..2beb2321825e3 100644 |
| --- a/drivers/bluetooth/btmtkuart.c |
| +++ b/drivers/bluetooth/btmtkuart.c |
| @@ -158,8 +158,10 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev, |
| int err; |
| |
| hlen = sizeof(*hdr) + wmt_params->dlen; |
| - if (hlen > 255) |
| - return -EINVAL; |
| + if (hlen > 255) { |
| + err = -EINVAL; |
| + goto err_free_skb; |
| + } |
| |
| hdr = (struct mtk_wmt_hdr *)&wc; |
| hdr->dir = 1; |
| @@ -173,7 +175,7 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev, |
| err = __hci_cmd_send(hdev, 0xfc6f, hlen, &wc); |
| if (err < 0) { |
| clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state); |
| - return err; |
| + goto err_free_skb; |
| } |
| |
| /* The vendor specific WMT commands are all answered by a vendor |
| @@ -190,13 +192,14 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev, |
| if (err == -EINTR) { |
| bt_dev_err(hdev, "Execution of wmt command interrupted"); |
| clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state); |
| - return err; |
| + goto err_free_skb; |
| } |
| |
| if (err) { |
| bt_dev_err(hdev, "Execution of wmt command timed out"); |
| clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state); |
| - return -ETIMEDOUT; |
| + err = -ETIMEDOUT; |
| + goto err_free_skb; |
| } |
| |
| /* Parse and handle the return WMT event */ |
| -- |
| 2.33.0 |
| |