Skip to content

Commit 6fe26f6

Browse files
committed
Bluetooth: MGMT: Protect mgmt_pending list with its own lock
This uses a mutex to protect from concurrent access of mgmt_pending list which can cause crashes like: ================================================================== BUG: KASAN: slab-use-after-free in hci_sock_get_channel+0x60/0x68 net/bluetooth/hci_sock.c:91 Read of size 2 at addr ffff0000c48885b2 by task syz.4.334/7318 CPU: 0 UID: 0 PID: 7318 Comm: syz.4.334 Not tainted 6.15.0-rc7-syzkaller-g187899f4124a #0 PREEMPT Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2025 Call trace: show_stack+0x2c/0x3c arch/arm64/kernel/stacktrace.c:466 (C) __dump_stack+0x30/0x40 lib/dump_stack.c:94 dump_stack_lvl+0xd8/0x12c lib/dump_stack.c:120 print_address_description+0xa8/0x254 mm/kasan/report.c:408 print_report+0x68/0x84 mm/kasan/report.c:521 kasan_report+0xb0/0x110 mm/kasan/report.c:634 __asan_report_load2_noabort+0x20/0x2c mm/kasan/report_generic.c:379 hci_sock_get_channel+0x60/0x68 net/bluetooth/hci_sock.c:91 mgmt_pending_find+0x7c/0x140 net/bluetooth/mgmt_util.c:223 pending_find net/bluetooth/mgmt.c:947 [inline] remove_adv_monitor+0x44/0x1a4 net/bluetooth/mgmt.c:5445 hci_mgmt_cmd+0x780/0xc00 net/bluetooth/hci_sock.c:1712 hci_sock_sendmsg+0x544/0xbb0 net/bluetooth/hci_sock.c:1832 sock_sendmsg_nosec net/socket.c:712 [inline] __sock_sendmsg net/socket.c:727 [inline] sock_write_iter+0x25c/0x378 net/socket.c:1131 new_sync_write fs/read_write.c:591 [inline] vfs_write+0x62c/0x97c fs/read_write.c:684 ksys_write+0x120/0x210 fs/read_write.c:736 __do_sys_write fs/read_write.c:747 [inline] __se_sys_write fs/read_write.c:744 [inline] __arm64_sys_write+0x7c/0x90 fs/read_write.c:744 __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline] invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:49 el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:132 do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:151 el0_svc+0x58/0x17c arch/arm64/kernel/entry-common.c:767 el0t_64_sync_handler+0x78/0x108 arch/arm64/kernel/entry-common.c:786 el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:600 Allocated by task 7037: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x40/0x78 mm/kasan/common.c:68 kasan_save_alloc_info+0x44/0x54 mm/kasan/generic.c:562 poison_kmalloc_redzone mm/kasan/common.c:377 [inline] __kasan_kmalloc+0x9c/0xb4 mm/kasan/common.c:394 kasan_kmalloc include/linux/kasan.h:260 [inline] __do_kmalloc_node mm/slub.c:4327 [inline] __kmalloc_noprof+0x2fc/0x4c8 mm/slub.c:4339 kmalloc_noprof include/linux/slab.h:909 [inline] sk_prot_alloc+0xc4/0x1f0 net/core/sock.c:2198 sk_alloc+0x44/0x3ac net/core/sock.c:2254 bt_sock_alloc+0x4c/0x300 net/bluetooth/af_bluetooth.c:148 hci_sock_create+0xa8/0x194 net/bluetooth/hci_sock.c:2202 bt_sock_create+0x14c/0x24c net/bluetooth/af_bluetooth.c:132 __sock_create+0x43c/0x91c net/socket.c:1541 sock_create net/socket.c:1599 [inline] __sys_socket_create net/socket.c:1636 [inline] __sys_socket+0xd4/0x1c0 net/socket.c:1683 __do_sys_socket net/socket.c:1697 [inline] __se_sys_socket net/socket.c:1695 [inline] __arm64_sys_socket+0x7c/0x94 net/socket.c:1695 __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline] invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:49 el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:132 do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:151 el0_svc+0x58/0x17c arch/arm64/kernel/entry-common.c:767 el0t_64_sync_handler+0x78/0x108 arch/arm64/kernel/entry-common.c:786 el0t_64_sync+0x198/0x19c arch/arm64/kernel/entry.S:600 Freed by task 6607: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x40/0x78 mm/kasan/common.c:68 kasan_save_free_info+0x58/0x70 mm/kasan/generic.c:576 poison_slab_object mm/kasan/common.c:247 [inline] __kasan_slab_free+0x68/0x88 mm/kasan/common.c:264 kasan_slab_free include/linux/kasan.h:233 [inline] slab_free_hook mm/slub.c:2380 [inline] slab_free mm/slub.c:4642 [inline] kfree+0x17c/0x474 mm/slub.c:4841 sk_prot_free net/core/sock.c:2237 [inline] __sk_destruct+0x4f4/0x760 net/core/sock.c:2332 sk_destruct net/core/sock.c:2360 [inline] __sk_free+0x320/0x430 net/core/sock.c:2371 sk_free+0x60/0xc8 net/core/sock.c:2382 sock_put include/net/sock.h:1944 [inline] mgmt_pending_free+0x88/0x118 net/bluetooth/mgmt_util.c:290 mgmt_pending_remove+0xec/0x104 net/bluetooth/mgmt_util.c:298 mgmt_set_powered_complete+0x418/0x5cc net/bluetooth/mgmt.c:1355 hci_cmd_sync_work+0x204/0x33c net/bluetooth/hci_sync.c:334 process_one_work+0x7e8/0x156c kernel/workqueue.c:3238 process_scheduled_works kernel/workqueue.c:3319 [inline] worker_thread+0x958/0xed8 kernel/workqueue.c:3400 kthread+0x5fc/0x75c kernel/kthread.c:464 ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:847 Fixes: a380b6c ("Bluetooth: Add generic mgmt helper API") Closes: https://syzkaller.appspot.com/bug?extid=0a7039d5d9986ff4ecec Closes: https://syzkaller.appspot.com/bug?extid=cc0cc52e7f43dc9e6df1 Reported-by: [email protected] Tested-by: [email protected] Tested-by: [email protected] Signed-off-by: Dmitry Antipov <[email protected]> Signed-off-by: Luiz Augusto von Dentz <[email protected]>
1 parent e6ed54e commit 6fe26f6

