Bluetooth: Fix using hci_conn_get() for hci_conn pointers
authorJohan Hedberg <johan.hedberg@intel.com>
Sun, 17 Aug 2014 20:28:57 +0000 (23:28 +0300)
committerMarcel Holtmann <marcel@holtmann.org>
Mon, 8 Sep 2014 17:07:53 +0000 (19:07 +0200)
Wherever we keep hci_conn pointers around we should be using
hci_conn_get/put to ensure that they stay valid. This patch fixes
all places violating against the principle currently.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
net/bluetooth/hci_conn.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/mgmt.c

index faff6247ac8fb8769bf58f235fd92c0deab6aaf1..4ecc9d5fce7a5cba59cbeb893e045de3eb0ebb54 100644 (file)
@@ -595,6 +595,7 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status)
                                           conn->dst_type);
        if (params && params->conn) {
                hci_conn_drop(params->conn);
+               hci_conn_put(params->conn);
                params->conn = NULL;
        }
 
index 9b7145959a49e7ea7b52cf7fb11e9a8f68fa7346..ed60d37ea6462320cec902acd6d6cbcc9b4374a9 100644 (file)
@@ -2541,6 +2541,7 @@ static void hci_pend_le_actions_clear(struct hci_dev *hdev)
        list_for_each_entry(p, &hdev->le_conn_params, list) {
                if (p->conn) {
                        hci_conn_drop(p->conn);
+                       hci_conn_put(p->conn);
                        p->conn = NULL;
                }
                list_del_init(&p->action);
@@ -3734,8 +3735,10 @@ void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
        if (!params)
                return;
 
-       if (params->conn)
+       if (params->conn) {
                hci_conn_drop(params->conn);
+               hci_conn_put(params->conn);
+       }
 
        list_del(&params->action);
        list_del(&params->list);
@@ -3767,8 +3770,10 @@ void hci_conn_params_clear_all(struct hci_dev *hdev)
        struct hci_conn_params *params, *tmp;
 
        list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
-               if (params->conn)
+               if (params->conn) {
                        hci_conn_drop(params->conn);
+                       hci_conn_put(params->conn);
+               }
                list_del(&params->action);
                list_del(&params->list);
                kfree(params);
index d2ee162ecddb8e386b57bbdcbac62635b8903a82..e6a496ae0318daab653674a0120297c21e63244a 100644 (file)
@@ -4231,6 +4231,7 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
                list_del_init(&params->action);
                if (params->conn) {
                        hci_conn_drop(params->conn);
+                       hci_conn_put(params->conn);
                        params->conn = NULL;
                }
        }
@@ -4322,7 +4323,7 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
                 * the parameters get removed and keep the reference
                 * count consistent once the connection is established.
                 */
-               params->conn = conn;
+               params->conn = hci_conn_get(conn);
                return;
        }
 
index c2457435a670149c2d368f1c81dae2697972da1f..d8c66663ade8cd77ee7894c9ac47c3e9c0fbf5a8 100644 (file)
@@ -3063,6 +3063,7 @@ static void pairing_complete(struct pending_cmd *cmd, u8 status)
        conn->disconn_cfm_cb = NULL;
 
        hci_conn_drop(conn);
+       hci_conn_put(conn);
 
        mgmt_pending_remove(cmd);
 }
@@ -3212,7 +3213,7 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
        }
 
        conn->io_capability = cp->io_cap;
-       cmd->user_data = conn;
+       cmd->user_data = hci_conn_get(conn);
 
        if ((conn->state == BT_CONNECTED || conn->state == BT_CONFIG) &&
            hci_conn_security(conn, sec_level, auth_type, true))
@@ -4914,6 +4915,7 @@ static void get_conn_info_complete(struct pending_cmd *cmd, void *data)
                     match->mgmt_status, &rp, sizeof(rp));
 
        hci_conn_drop(conn);
+       hci_conn_put(conn);
 
        mgmt_pending_remove(cmd);
 }
@@ -5070,7 +5072,7 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data,
                }
 
                hci_conn_hold(conn);
-               cmd->user_data = conn;
+               cmd->user_data = hci_conn_get(conn);
 
                conn->conn_info_timestamp = jiffies;
        } else {
@@ -5134,8 +5136,10 @@ send_rsp:
        cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(status),
                     &rp, sizeof(rp));
        mgmt_pending_remove(cmd);
-       if (conn)
+       if (conn) {
                hci_conn_drop(conn);
+               hci_conn_put(conn);
+       }
 
 unlock:
        hci_dev_unlock(hdev);
@@ -5198,7 +5202,7 @@ static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data,
 
        if (conn) {
                hci_conn_hold(conn);
-               cmd->user_data = conn;
+               cmd->user_data = hci_conn_get(conn);
 
                hci_cp.handle = cpu_to_le16(conn->handle);
                hci_cp.which = 0x01; /* Piconet clock */