diff --git a/Kconfig b/Kconfig index 7a31d45..1d6cfc1 100644 --- a/Kconfig +++ b/Kconfig @@ -107,6 +107,14 @@ config STD_MALLOC_RANDOM ---help--- TODO: Christophe +config STD_MALLOC_CANARIS_INTEGRITY + int "allocator canaries integrity check" + range 0 2 + depends on STD_MALLOC_STD || STD_MALLOC_BINS + default 1 + ---help--- + TODO: Christophe + endif endmenu diff --git a/alloc/malloc_ewok.c b/alloc/malloc_ewok.c index dd000e7..3233e2a 100644 --- a/alloc/malloc_ewok.c +++ b/alloc/malloc_ewok.c @@ -9,9 +9,13 @@ #include "malloc_priv.h" -//#include "../inc/memfct.h" +#if CONFIG_STD_MALLOC_MUTEX == 1 +extern void _set_wmalloc_semaphore(volatile uint32_t **ptr_semaphore); +#endif +extern void _set_wmalloc_heap(physaddr_t *start_heap, physaddr_t *end_heap, u__sz_t *heap_size); +extern volatile unsigned char allocator_initialized; /* Global variables */ @@ -21,12 +25,15 @@ static physaddr_t _end_heap; static u__sz_t _heap_size; /* Canaries (random or not) */ +#if (CONFIG_STD_MALLOC_INTEGRITY >= 1) && (CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1) static u_can_t _can_sz; static u_can_t _can_free; +extern void _set_wmalloc_canaries(u_can_t *can_sz, u_can_t *can_free); +#endif -#ifdef CONFIG_STD_MALLOC_MUTEX +#if CONFIG_STD_MALLOC_MUTEX == 1 /* Semaphore */ -static uint32_t _ptr_semaphore; +static volatile uint32_t *_ptr_semaphore; #endif @@ -65,6 +72,23 @@ static int check_free(struct block *b, uint16_t flag); static int check_consistency(struct block * b, uint16_t flag); #endif +/* + * This function should be called by malloc_init() to + * initialize local heap informations + */ +void malloc_ewok_init(physaddr_t start_heap, + physaddr_t end_heap, + u__sz_t heap_size) +{ + _start_heap = start_heap; + _end_heap = end_heap; + _heap_size = heap_size; + +#if CONFIG_STD_MALLOC_MUTEX == 1 + _set_wmalloc_semaphore(&_ptr_semaphore); +#endif +} + /*********************************************************************************************/ /* Malloc() function */ @@ -75,6 +99,11 @@ int wmalloc(void **ptr_to_alloc, const uint16_t len, const int flag) int wmalloc(void **ptr_to_alloc, const uint32_t len, const int flag) #endif { + if(allocator_initialized != 1){ + malloc_errno = EHEAPNODEF; + return -1; + } + void *ptr = NULL; u__sz_t len_bis = (u__sz_t) len; @@ -91,12 +120,17 @@ int wmalloc(void **ptr_to_alloc, const uint32_t len, const int flag) uint8_t insered_block = 0; -#if STD_FREEMEM_CHECK >= 1 +#if CONFIG_STD_FREEMEM_CHECK >= 1 u__sz_t memory_available = 0; #endif -#ifdef CONFIG_STD_MALLOC_RANDOM - int32_t random = (NB_FREE() ? (int32_t) (- ((uint8_t) ((uint32_t)rand() % NB_FREE()))) : 0); +#if CONFIG_STD_MALLOC_RANDOM == 1 + uint32_t tmp; + if(get_random((unsigned char*) &tmp, sizeof(tmp)) != MBED_ERROR_NONE){ + malloc_errno = EHEAPNODEF; + return -1; + } + int32_t random = (NB_FREE() ? (int32_t) (- ((uint8_t) (tmp % NB_FREE()))) : 0); #else int32_t random = 0; #endif @@ -104,11 +138,11 @@ int wmalloc(void **ptr_to_alloc, const uint32_t len, const int flag) /* Errno is initialized to zero */ malloc_errno = 0; -#ifdef CONFIG_STD_MALLOC_MUTEX - _set_wmalloc_semaphore((uint32_t *) _ptr_semaphore); +#if CONFIG_STD_MALLOC_MUTEX == 1 + _set_wmalloc_semaphore(&_ptr_semaphore); /* Trying to lock of wmalloc usage */ - if (!semaphore_trylock(&semaphore)) { + if (!semaphore_trylock(_ptr_semaphore)) { malloc_errno = EHEAPLOCKED; return -1; } @@ -116,7 +150,7 @@ int wmalloc(void **ptr_to_alloc, const uint32_t len, const int flag) /* Getting of heap specification values */ _set_wmalloc_heap(&_start_heap, &_end_heap, &_heap_size); -#if (CONFIG_STD_MALLOC_INTEGRITY == 1) && (CANARIS_INTEGRITY == 1) +#if (CONFIG_STD_MALLOC_INTEGRITY >= 1) && (CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1) _set_wmalloc_canaries(&_can_sz, &_can_free); #endif @@ -143,7 +177,7 @@ int wmalloc(void **ptr_to_alloc, const uint32_t len, const int flag) #elif CONFIG_STD_MALLOC_BASIC_CHECKS == 1 /* We check b_cur (and eventually b_cur_bis) are not out of range */ # if CONFIG_STD_MALLOC_DBLE_WAY_SEARCH == 1 - if ((OFFSET(b_cur) > OFFSET_MAX) || (OFFSET(_cur_bis) > OFFSET_MAX)) { + if ((OFFSET(b_cur) > OFFSET_MAX) || (OFFSET(b_cur_bis) > OFFSET_MAX)) { # elif CONFIG_STD_MALLOC_DBLE_WAY_SEARCH == 0 if ((OFFSET(b_cur) > OFFSET_MAX)) { # endif @@ -171,7 +205,7 @@ int wmalloc(void **ptr_to_alloc, const uint32_t len, const int flag) /* Block size is calculated */ sz = (u__sz_t) (len_bis + HDR_SZ); -#if STD_FREEMEM_CHECK >= 1 +#if CONFIG_STD_FREEMEM_CHECK >= 1 /* We check if there is definitively not enough memory for block */ memory_available = (u__sz_t) (SZ_FREE() - (u__sz_t)(HDR_FREE_SZ * (NB_FREE() - 1))); if (sz > memory_available) { @@ -211,7 +245,7 @@ int wmalloc(void **ptr_to_alloc, const uint32_t len, const int flag) } #endif -#if CONFIG_STD_MALLOC_INTEGRITY == 1 +#if CONFIG_STD_MALLOC_INTEGRITY >= 1 /* We check the integrity of the header (if no heap integrity checking) */ if (check_hdr(b_cur, CHECK_ALL_FREE)) { malloc_errno = EHEAPINTEGRITY; @@ -236,7 +270,7 @@ int wmalloc(void **ptr_to_alloc, const uint32_t len, const int flag) /* Current free block is updated and changed to allocated block */ b_cur->sz = sz; MAKE_ALLOC(b_cur); -#if CANARIS_INTEGRITY == 1 +#if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1 UPDATE_CANARI_SZ(b_cur); #endif @@ -259,7 +293,7 @@ int wmalloc(void **ptr_to_alloc, const uint32_t len, const int flag) * next block's "prv_sz" is completed with the current block's size */ if ((physaddr_t) b_nxt_now != _end_heap) { b_nxt_now->prv_sz = (insered_block ? SIZE(b_nxt_int) : sz); -#if CANARIS_INTEGRITY == 1 +#if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1 UPDATE_CANARI_GENE(b_nxt_now); #endif } @@ -271,7 +305,7 @@ int wmalloc(void **ptr_to_alloc, const uint32_t len, const int flag) } else { b_cur->prv_free = 0; b_cur->nxt_free = 0; -#if CANARIS_INTEGRITY == 1 +#if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1 b_cur->can_free = 0; #endif } @@ -279,7 +313,7 @@ int wmalloc(void **ptr_to_alloc, const uint32_t len, const int flag) /* Increase the field "prv_free" of b_0 (total size of allocated memory) */ DECREASE_SZ_FREE(sz); -#if CANARIS_INTEGRITY == 1 +#if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1 /* b_0 first canari are updated for taking into account the modification of * b_0->prv_sz = NB_FREE() and b_0->sz = SZ_FREE() */ UPDATE_CANARI_SZ(b_0); @@ -291,9 +325,9 @@ int wmalloc(void **ptr_to_alloc, const uint32_t len, const int flag) /**********************************************************/ *ptr_to_alloc = ptr; -#ifdef CONFIG_STD_MALLOC_MUTEX +#if CONFIG_STD_MALLOC_MUTEX == 1 /* Unlocking of wmalloc usage */ - if (!semaphore_release((uint32_t *) _ptr_semaphore)) { + if (!semaphore_release(_ptr_semaphore)) { malloc_errno = EHEAPSEMAPHORE; return -1; } @@ -304,7 +338,7 @@ int wmalloc(void **ptr_to_alloc, const uint32_t len, const int flag) /**********************************************************/ } -#if STD_FREEMEM_CHECK == 2 +#if CONFIG_STD_FREEMEM_CHECK == 2 /* We check if there is definitively not enough memory for block */ # if CONFIG_STD_MALLOC_DBLE_WAY_SEARCH == 0 memory_available -= (u__sz_t)(b_cur->sz - HDR_FREE_SZ); @@ -360,10 +394,10 @@ int wmalloc(void **ptr_to_alloc, const uint32_t len, const int flag) end_error: -#ifdef CONFIG_STD_MALLOC_MUTEX +#if CONFIG_STD_MALLOC_MUTEX == 1 /* Unlocking of wmalloc usage (malloc_errno is not modified in order to keep the value * of the initial error) */ - semaphore_release((uint32_t *) _ptr_semaphore); + semaphore_release(_ptr_semaphore); #endif return -1; @@ -380,7 +414,7 @@ static int _update_inter_free(struct block *b_cur, struct block *b_nxt_int, u__s b_nxt_int->prv_free = b_cur->prv_free; b_nxt_int->nxt_free = b_cur->nxt_free; -#if CANARIS_INTEGRITY == 1 +#if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1 UPDATE_CANARI_BOTH(b_nxt_int); #endif @@ -388,7 +422,7 @@ static int _update_inter_free(struct block *b_cur, struct block *b_nxt_int, u__s BLOCK(b_cur->prv_free)->nxt_free = OFFSET(b_nxt_int); BLOCK(b_cur->nxt_free)->prv_free = OFFSET(b_nxt_int); -#if CANARIS_INTEGRITY == 1 +#if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1 UPDATE_CANARI_FREE(PRV_FREE(b_nxt_int)); UPDATE_CANARI_FREE(NXT_FREE(b_nxt_int)); #endif @@ -404,7 +438,7 @@ static int _unlink(struct block *b_cur) BLOCK(b_cur->prv_free)->nxt_free = b_cur->nxt_free; BLOCK(b_cur->nxt_free)->prv_free = b_cur->prv_free; -#if CANARIS_INTEGRITY == 1 +#if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1 UPDATE_CANARI_FREE(PRV_FREE(b_cur)); UPDATE_CANARI_FREE(NXT_FREE(b_cur)); #endif @@ -427,6 +461,11 @@ static int _unlink(struct block *b_cur) /****************************************************************************************/ int wfree(void **ptr_to_free) { + if(allocator_initialized != 1){ + malloc_errno = EHEAPNODEF; + return -1; + } + struct block *b_0 = (struct block *) _start_heap; struct block *b_1 = b_0 + 1; @@ -439,11 +478,11 @@ int wfree(void **ptr_to_free) /* Errno is initialized to zero */ malloc_errno = 0; -#ifdef CONFIG_STD_MALLOC_MUTEX - _set_wmalloc_semaphore((uint32_t *) _ptr_semaphore); +#if CONFIG_STD_MALLOC_MUTEX == 1 + _set_wmalloc_semaphore(&_ptr_semaphore); /* Locking of wmalloc usage */ - if (!semaphore_trylock(&semaphore)) { + if (!semaphore_trylock(_ptr_semaphore)) { malloc_errno = EHEAPLOCKED; return -1; } @@ -451,7 +490,7 @@ int wfree(void **ptr_to_free) /* Getting of heap specification values */ _set_wmalloc_heap(&_start_heap, &_end_heap, &_heap_size); -#if (CONFIG_STD_MALLOC_INTEGRITY == 1) && (CANARIS_INTEGRITY == 1) +#if (CONFIG_STD_MALLOC_INTEGRITY >= 1) && (CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1) _set_wmalloc_canaries(&_can_sz, &_can_free); #endif @@ -530,7 +569,7 @@ int wfree(void **ptr_to_free) /* Last block updated (size increased) */ b_prv->sz = (u__sz_t) (SIZE(b_prv) + SIZE(b_cur)); -#if CANARIS_INTEGRITY == 1 +#if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1 UPDATE_CANARI_SZ(b_prv); #endif @@ -570,14 +609,14 @@ int wfree(void **ptr_to_free) if (!(merged & MERGED_WITH_PRV)) { b_cur->prv_free = b_nxt->prv_free; PRV_FREE(b_cur)->nxt_free = OFFSET(b_cur); -#if CANARIS_INTEGRITY == 1 +#if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1 UPDATE_CANARI_FREE(PRV_FREE(b_cur)); #endif } b_cur->nxt_free = b_nxt->nxt_free; NXT_FREE(b_cur)->prv_free = OFFSET(b_cur); -#if CANARIS_INTEGRITY == 1 +#if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1 UPDATE_CANARI_FREE(NXT_FREE(b_cur)); #endif @@ -587,14 +626,14 @@ int wfree(void **ptr_to_free) } /* Canari_1 is updated */ -#if CANARIS_INTEGRITY == 1 +#if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1 UPDATE_CANARI_BOTH(b_cur); #endif /* If the updated block is not the final one, the next block is updated (prv_sz) */ if (NOT_LAST_BLOCK(b_cur)) { ((struct block *) ((physaddr_t) b_cur + b_cur->sz))->prv_sz = b_cur->sz; -#if CANARIS_INTEGRITY == 1 +#if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1 UPDATE_CANARI_SZ((struct block *)((physaddr_t) b_cur + b_cur->sz)); #endif } @@ -623,15 +662,15 @@ int wfree(void **ptr_to_free) end: -#if CANARIS_INTEGRITY == 1 +#if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1 /* b_0 first canari are updated for taking into account the modification of * b_0->prv_sz = NB_FREE() and b_0->sz = SZ_FREE() */ UPDATE_CANARI_SZ(b_0); #endif -#ifdef CONFIG_STD_MALLOC_MUTEX +#if CONFIG_STD_MALLOC_MUTEX == 1 /* Unlocking of wmalloc usage */ - if (!semaphore_release((uint32_t *) _ptr_semaphore)) { + if (!semaphore_release(_ptr_semaphore)) { malloc_errno = EHEAPSEMAPHORE; return -1; } @@ -641,10 +680,10 @@ int wfree(void **ptr_to_free) end_error: -#ifdef CONFIG_STD_MALLOC_MUTEX +#if CONFIG_STD_MALLOC_MUTEX == 1 /* Unlocking of wmalloc usage (malloc_errno is not modified in order to keep the value * of the initial error) */ - semaphore_release((uint32_t *) _ptr_semaphore); + semaphore_release(_ptr_semaphore); #endif return -1; @@ -697,7 +736,7 @@ static int _link(struct block *b_cur, struct block *b_0) b_prv->nxt_free = o_cur; b_nxt->prv_free = o_cur; -#if CANARIS_INTEGRITY != 0 +#if CONFIG_STD_MALLOC_CANARIS_INTEGRITY != 0 /* Canaris are updated */ UPDATE_CANARI_FREE(b_cur); UPDATE_CANARI_FREE(b_prv); @@ -737,7 +776,7 @@ static void __attribute__((optimize("O0"))) *_safe_flood_char(void *dest, const /* Checking of the heap's integrity */ /****************************************************************************************/ #if CONFIG_STD_MALLOC_INTEGRITY >= 2 -int _heap_integrity(void) +static int _heap_integrity(void) { struct block *b_0 = (struct block *) _start_heap; struct block *b_cur = b_0 + 1; @@ -872,7 +911,7 @@ static inline int check_alloc_headers(void) } } -#if (CANARIS_INTEGRITY + SZ_VAL_INTEGRITY) == 0 +#if (CONFIG_STD_MALLOC_CANARIS_INTEGRITY + SZ_VAL_INTEGRITY) == 0 if (SIZE_SECU(b_cur) == 0) { error = INTEGRITY_SZ; goto out; @@ -905,7 +944,7 @@ static int check_hdr(struct block *b, u__sz_t flag) return INTEGRITY_FLAG; } -#if CANARIS_INTEGRITY == 1 +#if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1 if (flag & CHECK_CANARI) { if (BAD_CANARI(b)) { return INTEGRITY_CANARI; @@ -1004,7 +1043,7 @@ static int check_consistency(struct block * b, u__sz_t flag) { if (flag & CHECK_SZ_EQ_PRV) { if (NOT_FIRST_BLOCK(b)) { -# if CANARIS_INTEGRITY == 0 +# if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 0 if (b->prv_sz != SIZE(PREV_SECU(b))) { # else if (b->prv_sz != SIZE(PREV(b))) { @@ -1016,7 +1055,7 @@ static int check_consistency(struct block * b, u__sz_t flag) if (flag & CHECK_SZ_EQ_NXT) { if (NOT_LAST_BLOCK(b)) { -# if CANARIS_INTEGRITY == 0 +# if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 0 if (SIZE(b) != NEXT_SECU(b)->prv_sz) { # else if (SIZE(b) != NEXT(b)->prv_sz) { @@ -1031,7 +1070,7 @@ static int check_consistency(struct block * b, u__sz_t flag) } if (flag & CHECK_FREE_EQ_PRV) { -# if CANARIS_INTEGRITY == 0 +# if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 0 if (NXT_FREE_SECU((PRV_FREE_SECU(b))) != b) { # else if (NXT_FREE(PRV_FREE(b)) != b) { @@ -1041,7 +1080,7 @@ static int check_consistency(struct block * b, u__sz_t flag) } if (flag & CHECK_FREE_EQ_NXT) { -# if CANARIS_INTEGRITY == 0 +# if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 0 if (PRV_FREE_SECU(NXT_FREE_SECU(b)) != b) { # else if (PRV_FREE(NXT_FREE(b)) != b) { @@ -1063,6 +1102,11 @@ static int check_consistency(struct block * b, u__sz_t flag) #ifdef PRINT_HEAP int print_heap(void) { + if(allocator_initialized != 1){ + malloc_errno = EHEAPNODEF; + return -1; + } + struct block *b_0 = (struct block *) _start_heap; struct block *b_cur = NULL; diff --git a/alloc/malloc_ewok.h b/alloc/malloc_ewok.h index 15c26bb..494d889 100644 --- a/alloc/malloc_ewok.h +++ b/alloc/malloc_ewok.h @@ -12,7 +12,8 @@ #include "malloc_priv.h" - +#define SUM_VERSION 2 +#define HEAP_SIZE_LEN CONFIG_STD_MALLOC_SIZE_LEN /* Chunk structure : * - size and and previous chunk's size @@ -21,7 +22,7 @@ */ /*#pragma pack (1)*/ struct __attribute__((packed)) block { -#if CANARIS_INTEGRITY == 1 +#if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1 u_can_t can_sz; #endif u_flg_t flag; @@ -29,13 +30,13 @@ struct __attribute__((packed)) block { u__sz_t sz; u_off_t prv_free; /* Only for free blocks: relative address */ u_off_t nxt_free; /* Only for free blocks: relative address */ -#if CANARIS_INTEGRITY == 1 +#if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1 u_can_t can_free; #endif }; struct __attribute__((packed)) alloc_block { -#if CANARIS_INTEGRITY == 1 +#if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1 u_can_t can_sz; #endif u_flg_t flag; @@ -109,7 +110,7 @@ struct __attribute__((packed)) alloc_block { /* Canaries mamangement */ -#if CANARIS_INTEGRITY == 1 +#if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1 #define CAN_SHIFT HEAP_SIZE_LEN @@ -173,7 +174,7 @@ struct __attribute__((packed)) alloc_block { # define INCREASE_SZ_FREE(l) SZ_FREE() = (u__sz_t)(SZ_FREE() + (l)) # define DECREASE_SZ_FREE(l) SZ_FREE() = (u__sz_t)(SZ_FREE() - (l)) -#if CANARIS_INTEGRITY == 1 +#if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1 # define INC_NB_SZ_FREE(l) INCREASE_SZ_FREE(l); \ INCREASE_NB_FREE(); \ @@ -186,6 +187,9 @@ struct __attribute__((packed)) alloc_block { #endif +void malloc_ewok_init(physaddr_t start_heap, + physaddr_t end_heap, + u__sz_t heap_size); #endif #endif diff --git a/alloc/malloc_init.c b/alloc/malloc_init.c index 8f2f80e..cd174f0 100644 --- a/alloc/malloc_init.c +++ b/alloc/malloc_init.c @@ -2,10 +2,13 @@ #ifdef CONFIG_STD_MALLOC -#include "malloc_priv.h" +#define RANDOM_CANARIS +#if (CONFIG_STD_MALLOC_INTEGRITY == 1) && (CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1) +#include "malloc_ewok.h" +#endif -//#include "../inc/memfct.h" +#include "malloc_priv.h" /* Global variables */ @@ -33,7 +36,7 @@ static u_can_t _can_sz; static u_can_t _can_free; #endif -#ifdef CONFIG_STD_MALLOC_MUTEX +#if CONFIG_STD_MALLOC_MUTEX == 1 /* Semaphore */ static volatile uint32_t _semaphore; #endif @@ -77,11 +80,11 @@ void _set_wmalloc_canaries(u_can_t *can_sz, u_can_t *can_free) #endif -#ifdef CONFIG_STD_MALLOC_MUTEX +#if CONFIG_STD_MALLOC_MUTEX == 1 /* Set semaphore for allocator functions */ -void _set_wmalloc_semaphore(volatile uint32_t *ptr_semaphore) +void _set_wmalloc_semaphore(volatile uint32_t **ptr_semaphore) { - *ptr_semaphore = (physaddr_t) (&_semaphore); + *ptr_semaphore = (uint32_t*) (&_semaphore); return; } @@ -91,11 +94,17 @@ void _set_wmalloc_semaphore(volatile uint32_t *ptr_semaphore) /****************************************************************************************/ /* Initialization of heap global variables */ /****************************************************************************************/ +volatile unsigned char allocator_initialized = 0; int wmalloc_init(void) { physaddr_t task_start_heap = 0; uint32_t task_heap_size = 0; + /* If allocator already initialized, this is an error ... */ + if(allocator_initialized == 1){ + return -1; + } + #ifdef CONFIG_KERNEL_EWOK task_start_heap = (physaddr_t) (&_e_bss); task_heap_size = (physaddr_t)&_e_heap - task_start_heap; @@ -117,8 +126,44 @@ int wmalloc_init(void) printf("stack end: 0x%08x\n", &_e_stack); #endif -#ifdef CONFIG_STD_MALLOC_LIGHT +#if defined(CONFIG_STD_MALLOC_LIGHT) + printf("Light allocator used!\n"); +#elif defined(CONFIG_STD_MALLOC_STD) + printf("EwoK hardened allocator used!\n"); +#endif + +#ifdef CONFIG_STD_MALLOC_INTEGRITY + printf("CONFIG_STD_MALLOC_INTEGRITY = %d\n", CONFIG_STD_MALLOC_INTEGRITY); +#endif +#ifdef CONFIG_STD_MALLOC_MUTEX + printf("CONFIG_STD_MALLOC_MUTEX = %d\n", CONFIG_STD_MALLOC_MUTEX); +#endif +#ifdef CONFIG_STD_MALLOC_CANARIS_INTEGRITY + printf("CONFIG_STD_MALLOC_CANARIS_INTEGRITY = %d\n", CONFIG_STD_MALLOC_CANARIS_INTEGRITY); +#endif +#ifdef CONFIG_STD_MALLOC_CHECK_IF_NULL + printf("CONFIG_STD_MALLOC_CHECK_IF_NULL = %d\n", CONFIG_STD_MALLOC_CHECK_IF_NULL); +#endif +#ifdef CONFIG_STD_MALLOC_BASIC_CHECKS + printf("CONFIG_STD_MALLOC_BASIC_CHECKS = %d\n", CONFIG_STD_MALLOC_BASIC_CHECKS); +#endif +#ifdef CONFIG_STD_MALLOC_DBLE_WAY_SEARCH + printf("CONFIG_STD_MALLOC_DBLE_WAY_SEARCH = %d\n", CONFIG_STD_MALLOC_DBLE_WAY_SEARCH); +#endif +#ifdef CONFIG_STD_MALLOC_ALIGN + printf("CONFIG_STD_MALLOC_ALIGN = %d\n", CONFIG_STD_MALLOC_ALIGN); +#endif +#ifdef CONFIG_STD_FREEMEM_CHECK + printf("CONFIG_STD_FREEMEM_CHECK = %d\n", CONFIG_STD_FREEMEM_CHECK); +#endif +#ifdef CONFIG_STD_MALLOC_RANDOM + printf("CONFIG_STD_MALLOC_RANDOM = %d\n", CONFIG_STD_MALLOC_RANDOM); +#endif + +#if defined(CONFIG_STD_MALLOC_LIGHT) malloc_light_init(task_start_heap, (physaddr_t)task_start_heap + task_heap_size, (u__sz_t)task_heap_size); +#elif defined(CONFIG_STD_MALLOC_STD) + malloc_ewok_init(task_start_heap, (physaddr_t)task_start_heap + task_heap_size, (u__sz_t)task_heap_size); #else # error "init for other malloc not done yet" #endif @@ -132,7 +177,12 @@ int wmalloc_init(void) return -1; } - return _wmalloc_init(task_start_heap, task_heap_size); + if(_wmalloc_init(task_start_heap, task_heap_size)){ + return -1; + } + + allocator_initialized = 1; + return 0; } @@ -180,7 +230,7 @@ static int _wmalloc_init(const physaddr_t task_start_heap, const uint32_t task_h _heap_size = (u__sz_t) task_heap_size; _end_heap = (physaddr_t) (task_start_heap + task_heap_size); -#ifdef CONFIG_STD_MALLOC_MUTEX +#if CONFIG_STD_MALLOC_MUTEX == 1 /* Locking of wmalloc usage */ semaphore_init(1, &_semaphore); @@ -193,10 +243,16 @@ static int _wmalloc_init(const physaddr_t task_start_heap, const uint32_t task_h #endif /* Definition of canaries */ -#if CANARIS_INTEGRITY == 1 +#if CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1 # ifdef RANDOM_CANARIS - _can_sz = (u_can_t) rand(); - _can_free = (u_can_t) rand(); + if(get_random((unsigned char*) &_can_sz, sizeof(u_can_t)) != MBED_ERROR_NONE){ + malloc_errno = EHEAPNODEF; + return -1; + } + if(get_random((unsigned char*) &_can_free, sizeof(u_can_t)) != MBED_ERROR_NONE){ + malloc_errno = EHEAPNODEF; + return -1; + } # else _can_sz = (u_can_t) 0xF0F0F0F0; _can_free = (u_can_t) 0x0F0F0F0F; @@ -212,7 +268,7 @@ static int _wmalloc_init(const physaddr_t task_start_heap, const uint32_t task_h b_0->flag = 0; b_0->prv_free = HDR_FREE_SZ; b_0->nxt_free = HDR_FREE_SZ; -# if CANARIS_INTEGRITY == 1 +#if (CONFIG_STD_MALLOC_INTEGRITY >= 1) && (CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1) UPDATE_CANARI_BOTH(b_0); # endif @@ -225,11 +281,11 @@ static int _wmalloc_init(const physaddr_t task_start_heap, const uint32_t task_h b_1->flag = 0; b_1->prv_free = 0; b_1->nxt_free = 0; -# if CANARIS_INTEGRITY == 1 +#if (CONFIG_STD_MALLOC_INTEGRITY >= 1) && (CONFIG_STD_MALLOC_CANARIS_INTEGRITY == 1) UPDATE_CANARI_BOTH(b_1); # endif -#ifdef CONFIG_STD_MALLOC_MUTEX +#if CONFIG_STD_MALLOC_MUTEX == 1 /* Unlocking of wmalloc usage */ if (!semaphore_release(&_semaphore)) { malloc_errno = EHEAPSEMAPHORE; diff --git a/alloc/malloc_init.h b/alloc/malloc_init.h index bc908b5..07f2549 100644 --- a/alloc/malloc_init.h +++ b/alloc/malloc_init.h @@ -1,5 +1,5 @@ -#ifndef H_MALLOC_EWOK -#define H_MALLOC_EWOK +#ifndef H_MALLOC_INIT +#define H_MALLOC_INIT #include "autoconf.h" diff --git a/alloc/malloc_light.c b/alloc/malloc_light.c index b76da6e..a6c521d 100644 --- a/alloc/malloc_light.c +++ b/alloc/malloc_light.c @@ -10,8 +10,12 @@ #include "malloc_priv.h" #include "malloc_init.h" -//#include "../inc/memfct.h" +#if CONFIG_STD_MALLOC_MUTEX == 1 +extern void _set_wmalloc_semaphore(volatile uint32_t **ptr_semaphore); +#endif +extern void _set_wmalloc_heap(physaddr_t *start_heap, physaddr_t *end_heap, u__sz_t *heap_size); +extern volatile unsigned char allocator_initialized; /* Global variables */ @@ -20,9 +24,9 @@ static physaddr_t _start_heap; static physaddr_t _end_heap; static u__sz_t _heap_size; -#ifdef CONFIG_STD_MALLOC_MUTEX +#if CONFIG_STD_MALLOC_MUTEX == 1 /* Semaphore */ -volatile uint32_t _ptr_semaphore; +static volatile uint32_t *_ptr_semaphore; #endif @@ -45,8 +49,8 @@ void malloc_light_init(physaddr_t start_heap, _end_heap = end_heap; _heap_size = heap_size; -#ifdef CONFIG_STD_MALLOC_MUTEX - _set_wmalloc_semaphore((uint32_t *) _ptr_semaphore); +#if CONFIG_STD_MALLOC_MUTEX == 1 + _set_wmalloc_semaphore(&_ptr_semaphore); #endif } @@ -59,6 +63,11 @@ int wmalloc(void **ptr_to_alloc, const uint16_t len, const int flag) int wmalloc(void **ptr_to_alloc, const uint32_t len, const int flag) #endif { + if(allocator_initialized != 1){ + malloc_errno = EHEAPNODEF; + return -1; + } + void *ptr = NULL; u__sz_t len_bis = (u__sz_t) len; @@ -76,15 +85,14 @@ int wmalloc(void **ptr_to_alloc, const uint32_t len, const int flag) /* Errno is initialized to zero */ malloc_errno = 0; - + if (!is_malloc_initialized()) { return -1; } - b_cur = NXT_FREE(b_0); -#ifdef CONFIG_STD_MALLOC_MUTEX +#if CONFIG_STD_MALLOC_MUTEX == 1 /* Trying to lock of wmalloc usage */ - if (!semaphore_trylock(&_ptr_semaphore)) { + if (!semaphore_trylock(_ptr_semaphore)) { malloc_errno = EHEAPLOCKED; return -1; } @@ -186,9 +194,9 @@ int wmalloc(void **ptr_to_alloc, const uint32_t len, const int flag) /**********************************************************/ *ptr_to_alloc = ptr; -#ifdef CONFIG_STD_MALLOC_MUTEX +#if CONFIG_STD_MALLOC_MUTEX == 1 /* Unlocking of wmalloc usage */ - if (!semaphore_release(&_ptr_semaphore)) { + if (!semaphore_release(_ptr_semaphore)) { malloc_errno = EHEAPSEMAPHORE; return -1; } @@ -216,10 +224,10 @@ int wmalloc(void **ptr_to_alloc, const uint32_t len, const int flag) end_error: -#ifdef CONFIG_STD_MALLOC_MUTEX +#if CONFIG_STD_MALLOC_MUTEX == 1 /* Unlocking of wmalloc usage (malloc_errno is not modified in order to keep the value * of the initial error) */ - semaphore_release(&_ptr_semaphore); + semaphore_release(_ptr_semaphore); #endif return -1; @@ -269,6 +277,11 @@ static int _unlink(struct block *b_cur) /****************************************************************************************/ int wfree(void **ptr_to_free) { + if(allocator_initialized != 1){ + malloc_errno = EHEAPNODEF; + return -1; + } + struct block *b_0 = (struct block *) _start_heap; struct block *b_1 = b_0 + 1; @@ -284,12 +297,13 @@ int wfree(void **ptr_to_free) if (!is_malloc_initialized()) { return -1; } + -#ifdef CONFIG_STD_MALLOC_MUTEX +#if CONFIG_STD_MALLOC_MUTEX == 1 _set_wmalloc_semaphore(&_ptr_semaphore); /* Locking of wmalloc usage */ - if (!semaphore_trylock(&_ptr_semaphore)) { + if (!semaphore_trylock(_ptr_semaphore)) { malloc_errno = EHEAPLOCKED; return -1; } @@ -419,9 +433,9 @@ int wfree(void **ptr_to_free) end: -#ifdef CONFIG_STD_MALLOC_MUTEX +#if CONFIG_STD_MALLOC_MUTEX == 1 /* Unlocking of wmalloc usage */ - if (!semaphore_release(&_ptr_semaphore)) { + if (!semaphore_release(_ptr_semaphore)) { malloc_errno = EHEAPSEMAPHORE; return -1; } @@ -431,10 +445,10 @@ int wfree(void **ptr_to_free) end_error: -#ifdef CONFIG_STD_MALLOC_MUTEX +#if CONFIG_STD_MALLOC_MUTEX == 1 /* Unlocking of wmalloc usage (malloc_errno is not modified in order to keep the value * of the initial error) */ - semaphore_release(&_ptr_semaphore); + semaphore_release(_ptr_semaphore); #endif return -1; @@ -508,6 +522,11 @@ static void *_safe_flood_char(void *dest, const char c, uint32_t n) #ifdef PRINT_HEAP int print_heap(void) { + if(allocator_initialized != 1){ + malloc_errno = EHEAPNODEF; + return -1; + } + struct block *b_0 = (struct block *) _start_heap; struct block *b_cur = NULL; diff --git a/alloc/malloc_priv.h b/alloc/malloc_priv.h index 96edd72..977344f 100644 --- a/alloc/malloc_priv.h +++ b/alloc/malloc_priv.h @@ -10,7 +10,6 @@ #ifdef CONFIG_STD_MALLOC -#include "malloc_priv.h" #include "malloc_errno.h" /* Specific wmalloc errno values */ #include "libc/types.h" #include "libc/malloc.h" @@ -151,6 +150,8 @@ int _heap_integrity(void); #include "malloc_bins.h" #endif +/* For randomness source */ +#include "libc/random.h" #endif #endif diff --git a/alloc/std_config.h b/alloc/std_config.h index 3c1552c..9babaf5 100644 --- a/alloc/std_config.h +++ b/alloc/std_config.h @@ -92,7 +92,7 @@ /* Integrity checking mode */ -#define HEAP_INTEGRITY_CHECKING 1 /* Define the mode of integrity checking: +#define HEAP_INTEGRITY_CHECKING 3 /* Define the mode of integrity checking: 0 - no integrity checking 1 - integrity checking of each header to be read 2 - integrity of all free blocks' headers at each diff --git a/arch/cores/armv7-m/m4_syscall.c b/arch/cores/armv7-m/m4_syscall.c index 3e9c727..e8d5887 100644 --- a/arch/cores/armv7-m/m4_syscall.c +++ b/arch/cores/armv7-m/m4_syscall.c @@ -35,8 +35,7 @@ int _main(uint32_t slot); #pragma clang optimize off /* Well, clang support local stack protection deactivation only since v8 :-/ */ #if __clang_major__ > 7 -#pragma clang attribute push(__attribute__((no_stack_protector)), apply_to = do_starttask) -#endif +#pragma clang attribute push(__attribute__((no_stack_protector))) #endif __IN_SEC_VDSO void do_starttask(uint32_t slot, uint32_t seed) @@ -72,34 +71,6 @@ __IN_SEC_VDSO void __stack_chk_fail(void) }; } -#if __clang__ -#pragma clang optimize on -#if __clang_major__ > 7 -#pragma clang attribute pop -#endif -#endif - -#if __GNUC__ -#pragma GCC pop_options -#endif - -/** - ** \private - ** ISR handler glue. The kernel must set the real handler @ in the - ** stack frame to make the NVIC reload r0 with its @. - */ -__IN_SEC_VDSO void do_startisr(handler_t handler, uint8_t irq, uint32_t status, uint32_t data) -{ - if (handler) { - handler(irq, status, data); - } - - /* End of ISR */ - asm volatile ("svc %0\n"::"i" (SVC_EXIT):); - - while (1) { - }; -} /** ** \private @@ -278,3 +249,32 @@ __IN_SEC_VDSO e_syscall_ret do_syscall(e_svc_type svc, __attribute__ ((unused)) return SYS_E_INVAL; } } + +/** + ** \private + ** ISR handler glue. The kernel must set the real handler @ in the + ** stack frame to make the NVIC reload r0 with its @. + */ +__IN_SEC_VDSO void do_startisr(handler_t handler, uint8_t irq, uint32_t status, uint32_t data) +{ + if (handler) { + handler(irq, status, data); + } + + /* End of ISR */ + asm volatile ("svc %0\n"::"i" (SVC_EXIT):); + + while (1) { + }; +} + +#if __clang__ +#pragma clang optimize on +#if __clang_major__ > 7 +#pragma clang attribute pop +#endif +#endif + +#if __GNUC__ +#pragma GCC pop_options +#endif diff --git a/embed/queue.c b/embed/queue.c index 5aed2b1..806b32a 100644 --- a/embed/queue.c +++ b/embed/queue.c @@ -32,6 +32,7 @@ mbed_error_t queue_create(uint32_t capacity, queue_t ** queue) { queue_t *q = 0; + int ret; /* sanitizing */ if (!queue) { @@ -45,8 +46,9 @@ mbed_error_t queue_create(uint32_t capacity, queue_t ** queue) } /* allocating */ - if (wmalloc((void **) &q, sizeof(queue_t), ALLOC_NORMAL) != 0) { - goto nomem; + if ((ret = wmalloc((void **) &q, sizeof(queue_t), ALLOC_NORMAL)) != 0) { + aprintf("[ISR] Error queue_create in malloc: %x\n", ret); + goto unkown; } #if QUEUE_DEBUG aprintf("queue address is %x\n", q); @@ -61,15 +63,15 @@ mbed_error_t queue_create(uint32_t capacity, queue_t ** queue) *queue = q; return MBED_ERROR_NONE; - nomem: - return MBED_ERROR_NOMEM; + unkown: + return MBED_ERROR_UNKNOWN; invparam: return MBED_ERROR_INVPARAM; } mbed_error_t queue_enqueue(queue_t * q, void *data) { - struct node *n; + struct node *n = NULL; int ret; if (!q || !data) { @@ -81,8 +83,8 @@ mbed_error_t queue_enqueue(queue_t * q, void *data) } if ((ret = wmalloc((void **) &n, sizeof(struct node), ALLOC_NORMAL)) != 0) { - aprintf("[ISR] Error in malloc: %d\n", ret); - return MBED_ERROR_NOMEM; + aprintf("[ISR] Error queue_enqueue in malloc: %x\n", ret); + return MBED_ERROR_UNKNOWN; } /* We manipulate the queue: we need to lock it to stay thread-safe */ @@ -169,8 +171,9 @@ mbed_error_t queue_dequeue(queue_t * q, void **data) if (wfree((void **) &last) != 0) { #if QUEUE_DEBUG /* this error should not happend. */ - aprintf("free failed with %x\n", ret); + aprintf("[ISR] free failed in queue_dequeue with %x\n", ret); #endif + ret = MBED_ERROR_UNKNOWN; } nostorage: diff --git a/syscall.c b/syscall.c index c99f71f..8556f5f 100644 --- a/syscall.c +++ b/syscall.c @@ -37,7 +37,9 @@ static inline __IN_SEC_VDSO void _memset(void *s, int c, uint32_t n) { char *bytes = s; - + if(s == NULL){ + return; + } while (n) { *bytes = c; bytes++; @@ -51,6 +53,9 @@ static inline __IN_SEC_VDSO void _memcpy(void *dest, const void *src, uint32_t n char *d_bytes = dest; const char *s_bytes = src; + if((dest == NULL) || (src == NULL)){ + return; + } while (n) { *d_bytes = *s_bytes; d_bytes++;