File tree

5 files changed

+80
-59
lines changed

5 files changed

+80
-59
lines changed

include/net/bluetooth/hci_core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,7 @@ struct hci_dev {
546546
struct hci_conn_hash conn_hash;
547547

548548
struct list_head mesh_pending;
549+
struct mutex mgmt_pending_lock;
549550
struct list_head mgmt_pending;
550551
struct list_head reject_list;
551552
struct list_head accept_list;

net/bluetooth/hci_core.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2485,6 +2485,7 @@ struct hci_dev *hci_alloc_dev_priv(int sizeof_priv)
24852485

24862486
mutex_init(&hdev->lock);
24872487
mutex_init(&hdev->req_lock);
2488+
mutex_init(&hdev->mgmt_pending_lock);
24882489

24892490
ida_init(&hdev->unset_handle_ida);
24902491

net/bluetooth/mgmt.c

Lines changed: 49 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,22 +1447,17 @@ static void settings_rsp(struct mgmt_pending_cmd *cmd, void *data)
14471447

14481448
send_settings_rsp(cmd->sk, cmd->opcode, match->hdev);
14491449

1450-
list_del(&cmd->list);
1451-
14521450
if (match->sk == NULL) {
14531451
match->sk = cmd->sk;
14541452
sock_hold(match->sk);
14551453
}
1456-
1457-
mgmt_pending_free(cmd);
14581454
}
14591455

14601456
static void cmd_status_rsp(struct mgmt_pending_cmd *cmd, void *data)
14611457
{
14621458
u8 *status = data;
14631459

1464-
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, *status);
1465-
mgmt_pending_remove(cmd);
1460+
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, *status);
14661461
}
14671462

14681463
static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data)
@@ -1476,8 +1471,6 @@ static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data)
14761471

14771472
if (cmd->cmd_complete) {
14781473
cmd->cmd_complete(cmd, match->mgmt_status);
1479-
mgmt_pending_remove(cmd);
1480-
14811474
return;
14821475
}
14831476

@@ -1486,13 +1479,13 @@ static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data)
14861479

14871480
static int generic_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status)
14881481
{
1489-
return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status,
1482+
return mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status,
14901483
cmd->param, cmd->param_len);
14911484
}
14921485

14931486
static int addr_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status)
14941487
{
1495-
return mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status,
1488+
return mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status,
14961489
cmd->param, sizeof(struct mgmt_addr_info));
14971490
}
14981491

