1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

sys/malloc_thread_safety: fix overflow in calloc

some standard c libraries (e.g. newlib before 4.0.0) don't perform
proper overflow check in the multiplication. We just implement calloc
here ourselves on top of malloc with proper overflow check in place.
This might even safe a handful of ROM bytes.
This commit is contained in:
Marian Buschsieweke 2021-05-05 21:50:12 +02:00
parent 6c48fcd416
commit eefed0e0cd
No known key found for this signature in database
GPG Key ID: 61F64C6599B1539F

View File

@ -14,13 +14,14 @@
* @author Gunar Schorcht <gunar@schorcht.net>
*/
#include <string.h>
#include "assert.h"
#include "irq.h"
#include "mutex.h"
extern void *__real_malloc(size_t size);
extern void __real_free(void *ptr);
extern void *__real_calloc(size_t nmemb, size_t size);
extern void *__real_realloc(void *ptr, size_t size);
static mutex_t _lock;
@ -44,11 +45,20 @@ void __wrap_free(void *ptr)
void *__wrap_calloc(size_t nmemb, size_t size)
{
assert(!irq_is_in());
mutex_lock(&_lock);
void *ptr = __real_calloc(nmemb, size);
mutex_unlock(&_lock);
return ptr;
/* some c libs don't perform proper overflow check (e.g. newlib < 4.0.0). Hence, we
* just implement calloc on top of malloc ourselves. In addition to ensuring proper
* overflow checks, this likely saves a bit of ROM */
size_t total_size;
if (__builtin_mul_overflow(nmemb, size, &total_size)) {
return NULL;
}
void *res = __wrap_malloc(total_size);
if (res) {
memset(res, 0, total_size);
}
return res;
}
void *__wrap_realloc(void *ptr, size_t size)