Skip to content

Commit 67b3d90

Browse files
author
Bastien Nocera
committed
Bluetooth: MGMT: Fix possible deadlocks
JIRA: https://issues.redhat.com/browse/RHEL-64476 CVE: CVE-2024-49951 commit a66dfaf Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Date: Thu Nov 21 11:09:22 2024 -0500 Bluetooth: MGMT: Fix possible deadlocks This fixes possible deadlocks like the following caused by hci_cmd_sync_dequeue causing the destroy function to run: INFO: task kworker/u19:0:143 blocked for more than 120 seconds. Tainted: G W O 6.8.0-2024-03-19-intel-next-iLS-24ww14 #1 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. task:kworker/u19:0 state:D stack:0 pid:143 tgid:143 ppid:2 flags:0x00004000 Workqueue: hci0 hci_cmd_sync_work [bluetooth] Call Trace: <TASK> __schedule+0x374/0xaf0 schedule+0x3c/0xf0 schedule_preempt_disabled+0x1c/0x30 __mutex_lock.constprop.0+0x3ef/0x7a0 __mutex_lock_slowpath+0x13/0x20 mutex_lock+0x3c/0x50 mgmt_set_connectable_complete+0xa4/0x150 [bluetooth] ? kfree+0x211/0x2a0 hci_cmd_sync_dequeue+0xae/0x130 [bluetooth] ? __pfx_cmd_complete_rsp+0x10/0x10 [bluetooth] cmd_complete_rsp+0x26/0x80 [bluetooth] mgmt_pending_foreach+0x4d/0x70 [bluetooth] __mgmt_power_off+0x8d/0x180 [bluetooth] ? _raw_spin_unlock_irq+0x23/0x40 hci_dev_close_sync+0x445/0x5b0 [bluetooth] hci_set_powered_sync+0x149/0x250 [bluetooth] set_powered_sync+0x24/0x60 [bluetooth] hci_cmd_sync_work+0x90/0x150 [bluetooth] process_one_work+0x13e/0x300 worker_thread+0x2f7/0x420 ? __pfx_worker_thread+0x10/0x10 kthread+0x107/0x140 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x3d/0x60 ? __pfx_kthread+0x10/0x10 ret_from_fork_asm+0x1b/0x30 </TASK> Tested-by: Kiran K <kiran.k@intel.com> Fixes: f53e1c9 ("Bluetooth: MGMT: Fix possible crash on mgmt_index_removed") Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Bastien Nocera <bnocera@redhat.com>
1 parent 8d9f696 commit 67b3d90

File tree

1 file changed

+18
-9
lines changed

1 file changed

+18
-9
lines changed

net/bluetooth/mgmt.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,7 +1503,8 @@ static void mgmt_set_discoverable_complete(struct hci_dev *hdev, void *data,
15031503
bt_dev_dbg(hdev, "err %d", err);
15041504

15051505
/* Make sure cmd still outstanding. */
1506-
if (cmd != pending_find(MGMT_OP_SET_DISCOVERABLE, hdev))
1506+
if (err == -ECANCELED ||
1507+
cmd != pending_find(MGMT_OP_SET_DISCOVERABLE, hdev))
15071508
return;
15081509

15091510
hci_dev_lock(hdev);
@@ -1677,7 +1678,8 @@ static void mgmt_set_connectable_complete(struct hci_dev *hdev, void *data,
16771678
bt_dev_dbg(hdev, "err %d", err);
16781679

16791680
/* Make sure cmd still outstanding. */
1680-
if (cmd != pending_find(MGMT_OP_SET_CONNECTABLE, hdev))
1681+
if (err == -ECANCELED ||
1682+
cmd != pending_find(MGMT_OP_SET_CONNECTABLE, hdev))
16811683
return;
16821684

16831685
hci_dev_lock(hdev);
@@ -1910,7 +1912,7 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err)
19101912
bool changed;
19111913

19121914
/* Make sure cmd still outstanding. */
1913-
if (cmd != pending_find(MGMT_OP_SET_SSP, hdev))
1915+
if (err == -ECANCELED || cmd != pending_find(MGMT_OP_SET_SSP, hdev))
19141916
return;
19151917

19161918
if (err) {
@@ -3756,7 +3758,8 @@ static void set_name_complete(struct hci_dev *hdev, void *data, int err)
37563758

37573759
bt_dev_dbg(hdev, "err %d", err);
37583760

3759-
if (cmd != pending_find(MGMT_OP_SET_LOCAL_NAME, hdev))
3761+
if (err == -ECANCELED ||
3762+
cmd != pending_find(MGMT_OP_SET_LOCAL_NAME, hdev))
37603763
return;
37613764

37623765
if (status) {
@@ -3931,7 +3934,8 @@ static void set_default_phy_complete(struct hci_dev *hdev, void *data, int err)
39313934
struct sk_buff *skb = cmd->skb;
39323935
u8 status = mgmt_status(err);
39333936

3934-
if (cmd != pending_find(MGMT_OP_SET_PHY_CONFIGURATION, hdev))
3937+
if (err == -ECANCELED ||
3938+
cmd != pending_find(MGMT_OP_SET_PHY_CONFIGURATION, hdev))
39353939
return;
39363940

39373941
if (!status) {
@@ -5822,13 +5826,16 @@ static void start_discovery_complete(struct hci_dev *hdev, void *data, int err)
58225826
{
58235827
struct mgmt_pending_cmd *cmd = data;
58245828

5829+
bt_dev_dbg(hdev, "err %d", err);
5830+
5831+
if (err == -ECANCELED)
5832+
return;
5833+
58255834
if (cmd != pending_find(MGMT_OP_START_DISCOVERY, hdev) &&
58265835
cmd != pending_find(MGMT_OP_START_LIMITED_DISCOVERY, hdev) &&
58275836
cmd != pending_find(MGMT_OP_START_SERVICE_DISCOVERY, hdev))
58285837
return;
58295838

5830-
bt_dev_dbg(hdev, "err %d", err);
5831-
58325839
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err),
58335840
cmd->param, 1);
58345841
mgmt_pending_remove(cmd);
@@ -6061,7 +6068,8 @@ static void stop_discovery_complete(struct hci_dev *hdev, void *data, int err)
60616068
{
60626069
struct mgmt_pending_cmd *cmd = data;
60636070

6064-
if (cmd != pending_find(MGMT_OP_STOP_DISCOVERY, hdev))
6071+
if (err == -ECANCELED ||
6072+
cmd != pending_find(MGMT_OP_STOP_DISCOVERY, hdev))
60656073
return;
60666074

60676075
bt_dev_dbg(hdev, "err %d", err);
@@ -8020,7 +8028,8 @@ static void read_local_oob_ext_data_complete(struct hci_dev *hdev, void *data,
80208028
u8 status = mgmt_status(err);
80218029
u16 eir_len;
80228030

8023-
if (cmd != pending_find(MGMT_OP_READ_LOCAL_OOB_EXT_DATA, hdev))
8031+
if (err == -ECANCELED ||
8032+
cmd != pending_find(MGMT_OP_READ_LOCAL_OOB_EXT_DATA, hdev))
80248033
return;
80258034

80268035
if (!status) {

0 commit comments

Comments
 (0)