Skip to content

Commit 553fbb1

Browse files
author
Mika Leppänen
committed
Corrected memory error on security protocol finish
Security protocols accessed freed data, when incoming data arrived to FINISH state. This is now corrected so that incoming data frames are ignored on FINISH state.
1 parent f47ad87 commit 553fbb1

File tree

4 files changed

+77
-42
lines changed

4 files changed

+77
-42
lines changed

source/Security/kmp/kmp_api.c

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,17 @@
3737
#define TRACE_GROUP "kmap"
3838

3939
struct kmp_api_s {
40-
void *app_data_ptr; /**< Opaque pointer for application data */
41-
kmp_api_create_confirm *create_conf; /**< KMP-CREATE.confirm callback */
42-
kmp_api_create_indication *create_ind; /**< KMP-CREATE.indication callback */
43-
kmp_api_finished_indication *finished_ind; /**< KMP-FINISHED.indication callback */
44-
kmp_api_finished *finished; /**< Finished i.e. ready to be deleted callback */
45-
kmp_type_e type; /**< KMP type */
46-
kmp_addr_t *addr; /**< Supplicant EUI-64, Relay IP address, Relay port */
47-
kmp_service_t *service; /**< KMP service */
48-
bool timer_start_pending; /**< Timer is pending to start */
49-
sec_prot_t sec_prot; /**< Security protocol interface */
40+
void *app_data_ptr; /**< Opaque pointer for application data */
41+
kmp_api_create_confirm *create_conf; /**< KMP-CREATE.confirm callback */
42+
kmp_api_create_indication *create_ind; /**< KMP-CREATE.indication callback */
43+
kmp_api_finished_indication *finished_ind; /**< KMP-FINISHED.indication callback */
44+
kmp_api_finished *finished; /**< Finished i.e. ready to be deleted callback */
45+
kmp_type_e type; /**< KMP type */
46+
kmp_addr_t *addr; /**< Supplicant EUI-64, Relay IP address, Relay port */
47+
kmp_service_t *service; /**< KMP service */
48+
bool timer_start_pending :1; /**< Timer is pending to start */
49+
bool receive_disable :1; /**< Receiving disabled, do not route messages anymore */
50+
sec_prot_t sec_prot; /**< Security protocol interface */
5051
};
5152