@@ -1532,7 +1525,7 @@ static void mgmt_set_discoverable_complete(struct hci_dev *hdev, void *data,
15321525

15331526
if (err) {
15341527
u8 mgmt_err = mgmt_status(err);
1535-
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
1528+
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err);
15361529
hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
15371530
goto done;
15381531
}
@@ -1707,7 +1700,7 @@ static void mgmt_set_connectable_complete(struct hci_dev *hdev, void *data,
17071700

17081701
if (err) {
17091702
u8 mgmt_err = mgmt_status(err);
1710-
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
1703+
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err);
17111704
goto done;
17121705
}
17131706

@@ -1943,8 +1936,8 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err)
19431936
new_settings(hdev, NULL);
19441937
}
19451938

1946-
mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, cmd_status_rsp,
1947-
&mgmt_err);
1939+
mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, true,
1940+
cmd_status_rsp, &mgmt_err);
19481941
return;
19491942
}
19501943

@@ -1954,7 +1947,7 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err)
19541947
changed = hci_dev_test_and_clear_flag(hdev, HCI_SSP_ENABLED);
19551948
}
19561949

1957-
mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, settings_rsp, &match);
1950+
mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, true, settings_rsp, &match);
19581951

19591952
if (changed)
19601953
new_settings(hdev, match.sk);
@@ -2074,12 +2067,12 @@ static void set_le_complete(struct hci_dev *hdev, void *data, int err)
20742067
bt_dev_dbg(hdev, "err %d", err);
20752068

20762069
if (status) {
2077-
mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, cmd_status_rsp,
2078-
&status);
2070+
mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, true, cmd_status_rsp,
2071+
&status);
20792072
return;
20802073
}
20812074

2082-
mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, settings_rsp, &match);
2075+
mgmt_pending_foreach(MGMT_OP_SET_LE, hdev, true, settings_rsp, &match);
20832076

20842077
new_settings(hdev, match.sk);
20852078

@@ -2138,7 +2131,7 @@ static void set_mesh_complete(struct hci_dev *hdev, void *data, int err)
21382131
struct sock *sk = cmd->sk;
21392132

21402133
if (status) {
2141-
mgmt_pending_foreach(MGMT_OP_SET_MESH_RECEIVER, hdev,
2134+
mgmt_pending_foreach(MGMT_OP_SET_MESH_RECEIVER, hdev, true,
21422135
cmd_status_rsp, &status);
21432136
return;
21442137
}
@@ -2638,7 +2631,7 @@ static void mgmt_class_complete(struct hci_dev *hdev, void *data, int err)
26382631

26392632
bt_dev_dbg(hdev, "err %d", err);
26402633

2641-
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
2634+
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode,
26422635
mgmt_status(err), hdev->dev_class, 3);
26432636

26442637
mgmt_pending_free(cmd);
@@ -3427,7 +3420,7 @@ static int pairing_complete(struct mgmt_pending_cmd *cmd, u8 status)
34273420
bacpy(&rp.addr.bdaddr, &conn->dst);
34283421
rp.addr.type = link_to_bdaddr(conn->type, conn->dst_type);
34293422

3430-
err = mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_PAIR_DEVICE,
3423+
err = mgmt_cmd_complete(cmd->sk, cmd->hdev->id, MGMT_OP_PAIR_DEVICE,
34313424
status, &rp, sizeof(rp));
34323425

34333426
/* So we don't get further callbacks for this connection */
@@ -5186,7 +5179,7 @@ static void mgmt_add_adv_patterns_monitor_complete(struct hci_dev *hdev,
51865179
hci_update_passive_scan(hdev);
51875180
}
51885181

5189-
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
5182+
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode,
51905183
mgmt_status(status), &rp, sizeof(rp));
51915184
mgmt_pending_remove(cmd);
51925185

@@ -5401,7 +5394,7 @@ static void mgmt_remove_adv_monitor_complete(struct hci_dev *hdev,
54015394
hci_update_passive_scan(hdev);
54025395
}
54035396

5404-
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
5397+
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode,
54055398
mgmt_status(status), &rp, sizeof(rp));
54065399
mgmt_pending_free(cmd);
54075400

@@ -5777,7 +5770,7 @@ static void start_discovery_complete(struct hci_dev *hdev, void *data, int err)
57775770
cmd != pending_find(MGMT_OP_START_SERVICE_DISCOVERY, hdev))
57785771
return;
57795772

