TEST(dynmem, test_both_allocs_with_hole_usage) { uint16_t size = 112; mem_stat_t info; void *p[size]; uint8_t *heap = (uint8_t*)malloc(size); CHECK(NULL != heap); reset_heap_error(); ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); CHECK(!heap_have_failed()); void *ptr = ns_dyn_mem_alloc(15); void *ptr2 = ns_dyn_mem_alloc(4); ns_dyn_mem_free(ptr); ns_dyn_mem_free(ptr2); CHECK(info.heap_sector_allocated_bytes == 0); void *ptr3 = ns_dyn_mem_temporary_alloc(15); void *ptr4 = ns_dyn_mem_temporary_alloc(5); ns_dyn_mem_free(ptr3); ns_dyn_mem_free(ptr4); CHECK(info.heap_sector_allocated_bytes == 0); free(heap); }
bool rpl_data_remember_outer(buffer_t *buf) { /* We're stripping the IP header - need the HBH header for future reference */ uint8_t *hbh; rpl_data_locate_info(buf, &hbh, NULL); if (hbh) { uint8_t instance_id = hbh[3]; /* For local instances, also need to extract the DODAG ID from src/dst */ bool local = rpl_instance_id_is_local(instance_id); /* Copy the length byte and the option data (and optionally DODAG ID) */ buf->rpl_option = ns_dyn_mem_temporary_alloc(hbh[1] + 1 + (local ? 16 : 0)); if (buf->rpl_option) { memcpy(buf->rpl_option, hbh + 1, hbh[1] + 1); if (local) { uint8_t *dodagid = instance_id & RPL_INSTANCE_DEST ? buf->dst_sa.address : buf->src_sa.address; memcpy(buf->rpl_option + hbh[1] + 1, dodagid, 16); } } } if ((buf->options.ip_extflags & IPEXT_HBH_RPL) && !buf->rpl_option) { tr_warn("RPL tunnel exit HbH fail"); return false; } return true; }
TEST(dynmem, ns_dyn_mem_temporary_alloc) { uint16_t size = 1000; mem_stat_t info; void *p[size]; uint8_t *heap = (uint8_t*)malloc(size); CHECK(NULL != heap); reset_heap_error(); ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); CHECK(!heap_have_failed()); int block = 1; int i; for (i=0; i<size; i++) { p[i] = ns_dyn_mem_temporary_alloc(block); if (!p[i]) break; } CHECK(!heap_have_failed()); CHECK(info.heap_alloc_fail_cnt == 1); CHECK(info.heap_sector_alloc_cnt == i); CHECK(info.heap_sector_allocated_bytes == info.heap_sector_allocated_bytes_max); for (; i>=0; i--) { ns_dyn_mem_free(p[i]); } CHECK(!heap_have_failed()); CHECK(info.heap_sector_alloc_cnt == 0); free(heap); }
uint8_t *sec_prot_lib_message_handle(uint8_t *ptk, uint16_t *kde_len, eapol_pdu_t *eapol_pdu) { if (eapol_pdu->msg.key.key_data_length == 0 || eapol_pdu->msg.key.key_data == NULL) { return NULL; } uint8_t *key_data = eapol_pdu->msg.key.key_data; uint16_t key_data_len = eapol_pdu->msg.key.key_data_length; uint8_t *kde = ns_dyn_mem_temporary_alloc(key_data_len); *kde_len = key_data_len; if (eapol_pdu->msg.key.key_information.encrypted_key_data) { size_t output_len = eapol_pdu->msg.key.key_data_length; if (nist_aes_key_wrap(0, &ptk[KEK_INDEX], 128, key_data, key_data_len, kde, &output_len) < 0 || output_len != (size_t) key_data_len - 8) { ns_dyn_mem_free(kde); return NULL; } *kde_len = output_len; } else { memcpy(kde, key_data, *kde_len); } return kde; }
uint8_t *sec_prot_lib_message_build(uint8_t *ptk, uint8_t *kde, uint16_t kde_len, eapol_pdu_t *eapol_pdu, uint16_t eapol_pdu_size, uint8_t header_size) { uint8_t *eapol_pdu_frame = ns_dyn_mem_temporary_alloc(header_size + eapol_pdu_size); if (!eapol_pdu_frame) { return NULL; } uint8_t *eapol_kde = eapol_write_pdu_frame(eapol_pdu_frame + header_size, eapol_pdu); if (kde) { if (eapol_pdu->msg.key.key_information.encrypted_key_data) { size_t output_len = kde_len; if (nist_aes_key_wrap(1, &ptk[KEK_INDEX], 128, kde, kde_len - 8, eapol_kde, &output_len) < 0 || output_len != kde_len) { ns_dyn_mem_free(eapol_pdu_frame); return NULL; } } else { memcpy(eapol_kde, kde, kde_len); } } if (eapol_pdu->msg.key.key_information.key_mic) { uint8_t mic[EAPOL_KEY_MIC_LEN]; if (hmac_sha1_calc(ptk, KCK_LEN, eapol_pdu_frame + header_size, eapol_pdu_size, mic) < 0) { ns_dyn_mem_free(eapol_pdu_frame); return NULL; } eapol_write_key_packet_mic(eapol_pdu_frame + header_size, mic); } return eapol_pdu_frame; }
static void *own_alloc(uint16_t size) { if (size) { return ns_dyn_mem_temporary_alloc(size); } else { return 0; } }
pana_heap_t *pana_heap_structure_allocate(void) { pana_heap_t *heap = ns_dyn_mem_temporary_alloc(sizeof(pana_heap_t)); if (heap) { heap->handshake_len = 0; heap->handshake_req_offset = 0; randLIB_get_n_bytes_random(heap->client_nonce, 16); } return heap; }
TEST(dynmem, test_free_corrupted_next_block) { uint16_t size = 1000; uint8_t *heap = (uint8_t*)malloc(size); uint8_t *p; CHECK(NULL != heap); reset_heap_error(); ns_dyn_mem_init(heap, size, &heap_fail_callback, NULL); CHECK(!heap_have_failed()); int *ptr = (int *)ns_dyn_mem_temporary_alloc(4); int *ptr2 = (int *)ns_dyn_mem_temporary_alloc(4); ns_dyn_mem_free(ptr); ptr = ptr2 + 2; *ptr = -2; ns_dyn_mem_free(ptr2); CHECK(NS_DYN_MEM_HEAP_SECTOR_CORRUPTED == current_heap_error); free(heap); }
TEST(dynmem, no_big_enough_sector) { uint16_t size = 112; mem_stat_t info; uint8_t *heap = (uint8_t*)malloc(size); uint8_t *ptr = heap; CHECK(NULL != heap); reset_heap_error(); ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); CHECK(!heap_have_failed()); int *pt = (int *)ns_dyn_mem_alloc(8); pt = (int *)ns_dyn_mem_alloc(8); ns_dyn_mem_alloc(8); ns_dyn_mem_temporary_alloc(8); ns_dyn_mem_temporary_alloc(8); ns_dyn_mem_free(pt); pt = (int *)ns_dyn_mem_temporary_alloc(32); CHECK(NULL == pt); free(heap); }
static thread_announce_request_info_t * thread_announce_discovery_request_allocate(thread_announce_discover_reques_t *scan_request, thread_announce_scan_ready_cb *response_cb) { thread_announce_request_info_t * discover_request = ns_dyn_mem_temporary_alloc(sizeof(thread_announce_request_info_t)); if (discover_request) { discover_request->waiting_response = false; discover_request->active_timer = 0; discover_request->channel_mask = scan_request->channel_mask; discover_request->pan_id = scan_request->pan_id; discover_request->active_time_stamp = scan_request->active_timestamp; discover_request->response_cb = response_cb; discover_request->network = NULL; } return discover_request; }
int entropy_poll( void *ctx, unsigned char *output, size_t len, size_t *olen ) { (void)ctx; //TODO: change to more secure random randLIB_seed_random(); char *c = (char*)ns_dyn_mem_temporary_alloc(len); if( !c ){ return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; } memset(c, 0, len); for(uint16_t i=0; i < len; i++){ *(c + i) = (char)randLIB_get_8bit(); } memmove(output, c, len); *olen = len; ns_dyn_mem_free(c); return( 0 ); }
static thread_discovery_request_info_t * thread_discovery_request_allocate(thread_discover_reques_t *scan_request, thread_discovery_ready_cb *response_cb) { thread_discovery_request_info_t * discover_request = ns_dyn_mem_temporary_alloc(sizeof(thread_discovery_request_info_t) + scan_request->filter_tlv_length); if (discover_request) { discover_request->waiting_response = false; discover_request->active_timer = 0; discover_request->channel_mask = scan_request->channel_mask; discover_request->joiner_flag = scan_request->joiner_flag; discover_request->native_commisioner_scan = scan_request->native_commisioner; discover_request->filter_tlv_length = scan_request->filter_tlv_length; discover_request->random_panid = randLIB_get_random_in_range(1, 0xfffd); //Generate random pan-id randLIB_get_n_bytes_random(discover_request->temporary_mac64, 8); //Generate random temporary mac64 discover_request->response_cb = response_cb; if (discover_request->filter_tlv_length) { memcpy(discover_optional_start_pointer(discover_request), scan_request->filter_tlv_data, discover_request->filter_tlv_length); } } return discover_request; }
TEST(dynmem, diff_sizes) { uint16_t size = 1000; mem_stat_t info; void *p; uint8_t *heap = (uint8_t*)malloc(size); CHECK(NULL != heap); reset_heap_error(); ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); CHECK(!heap_have_failed()); int i; for (i=1; i<(size-72); i++) { p = ns_dyn_mem_temporary_alloc(i); CHECK(p); ns_dyn_mem_free(p); CHECK(!heap_have_failed()); } CHECK(!heap_have_failed()); CHECK(info.heap_sector_alloc_cnt == 0); free(heap); }
TEST(dynmem, middle_free) { uint16_t size = 1000; mem_stat_t info; uint8_t *heap = (uint8_t*)malloc(size); void *p[3]; CHECK(NULL != heap); reset_heap_error(); ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); CHECK(!heap_have_failed()); for (int i=0; i<3; i++) { p[i] = ns_dyn_mem_temporary_alloc(100); CHECK(p); } ns_dyn_mem_free(p[1]); CHECK(!heap_have_failed()); ns_dyn_mem_free(p[0]); CHECK(!heap_have_failed()); ns_dyn_mem_free(p[2]); CHECK(!heap_have_failed()); free(heap); }
TEST(dynmem, ns_dyn_mem_temporary_alloc_with_heap_threshold) { uint16_t size = 1000; mem_stat_t info; void *p1, *p2; int ret_val; uint8_t *heap = (uint8_t*)malloc(size); CHECK(NULL != heap); reset_heap_error(); ns_dyn_mem_init(heap, size, &heap_fail_callback, &info); CHECK(!heap_have_failed()); // test1: temporary alloc will fail if there is less than 5% heap free p1 = ns_dyn_mem_temporary_alloc((size-72)*0.96); CHECK(!heap_have_failed()); CHECK(p1); p2 = ns_dyn_mem_temporary_alloc((size-72)*0.02); CHECK(p2 == NULL); CHECK(!heap_have_failed()); CHECK(info.heap_alloc_fail_cnt == 1); // Test2, disable threshold feature and try p2 allocation again ns_dyn_mem_set_temporary_alloc_free_heap_threshold(0, 0); p2 = ns_dyn_mem_temporary_alloc((size-72)*0.02); CHECK(!heap_have_failed()); CHECK(p2); ns_dyn_mem_free(p1); ns_dyn_mem_free(p2); CHECK(info.heap_alloc_fail_cnt == 1); CHECK(info.heap_sector_alloc_cnt == 0); // Test3, enable feature by free heap percentage ns_dyn_mem_set_temporary_alloc_free_heap_threshold(40, 0); p1 = ns_dyn_mem_temporary_alloc((size-72)*0.65); CHECK(p1); p2 = ns_dyn_mem_temporary_alloc((size-72)*0.10); CHECK(p2==NULL); ns_dyn_mem_free(p1); CHECK(!heap_have_failed()); CHECK(info.heap_alloc_fail_cnt == 2); CHECK(info.heap_sector_alloc_cnt == 0); // Test4, enable feature by free heap amount ns_dyn_mem_set_temporary_alloc_free_heap_threshold(0, 200); p1 = ns_dyn_mem_temporary_alloc(size-72-100 /*828 bytes */); CHECK(p1); p2 = ns_dyn_mem_temporary_alloc(1); CHECK(p2==NULL); ns_dyn_mem_free(p1); // Test5, illegal API parameters ret_val = ns_dyn_mem_set_temporary_alloc_free_heap_threshold(0, size/2); CHECK(ret_val==-2); ret_val = ns_dyn_mem_set_temporary_alloc_free_heap_threshold(0, size*2); CHECK(ret_val==-2); ret_val = ns_dyn_mem_set_temporary_alloc_free_heap_threshold(51, 0); CHECK(ret_val==-2); ret_val = ns_dyn_mem_set_temporary_alloc_free_heap_threshold(255, 0); CHECK(ret_val==-2); CHECK(!heap_have_failed()); CHECK(info.heap_alloc_fail_cnt == 3); CHECK(info.heap_sector_alloc_cnt == 0); free(heap); // Test6, feature is disabled if info is not set heap = (uint8_t*)malloc(size); CHECK(NULL != heap); ns_dyn_mem_init(heap, size, &heap_fail_callback, NULL); ret_val = ns_dyn_mem_set_temporary_alloc_free_heap_threshold(0, 0); CHECK(ret_val==-1); CHECK(!heap_have_failed()); free(heap); }