kopia lustrzana https://github.com/espressif/esp-idf
Merge branch 'bugfix/heap_allocator_fix_add_region' into 'master'
heap: Fix regression in `heap_caps_add_region` API related to address range checks See merge request espressif/esp-idf!17570pull/8755/head
commit
9fea2a19c1
|
@ -162,15 +162,9 @@ esp_err_t heap_caps_add_region(intptr_t start, intptr_t end)
|
|||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
esp_err_t heap_caps_add_region_with_caps(const uint32_t caps[], intptr_t start, intptr_t end)
|
||||
/* This API is used for internal test purpose and hence its not marked as static */
|
||||
bool heap_caps_check_add_region_allowed(intptr_t heap_start, intptr_t heap_end, intptr_t start, intptr_t end)
|
||||
{
|
||||
esp_err_t err = ESP_FAIL;
|
||||
if (caps == NULL || start == 0 || end == 0 || end <= start) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
//Check if region overlaps the start and/or end of an existing region. If so, the
|
||||
//region is invalid (or maybe added twice)
|
||||
/*
|
||||
* We assume that in any region, the "start" must be stictly less than the end.
|
||||
* Specially, the 3rd scenario can be allowed. For example, allocate memory from heap,
|
||||
|
@ -183,27 +177,39 @@ esp_err_t heap_caps_add_region_with_caps(const uint32_t caps[], intptr_t start,
|
|||
* the existing heap region s(tart) e(nd)
|
||||
* |----------------------|
|
||||
*
|
||||
* 1.add region (e1<s) |-----| correct: bool condition_1 = end < heap->start;
|
||||
* 1.add region (e1<s) |-----| correct: bool condition_1 = end < heap_start;
|
||||
*
|
||||
* 2.add region (s2<s && e2>=s) |-----------------| wrong: bool condition_2 = start < heap->start && end >= heap->start;
|
||||
* 2.add region (s2<s && e2>s) |-----------------| wrong: bool condition_2 = start < heap_start && end > heap_start;
|
||||
* |---------------------------------| wrong
|
||||
*
|
||||
* 3.add region (s3>=s && e3<e) |---------------| correct: bool condition_3 = start >= heap->start && end < heap->end;
|
||||
* 3.add region (s3>=s && e3<e) |---------------| correct: bool condition_3 = start >= heap_start && end < heap_end;
|
||||
* |--------------| correct
|
||||
*
|
||||
* 4.add region (s4<e && e4>=e) |----------------------| wrong: bool condition_4 = start < heap->end && end >= heap->end;
|
||||
* 4.add region (s4<e && e4>e) |------------------------| wrong: bool condition_4 = start < heap_end && end > heap_end;
|
||||
* |---------------------| wrong
|
||||
*
|
||||
* 5.add region (s5>=e) |----| correct: bool condition_5 = start >= heap->end;
|
||||
* 5.add region (s5>=e) |----| correct: bool condition_5 = start >= heap_end;
|
||||
*/
|
||||
|
||||
bool condition_2 = start < heap_start && end > heap_start; // if true then region not allowed
|
||||
bool condition_4 = start < heap_end && end > heap_end; // if true then region not allowed
|
||||
|
||||
return (condition_2 || condition_4) ? false: true;
|
||||
}
|
||||
|
||||
esp_err_t heap_caps_add_region_with_caps(const uint32_t caps[], intptr_t start, intptr_t end)
|
||||
{
|
||||
esp_err_t err = ESP_FAIL;
|
||||
if (caps == NULL || start == 0 || end == 0 || end <= start) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
//Check if region overlaps the start and/or end of an existing region. If so, the
|
||||
//region is invalid (or maybe added twice)
|
||||
heap_t *heap;
|
||||
SLIST_FOREACH(heap, ®istered_heaps, next) {
|
||||
bool condition_2 = start < heap->start && end >= heap->start; //if 1, wrong
|
||||
bool condition_4 = start < heap->end && end >= heap->end; //if 1, wrong
|
||||
bool wrong_region = condition_2 || condition_4;
|
||||
|
||||
if (wrong_region) {
|
||||
if (!heap_caps_check_add_region_allowed(heap->start, heap->end, start, end)) {
|
||||
ESP_EARLY_LOGD(TAG, "invalid overlap detected with existing heap region");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,20 @@ void heap_caps_enable_nonos_stack_heaps(void);
|
|||
*
|
||||
* Use heap_caps_add_region_with_caps() to register a region with custom capabilities.
|
||||
*
|
||||
* @note Please refer to following example for memory regions allowed for addition to heap based on an existing region
|
||||
* (address range for demonstration purpose only):
|
||||
@verbatim
|
||||
Existing region: 0x1000 <-> 0x3000
|
||||
New region: 0x1000 <-> 0x3000 (Allowed)
|
||||
New region: 0x1000 <-> 0x2000 (Allowed)
|
||||
New region: 0x0000 <-> 0x1000 (Allowed)
|
||||
New region: 0x3000 <-> 0x4000 (Allowed)
|
||||
New region: 0x0000 <-> 0x2000 (NOT Allowed)
|
||||
New region: 0x0000 <-> 0x4000 (NOT Allowed)
|
||||
New region: 0x1000 <-> 0x4000 (NOT Allowed)
|
||||
New region: 0x2000 <-> 0x4000 (NOT Allowed)
|
||||
@endverbatim
|
||||
*
|
||||
* @param start Start address of new region.
|
||||
* @param end End address of new region.
|
||||
*
|
||||
|
@ -63,6 +77,20 @@ esp_err_t heap_caps_add_region(intptr_t start, intptr_t end);
|
|||
*
|
||||
* Similar to heap_caps_add_region(), only custom memory capabilities are specified by the caller.
|
||||
*
|
||||
* @note Please refer to following example for memory regions allowed for addition to heap based on an existing region
|
||||
* (address range for demonstration purpose only):
|
||||
@verbatim
|
||||
Existing region: 0x1000 <-> 0x3000
|
||||
New region: 0x1000 <-> 0x3000 (Allowed)
|
||||
New region: 0x1000 <-> 0x2000 (Allowed)
|
||||
New region: 0x0000 <-> 0x1000 (Allowed)
|
||||
New region: 0x3000 <-> 0x4000 (Allowed)
|
||||
New region: 0x0000 <-> 0x2000 (NOT Allowed)
|
||||
New region: 0x0000 <-> 0x4000 (NOT Allowed)
|
||||
New region: 0x1000 <-> 0x4000 (NOT Allowed)
|
||||
New region: 0x2000 <-> 0x4000 (NOT Allowed)
|
||||
@endverbatim
|
||||
*
|
||||
* @param caps Ordered array of capability masks for the new region, in order of priority. Must have length
|
||||
* SOC_MEMORY_TYPE_NO_PRIOS. Does not need to remain valid after the call returns.
|
||||
* @param start Start address of new region.
|
||||
|
|
|
@ -71,3 +71,20 @@ TEST_CASE("Add .bss memory to heap region runtime", "[heap][ignore]")
|
|||
/* Twice add must be failed */
|
||||
TEST_ASSERT( (heap_caps_add_region((intptr_t)s_buffer, (intptr_t)s_buffer + BUF_SZ) != ESP_OK) );
|
||||
}
|
||||
|
||||
extern esp_err_t heap_caps_check_add_region_allowed(intptr_t heap_start, intptr_t heap_end, intptr_t start, intptr_t end);
|
||||
|
||||
TEST_CASE("Add heap region address range checks", "[heap]")
|
||||
{
|
||||
const intptr_t heap_start = 0x1000;
|
||||
const intptr_t heap_end = 0x3000;
|
||||
|
||||
TEST_ASSERT_TRUE(heap_caps_check_add_region_allowed(heap_start, heap_end, 0x0, 0x1000));
|
||||
TEST_ASSERT_TRUE(heap_caps_check_add_region_allowed(heap_start, heap_end, 0x1000, 0x2000));
|
||||
TEST_ASSERT_TRUE(heap_caps_check_add_region_allowed(heap_start, heap_end, 0x1000, 0x3000));
|
||||
TEST_ASSERT_TRUE(heap_caps_check_add_region_allowed(heap_start, heap_end, 0x3000, 0x4000));
|
||||
TEST_ASSERT_FALSE(heap_caps_check_add_region_allowed(heap_start, heap_end, 0x0, 0x2000));
|
||||
TEST_ASSERT_FALSE(heap_caps_check_add_region_allowed(heap_start, heap_end, 0x0, 0x4000));
|
||||
TEST_ASSERT_FALSE(heap_caps_check_add_region_allowed(heap_start, heap_end, 0x1000, 0x4000));
|
||||
TEST_ASSERT_FALSE(heap_caps_check_add_region_allowed(heap_start, heap_end, 0x2000, 0x4000));
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue