Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: memalign: respect malloc_alwaysinternal_limit (IDFGH-11209) #12375

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 74 additions & 24 deletions components/heap/heap_caps.c
Original file line number Diff line number Diff line change
Expand Up @@ -655,31 +655,10 @@ size_t heap_caps_get_allocated_size( void *ptr )
return size;
}

HEAP_IRAM_ATTR void *heap_caps_aligned_alloc(size_t alignment, size_t size, uint32_t caps)
static HEAP_IRAM_ATTR void *heap_caps_aligned_alloc_base(size_t alignment, size_t size, uint32_t caps)
{
void *ret = NULL;

if(!alignment) {
return NULL;
}

//Alignment must be a power of two:
if((alignment & (alignment - 1)) != 0) {
return NULL;
}

if (size == 0) {
return NULL;
}

if (size > HEAP_SIZE_MAX) {
// Avoids int overflow when adding small numbers to size, or
// calculating 'end' from start+size, by limiting 'size' to the possible range
heap_caps_alloc_failed(size, caps, __func__);

return NULL;
}

for (int prio = 0; prio < SOC_MEMORY_TYPE_NO_PRIOS; prio++) {
//Iterate over heaps and check capabilities at this priority
heap_t *heap;
Expand All @@ -702,12 +681,83 @@ HEAP_IRAM_ATTR void *heap_caps_aligned_alloc(size_t alignment, size_t size, uint
}
}

heap_caps_alloc_failed(size, caps, __func__);

//Nothing usable found.
return NULL;
}

static HEAP_IRAM_ATTR int heap_caps_aligned_check_args(size_t alignment, size_t size, const char *funcname) {
if (!alignment) {
return -1;
}

// Alignment must be a power of two:
if ((alignment & (alignment - 1)) != 0) {
return -1;
}

if (size == 0) {
return -1;
}

if (size > HEAP_SIZE_MAX) {
// Avoids int overflow when adding small numbers to size, or
// calculating 'end' from start+size, by limiting 'size' to the possible range
heap_caps_alloc_failed(size, MALLOC_CAP_DEFAULT, funcname);

return -1;
}

return 0;
}

HEAP_IRAM_ATTR void *heap_caps_aligned_alloc_default(size_t alignment, size_t size)
{
void *ret = NULL;

if (malloc_alwaysinternal_limit == MALLOC_DISABLE_EXTERNAL_ALLOCS) {
return heap_caps_aligned_alloc(alignment, size, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL);
}

if (heap_caps_aligned_check_args(alignment, size, __func__) != 0) {
return NULL;
}

if (size <= (size_t)malloc_alwaysinternal_limit) {
ret = heap_caps_aligned_alloc_base(alignment, size, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL);
} else {
ret = heap_caps_aligned_alloc_base(alignment, size, MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM);
}

if (ret != NULL) {
return ret;
}

ret = heap_caps_aligned_alloc_base(alignment, size, MALLOC_CAP_DEFAULT);

if (ret == NULL) {
heap_caps_alloc_failed(size, MALLOC_CAP_DEFAULT, __func__);
}

return ret;
}

HEAP_IRAM_ATTR void *heap_caps_aligned_alloc(size_t alignment, size_t size, uint32_t caps)
{
void *ret = NULL;

if (heap_caps_aligned_check_args(alignment, size, __func__) != 0) {
return NULL;
}

ret = heap_caps_aligned_alloc_base(alignment, size, caps);

if (ret == NULL) {
heap_caps_alloc_failed(size, caps, __func__);
}

return ret;
}

HEAP_IRAM_ATTR void heap_caps_aligned_free(void *ptr)
{
heap_caps_free(ptr);
Expand Down
1 change: 1 addition & 0 deletions components/heap/heap_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ inline static uint32_t get_all_caps(const heap_t *heap)
*/
void *heap_caps_realloc_default(void *p, size_t size);
void *heap_caps_malloc_default(size_t size);
void *heap_caps_aligned_alloc_default(size_t alignment, size_t size);


#ifdef __cplusplus
Expand Down
7 changes: 4 additions & 3 deletions components/newlib/heap.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -18,6 +18,7 @@
*/
extern void *heap_caps_malloc_default( size_t size );
extern void *heap_caps_realloc_default( void *ptr, size_t size );
extern void *heap_caps_aligned_alloc_default( size_t alignment, size_t size );

void* malloc(size_t size)
{
Expand Down Expand Up @@ -71,7 +72,7 @@ void* _calloc_r(struct _reent *r, size_t nmemb, size_t size)

void* memalign(size_t alignment, size_t n)
{
return heap_caps_aligned_alloc(alignment, n, MALLOC_CAP_DEFAULT);
return heap_caps_aligned_alloc_default(alignment, n);
}

int posix_memalign(void **out_ptr, size_t alignment, size_t size)
Expand All @@ -81,7 +82,7 @@ int posix_memalign(void **out_ptr, size_t alignment, size_t size)
*out_ptr = NULL;
return 0;
}
void *result = heap_caps_aligned_alloc(alignment, size, MALLOC_CAP_DEFAULT);
void *result = heap_caps_aligned_alloc_default(alignment, size);
if (result != NULL) {
/* Modify output pointer only on success */
*out_ptr = result;
Expand Down
6 changes: 0 additions & 6 deletions tools/ci/check_public_headers_exceptions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ components/esp_rom/include/esp32s2/rom/rsa_pss.h

# LWIP: sockets.h uses #include_next<>, which doesn't work correctly with the checker
# memp_std.h is supposed to be included multiple times with different settings
components/lwip/lwip/src/include/lwip/priv/memp_std.h
components/lwip/include/lwip/sockets.h
components/lwip/lwip/src/include/lwip/prot/nd6.h

## Header produced non-zero object:
components/esp_phy/esp32/include/phy_init_data.h
Expand Down Expand Up @@ -68,13 +66,9 @@ components/json/cJSON/

components/spiffs/include/spiffs_config.h

components/unity/unity/src/unity_internals.h
components/unity/unity/extras/
components/unity/include/unity_config.h
components/unity/include/unity_test_runner.h

components/cmock/CMock/src/cmock.h
components/cmock/CMock/src/cmock_internals.h


components/openthread/openthread/
Expand Down
Loading