Bluetooth: Fix LE pairing scenarios when initiated remotely
Fix setting of ENCRYPTION_PENDING and Connection refcnt's that could be out of sync due to remote slave issued security requests. Change-Id: Ie72abd0648182db0ef60693820139f40ef2e4bf6 Signed-off-by: Brian Gix <bgix@codeaurora.org>
This commit is contained in:
@@ -438,6 +438,7 @@ int le_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, void *cp)
|
||||
smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
|
||||
&reason);
|
||||
del_timer(&hcon->smp_timer);
|
||||
clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
|
||||
mgmt_auth_failed(hcon->hdev->id, conn->dst, reason);
|
||||
hci_conn_put(hcon);
|
||||
} else if (hcon->cfm_pending) {
|
||||
@@ -686,6 +687,8 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
|
||||
|
||||
set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
|
||||
|
||||
hci_conn_hold(hcon);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -846,6 +849,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
|
||||
reason = 0;
|
||||
err = -EPERM;
|
||||
del_timer(&hcon->smp_timer);
|
||||
clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
|
||||
mgmt_auth_failed(hcon->hdev->id, conn->dst, skb->data[1]);
|
||||
hci_conn_put(hcon);
|
||||
break;
|
||||
@@ -895,6 +899,7 @@ done:
|
||||
smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
|
||||
&reason);
|
||||
del_timer(&hcon->smp_timer);
|
||||
clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
|
||||
mgmt_auth_failed(hcon->hdev->id, conn->dst, reason);
|
||||
hci_conn_put(hcon);
|
||||
}
|
||||
@@ -989,6 +994,7 @@ static int smp_distribute_keys(struct l2cap_conn *conn, __u8 force)
|
||||
hcon->disconn_cfm_cb(hcon, 0);
|
||||
|
||||
del_timer(&hcon->smp_timer);
|
||||
clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
|
||||
mgmt_auth_failed(hcon->hdev->id, conn->dst, SMP_UNSPECIFIED);
|
||||
hci_conn_put(hcon);
|
||||
}
|
||||
@@ -1002,6 +1008,8 @@ int smp_link_encrypt_cmplt(struct l2cap_conn *conn, u8 status, u8 encrypt)
|
||||
|
||||
BT_DBG("smp: %d %d %d", status, encrypt, hcon->sec_req);
|
||||
|
||||
clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
|
||||
|
||||
if (!status && encrypt && !hcon->sec_req)
|
||||
smp_distribute_keys(conn, 0);
|
||||
|
||||
@@ -1009,6 +1017,9 @@ int smp_link_encrypt_cmplt(struct l2cap_conn *conn, u8 status, u8 encrypt)
|
||||
else if (hcon->sec_req && (status || !encrypt))
|
||||
smp_conn_security(conn, hcon->sec_level);
|
||||
|
||||
else
|
||||
hci_conn_put(hcon);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1020,6 +1031,7 @@ void smp_timeout(unsigned long arg)
|
||||
BT_DBG("%p", conn);
|
||||
|
||||
smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), &reason);
|
||||
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->pend);
|
||||
mgmt_auth_failed(conn->hcon->hdev->id, conn->dst, SMP_UNSPECIFIED);
|
||||
hci_conn_put(conn->hcon);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user