mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-08-29 13:20:04 +00:00
fix(nimble): Out of order messages during SMP causing DOS vulerability
This commit is contained in:
committed by
Abhinav Kudnar
parent
8bcef4e241
commit
62adb830ff
@@ -755,8 +755,13 @@ static void
|
||||
ble_sm_rx_noop(uint16_t conn_handle, struct os_mbuf **om,
|
||||
struct ble_sm_result *res)
|
||||
{
|
||||
/**
|
||||
* Unsupported PDU received
|
||||
* Recommended action: Ignore
|
||||
*/
|
||||
res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_CMD_NOT_SUPP);
|
||||
res->sm_err = BLE_SM_ERR_CMD_NOT_SUPP;
|
||||
res->out_of_order = 1;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
@@ -952,6 +957,17 @@ ble_sm_process_result(uint16_t conn_handle, struct ble_sm_result *res,
|
||||
|
||||
rm = 0;
|
||||
|
||||
if (res && res->out_of_order) {
|
||||
/**
|
||||
* An unexpected SM PDU received.
|
||||
* Spec recommends ignore the PDU.
|
||||
*/
|
||||
memset(res, 0, sizeof *res);
|
||||
res->sm_err = BLE_SM_ERR_UNSPECIFIED;
|
||||
res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_UNSPECIFIED);
|
||||
return;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
ble_hs_lock();
|
||||
proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_NONE, -1,
|
||||
@@ -1544,7 +1560,12 @@ ble_sm_random_rx(uint16_t conn_handle, struct os_mbuf **om,
|
||||
ble_hs_lock();
|
||||
proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_RANDOM, -1, NULL);
|
||||
if (proc == NULL) {
|
||||
/**
|
||||
* Unexpectedly received pairing random value.
|
||||
* Recommended action: Ignore
|
||||
*/
|
||||
res->app_status = BLE_HS_ENOENT;
|
||||
res->out_of_order = 1;
|
||||
} else {
|
||||
memcpy(ble_sm_peer_pair_rand(proc), cmd->value, 16);
|
||||
|
||||
@@ -1592,7 +1613,12 @@ ble_sm_confirm_rx(uint16_t conn_handle, struct os_mbuf **om,
|
||||
ble_hs_lock();
|
||||
proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_CONFIRM, -1, NULL);
|
||||
if (proc == NULL) {
|
||||
/**
|
||||
* Unexpectedly received pairing confirm value.
|
||||
* Recommended action: Ignore
|
||||
*/
|
||||
res->app_status = BLE_HS_ENOENT;
|
||||
res->out_of_order = 1;
|
||||
} else {
|
||||
memcpy(proc->confirm_peer, cmd->value, 16);
|
||||
|
||||
@@ -1849,12 +1875,13 @@ ble_sm_pair_req_rx(uint16_t conn_handle, struct os_mbuf **om,
|
||||
*/
|
||||
proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_NONE, -1, &prev);
|
||||
if (proc != NULL) {
|
||||
/* Fail if procedure is in progress unless we sent a slave security
|
||||
/* Ignore if procedure is in progress unless we sent a slave security
|
||||
* request to peer.
|
||||
*/
|
||||
if (proc->state != BLE_SM_PROC_STATE_SEC_REQ) {
|
||||
res->sm_err = BLE_SM_ERR_UNSPECIFIED;
|
||||
res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_UNSPECIFIED);
|
||||
res->out_of_order = 1;
|
||||
ble_hs_unlock();
|
||||
return;
|
||||
}
|
||||
@@ -2006,6 +2033,14 @@ ble_sm_pair_rsp_rx(uint16_t conn_handle, struct os_mbuf **om,
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* Unexpectedly received pairing response.
|
||||
* Recommended action: Ignore
|
||||
*/
|
||||
res->sm_err = BLE_SM_ERR_UNSPECIFIED;
|
||||
res->app_status = BLE_HS_SM_US_ERR(BLE_SM_ERR_UNSPECIFIED);
|
||||
res->out_of_order = 1;
|
||||
}
|
||||
|
||||
ble_hs_unlock();
|
||||
@@ -2046,6 +2081,7 @@ ble_sm_sec_req_rx(uint16_t conn_handle, struct os_mbuf **om,
|
||||
struct ble_hs_conn_addrs addrs;
|
||||
struct ble_sm_sec_req *cmd;
|
||||
struct ble_hs_conn *conn;
|
||||
struct ble_sm_proc *proc;
|
||||
int authreq_mitm;
|
||||
|
||||
res->app_status = ble_hs_mbuf_pullup_base(om, sizeof(*cmd));
|
||||
@@ -2096,6 +2132,16 @@ ble_sm_sec_req_rx(uint16_t conn_handle, struct os_mbuf **om,
|
||||
}
|
||||
}
|
||||
|
||||
/** Make sure a procedure isn't already in progress for this connection. */
|
||||
ble_hs_lock();
|
||||
proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_NONE, -1, NULL);
|
||||
ble_hs_unlock();
|
||||
if (proc != NULL) {
|
||||
res->out_of_order = 1;
|
||||
proc = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (res->app_status == 0) {
|
||||
res->app_status = ble_sm_enc_initiate(conn_handle,
|
||||
value_sec.key_size,
|
||||
@@ -2391,8 +2437,13 @@ ble_sm_enc_info_rx(uint16_t conn_handle, struct os_mbuf **om,
|
||||
|
||||
proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_KEY_EXCH, -1, NULL);
|
||||
if (proc == NULL) {
|
||||
/**
|
||||
* Unexpected encryption info received
|
||||
* Recommended action: Ignore
|
||||
*/
|
||||
res->app_status = BLE_HS_ENOENT;
|
||||
res->sm_err = BLE_SM_ERR_UNSPECIFIED;
|
||||
res->out_of_order = 1;
|
||||
} else {
|
||||
proc->rx_key_flags &= ~BLE_SM_KE_F_ENC_INFO;
|
||||
proc->peer_keys.ltk_valid = 1;
|
||||
@@ -2425,8 +2476,13 @@ ble_sm_master_id_rx(uint16_t conn_handle, struct os_mbuf **om,
|
||||
|
||||
proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_KEY_EXCH, -1, NULL);
|
||||
if (proc == NULL) {
|
||||
/**
|
||||
* Unexpected central indentification info recieved
|
||||
* Recommended action: Ignore
|
||||
*/
|
||||
res->app_status = BLE_HS_ENOENT;
|
||||
res->sm_err = BLE_SM_ERR_UNSPECIFIED;
|
||||
res->out_of_order = 1;
|
||||
} else {
|
||||
proc->rx_key_flags &= ~BLE_SM_KE_F_MASTER_ID;
|
||||
proc->peer_keys.ediv_rand_valid = 1;
|
||||
@@ -2460,8 +2516,13 @@ ble_sm_id_info_rx(uint16_t conn_handle, struct os_mbuf **om,
|
||||
|
||||
proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_KEY_EXCH, -1, NULL);
|
||||
if (proc == NULL) {
|
||||
/**
|
||||
* Unexpected ID info received
|
||||
* Recommended action: Ignore
|
||||
*/
|
||||
res->app_status = BLE_HS_ENOENT;
|
||||
res->sm_err = BLE_SM_ERR_UNSPECIFIED;
|
||||
res->out_of_order = 1;
|
||||
} else {
|
||||
proc->rx_key_flags &= ~BLE_SM_KE_F_ID_INFO;
|
||||
|
||||
@@ -2494,8 +2555,13 @@ ble_sm_id_addr_info_rx(uint16_t conn_handle, struct os_mbuf **om,
|
||||
|
||||
proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_KEY_EXCH, -1, NULL);
|
||||
if (proc == NULL) {
|
||||
/**
|
||||
* Unexpected identity address info received
|
||||
* Recommended action: Ignore
|
||||
*/
|
||||
res->app_status = BLE_HS_ENOENT;
|
||||
res->sm_err = BLE_SM_ERR_UNSPECIFIED;
|
||||
res->out_of_order = 1;
|
||||
} else {
|
||||
proc->rx_key_flags &= ~BLE_SM_KE_F_ADDR_INFO;
|
||||
proc->peer_keys.addr_valid = 1;
|
||||
@@ -2528,8 +2594,13 @@ ble_sm_sign_info_rx(uint16_t conn_handle, struct os_mbuf **om,
|
||||
|
||||
proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_KEY_EXCH, -1, NULL);
|
||||
if (proc == NULL) {
|
||||
/**
|
||||
* Unexpected signing info received
|
||||
* Recommended action: Ignore
|
||||
*/
|
||||
res->app_status = BLE_HS_ENOENT;
|
||||
res->sm_err = BLE_SM_ERR_UNSPECIFIED;
|
||||
res->out_of_order = 1;
|
||||
} else {
|
||||
proc->rx_key_flags &= ~BLE_SM_KE_F_SIGN_INFO;
|
||||
|
||||
|
||||
@@ -287,6 +287,7 @@ struct ble_sm_result {
|
||||
unsigned enc_cb : 1;
|
||||
unsigned bonded : 1;
|
||||
unsigned restore : 1;
|
||||
unsigned out_of_order : 1;
|
||||
};
|
||||
|
||||
#if MYNEWT_VAL(BLE_HS_DEBUG)
|
||||
|
||||
@@ -624,8 +624,13 @@ ble_sm_sc_public_key_rx(uint16_t conn_handle, struct os_mbuf **om,
|
||||
proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_PUBLIC_KEY, -1,
|
||||
NULL);
|
||||
if (proc == NULL) {
|
||||
/**
|
||||
* Unexpected public key information received
|
||||
* Recommended action: Ignore
|
||||
*/
|
||||
res->app_status = BLE_HS_ENOENT;
|
||||
res->sm_err = BLE_SM_ERR_UNSPECIFIED;
|
||||
res->out_of_order = 1;
|
||||
} else {
|
||||
memcpy(&proc->pub_key_peer, cmd, sizeof(*cmd));
|
||||
rc = ble_sm_alg_gen_dhkey(proc->pub_key_peer.x,
|
||||
@@ -850,7 +855,12 @@ ble_sm_sc_dhkey_check_rx(uint16_t conn_handle, struct os_mbuf **om,
|
||||
proc = ble_sm_proc_find(conn_handle, BLE_SM_PROC_STATE_DHKEY_CHECK, -1,
|
||||
NULL);
|
||||
if (proc == NULL) {
|
||||
/**
|
||||
* Unexpected DHKey check values received
|
||||
* Recommended action: Ignore
|
||||
*/
|
||||
res->app_status = BLE_HS_ENOENT;
|
||||
res->out_of_order = 1;
|
||||
} else {
|
||||
ble_sm_dhkey_check_process(proc, cmd, res);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user