Re: [syzbot] [bluetooth?] [usb?] memory leak in __hci_cmd_sync_sk

shaurya
2025-11-19T18:46:00Z

[-- Attachment #1: Type: text/plain, Size: 83 bytes --]

#syz test:
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master

[-- Attachment #2: 0001-Bluetooth-hci_sync-fix-memory-leak-in-__hci_cmd_sync.patch --]
[-- Type: text/x-patch, Size: 2002 bytes --]

From 31c93fbc37d699e498cf51f7dc17e69cb210faaf Mon Sep 17 00:00:00 2001
From: Shaurya Rane <ssrane_b23@ee.vjti.ac.in>
Date: Thu, 20 Nov 2025 00:11:40 +0530
Subject: [PATCH] Bluetooth: hci_sync: fix memory leak in __hci_cmd_sync_sk

Fix a memory leak in __hci_cmd_sync_sk where allocated request command
SKBs are not properly cleaned up when the function fails.

The issue occurs when hci_cmd_sync_alloc() successfully allocates an SKB
and it gets queued via hci_cmd_sync_add(), but then __hci_cmd_sync_sk()
fails due to timeout, interruption, or cancellation. In these error
paths, the req_skb that was cloned and stored in hdev->req_skb is not
freed, leading to memory leaks.

The memory leak can be reproduced when __hci_cmd_sync_sk() allocates
and queues an HCI command SKB, and hci_req_sync_run() transfers this
SKB to hdev->cmd_q and clones it to hdev->req_skb. If the subsequent
wait_event_interruptible_timeout() call fails (due to timeout or
interruption), the function returns an error without hdev->req_skb
ever being cleaned up.

The fix ensures that when __hci_cmd_sync_sk() returns an error, any
pending request command SKB in hdev->req_skb is properly freed before
returning. This matches the cleanup pattern used elsewhere in the HCI
sync code.

Reported-by: syzbot+f098d64cc684b8dbaf65@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=f098d64cc684b8dbaf65
Signed-off-by: Shaurya Rane <ssrane_b23@ee.vjti.ac.in>
---
net/bluetooth/hci_sync.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index 6e76798ec786..fbaa5749ad7b 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -203,6 +203,11 @@ struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hdev, u16 opcode, u32 plen,

if (err < 0) {
kfree_skb(skb);
+ /* Clean up any pending request command */
+ if (hdev->req_skb) {
+ kfree_skb(hdev->req_skb);
+ hdev->req_skb = NULL;
+ }
return ERR_PTR(err);
}

--
2.34.1