5253
typedef struct {
@@ -88,6 +89,7 @@ static void kmp_sec_prot_timer_stop(sec_prot_t *prot);
8889
static void kmp_sec_prot_state_machine_call(sec_prot_t *prot);
8990
static void kmp_sec_prot_eui64_addr_get(sec_prot_t *prot, uint8_t *local_eui64, uint8_t *remote_eui64);
9091
static sec_prot_t *kmp_sec_prot_by_type_get(sec_prot_t *prot, uint8_t type);
92+
static void kmp_sec_prot_receive_disable(sec_prot_t *prot);
9193

9294
#define kmp_api_get_from_prot(prot) (kmp_api_t *)(((uint8_t *)prot) - offsetof(kmp_api_t, sec_prot));
9395

@@ -126,6 +128,7 @@ kmp_api_t *kmp_api_create(kmp_service_t *service, kmp_type_e type)
126128
kmp->addr = 0;
127129
kmp->service = service;
128130
kmp->timer_start_pending = false;
131+
kmp->receive_disable = false;
129132

130133
memset(&kmp->sec_prot, 0, sec_size);
131134

@@ -140,6 +143,7 @@ kmp_api_t *kmp_api_create(kmp_service_t *service, kmp_type_e type)
140143
kmp->sec_prot.state_machine_call = kmp_sec_prot_state_machine_call;
141144
kmp->sec_prot.addr_get = kmp_sec_prot_eui64_addr_get;
142145
kmp->sec_prot.type_get = kmp_sec_prot_by_type_get;
146+
kmp->sec_prot.receive_disable = kmp_sec_prot_receive_disable;
143147

144148
if (sec_prot->init(&kmp->sec_prot) < 0) {
145149
ns_dyn_mem_free(kmp);
@@ -279,6 +283,12 @@ static sec_prot_t *kmp_sec_prot_by_type_get(sec_prot_t *prot, uint8_t type)
279283
return &kmp_by_type->sec_prot;
280284
}
281285

286+
static void kmp_sec_prot_receive_disable(sec_prot_t *prot)
287+
{
288+
kmp_api_t *kmp = kmp_api_get_from_prot(prot);
289+
kmp->receive_disable = true;
290+
}
291+
282292
void kmp_api_delete(kmp_api_t *kmp)
283293
{
284294
if (kmp->sec_prot.delete) {
@@ -426,6 +436,11 @@ int8_t kmp_service_msg_if_receive(kmp_service_t *service, kmp_type_e type, const
426436
return -1;
427437
}
428438

439+
// Security protocol has disables message receiving
440+
if (kmp->receive_disable) {
441+
return -1;
442+
}
443+
429444
int8_t ret = kmp->sec_prot.receive(&kmp->sec_prot, pdu, size);
430445
return ret;
431446
}

source/Security/protocols/fwh_sec_prot/supp_fwh_sec_prot.c

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ typedef enum {
4747
FWH_STATE_CREATE_IND = SEC_STATE_CREATE_IND,
4848
FWH_STATE_MESSAGE_1 = SEC_STATE_FIRST,
4949
FWH_STATE_MESSAGE_3,
50+
FWH_STATE_MESSAGE_3_RETRY_WAIT,
5051
FWH_STATE_CREATE_RESP_SUPP_RETRY,
5152
FWH_STATE_FINISH = SEC_STATE_FINISH,
5253
FWH_STATE_FINISHED = SEC_STATE_FINISHED
@@ -76,15 +77,9 @@ typedef struct {
7677
void *recv_pdu; /**< received pdu */
7778
uint16_t recv_size; /**< received pdu size */
7879
uint64_t recv_replay_cnt; /**< received replay counter */
80+
bool msg3_retry_wait :1; /**< Waiting for Message 3 retry */
7981
} fwh_sec_prot_int_t;
8082

81-
static const trickle_params_t fwh_trickle_params = {
82-
.Imin = 50, /* 5000ms; ticks are 100ms */
83-
.Imax = 150, /* 15000ms */
84-
.k = 0, /* infinity - no consistency checking */
85-
.TimerExpirations = 4
86-
};
87-
8883
static uint16_t supp_fwh_sec_prot_size(void);
8984
static int8_t supp_fwh_sec_prot_init(sec_prot_t *prot);
9085

@@ -141,6 +136,7 @@ static int8_t supp_fwh_sec_prot_init(sec_prot_t *prot)
141136
sec_prot_state_set(prot, &data->common, FWH_STATE_INIT);
142137

143138
data->common.ticks = 30 * 10; // 30 seconds
139+
data->msg3_retry_wait = false;
144140

145141
uint8_t eui64[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
146142
sec_prot_lib_nonce_init(data->snonce, eui64, 1000);
@@ -173,7 +169,7 @@ static int8_t supp_fwh_sec_prot_receive(sec_prot_t *prot, void *pdu, uint16_t si
173169
// Get message
174170
data->recv_msg = supp_fwh_sec_prot_message_get(&data->recv_eapol_pdu, prot->sec_keys);
175171
if (data->recv_msg != FWH_MESSAGE_UNKNOWN) {
176-
tr_info("4WH: recv %s", data->recv_msg == FWH_MESSAGE_1 ? "Message 1" : "Message 2");
172+
tr_info("4WH: recv %s", data->recv_msg == FWH_MESSAGE_1 ? "Message 1" : "Message 3");
177173

178174
// Call state machine
179175
data->recv_pdu = pdu;
@@ -278,7 +274,7 @@ static int8_t supp_fwh_sec_prot_message_send(sec_prot_t *prot, fwh_sec_prot_msg_
278274
static void supp_fwh_sec_prot_timer_timeout(sec_prot_t *prot, uint16_t ticks)
279275
{
280276
fwh_sec_prot_int_t *data = fwh_sec_prot_get(prot);
281-
sec_prot_timer_timeout_handle(prot, &data->common, &fwh_trickle_params, ticks);
277+
sec_prot_timer_timeout_handle(prot, &data->common, NULL, ticks);
282278
}
283279

284280
static void supp_fwh_sec_prot_state_machine(sec_prot_t *prot)
@@ -379,19 +375,28 @@ static void supp_fwh_sec_prot_state_machine(sec_prot_t *prot)
379375
break;
380376

381377
case FWH_STATE_FINISH:
382-
tr_info("4WH: finish");
378+
if (data->msg3_retry_wait) {
379+
tr_info("4WH: Message 3 retry timeout");
380+
sec_prot_state_set(prot, &data->common, FWH_STATE_FINISHED);
381+
return;
382+
}
383+
data->msg3_retry_wait = true;
384+
385+
tr_info("4WH: finish, wait Message 3 retry");
383386

384387
// KMP-FINISHED.indication
385388
sec_prot_keys_ptk_write(prot->sec_keys, data->new_ptk);
386389
sec_prot_keys_ptk_eui_64_write(prot->sec_keys, data->remote_eui64);
387390
prot->finished_ind(prot, sec_prot_result_get(&data->common), prot->sec_keys);
388-
sec_prot_state_set(prot, &data->common, FWH_STATE_FINISHED);
391+
392+
data->common.ticks = 60 * 10; // 60 seconds
393+
sec_prot_state_set(prot, &data->common, FWH_STATE_MESSAGE_3_RETRY_WAIT);
389394
break;
390395

391-
case FWH_STATE_FINISHED:
396+
case FWH_STATE_MESSAGE_3_RETRY_WAIT:
392397
if (sec_prot_result_timeout_check(&data->common)) {
393-
prot->timer_stop(prot);
394-
prot->finished(prot);
398+
tr_info("4WH: Message 3 retry timeout");
399+
sec_prot_state_set(prot, &data->common, FWH_STATE_FINISHED);
395400
} else {
396401
if (data->recv_msg != FWH_MESSAGE_3) {
397402
return;
@@ -415,25 +420,15 @@ static void supp_fwh_sec_prot_state_machine(sec_prot_t *prot)
415420
supp_fwh_sec_prot_recv_replay_counter_store(prot);
416421
supp_fwh_sec_prot_security_replay_counter_update(prot);
417422

418-
tr_info("4WH: start again");
423+
tr_info("4WH: send Message 4 again");
419424

420-
// Send KMP-CREATE.indication
421-
prot->create_ind(prot);
422-
sec_prot_state_set(prot, &data->common, FWH_STATE_CREATE_RESP_SUPP_RETRY);
425+
supp_fwh_sec_prot_message_send(prot, FWH_MESSAGE_4);
423426
}
424427
break;
425428

426-
// Special case for second receiving of 4WH message 3
427-
case FWH_STATE_CREATE_RESP_SUPP_RETRY:
428-
if (sec_prot_result_ok_check(&data->common)) {
429-
// Send 4WH message 4
430-
supp_fwh_sec_prot_message_send(prot, FWH_MESSAGE_4);
431-
data->common.ticks = 30 * 10; // 30 seconds
432-
sec_prot_state_set(prot, &data->common, FWH_STATE_FINISH);
433-
} else {
434-
// Ready to be deleted
435-
sec_prot_state_set(prot, &data->common, FWH_STATE_FINISHED);
436-
}
429+
case FWH_STATE_FINISHED:
430+
prot->timer_stop(prot);
431+
prot->finished(prot);
437432
break;
438433

439434
default:

source/Security/protocols/sec_prot.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,16 @@ typedef void sec_prot_eui64_addr_get(sec_prot_t *prot, uint8_t *local_eui64, uin
207207
*/
208208
typedef sec_prot_t *sec_prot_by_type_get(sec_prot_t *prot, uint8_t type);
209209

210+
/**
211+
* sec_prot_receive_disable disables receiving of messages
212+
*
213+
* \param prot protocol
214+
*
215+
* \return security protocol or NULL
216+
*
217+
*/
218+
typedef void sec_prot_receive_disable(sec_prot_t *prot);
219+
210220
// Security protocol data
211221
struct sec_prot_s {
212222
sec_prot_create_request *create_req; /**< Create request */
@@ -232,6 +242,7 @@ struct sec_prot_s {
232242

233243
sec_prot_eui64_addr_get *addr_get; /**< Gets EUI-64 addresses */
234244
sec_prot_by_type_get *type_get; /**< Gets security protocol by type */
245+
sec_prot_receive_disable *receive_disable; /**< Disable receiving of messages */
235246

236247
sec_prot_keys_t *sec_keys; /**< Security keys storage pointer */
237248
uint8_t header_size; /**< Header size */

source/Security/protocols/sec_prot_lib.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ void sec_prot_init(sec_prot_common_t *data)
5454

5555
void sec_prot_timer_timeout_handle(sec_prot_t *prot, sec_prot_common_t *data, const trickle_params_t *trickle_params, uint16_t ticks)
5656
{
57-
if (data->trickle_running) {
57+
if (data->trickle_running && trickle_params) {
5858
bool running = trickle_running(&data->trickle_timer, trickle_params);
5959

6060
// Checks for trickle timer expiration */
@@ -112,6 +112,10 @@ void sec_prot_state_set(sec_prot_t *prot, sec_prot_common_t *data, uint8_t state
112112
// Wait for timeout
113113
data->trickle_running = false;
114114
data->ticks = SEC_FINISHED_TIMEOUT;
115+
116+
// Disables receiving of messages when state machine sets SEC_STATE_FINISHED
117+
prot->receive_disable(prot);
118+
115119
// Clear result
116120
sec_prot_result_set(data, SEC_RESULT_OK);
117121
break;
@@ -290,6 +294,7 @@ int8_t sec_prot_lib_pmkid_calc(const uint8_t *pmk, const uint8_t *auth_eui64, co
290294
return -1;
291295
}
292296

297+
tr_info("PMKID %s EUI-64 %s %s", trace_array(pmkid, PMKID_LEN), trace_array(auth_eui64, 8), trace_array(supp_eui64, 8));
293298
return 0;
294299
}
295300

@@ -311,6 +316,7 @@ int8_t sec_prot_lib_ptkid_calc(const uint8_t *ptk, const uint8_t *auth_eui64, co
311316
return -1;
312317
}
313318

319+
tr_info("PTKID %s EUI-64 %s %s", trace_array(ptkid, PTKID_LEN), trace_array(auth_eui64, 8), trace_array(supp_eui64, 8));
314320
return 0;
315321
}
316322

@@ -471,11 +477,15 @@ int8_t sec_prot_lib_pmkid_generate(sec_prot_t *prot, uint8_t *pmkid, bool is_aut
471477
prot->addr_get(prot, local_eui64, remote_eui64);
472478
}
473479

480+
int8_t ret;
481+
474482
if (is_auth) {
475-
return sec_prot_lib_pmkid_calc(pmk, local_eui64, remote_eui64, pmkid);
483+
ret = sec_prot_lib_pmkid_calc(pmk, local_eui64, remote_eui64, pmkid);
476484
} else {
477-
return sec_prot_lib_pmkid_calc(pmk, remote_eui64, local_eui64, pmkid);
485+
ret = sec_prot_lib_pmkid_calc(pmk, remote_eui64, local_eui64, pmkid);
478486
}
487+
488+
return ret;
479489
}
480490

481491
int8_t sec_prot_lib_ptkid_generate(sec_prot_t *prot, uint8_t *ptkid, bool is_auth)
@@ -492,11 +502,15 @@ int8_t sec_prot_lib_ptkid_generate(sec_prot_t *prot, uint8_t *ptkid, bool is_aut
492502
return -1;
493503
}
494504

505+
int8_t ret;
506+
495507
if (is_auth) {
496508
return sec_prot_lib_ptkid_calc(ptk, local_eui64, remote_eui64, ptkid);
497509
} else {
498510
return sec_prot_lib_ptkid_calc(ptk, remote_eui64, local_eui64, ptkid);
499511
}
512+
513+
return ret;
500514
}
501515

502516
int8_t sec_prot_lib_gtkhash_generate(uint8_t *gtk, uint8_t *gtk_hash)

0 commit comments

Comments
 (0)