mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-08-06 10:07:55 +00:00
fix(nimble):fix array overflow caused by invalid connection handle indexing
This commit is contained in:
+35
-26
@@ -318,7 +318,6 @@ static uint8_t pawr_adv_handle;
|
||||
static uint16_t pawr_sync_handle;
|
||||
#endif
|
||||
|
||||
int slave_conn[MYNEWT_VAL(BLE_MAX_CONNECTIONS) + 1];
|
||||
static void ble_gap_update_entry_free(struct ble_gap_update_entry *entry);
|
||||
|
||||
#if NIMBLE_BLE_CONNECT
|
||||
@@ -345,11 +344,6 @@ static int ble_gap_conn_cancel_tx(void);
|
||||
static int ble_gap_disc_enable_tx(int enable, int filter_duplicates);
|
||||
#endif
|
||||
|
||||
uint16_t g_max_tx_time[MYNEWT_VAL(BLE_MAX_CONNECTIONS) + 1];
|
||||
uint16_t g_max_rx_time[MYNEWT_VAL(BLE_MAX_CONNECTIONS) + 1 ];
|
||||
uint16_t g_max_tx_octets[MYNEWT_VAL(BLE_MAX_CONNECTIONS) + 1];
|
||||
uint16_t g_max_rx_octets[MYNEWT_VAL(BLE_MAX_CONNECTIONS) + 1];
|
||||
|
||||
STATS_SECT_DECL(ble_gap_stats) ble_gap_stats;
|
||||
STATS_NAME_START(ble_gap_stats)
|
||||
STATS_NAME(ble_gap_stats, wl_set)
|
||||
@@ -1626,8 +1620,8 @@ ble_gap_conn_broken(uint16_t conn_handle, int reason)
|
||||
|
||||
// Send disconnect event in slave role if connect was sent
|
||||
if ((conn != NULL) && !(conn->bhc_flags & BLE_HS_CONN_F_MASTER)) {
|
||||
if (slave_conn[conn_handle]) {
|
||||
slave_conn[conn_handle] = 0;
|
||||
if (conn->slave_conn) {
|
||||
conn->slave_conn = 0;
|
||||
} else {
|
||||
send = 0;
|
||||
}
|
||||
@@ -1644,10 +1638,15 @@ ble_gap_conn_broken(uint16_t conn_handle, int reason)
|
||||
|
||||
ble_hs_atomic_conn_delete(conn_handle);
|
||||
|
||||
g_max_tx_time[conn_handle] = 0;
|
||||
g_max_rx_time[conn_handle] = 0;
|
||||
g_max_tx_octets[conn_handle] = 0;
|
||||
g_max_rx_octets[conn_handle] = 0;
|
||||
ble_hs_lock();
|
||||
conn = ble_hs_conn_find(conn_handle);
|
||||
if (conn != NULL) {
|
||||
conn->bhc_max_tx_time = 0;
|
||||
conn->bhc_max_rx_time = 0;
|
||||
conn->bhc_max_tx_octets = 0;
|
||||
conn->bhc_max_rx_octets = 0;
|
||||
}
|
||||
ble_hs_unlock();
|
||||
|
||||
event.type = BLE_GAP_EVENT_DISCONNECT;
|
||||
event.disconnect.reason = reason;
|
||||
@@ -3137,9 +3136,9 @@ ble_gap_rx_rd_rem_sup_feat_complete(const struct ble_hci_ev_le_subev_rd_rem_used
|
||||
conn->supported_feat = get_le32(ev->features);
|
||||
}
|
||||
|
||||
if (conn != NULL) {
|
||||
ble_gap_event_connect_call(ev->conn_handle, 0);
|
||||
slave_conn[ev->conn_handle] = 1;
|
||||
if (conn != NULL) {
|
||||
ble_gap_event_connect_call(ev->conn_handle, ev->status);
|
||||
conn->slave_conn = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -3221,7 +3220,7 @@ ble_gap_rx_data_len_change(const struct ble_hci_ev_le_subev_data_len_chg *ev)
|
||||
#if NIMBLE_BLE_CONNECT
|
||||
struct ble_gap_event event;
|
||||
uint16_t conn_handle = le16toh(ev->conn_handle);
|
||||
|
||||
struct ble_hs_conn *conn;
|
||||
memset(&event, 0, sizeof event);
|
||||
event.type = BLE_GAP_EVENT_DATA_LEN_CHG;
|
||||
event.data_len_chg.max_tx_octets = le16toh(ev->max_tx_octets);
|
||||
@@ -3229,11 +3228,16 @@ ble_gap_rx_data_len_change(const struct ble_hci_ev_le_subev_data_len_chg *ev)
|
||||
event.data_len_chg.max_tx_time = le16toh(ev->max_tx_time);
|
||||
event.data_len_chg.max_rx_time = le16toh(ev->max_rx_time);
|
||||
|
||||
g_max_tx_octets[conn_handle] = event.data_len_chg.max_tx_octets;
|
||||
g_max_rx_octets[conn_handle] = event.data_len_chg.max_rx_octets;
|
||||
g_max_tx_time[conn_handle] = event.data_len_chg.max_tx_time;
|
||||
g_max_rx_time[conn_handle] = event.data_len_chg.max_rx_time;
|
||||
|
||||
ble_hs_lock();
|
||||
conn = ble_hs_conn_find(conn_handle);
|
||||
if (conn != NULL) {
|
||||
conn->bhc_max_tx_octets = event.data_len_chg.max_tx_octets;
|
||||
conn->bhc_max_rx_octets = event.data_len_chg.max_rx_octets;
|
||||
conn->bhc_max_tx_time = event.data_len_chg.max_tx_time;
|
||||
conn->bhc_max_rx_time = event.data_len_chg.max_rx_time;
|
||||
}
|
||||
ble_hs_unlock();
|
||||
|
||||
ble_gap_event_listener_call(&event);
|
||||
ble_gap_call_conn_event_cb(&event, conn_handle);
|
||||
#endif
|
||||
@@ -8346,16 +8350,21 @@ ble_gap_set_data_len(uint16_t conn_handle, uint16_t tx_octets,
|
||||
* If yes, then just return event to host indicating success
|
||||
* since controller will not send any event in this scenario
|
||||
*/
|
||||
if (g_max_tx_time[conn_handle] == tx_time && g_max_tx_octets[conn_handle] == tx_octets) {
|
||||
struct ble_hs_conn *conn;
|
||||
|
||||
ble_hs_lock();
|
||||
conn = ble_hs_conn_find(conn_handle);
|
||||
ble_hs_unlock();
|
||||
|
||||
if (conn != NULL && conn->bhc_max_tx_time == tx_time && conn->bhc_max_tx_octets == tx_octets) {
|
||||
struct ble_gap_event event;
|
||||
|
||||
memset(&event, 0, sizeof event);
|
||||
event.type = BLE_GAP_EVENT_DATA_LEN_CHG;
|
||||
event.data_len_chg.max_tx_octets = g_max_tx_octets[conn_handle];
|
||||
event.data_len_chg.max_rx_octets = g_max_rx_octets[conn_handle];
|
||||
event.data_len_chg.max_tx_time = g_max_tx_time[conn_handle];
|
||||
event.data_len_chg.max_rx_time = g_max_rx_time[conn_handle];
|
||||
event.data_len_chg.max_tx_octets = conn->bhc_max_tx_octets;
|
||||
event.data_len_chg.max_rx_octets = conn->bhc_max_rx_octets;
|
||||
event.data_len_chg.max_tx_time = conn->bhc_max_tx_time;
|
||||
event.data_len_chg.max_rx_time = conn->bhc_max_rx_time;
|
||||
event.data_len_chg.conn_handle = conn_handle;
|
||||
|
||||
ble_gap_event_listener_call(&event);
|
||||
|
||||
@@ -51,6 +51,7 @@ struct ble_hs_conn {
|
||||
SLIST_ENTRY(ble_hs_conn) bhc_next;
|
||||
uint16_t bhc_handle;
|
||||
uint8_t bhc_our_addr_type;
|
||||
uint8_t slave_conn : 1;
|
||||
#if MYNEWT_VAL(BLE_EXT_ADV)
|
||||
uint8_t bhc_our_rnd_addr[6];
|
||||
#endif
|
||||
@@ -61,6 +62,10 @@ struct ble_hs_conn {
|
||||
uint16_t bhc_itvl;
|
||||
uint16_t bhc_latency;
|
||||
uint16_t bhc_supervision_timeout;
|
||||
uint16_t bhc_max_tx_octets;
|
||||
uint16_t bhc_max_rx_octets;
|
||||
uint16_t bhc_max_tx_time;
|
||||
uint16_t bhc_max_rx_time;
|
||||
uint8_t bhc_master_clock_accuracy;
|
||||
|
||||
uint32_t supported_feat;
|
||||
|
||||
@@ -38,7 +38,6 @@ struct ble_gap_reattempt_ctxt {
|
||||
|
||||
extern int ble_gap_master_connect_reattempt(uint16_t conn_handle);
|
||||
extern int ble_gap_slave_adv_reattempt(void);
|
||||
extern int slave_conn[MYNEWT_VAL(BLE_MAX_CONNECTIONS) + 1];
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_QUEUE_CONG_CHECK)
|
||||
@@ -330,7 +329,7 @@ ble_hs_hci_evt_disconn_complete(uint8_t event_code, const void *data,
|
||||
}
|
||||
else if (!(conn->bhc_flags & BLE_HS_CONN_F_MASTER) && \
|
||||
((ev->reason == BLE_ERR_CONN_ESTABLISHMENT) || \
|
||||
(!slave_conn[ev->conn_handle] && ev->reason == BLE_ERR_CONN_SPVN_TMO))) { //slave
|
||||
(!conn->slave_conn && ev->reason == BLE_ERR_CONN_SPVN_TMO))) { //slave
|
||||
|
||||
BLE_HS_LOG(INFO, "Reattempt advertising; reason: 0x%x, status = %x",
|
||||
ev->reason, ev->status);
|
||||
|
||||
Reference in New Issue
Block a user