Skip to content

Commit 8d9f696

Browse files
CKI Backport BotBastien Nocera
authored andcommitted
Bluetooth: MGMT: Fix possible crash on mgmt_index_removed
JIRA: https://issues.redhat.com/browse/RHEL-64476 CVE: CVE-2024-49951 commit f53e1c9 Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Date: Thu Sep 12 12:34:42 2024 -0400 Bluetooth: MGMT: Fix possible crash on mgmt_index_removed If mgmt_index_removed is called while there are commands queued on cmd_sync it could lead to crashes like the bellow trace: 0x0000053D: __list_del_entry_valid_or_report+0x98/0xdc 0x0000053D: mgmt_pending_remove+0x18/0x58 [bluetooth] 0x0000053E: mgmt_remove_adv_monitor_complete+0x80/0x108 [bluetooth] 0x0000053E: hci_cmd_sync_work+0xbc/0x164 [bluetooth] So while handling mgmt_index_removed this attempts to dequeue commands passed as user_data to cmd_sync. Fixes: 7cf5c29 ("Bluetooth: hci_sync: Refactor remove Adv Monitor") Reported-by: jiaymao <quic_jiaymao@quicinc.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
1 parent cd58e17 commit 8d9f696

File tree

1 file changed

+14
-9
lines changed

1 file changed

+14
-9
lines changed

net/bluetooth/mgmt.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,10 +1446,15 @@ static void cmd_status_rsp(struct mgmt_pending_cmd *cmd, void *data)
14461446

14471447
static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data)
14481448
{
1449-
if (cmd->cmd_complete) {
1450-
u8 *status = data;
1449+
struct cmd_lookup *match = data;
1450+
1451+
/* dequeue cmd_sync entries using cmd as data as that is about to be
1452+
* removed/freed.
1453+
*/
1454+
hci_cmd_sync_dequeue(match->hdev, NULL, cmd, NULL);
14511455

1452-
cmd->cmd_complete(cmd, *status);
1456+
if (cmd->cmd_complete) {
1457+
cmd->cmd_complete(cmd, match->mgmt_status);
14531458
mgmt_pending_remove(cmd);
14541459

14551460
return;
@@ -9337,12 +9342,12 @@ void mgmt_index_added(struct hci_dev *hdev)
93379342
void mgmt_index_removed(struct hci_dev *hdev)
93389343
{
93399344
struct mgmt_ev_ext_index ev;
9340-
u8 status = MGMT_STATUS_INVALID_INDEX;
9345+
struct cmd_lookup match = { NULL, hdev, MGMT_STATUS_INVALID_INDEX };
93419346

93429347
if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
93439348
return;
93449349

9345-
mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &status);
9350+
mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match);
93469351

93479352
if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
93489353
mgmt_index_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev, NULL, 0,
@@ -9393,7 +9398,7 @@ void mgmt_power_on(struct hci_dev *hdev, int err)
93939398
void __mgmt_power_off(struct hci_dev *hdev)
93949399
{
93959400
struct cmd_lookup match = { NULL, hdev };
9396-
u8 status, zero_cod[] = { 0, 0, 0 };
9401+
u8 zero_cod[] = { 0, 0, 0 };
93979402

93989403
mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
93999404

@@ -9405,11 +9410,11 @@ void __mgmt_power_off(struct hci_dev *hdev)
94059410
* status responses.
94069411
*/
94079412
if (hci_dev_test_flag(hdev, HCI_UNREGISTER))
9408-
status = MGMT_STATUS_INVALID_INDEX;
9413+
match.mgmt_status = MGMT_STATUS_INVALID_INDEX;
94099414
else
9410-
status = MGMT_STATUS_NOT_POWERED;
9415+
match.mgmt_status = MGMT_STATUS_NOT_POWERED;
94119416

9412-
mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &status);
9417+
mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match);
94139418

94149419
if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0) {
94159420
mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev,

0 commit comments

Comments
 (0)