Bluetooth: hci_conn: Fix memory leaks
authorZhengchao Shao <shaozhengchao@huawei.com>
Wed, 4 Jan 2023 06:46:23 +0000 (14:46 +0800)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Tue, 17 Jan 2023 23:59:02 +0000 (15:59 -0800)
When hci_cmd_sync_queue() failed in hci_le_terminate_big() or
hci_le_big_terminate(), the memory pointed by variable d is not freed,
which will cause memory leak. Add release process to error path.

Fixes: eca0ae4aea66 ("Bluetooth: Add initial implementation of BIS connections")
Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
net/bluetooth/hci_conn.c

index d3e542c..acf563f 100644 (file)
@@ -821,6 +821,7 @@ static void terminate_big_destroy(struct hci_dev *hdev, void *data, int err)
 static int hci_le_terminate_big(struct hci_dev *hdev, u8 big, u8 bis)
 {
        struct iso_list_data *d;
+       int ret;
 
        bt_dev_dbg(hdev, "big 0x%2.2x bis 0x%2.2x", big, bis);
 
@@ -831,8 +832,12 @@ static int hci_le_terminate_big(struct hci_dev *hdev, u8 big, u8 bis)
        d->big = big;
        d->bis = bis;
 
-       return hci_cmd_sync_queue(hdev, terminate_big_sync, d,
-                                 terminate_big_destroy);
+       ret = hci_cmd_sync_queue(hdev, terminate_big_sync, d,
+                                terminate_big_destroy);
+       if (ret)
+               kfree(d);
+
+       return ret;
 }
 
 static int big_terminate_sync(struct hci_dev *hdev, void *data)
@@ -857,6 +862,7 @@ static int big_terminate_sync(struct hci_dev *hdev, void *data)
 static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, u16 sync_handle)
 {
        struct iso_list_data *d;
+       int ret;
 
        bt_dev_dbg(hdev, "big 0x%2.2x sync_handle 0x%4.4x", big, sync_handle);
 
@@ -867,8 +873,12 @@ static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, u16 sync_handle)
        d->big = big;
        d->sync_handle = sync_handle;
 
-       return hci_cmd_sync_queue(hdev, big_terminate_sync, d,
-                                 terminate_big_destroy);
+       ret = hci_cmd_sync_queue(hdev, big_terminate_sync, d,
+                                terminate_big_destroy);
+       if (ret)
+               kfree(d);
+
+       return ret;
 }
 
 /* Cleanup BIS connection