Bluetooth: Fix HCI channel reference counting

When an incoming HCI logical link event came in at the same time
a socket structure was deleted, it was possible to end up with a stale
pointer to the socket.  The socket and associated HCI channel struct
need to be properly reference counted so they are not freed
prematurely.

CRs-Fixed: 325023
Change-Id: Ia5724a9ce2000acd60a174c354be04029bac5324
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 78d1c61..53a9cac 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -511,18 +511,24 @@
 int hci_chan_put(struct hci_chan *chan)
 {
 	struct hci_cp_disconn_logical_link cp;
+	struct hci_conn *hcon;
+	u16 ll_handle;
 
 	BT_DBG("chan %p refcnt %d", chan, atomic_read(&chan->refcnt));
 	if (!atomic_dec_and_test(&chan->refcnt))
 		return 0;
 
-	BT_DBG("chan->conn->state %d", chan->conn->state);
-	if (chan->conn->state == BT_CONNECTED) {
-		cp.log_handle = cpu_to_le16(chan->ll_handle);
-		hci_send_cmd(chan->conn->hdev, HCI_OP_DISCONN_LOGICAL_LINK,
+	hcon = chan->conn;
+	ll_handle = chan->ll_handle;
+
+	hci_chan_del(chan);
+
+	BT_DBG("chan->conn->state %d", hcon->state);
+	if (hcon->state == BT_CONNECTED) {
+		cp.log_handle = cpu_to_le16(ll_handle);
+		hci_send_cmd(hcon->hdev, HCI_OP_DISCONN_LOGICAL_LINK,
 				sizeof(cp), &cp);
-	} else
-		hci_chan_del(chan);
+	}
 
 	return 1;
 }