diff options
author | Mark-YW.Chen <mark-yw.chen@mediatek.com> | 2021-10-13 19:22:04 +0300 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2021-10-13 19:17:34 +0300 |
commit | 60c6a63a3d3080a62f3e0e20084f58dbeff16748 (patch) | |
tree | 0e2068298e18292b8a043a6be91d04bf335a9456 | |
parent | 75d9b8559ac36e059238ee4f8e33cd86086586ba (diff) | |
download | linux-60c6a63a3d3080a62f3e0e20084f58dbeff16748.tar.xz |
Bluetooth: btusb: fix memory leak in btusb_mtk_submit_wmt_recv_urb()
Driver should free `usb->setup_packet` to avoid the leak.
$ cat /sys/kernel/debug/kmemleak
unreferenced object 0xffffffa564a58080 (size 128):
backtrace:
[<000000007eb8dd70>] kmem_cache_alloc_trace+0x22c/0x384
[<000000008a44191d>] btusb_mtk_hci_wmt_sync+0x1ec/0x994
[btusb]
[<00000000ca7189a3>] btusb_mtk_setup+0x6b8/0x13cc
[btusb]
[<00000000c6105069>] hci_dev_do_open+0x290/0x974
[bluetooth]
[<00000000a583f8b8>] hci_power_on+0xdc/0x3cc [bluetooth]
[<000000005d80e687>] process_one_work+0x514/0xc80
[<00000000f4d57637>] worker_thread+0x818/0xd0c
[<00000000dc7bdb55>] kthread+0x2f8/0x3b8
[<00000000f9999513>] ret_from_fork+0x10/0x30
Fixes: a1c49c434e150 ("Bluetooth: btusb: Add protocol support for MediaTek MT7668U USB devices")
Signed-off-by: Mark-YW.Chen <mark-yw.chen@mediatek.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r-- | drivers/bluetooth/btusb.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 3e26f60b457e..87b71740fad8 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -2265,6 +2265,7 @@ static void btusb_mtk_wmt_recv(struct urb *urb) skb = bt_skb_alloc(HCI_WMT_MAX_EVENT_SIZE, GFP_ATOMIC); if (!skb) { hdev->stat.err_rx++; + kfree(urb->setup_packet); return; } @@ -2285,6 +2286,7 @@ static void btusb_mtk_wmt_recv(struct urb *urb) data->evt_skb = skb_clone(skb, GFP_ATOMIC); if (!data->evt_skb) { kfree_skb(skb); + kfree(urb->setup_packet); return; } } @@ -2293,6 +2295,7 @@ static void btusb_mtk_wmt_recv(struct urb *urb) if (err < 0) { kfree_skb(data->evt_skb); data->evt_skb = NULL; + kfree(urb->setup_packet); return; } @@ -2303,6 +2306,7 @@ static void btusb_mtk_wmt_recv(struct urb *urb) wake_up_bit(&data->flags, BTUSB_TX_WAIT_VND_EVT); } + kfree(urb->setup_packet); return; } else if (urb->status == -ENOENT) { /* Avoid suspend failed when usb_kill_urb */ @@ -2323,6 +2327,7 @@ static void btusb_mtk_wmt_recv(struct urb *urb) usb_anchor_urb(urb, &data->ctrl_anchor); err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { + kfree(urb->setup_packet); /* -EPERM: urb is being killed; * -ENODEV: device got disconnected */ |