Commit 7b445e22 authored by Luiz Augusto von Dentz's avatar Luiz Augusto von Dentz
Browse files

Bluetooth: MGMT: Fix holding hci_conn reference while command is queued



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: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent 1f7435c8
Loading
Loading
Loading
Loading
+12 −39
Original line number Diff line number Diff line
@@ -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);
	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) {
	cmd->user_data = conn;
	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;
		}
	}

	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);
	}