5780-
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err),
5773+
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err),
57815774
cmd->param, 1);
57825775
mgmt_pending_remove(cmd);
57835776

@@ -5998,7 +5991,7 @@ static void stop_discovery_complete(struct hci_dev *hdev, void *data, int err)
59985991

59995992
bt_dev_dbg(hdev, "err %d", err);
60005993

6001-
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err),
5994+
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_status(err),
60025995
cmd->param, 1);
60035996
mgmt_pending_remove(cmd);
60045997

@@ -6223,7 +6216,7 @@ static void set_advertising_complete(struct hci_dev *hdev, void *data, int err)
62236216
u8 status = mgmt_status(err);
62246217

62256218
if (status) {
6226-
mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev,
6219+
mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, true,
62276220
cmd_status_rsp, &status);
62286221
return;
62296222
}
@@ -6233,7 +6226,7 @@ static void set_advertising_complete(struct hci_dev *hdev, void *data, int err)
62336226
else
62346227
hci_dev_clear_flag(hdev, HCI_ADVERTISING);
62356228

6236-
mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, settings_rsp,
6229+
mgmt_pending_foreach(MGMT_OP_SET_ADVERTISING, hdev, true, settings_rsp,
62376230
&match);
62386231

62396232
new_settings(hdev, match.sk);
@@ -6577,7 +6570,7 @@ static void set_bredr_complete(struct hci_dev *hdev, void *data, int err)
65776570
*/
65786571
hci_dev_clear_flag(hdev, HCI_BREDR_ENABLED);
65796572

6580-
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
6573+
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err);
65816574
} else {
65826575
send_settings_rsp(cmd->sk, MGMT_OP_SET_BREDR, hdev);
65836576
new_settings(hdev, cmd->sk);
@@ -6714,7 +6707,7 @@ static void set_secure_conn_complete(struct hci_dev *hdev, void *data, int err)
67146707
if (err) {
67156708
u8 mgmt_err = mgmt_status(err);
67166709

6717-
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
6710+
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err);
67186711
goto done;
67196712
}
67206713

@@ -7161,7 +7154,7 @@ static void get_conn_info_complete(struct hci_dev *hdev, void *data, int err)
71617154
rp.max_tx_power = HCI_TX_POWER_INVALID;
71627155
}
71637156

7164-
mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_GET_CONN_INFO, status,
7157+
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, MGMT_OP_GET_CONN_INFO, status,
71657158
&rp, sizeof(rp));
71667159

71677160
mgmt_pending_free(cmd);
@@ -7321,7 +7314,7 @@ static void get_clock_info_complete(struct hci_dev *hdev, void *data, int err)
73217314
}
73227315

73237316
complete:
7324-
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, status, &rp,
7317+
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status, &rp,
73257318
sizeof(rp));
73267319

73277320
mgmt_pending_free(cmd);
@@ -8571,10 +8564,10 @@ static void add_advertising_complete(struct hci_dev *hdev, void *data, int err)
85718564
rp.instance = cp->instance;
85728565

85738566
if (err)
8574-
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode,
8567+
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode,
85758568
mgmt_status(err));
85768569
else
8577-
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
8570+
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode,
85788571
mgmt_status(err), &rp, sizeof(rp));
85798572

85808573
add_adv_complete(hdev, cmd->sk, cp->instance, err);
@@ -8762,10 +8755,10 @@ static void add_ext_adv_params_complete(struct hci_dev *hdev, void *data,
87628755

87638756
hci_remove_adv_instance(hdev, cp->instance);
87648757

8765-
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode,
8758+
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode,
87668759
mgmt_status(err));
87678760
} else {
8768-
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
8761+
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode,
87698762
mgmt_status(err), &rp, sizeof(rp));
87708763
}
87718764

@@ -8912,10 +8905,10 @@ static void add_ext_adv_data_complete(struct hci_dev *hdev, void *data, int err)
89128905
rp.instance = cp->instance;
89138906

89148907
if (err)
8915-
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode,
8908+
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode,
89168909
mgmt_status(err));
89178910
else
8918-
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
8911+
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode,
89198912
mgmt_status(err), &rp, sizeof(rp));
89208913

