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@xxxxxxxxxxxxxxxxxxxxxxxxx Closes: https://syzkaller.appspot.com/bug?extid=35ebc808442df6420eae Signed-off-by: Edward Adam Davis <eadavis@xxxxxx> --- 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