diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 09ddca5..51fdac8 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -14,6 +14,7 @@ "extensions": [ "ms-azuretools.vscode-docker", "ms-vscode.cpptools-extension-pack", + "eamodio.gitlens", ], // allow access to the toradex board diff --git a/errors/errno.fugu b/errors/errno.fugu index 6290f61..9b14e71 100755 --- a/errors/errno.fugu +++ b/errors/errno.fugu @@ -322,6 +322,7 @@ errors libaos LIB_ERR_ { failure PMAP_FRAME_IDENTIFY "Frame could not be identified", failure PMAP_NOT_MAPPED "No mapping in given address range", failure PMAP_ALLOC_CNODE "Failure while allocating Mapping CNode", + failure PMAP_ADDR_IS_GUARDED "The requested address is in a guarded range", failure OUT_OF_VIRTUAL_ADDR "Out of virtual address", diff --git a/include/aos/paging.h b/include/aos/paging.h index fce1c0a..1a996fc 100644 --- a/include/aos/paging.h +++ b/include/aos/paging.h @@ -25,6 +25,7 @@ struct paging_state; +void * paging_malloc(size_t bytes, size_t * retbytes, size_t guarded_region_size); struct thread; errval_t paging_init_state(struct paging_state *st, lvaddr_t start_vaddr, @@ -39,7 +40,7 @@ errval_t paging_init_onthread(struct thread *t); errval_t paging_alloc_ext(struct paging_state *st, void **buf, size_t bytes, - size_t alignment, bool heap); + size_t alignment, bool heap, size_t guarded_region_size); /** * \brief Find a bit of free virtual address space that is large enough to diff --git a/include/aos/paging_types.h b/include/aos/paging_types.h index 4d4bb14..230b467 100644 --- a/include/aos/paging_types.h +++ b/include/aos/paging_types.h @@ -63,6 +63,7 @@ struct pt_vaddr_reg_t { size_t size; uint8_t free:1; // Is the region free? uint8_t heap:1; // Is the region part of the heap? + size_t guarded_region_size; //the first n bits of this region are guarded and will panic when mapped! (e.g to detect stack overflows) struct pt_vaddr_reg_t *next; }; diff --git a/lib/aos/morecore.c b/lib/aos/morecore.c index 2207d20..b599f07 100644 --- a/lib/aos/morecore.c +++ b/lib/aos/morecore.c @@ -101,18 +101,7 @@ errval_t morecore_reinit(void) */ static void *morecore_alloc(size_t bytes, size_t *retbytes) { - errval_t err; - // struct morecore_state *state = get_morecore_state(); - - size_t aligned_bytes = ROUND_UP(bytes, LARGE_PAGE_SIZE); - void *ret = NULL; - err = paging_alloc_ext(get_current_paging_state(), &ret, aligned_bytes, LARGE_PAGE_SIZE, true); - if (err_is_fail(err)) { - DEBUG_ERR(err, "in morecore_alloc, size=%"PRIuPTR"\n", aligned_bytes); - aligned_bytes = 0; - } - *retbytes = aligned_bytes; - return ret; + return paging_malloc(bytes, retbytes, 0); } static void morecore_free(void *base, size_t bytes) diff --git a/lib/aos/paging.c b/lib/aos/paging.c index 30b7c8d..65490fc 100644 --- a/lib/aos/paging.c +++ b/lib/aos/paging.c @@ -134,7 +134,8 @@ static void pt_exception_handler(enum exception_type type, int subtype, } } if (vaddr_reg == NULL || vaddr_reg->free) { - USER_PANIC("[ERROR] Page fault ouside allocated address space"); + debug_printf("[pt_exception_handler] page_addr = %x, base = %x, size = %x\n", page_addr, vaddr_reg->base, vaddr_reg->size); + USER_PANIC("[pt_exception_handler][ERROR] Page fault ouside allocated address space"); } if (!vaddr_reg->heap) { USER_PANIC("[ERROR] Page fault in allocated address space but outside heap"); @@ -259,6 +260,27 @@ void pt_print_state(struct paging_state *st) { PAGING_UNLOCK } +void * paging_malloc(size_t bytes, size_t * retbytes, size_t guarded_region_size) { + errval_t err; + + assert(guarded_region_size < bytes); + + size_t aligned_bytes = ROUND_UP(bytes, LARGE_PAGE_SIZE); + void *ret = NULL; + err = paging_alloc_ext(get_current_paging_state(), &ret, aligned_bytes, LARGE_PAGE_SIZE, true, guarded_region_size); + if (err_is_fail(err)) { + DEBUG_ERR(err, "in paging_malloc, size=%"PRIuPTR"\n", aligned_bytes); + aligned_bytes = 0; + } + *retbytes = aligned_bytes; + debug_printf("[paging_malloc]: bytes = %x, aligned_bytes = %x, base = %p\n", bytes, aligned_bytes, ret); + return ret; +} + +// void paging_free(void * ptr) { + +// } + // refill the slab and hold the paging lock for the slab growing but not before static errval_t pt_slab_refill_locked(struct paging_state *st, struct slab_allocator *slabs, size_t size) { errval_t err; @@ -480,6 +502,7 @@ errval_t paging_init_state(struct paging_state *st, lvaddr_t start_vaddr, st->vaddr_head.free = true; st->vaddr_head.heap = false; st->vaddr_head.next = NULL; + st->vaddr_head.guarded_region_size = 0; st->slot_alloc = ca; st->refilling = 0; @@ -608,7 +631,7 @@ errval_t paging_init_onthread(struct thread *t) static errval_t paging_insert_vaddr_reg( struct paging_state *st, struct pt_vaddr_reg_t *target_region, - size_t prefix_size, size_t alloc_size, bool heap + size_t prefix_size, size_t alloc_size, bool heap, size_t guarded_region_size ) { assert(target_region->free); assert(target_region->size >= prefix_size + alloc_size); @@ -629,6 +652,7 @@ static errval_t paging_insert_vaddr_reg( } else { main_reg = target_region; } + if (postfix_size > 0) { postfix_reg = slab_alloc(&st->pt_slabs); if (postfix_reg == NULL) { @@ -645,6 +669,7 @@ static errval_t paging_insert_vaddr_reg( if (prefix_size > 0) { prefix_reg->base = base; prefix_reg->size = prefix_size; + prefix_reg->guarded_region_size = 0; main_reg->next = prefix_reg->next; prefix_reg->next = main_reg; @@ -656,6 +681,11 @@ static errval_t paging_insert_vaddr_reg( main_reg->size = alloc_size; main_reg->free = false; main_reg->heap = heap; + main_reg->guarded_region_size = guarded_region_size; + + // if (guarded_region_size > 0) { + // debug_printf("[paging_insert_vaddr_reg] guarding region: base = %x, size = %x, guarded_region_size = %x\n", main_reg->base, main_reg->size, main_reg->guarded_region_size); + // } base += alloc_size; @@ -664,6 +694,7 @@ static errval_t paging_insert_vaddr_reg( postfix_reg->size = postfix_size; postfix_reg->free = true; postfix_reg->heap = false; + postfix_reg->guarded_region_size = 0; postfix_reg->next = main_reg->next; main_reg->next = postfix_reg; @@ -674,7 +705,7 @@ static errval_t paging_insert_vaddr_reg( errval_t paging_alloc_ext( struct paging_state *st, void **buf, size_t bytes, - size_t alignment, bool heap + size_t alignment, bool heap, size_t guarded_region_size ) { errval_t err; @@ -707,7 +738,7 @@ errval_t paging_alloc_ext( if (vaddr_reg->free && vaddr_reg->size >= prefix_size + bytes) { // allocate the new region, potentially splitting off a prefix and postfix from the region - err = paging_insert_vaddr_reg(st, vaddr_reg, prefix_size, bytes, heap); + err = paging_insert_vaddr_reg(st, vaddr_reg, prefix_size, bytes, heap, guarded_region_size); if (err_is_fail(err)) { PAGING_UNLOCK return err; @@ -738,7 +769,7 @@ errval_t paging_alloc_ext( */ errval_t paging_alloc(struct paging_state *st, void **buf, size_t bytes, size_t alignment) { - return paging_alloc_ext(st, buf, bytes, alignment, false); + return paging_alloc_ext(st, buf, bytes, alignment, false, 0); } /** @@ -840,9 +871,15 @@ errval_t paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr, for(;vaddr_reg != NULL; vaddr_reg = vaddr_reg->next) { // we have found the region it belongs to if(vaddr_reg->base <= vaddr && end_vaddr <= vaddr_reg->base + vaddr_reg->size) { + //check if we try to map anything in the guarded region! + if (vaddr < vaddr_reg->base + vaddr_reg->guarded_region_size) { + debug_printf("[paging_map_fixed_attr] attempt to map guarded region!, vaddr = %p, guarded_region_size = %x\n", vaddr, vaddr_reg->guarded_region_size); + return LIB_ERR_PMAP_ADDR_IS_GUARDED; + } + if (vaddr_reg->free == true) { // make sure the virtual memory is not used by anyone else - err = paging_insert_vaddr_reg(st, vaddr_reg, vaddr - vaddr_reg->base, bytes, false); + err = paging_insert_vaddr_reg(st, vaddr_reg, vaddr - vaddr_reg->base, bytes, false, 0); if (err_is_fail(err)) { PAGING_UNLOCK return err; diff --git a/lib/aos/threads.c b/lib/aos/threads.c index 75199b9..eeea8e7 100644 --- a/lib/aos/threads.c +++ b/lib/aos/threads.c @@ -317,7 +317,8 @@ static void free_thread(struct thread *thread) ldt_free_segment(thread->thread_seg_selector); #endif - free(thread->stack); + //TODO: afeer: properly free stack again + // free(thread->stack); if (thread->tls_dtv != NULL) { free(thread->tls_dtv); } @@ -345,7 +346,9 @@ struct thread *thread_create_unrunnable(thread_func_t start_func, void *arg, { // allocate stack assert((stacksize % sizeof(uintptr_t)) == 0); - void *stack = malloc(stacksize); + stacksize += BASE_PAGE_SIZE; + size_t bytes_allocated; + void *stack = paging_malloc(stacksize, &bytes_allocated, BASE_PAGE_SIZE); if (stack == NULL) { return NULL; }