bluetooth: host: Fix simultaneous pairings getting the same keys slot
Fix an issue where a slot in the key pool was considered free when either the address was cleared or no keys were written in the entry (enc_size == 0). This caused a problem with simultaneous pairing attempts that would be assigned the same entry. This patch makes it so a a slot is considered free even when keys are not yet present in the entry, and makes sure the address is cleared in case of pairing failure or timeout so to mark the slot as free. Signed-off-by: François Delawarde <fnde@oticon.com>
This commit is contained in:
parent
171a9fa167
commit
a3e89e84a8
2 changed files with 9 additions and 20 deletions
|
@ -54,8 +54,7 @@ struct bt_keys *bt_keys_get_addr(u8_t id, const bt_addr_le_t *addr)
|
|||
}
|
||||
|
||||
if (first_free_slot == ARRAY_SIZE(key_pool) &&
|
||||
(!bt_addr_le_cmp(&keys->addr, BT_ADDR_LE_ANY) ||
|
||||
!keys->enc_size)) {
|
||||
!bt_addr_le_cmp(&keys->addr, BT_ADDR_LE_ANY)) {
|
||||
first_free_slot = i;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1763,6 +1763,14 @@ static void smp_pairing_complete(struct bt_smp *smp, u8_t status)
|
|||
} else {
|
||||
u8_t auth_err = auth_err_get(status);
|
||||
|
||||
/*
|
||||
* Clear the key pool entry in case of pairing failure.
|
||||
*/
|
||||
if (smp->chan.chan.conn->le.keys) {
|
||||
bt_keys_clear(smp->chan.chan.conn->le.keys);
|
||||
smp->chan.chan.conn->le.keys = NULL;
|
||||
}
|
||||
|
||||
if (!atomic_test_bit(smp->flags, SMP_FLAG_KEYS_DISTR)) {
|
||||
bt_conn_security_changed(smp->chan.chan.conn, auth_err);
|
||||
}
|
||||
|
@ -1781,15 +1789,6 @@ static void smp_timeout(struct k_work *work)
|
|||
|
||||
BT_ERR("SMP Timeout");
|
||||
|
||||
/*
|
||||
* If SMP timeout occurred during key distribution we should assume
|
||||
* pairing failed and don't store any keys from this pairing.
|
||||
*/
|
||||
if (atomic_test_bit(smp->flags, SMP_FLAG_KEYS_DISTR) &&
|
||||
smp->chan.chan.conn->le.keys) {
|
||||
bt_keys_clear(smp->chan.chan.conn->le.keys);
|
||||
}
|
||||
|
||||
atomic_set_bit(smp->flags, SMP_FLAG_TIMEOUT);
|
||||
|
||||
smp_pairing_complete(smp, BT_SMP_ERR_UNSPECIFIED);
|
||||
|
@ -3519,15 +3518,6 @@ static u8_t smp_pairing_failed(struct bt_smp *smp, struct net_buf *buf)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Pairing Failed command may be sent at any time during the pairing,
|
||||
* so if there are any keys distributed, shall be cleared.
|
||||
*/
|
||||
if (atomic_test_bit(smp->flags, SMP_FLAG_KEYS_DISTR) &&
|
||||
smp->chan.chan.conn->le.keys) {
|
||||
bt_keys_clear(smp->chan.chan.conn->le.keys);
|
||||
}
|
||||
|
||||
smp_pairing_complete(smp, req->reason);
|
||||
|
||||
/* return no error to avoid sending Pairing Failed in response */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue