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:
Brian Gix
2011-10-12 15:12:42 -07:00
committed by Stephen Boyd
parent 7b18f01664
commit 82c88a73d9

View File

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