Bluetooth: MGMT: Fix holding hci_conn reference while command is queued
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Thu, 21 Jul 2022 22:56:28 +0000 (15:56 -0700)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Fri, 22 Jul 2022 18:02:58 +0000 (11:02 -0700)
This removes the use of hci_conn_hold from Get Conn Info and Get Clock
Info since the callback can just do a lookup by address using the cmd
data and only then set cmd->user_data to pass to the complete callback.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
net/bluetooth/mgmt.c

index 0c68780..aa65112 100644 (file)
@@ -6711,11 +6711,6 @@ static void get_conn_info_complete(struct hci_dev *hdev, void *data, int err)
        mgmt_cmd_complete(cmd->sk, cmd->index, MGMT_OP_GET_CONN_INFO, status,
                          &rp, sizeof(rp));
 
-       if (conn) {
-               hci_conn_drop(conn);
-               hci_conn_put(conn);
-       }
-
        mgmt_pending_free(cmd);
 }
 
@@ -6734,15 +6729,10 @@ static int get_conn_info_sync(struct hci_dev *hdev, void *data)
        else
                conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr);
 
-       if (!conn || conn != cmd->user_data || conn->state != BT_CONNECTED) {
-               if (cmd->user_data) {
-                       hci_conn_drop(cmd->user_data);
-                       hci_conn_put(cmd->user_data);
-                       cmd->user_data = NULL;
-               }
+       if (!conn || conn->state != BT_CONNECTED)
                return MGMT_STATUS_NOT_CONNECTED;
-       }
 
+       cmd->user_data = conn;
        handle = cpu_to_le16(conn->handle);
 
        /* Refresh RSSI each time */
@@ -6824,8 +6814,6 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data,
                if (!cmd) {
                        err = -ENOMEM;
                } else {
-                       hci_conn_hold(conn);
-                       cmd->user_data = hci_conn_get(conn);
                        err = hci_cmd_sync_queue(hdev, get_conn_info_sync,
                                                 cmd, get_conn_info_complete);
                }
@@ -6878,8 +6866,6 @@ static void get_clock_info_complete(struct hci_dev *hdev, void *data, int err)
        if (conn) {
                rp.piconet_clock = cpu_to_le32(conn->clock);
                rp.accuracy = cpu_to_le16(conn->clock_accuracy);
-               hci_conn_drop(conn);
-               hci_conn_put(conn);
        }
 
 complete:
@@ -6894,30 +6880,21 @@ static int get_clock_info_sync(struct hci_dev *hdev, void *data)
        struct mgmt_pending_cmd *cmd = data;
        struct mgmt_cp_get_clock_info *cp = cmd->param;
        struct hci_cp_read_clock hci_cp;
-       struct hci_conn *conn = cmd->user_data;
-       int err;
+       struct hci_conn *conn;
 
        memset(&hci_cp, 0, sizeof(hci_cp));
-       err = hci_read_clock_sync(hdev, &hci_cp);
+       hci_read_clock_sync(hdev, &hci_cp);
 
-       if (conn) {
-               /* Make sure connection still exists */
-               conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK,
-                                              &cp->addr.bdaddr);
+       /* Make sure connection still exists */
+       conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->addr.bdaddr);
+       if (!conn || conn->state != BT_CONNECTED)
+               return MGMT_STATUS_NOT_CONNECTED;
 
-               if (conn && conn == cmd->user_data &&
-                   conn->state == BT_CONNECTED) {
-                       hci_cp.handle = cpu_to_le16(conn->handle);
-                       hci_cp.which = 0x01; /* Piconet clock */
-                       err = hci_read_clock_sync(hdev, &hci_cp);
-               } else if (cmd->user_data) {
-                       hci_conn_drop(cmd->user_data);
-                       hci_conn_put(cmd->user_data);
-                       cmd->user_data = NULL;
-               }
-       }
+       cmd->user_data = conn;
+       hci_cp.handle = cpu_to_le16(conn->handle);
+       hci_cp.which = 0x01; /* Piconet clock */
 
-       return err;
+       return hci_read_clock_sync(hdev, &hci_cp);
 }
 
 static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data,
@@ -6976,10 +6953,6 @@ static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data,
 
                if (cmd)
                        mgmt_pending_free(cmd);
-
-       } else if (conn) {
-               hci_conn_hold(conn);
-               cmd->user_data = hci_conn_get(conn);
        }