[PATCH 2/2] Bluetooth: hci_core: Handle skb_clone() failure in hci_send_cmd_sync()

Hans de Goede <[email protected]>
Newsgroups org.kernel.vger.linux-bluetooth,org.kernel.vger.linux-arm-msm
Message-ID <[email protected]>
From: Ibrahim Abdelkader <[email protected]>

hci_send_cmd_sync() does not handle the second skb_clone() failure as it
does the first one. At that point the command has already been sent and
HCI_CMD_PENDING is set, so an allocation failure leaves the flag set with
req_skb NULL. The response then matches nothing and the caller blocks for
HCI_INIT_TIMEOUT before getting -ETIMEDOUT, reporting a memory shortage as
a controller timeout.

Clear the flag, cancel the pending request with -ENOMEM so the caller fails
immediately instead of waiting out the timeout, and return -ENOMEM so
hci_cmd_work() does not arm cmd_timer for a request that no longer exists.

Clearing HCI_CMD_PENDING here is safe: all code touching that flag runs
from hdev->workqueue, which is an ordered workqueue, so those paths are
serialised and cannot race. The one exception is the cleanup added by
commit ed516e3f1aa6 ("Bluetooth: hci_sync: Clear HCI_CMD_PENDING when
dropping the last request"), which runs on hci_dev_open_sync() failure and
from hci_dev_close_sync(), and the workqueue is stopped before that runs.

Fixes: 2615fd9a7c25 ("Bluetooth: hci_sync: Fix overwriting request callback")
Signed-off-by: Ibrahim Abdelkader <[email protected]>
Signed-off-by: Hans de Goede <[email protected]>
---
 net/bluetooth/hci_core.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 8aeb3024428b..9585b42e7970 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -4092,6 +4092,11 @@ static int hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb)
 	    !hci_dev_test_and_set_flag(hdev, HCI_CMD_PENDING)) {
 		kfree_skb(hdev->req_skb);
 		hdev->req_skb = skb_clone(hdev->sent_cmd, GFP_KERNEL);
+		if (!hdev->req_skb) {
+			hci_dev_clear_flag(hdev, HCI_CMD_PENDING);
+			hci_cmd_sync_cancel_sync(hdev, ENOMEM);
+			err = -ENOMEM;
+		}
 	}
 
 	return err;
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.