From a9dea12eb8d60bc531c69887edaef535635b920d Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Thu, 6 May 2021 09:23:22 +0200 Subject: [PATCH] cpu/esp_common: add overflow detection to calloc If esp_idf_heap is not used, implement calloc through a custom wrapper function on top of malloc to add overflow detection, which is not present in the newlib forks with xtensa support yet. --- cpu/esp32/vendor/esp-idf/heap/heap_trace.c | 9 ++++++--- cpu/esp_common/Makefile.include | 6 ++++++ cpu/esp_common/syscalls.c | 19 +++++++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/cpu/esp32/vendor/esp-idf/heap/heap_trace.c b/cpu/esp32/vendor/esp-idf/heap/heap_trace.c index de703f5f4c..577a09da3a 100644 --- a/cpu/esp32/vendor/esp-idf/heap/heap_trace.c +++ b/cpu/esp32/vendor/esp-idf/heap/heap_trace.c @@ -407,10 +407,13 @@ IRAM_ATTR void *__wrap_realloc(void *p, size_t size) IRAM_ATTR void *__wrap_calloc(size_t nmemb, size_t size) { - size = size * nmemb; - void *result = trace_malloc(size, 0, TRACE_MALLOC_DEFAULT); + size_t total_size; + if (__builtin_mul_overflow(nmemb, size, &total_size)) { + return NULL; + } + void *result = trace_malloc(total_size, 0, TRACE_MALLOC_DEFAULT); if (result != NULL) { - memset(result, 0, size); + memset(result, 0, total_size); } return result; } diff --git a/cpu/esp_common/Makefile.include b/cpu/esp_common/Makefile.include index 63109cc4ec..684afff317 100644 --- a/cpu/esp_common/Makefile.include +++ b/cpu/esp_common/Makefile.include @@ -85,6 +85,12 @@ LINKFLAGS += -L$(ESP_SDK_DIR)/components/$(CPU) LINKFLAGS += -L$(ESP_SDK_DIR)/components/$(CPU)/lib LINKFLAGS += -nostdlib -Wl,-gc-sections -Wl,-static +ifeq (,$(filter esp_idf_heap,$(USEMODULE))) + # use the wrapper functions for calloc to add correct overflow detection missing + # in the newlib's version. + LINKFLAGS += -Wl,-wrap=calloc +endif + # LINKFLAGS += -Wl,--verbose # LINKFLAGS += -Wl,--print-gc-sections diff --git a/cpu/esp_common/syscalls.c b/cpu/esp_common/syscalls.c index 9bc337dc61..b1c5f9fe76 100644 --- a/cpu/esp_common/syscalls.c +++ b/cpu/esp_common/syscalls.c @@ -289,6 +289,25 @@ void* IRAM_ATTR __wrap__calloc_r(struct _reent *r, size_t count, size_t size) #else /* MODULE_ESP_IDF_HEAP */ +void *__wrap_calloc(size_t nmemb, size_t size) +{ + /* The xtensa support has not yet upstreamed to newlib. Hence, the fixed + * calloc implementation of newlib >= 4.0.0 is not available to the ESP + * platform. We fix this by implementing calloc on top of malloc ourselves */ + size_t total_size; + if (__builtin_mul_overflow(nmemb, size, &total_size)) { + return NULL; + } + + void *res = malloc(total_size); + + if (res) { + memset(res, 0, total_size); + } + + return res; +} + /* for compatibility with ESP-IDF heap functions */ void* _heap_caps_malloc(size_t size, uint32_t caps, const char *file, size_t line)