[PATCH] Bluetooth: fix double free in hci_req_sync_complete

Edward Adam Davis
2024-06-23T09:11:56Z

Look at the following situation:

cpu1 cpu2
==== ====
sock_ioctl
sock_do_ioctl
hci_sock_ioctl
hci_rx_work hci_dev_cmd
hci_event_packet hci_req_sync
req_complete_skb __hci_req_sync
hci_req_sync_complete

If hci_rx_work executes before __hci_req_sync releases req_skb, everything
is normal, otherwise it will result in double free of req_skb.

Adding NULL check of req_skb before releasing it can avoid double free.

Fixes: 45d355a926ab ("Bluetooth: Fix memory leak in hci_req_sync_complete()")
Reported-and-tested-by: syzbot+35ebc808442df6420eae@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=35ebc808442df6420eae
Signed-off-by: Edward Adam Davis <eadavis@qq.com>
---
net/bluetooth/hci_request.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index efea25eb56ce..3862fa6bb288 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -106,7 +106,8 @@ void hci_req_sync_complete(struct hci_dev *hdev, u8 result, u16 opcode,
hdev->req_result = result;
hdev->req_status = HCI_REQ_DONE;
if (skb) {
- kfree_skb(hdev->req_skb);
+ if (hdev->req_skb)
+ kfree_skb(hdev->req_skb);
hdev->req_skb = skb_get(skb);
}
wake_up_interruptible(&hdev->req_wait_q);
--
2.43.0