summaryrefslogtreecommitdiff
path: root/drivers/bluetooth
diff options
context:
space:
mode:
authorMark-YW.Chen <mark-yw.chen@mediatek.com>2021-10-14 00:22:04 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-01-16 09:15:38 +0100
commit784e873af3dc69b61c80f0ce7d99bb7a1bdc3100 (patch)
tree89b529698da804470204f7e3d510525c4dd11454 /drivers/bluetooth
parentad07b60837b24346a9bb3bf018da5a6926c22a53 (diff)
Bluetooth: btusb: fix memory leak in btusb_mtk_submit_wmt_recv_urb()
commit 60c6a63a3d3080a62f3e0e20084f58dbeff16748 upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r--drivers/bluetooth/btusb.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 6d643651d69f..c8f2b991e9cf 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -2568,6 +2568,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;
}
@@ -2588,6 +2589,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;
}
}
@@ -2596,6 +2598,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;
}
@@ -2606,6 +2609,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 */
@@ -2626,6 +2630,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
*/