From a82cf0b00c7450b66c6bd3671f9604a222374ef5 Mon Sep 17 00:00:00 2001 From: Guillaume Souchere Date: Tue, 31 Jan 2023 09:41:56 +0100 Subject: [PATCH] heap: Fix erroneous value returned by heap_caps_get_allocated_size() when poisoning is enabled When light (or comprehensive) poisoning is enabled, the size requested by the user for allocation is extended by a few bytes to store the canary header and footer. heap_caps_get_allocated_size() should return the original size asked by the user (without the additional canary bytes). test_malloc.c extended with a new test assuring that heap_caps_get_allocated_size() returns the proper size regardless of the degree of poisoning. --- components/heap/multi_heap_poisoning.c | 1 + components/heap/test/test_malloc.c | 28 +++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/components/heap/multi_heap_poisoning.c b/components/heap/multi_heap_poisoning.c index ca27f3f290..3dacb85ac3 100644 --- a/components/heap/multi_heap_poisoning.c +++ b/components/heap/multi_heap_poisoning.c @@ -356,6 +356,7 @@ size_t multi_heap_get_allocated_size(multi_heap_handle_t heap, void *p) poison_head_t *head = verify_allocated_region(p, true); assert(head != NULL); size_t result = multi_heap_get_allocated_size_impl(heap, head); + subtract_poison_overhead(&result); return result; } diff --git a/components/heap/test/test_malloc.c b/components/heap/test/test_malloc.c index 6f4bbd8728..f5fcc42058 100644 --- a/components/heap/test/test_malloc.c +++ b/components/heap/test/test_malloc.c @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ /* Generic test for malloc/free */ @@ -18,7 +23,6 @@ static int **allocatedMem; static int noAllocated; - static int tryAllocMem(void) { int i, j; const int allocateMaxK=1024*5; //try to allocate a max of 5MiB @@ -132,3 +136,25 @@ TEST_CASE("malloc(0) should return a NULL pointer", "[heap]") p = malloc(0); TEST_ASSERT(p == NULL); } + +TEST_CASE("test get allocated size", "[heap]") +{ + // random values to test, some are 4 bytes aligned, some are not + const size_t alloc_sizes[] = { 1035, 1064, 1541 }; + const size_t iterations = sizeof(alloc_sizes) / sizeof(size_t); + void *ptr_array[iterations]; + + for (size_t i = 0; i < iterations; i++) { + ptr_array[i] = heap_caps_malloc(alloc_sizes[i], MALLOC_CAP_DEFAULT); + TEST_ASSERT_NOT_NULL(ptr_array[i]); + + // test that the heap_caps_get_allocated_size() returns the right number of bytes (aligned to 4 bytes + // since the heap component aligns to 4 bytes) + const size_t aligned_size = (alloc_sizes[i] + 3) & ~3; + const size_t real_size = heap_caps_get_allocated_size(ptr_array[i]); + printf("initial size: %d, requested size : %d, allocated size: %d\n", alloc_sizes[i], aligned_size, real_size); + TEST_ASSERT_EQUAL(aligned_size, real_size); + + heap_caps_free(ptr_array[i]); + } +}