Skip to content

Commit c9fd7a6

Browse files
faisalSaleemSeteccarlescufi
authored andcommitted
Bluetooth: Keys: Fix BT_KEYS_OVERWRITE_OLDEST logic for BT_MAX_CONN > 1
When the Bluetooth stack is configured for CONFIG_BT_MAX_CONN > 1 the oldest key might currently be in use. Fix the logic to ensure the oldest key overwritten is from the set of keys currently not in use. Fixes: #35999 Signed-off-by: Faisal Saleem <[email protected]> Signed-off-by: Nick Ward <[email protected]>
1 parent 1b4dad4 commit c9fd7a6

File tree

2 files changed

+51
-8
lines changed

2 files changed

+51
-8
lines changed

subsys/bluetooth/host/Kconfig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -421,11 +421,11 @@ config BT_OOB_DATA_FIXED
421421
Use of this feature in production is strongly discouraged.
422422

423423
config BT_KEYS_OVERWRITE_OLDEST
424-
bool "Overwrite oldest keys with new ones if key storage is full"
424+
bool "Overwrite the oldest key if key storage is full"
425425
help
426-
With this option enabled, if a pairing attempt occurs and the key storage
427-
is full, then the oldest keys in storage will be removed to free space
428-
for the new pairing keys.
426+
If a pairing attempt occurs and the key storage is full then the
427+
oldest key from the set of not currently in use keys will be selected
428+
and overwritten by the pairing device.
429429

430430
config BT_KEYS_SAVE_AGING_COUNTER_ON_PAIRING
431431
bool "Store aging counter every time a successful paring occurs"

subsys/bluetooth/host/keys.c

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <settings/settings.h>
1717

1818
#include <bluetooth/bluetooth.h>
19+
#include <bluetooth/buf.h>
1920
#include <bluetooth/conn.h>
2021
#include <bluetooth/hci.h>
2122

@@ -24,6 +25,7 @@
2425
#include "common/log.h"
2526

2627
#include "common/rpa.h"
28+
#include "conn_internal.h"
2729
#include "gatt_internal.h"
2830
#include "hci_core.h"
2931
#include "smp.h"
@@ -37,6 +39,38 @@ static struct bt_keys key_pool[CONFIG_BT_MAX_PAIRED];
3739
#if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
3840
static uint32_t aging_counter_val;
3941
static struct bt_keys *last_keys_updated;
42+
43+
struct key_data {
44+
bool in_use;
45+
uint8_t id;
46+
};
47+
48+
static void find_key_in_use(struct bt_conn *conn, void *data)
49+
{
50+
struct key_data *kdata = data;
51+
struct bt_keys *key;
52+
53+
if (conn->state == BT_CONN_CONNECTED) {
54+
key = bt_keys_find_addr(conn->id, bt_conn_get_dst(conn));
55+
if (key == NULL) {
56+
return;
57+
}
58+
if (bt_addr_cmp(&key->addr.a, &key_pool[kdata->id].addr.a) == 0) {
59+
kdata->in_use = true;
60+
BT_DBG("Connected device %s is using key_pool[%d]",
61+
bt_addr_le_str(bt_conn_get_dst(conn)), kdata->id);
62+
}
63+
}
64+
}
65+
66+
static bool key_is_in_use(uint8_t id)
67+
{
68+
struct key_data kdata = { false, id };
69+
70+
bt_conn_foreach(BT_CONN_TYPE_ALL, find_key_in_use, &kdata);
71+
72+
return kdata.in_use;
73+
}
4074
#endif /* CONFIG_BT_KEYS_OVERWRITE_OLDEST */
4175

4276
struct bt_keys *bt_keys_get_addr(uint8_t id, const bt_addr_le_t *addr)
@@ -53,7 +87,6 @@ struct bt_keys *bt_keys_get_addr(uint8_t id, const bt_addr_le_t *addr)
5387
if (keys->id == id && !bt_addr_le_cmp(&keys->addr, addr)) {
5488
return keys;
5589
}
56-
5790
if (first_free_slot == ARRAY_SIZE(key_pool) &&
5891
!bt_addr_le_cmp(&keys->addr, BT_ADDR_LE_ANY)) {
5992
first_free_slot = i;
@@ -62,17 +95,27 @@ struct bt_keys *bt_keys_get_addr(uint8_t id, const bt_addr_le_t *addr)
6295

6396
#if IS_ENABLED(CONFIG_BT_KEYS_OVERWRITE_OLDEST)
6497
if (first_free_slot == ARRAY_SIZE(key_pool)) {
65-
struct bt_keys *oldest = &key_pool[0];
98+
struct bt_keys *oldest = NULL;
6699
bt_addr_le_t oldest_addr;
67100

68-
for (i = 1; i < ARRAY_SIZE(key_pool); i++) {
101+
for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
69102
struct bt_keys *current = &key_pool[i];
103+
bool key_in_use = (CONFIG_BT_MAX_CONN > 1) && key_is_in_use(i);
70104

71-
if (current->aging_counter < oldest->aging_counter) {
105+
if (key_in_use) {
106+
continue;
107+
}
108+
109+
if ((oldest == NULL) || (current->aging_counter < oldest->aging_counter)) {
72110
oldest = current;
73111
}
74112
}
75113

114+
if (oldest == NULL) {
115+
BT_DBG("unable to create keys for %s", bt_addr_le_str(addr));
116+
return NULL;
117+
}
118+
76119
/* Use a copy as bt_unpair will clear the oldest key. */
77120
bt_addr_le_copy(&oldest_addr, &oldest->addr);
78121
bt_unpair(oldest->id, &oldest_addr);

0 commit comments

Comments
 (0)