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