diff --git a/components/heap/multi_heap_poisoning.c b/components/heap/multi_heap_poisoning.c index 01e98f9b35..906c827d47 100644 --- a/components/heap/multi_heap_poisoning.c +++ b/components/heap/multi_heap_poisoning.c @@ -204,27 +204,30 @@ void *multi_heap_aligned_alloc(multi_heap_handle_t heap, size_t size, size_t ali return NULL; } - if(size > SIZE_MAX /* - POISON_OVERHEAD*/) { + if(size > SIZE_MAX - POISON_OVERHEAD) { return NULL; } - uint32_t overhead = (sizeof(uint32_t) + (alignment - 1) /*+ POISON_OVERHEAD*/); + uint32_t overhead = (sizeof(uint32_t) + (alignment - 1) + POISON_OVERHEAD); multi_heap_internal_lock(heap); poison_head_t *head = multi_heap_malloc_impl(heap, size + overhead); - //uint8_t *data = NULL; + uint8_t *data = NULL; if (head != NULL) { - //data = poison_allocated_region(head, size); + data = poison_allocated_region(head, size + (overhead - POISON_OVERHEAD)); #ifdef SLOW /* check everything we got back is FREE_FILL_PATTERN & swap for MALLOC_FILL_PATTERN */ - //bool ret = verify_fill_pattern(data, size, true, true, true); - //assert( ret ); + bool ret = verify_fill_pattern(data, size, true, true, true); + assert( ret ); +#else + (void)data; #endif } //Lets align our new obtained block address: - //and save the original heap pointer to allow deallocation - void *ptr = (void *)ALIGN_UP((uintptr_t)head + sizeof(uint32_t) /* + POISON_OVERHEAD*/, alignment); + //and save information to recover original block pointer + //to allow us to deallocate the memory when needed + void *ptr = (void *)ALIGN_UP((uintptr_t)head + sizeof(uint32_t) + sizeof(poison_head_t), alignment); *((uint32_t *)ptr - 1) = (uint32_t)((uintptr_t)ptr - (uintptr_t)head); multi_heap_internal_unlock(heap); @@ -262,14 +265,15 @@ void multi_heap_aligned_free(multi_heap_handle_t heap, void *p) multi_heap_internal_lock(heap); uint32_t offset = *((uint32_t *)p - 1); - void *block_head = (void *)((uint8_t *)p - (offset /*- POISON_OVERHEAD*/)); - - /* poison_head_t *head = verify_allocated_region(block_head, true); - assert(head != NULL); */ + void *block_head = (void *)((uint8_t *)p - offset); + block_head += sizeof(poison_head_t); + poison_head_t *head = verify_allocated_region(block_head, true); + assert(head != NULL); + block_head -= sizeof(poison_head_t); #ifdef SLOW /* replace everything with FREE_FILL_PATTERN, including the poison head/tail */ - //memset(head, FREE_FILL_PATTERN, head->alloc_size + POISON_OVERHEAD); + memset(block_head, FREE_FILL_PATTERN, head->alloc_size + POISON_OVERHEAD); #endif multi_heap_free_impl(heap, block_head); diff --git a/components/heap/test_multi_heap_host/test_multi_heap.cpp b/components/heap/test_multi_heap_host/test_multi_heap.cpp index 5bfa74ee5f..6f00868803 100644 --- a/components/heap/test_multi_heap_host/test_multi_heap.cpp +++ b/components/heap/test_multi_heap_host/test_multi_heap.cpp @@ -500,16 +500,19 @@ TEST_CASE("multi_heap aligned allocations", "[multi_heap]") uint8_t test_heap[1024 * 1024]; multi_heap_handle_t heap = multi_heap_register(test_heap, sizeof(test_heap)); uint32_t aligments = 0; // starts from alignment by 4-byte boundary + size_t old_size = multi_heap_free_size(heap); + size_t leakage = 1024; + printf("[ALIGNED_ALLOC] heap_size before: %d \n", old_size); printf("New heap:\n"); multi_heap_dump(heap); printf("*********************\n"); - for(;aligments < 4096; aligments++) { + for(;aligments < 500 * 1024; aligments++) { - //Use a non-sense size to test correct alignment even in strange + //Use some stupid size value to test correct alignment even in strange //memory layout objects: - uint8_t *buf = (uint8_t *)multi_heap_aligned_alloc(heap, (aligments + 117), aligments ); + uint8_t *buf = (uint8_t *)multi_heap_aligned_alloc(heap, (aligments + 137), aligments ); if(((aligments & (aligments - 1)) != 0) || (!aligments)) { REQUIRE( buf == NULL ); //printf("[ALIGNED_ALLOC] alignment: %u is not a power of two, don't allow allocation \n", aligments); @@ -521,9 +524,17 @@ TEST_CASE("multi_heap aligned allocations", "[multi_heap]") printf("[ALIGNED_ALLOC] alignment required: %u \n", aligments); //printf("[ALIGNED_ALLOC] allocated size: %d \n", multi_heap_get_allocated_size(heap, buf)); printf("[ALIGNED_ALLOC] address of allocated memory: %p \n\n", (void *)buf); - + //Address of obtained block must be aligned with selected value REQUIRE(((intptr_t)buf & (aligments - 1)) == 0); + + //Write some data, if it corrupts memory probably the heap + //canary verification will fail: + memset(buf, 0xA5, (aligments + 137)); + multi_heap_aligned_free(heap, buf); } } + + printf("[ALIGNED_ALLOC] heap_size after: %d \n", multi_heap_free_size(heap)); + REQUIRE((old_size - multi_heap_free_size(heap)) <= leakage); }