89218914
mgmt_pending_free(cmd);
@@ -9074,10 +9067,10 @@ static void remove_advertising_complete(struct hci_dev *hdev, void *data,
90749067
rp.instance = cp->instance;
90759068

90769069
if (err)
9077-
mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode,
9070+
mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode,
90789071
mgmt_status(err));
90799072
else
9080-
mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode,
9073+
mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode,
90819074
MGMT_STATUS_SUCCESS, &rp, sizeof(rp));
90829075

90839076
mgmt_pending_free(cmd);
@@ -9349,7 +9342,7 @@ void mgmt_index_removed(struct hci_dev *hdev)
93499342
if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
93509343
return;
93519344

9352-
mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match);
9345+
mgmt_pending_foreach(0, hdev, true, cmd_complete_rsp, &match);
93539346

93549347
if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
93559348
mgmt_index_event(MGMT_EV_UNCONF_INDEX_REMOVED, hdev, NULL, 0,
@@ -9387,7 +9380,8 @@ void mgmt_power_on(struct hci_dev *hdev, int err)
93879380
hci_update_passive_scan(hdev);
93889381
}
93899382

9390-
mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
9383+
mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, true, settings_rsp,
9384+
&match);
93919385

93929386
new_settings(hdev, match.sk);
93939387

@@ -9402,7 +9396,8 @@ void __mgmt_power_off(struct hci_dev *hdev)
94029396
struct cmd_lookup match = { NULL, hdev };
94039397
u8 zero_cod[] = { 0, 0, 0 };
94049398

9405-
mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match);
9399+
mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, true, settings_rsp,
9400+
&match);
94069401

94079402
/* If the power off is because of hdev unregistration let
94089403
* use the appropriate INVALID_INDEX status. Otherwise use
@@ -9416,7 +9411,7 @@ void __mgmt_power_off(struct hci_dev *hdev)
94169411
else
94179412
match.mgmt_status = MGMT_STATUS_NOT_POWERED;
94189413

9419-
mgmt_pending_foreach(0, hdev, cmd_complete_rsp, &match);
9414+
mgmt_pending_foreach(0, hdev, true, cmd_complete_rsp, &match);
94209415

94219416
if (memcmp(hdev->dev_class, zero_cod, sizeof(zero_cod)) != 0) {
94229417
mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev,
@@ -9657,7 +9652,6 @@ static void unpair_device_rsp(struct mgmt_pending_cmd *cmd, void *data)
96579652
device_unpaired(hdev, &cp->addr.bdaddr, cp->addr.type, cmd->sk);
96589653

96599654
cmd->cmd_complete(cmd, 0);
9660-
mgmt_pending_remove(cmd);
96619655
}
96629656

96639657
bool mgmt_powering_down(struct hci_dev *hdev)
@@ -9713,8 +9707,8 @@ void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
97139707
struct mgmt_cp_disconnect *cp;
97149708
struct mgmt_pending_cmd *cmd;
97159709

9716-
mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp,
9717-
hdev);
9710+
mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, true,
9711+
unpair_device_rsp, hdev);
97189712

97199713
cmd = pending_find(MGMT_OP_DISCONNECT, hdev);
97209714
if (!cmd)
@@ -9907,7 +9901,7 @@ void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status)
99079901

99089902
if (status) {
99099903
u8 mgmt_err = mgmt_status(status);
9910-
mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev,
9904+
mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, true,
99119905
cmd_status_rsp, &mgmt_err);
99129906
return;
99139907
}
@@ -9917,8 +9911,8 @@ void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status)
99179911
else
99189912
changed = hci_dev_test_and_clear_flag(hdev, HCI_LINK_SECURITY);
99199913

9920-
mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, settings_rsp,
9921-
&match);
9914+
mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, true,
9915+
settings_rsp, &match);
99229916

99239917
if (changed)
99249918
new_settings(hdev, match.sk);
@@ -9942,9 +9936,12 @@ void mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
99429936
{
99439937
struct cmd_lookup match = { NULL, hdev, mgmt_status(status) };
99449938

9945-
mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, sk_lookup, &match);
9946-
mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, sk_lookup, &match);
9947-
mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, sk_lookup, &match);
9939+
mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, false, sk_lookup,
9940+
&match);
9941+
mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, false, sk_lookup,
9942+
&match);
9943+
mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, false, sk_lookup,
9944+
&match);
99489945

99499946
if (!status) {
99509947
mgmt_limited_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, dev_class,

0 commit comments

Comments
 (0)