Skip to content

Commit d3c6299

Browse files
author
Bastien Nocera
committed
Bluetooth: MGMT: Fix Add Device to responding before completing
JIRA: https://issues.redhat.com/browse/RHEL-74483 commit a182d9c Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Date: Mon Nov 25 15:42:10 2024 -0500 Bluetooth: MGMT: Fix Add Device to responding before completing Add Device with LE type requires updating resolving/accept list which requires quite a number of commands to complete and each of them may fail, so instead of pretending it would always work this checks the return of hci_update_passive_scan_sync which indicates if everything worked as intended. Fixes: e8907f7 ("Bluetooth: hci_sync: Make use of hci_cmd_sync_queue set 3") Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Bastien Nocera <bnocera@redhat.com>
1 parent 9a1cd25 commit d3c6299

File tree

1 file changed

+36
-2
lines changed

1 file changed

+36
-2
lines changed

net/bluetooth/mgmt.c

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7656,6 +7656,24 @@ static void device_added(struct sock *sk, struct hci_dev *hdev,
76567656
mgmt_event(MGMT_EV_DEVICE_ADDED, hdev, &ev, sizeof(ev), sk);
76577657
}
76587658

7659+
static void add_device_complete(struct hci_dev *hdev, void *data, int err)
7660+
{
7661+
struct mgmt_pending_cmd *cmd = data;
7662+
struct mgmt_cp_add_device *cp = cmd->param;
7663+
7664+
if (!err) {
7665+
device_added(cmd->sk, hdev, &cp->addr.bdaddr, cp->addr.type,
7666+
cp->action);
7667+
device_flags_changed(NULL, hdev, &cp->addr.bdaddr,
7668+
cp->addr.type, hdev->conn_flags,
7669+
PTR_UINT(cmd->user_data));
7670+
}
7671+
7672+
mgmt_cmd_complete(cmd->sk, hdev->id, MGMT_OP_ADD_DEVICE,
7673+
mgmt_status(err), &cp->addr, sizeof(cp->addr));
7674+
mgmt_pending_free(cmd);
7675+
}
7676+
76597677
static int add_device_sync(struct hci_dev *hdev, void *data)
76607678
{
76617679
return hci_update_passive_scan_sync(hdev);
@@ -7664,6 +7682,7 @@ static int add_device_sync(struct hci_dev *hdev, void *data)
76647682
static int add_device(struct sock *sk, struct hci_dev *hdev,
76657683
void *data, u16 len)
76667684
{
7685+
struct mgmt_pending_cmd *cmd;
76677686
struct mgmt_cp_add_device *cp = data;
76687687
u8 auto_conn, addr_type;
76697688
struct hci_conn_params *params;
@@ -7744,9 +7763,24 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
77447763
current_flags = params->flags;
77457764
}
77467765

7747-
err = hci_cmd_sync_queue(hdev, add_device_sync, NULL, NULL);
7748-
if (err < 0)
7766+
cmd = mgmt_pending_new(sk, MGMT_OP_ADD_DEVICE, hdev, data, len);
7767+
if (!cmd) {
7768+
err = -ENOMEM;
77497769
goto unlock;
7770+
}
7771+
7772+
cmd->user_data = UINT_PTR(current_flags);
7773+
7774+
err = hci_cmd_sync_queue(hdev, add_device_sync, cmd,
7775+
add_device_complete);
7776+
if (err < 0) {
7777+
err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
7778+
MGMT_STATUS_FAILED, &cp->addr,
7779+
sizeof(cp->addr));
7780+
mgmt_pending_free(cmd);
7781+
}
7782+
7783+
goto unlock;
77507784

77517785
added:
77527786
device_added(sk, hdev, &cp->addr.bdaddr, cp->addr.type, cp->action);

0 commit comments

Comments
 (0)