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: a1c49c434e ("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>
This commit is contained in:
Mark-YW.Chen 2021-10-14 00:22:04 +08:00 committed by Greg Kroah-Hartman
parent ad07b60837
commit 784e873af3

View File

@ -2568,6 +2568,7 @@ static void btusb_mtk_wmt_recv(struct urb *urb)
skb = bt_skb_alloc(HCI_WMT_MAX_EVENT_SIZE, GFP_ATOMIC); skb = bt_skb_alloc(HCI_WMT_MAX_EVENT_SIZE, GFP_ATOMIC);
if (!skb) { if (!skb) {
hdev->stat.err_rx++; hdev->stat.err_rx++;
kfree(urb->setup_packet);
return; return;
} }
@ -2588,6 +2589,7 @@ static void btusb_mtk_wmt_recv(struct urb *urb)
data->evt_skb = skb_clone(skb, GFP_ATOMIC); data->evt_skb = skb_clone(skb, GFP_ATOMIC);
if (!data->evt_skb) { if (!data->evt_skb) {
kfree_skb(skb); kfree_skb(skb);
kfree(urb->setup_packet);
return; return;
} }
} }
@ -2596,6 +2598,7 @@ static void btusb_mtk_wmt_recv(struct urb *urb)
if (err < 0) { if (err < 0) {
kfree_skb(data->evt_skb); kfree_skb(data->evt_skb);
data->evt_skb = NULL; data->evt_skb = NULL;
kfree(urb->setup_packet);
return; return;
} }
@ -2606,6 +2609,7 @@ static void btusb_mtk_wmt_recv(struct urb *urb)
wake_up_bit(&data->flags, wake_up_bit(&data->flags,
BTUSB_TX_WAIT_VND_EVT); BTUSB_TX_WAIT_VND_EVT);
} }
kfree(urb->setup_packet);
return; return;
} else if (urb->status == -ENOENT) { } else if (urb->status == -ENOENT) {
/* Avoid suspend failed when usb_kill_urb */ /* 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); usb_anchor_urb(urb, &data->ctrl_anchor);
err = usb_submit_urb(urb, GFP_ATOMIC); err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) { if (err < 0) {
kfree(urb->setup_packet);
/* -EPERM: urb is being killed; /* -EPERM: urb is being killed;
* -ENODEV: device got disconnected * -ENODEV: device got disconnected
*/ */