From da804296c6f45c8bf7c6d29570552df43da3c853 Mon Sep 17 00:00:00 2001 From: Starnakin Date: Tue, 26 Nov 2024 12:43:09 +0100 Subject: [PATCH] fix: memory: protect kernel code --- headers/memory.h | 26 ++++++++++++---------- libbozo/headers/utils.h | 6 +++-- src/kernel.c | 17 ++++++++------ src/memory/memory.c | 49 +++++++++++++++++++++++++++++------------ 4 files changed, 63 insertions(+), 35 deletions(-) diff --git a/headers/memory.h b/headers/memory.h index 16c334f..c9a9c61 100644 --- a/headers/memory.h +++ b/headers/memory.h @@ -5,18 +5,20 @@ #include #include -#define PRESENT (1 << 0) -#define RW (1 << 1) -#define SUPERVISOR (0 << 2) -#define ACCESSED (1 << 4) -#define INIT_FLAGS (PRESENT | RW | SUPERVISOR) -#define PAGE_SIZE 4096 -#define PT_SIZE 1024 -#define PD_SIZE 1024 -#define PAGE_MASK 0xFFFFF000 -#define HEAP_END 0xC0000000 -#define HEAP_START ((uint32_t) & _kernel_end - HEAP_END) -#define PT_START 256 +#define PRESENT (1 << 0) +#define RW (1 << 1) +#define SUPERVISOR (0 << 2) +#define ACCESSED (1 << 4) +#define INIT_FLAGS (PRESENT | RW | SUPERVISOR) +#define PAGE_SIZE 4096 +#define PT_SIZE 1024 +#define PD_SIZE 1024 +#define PAGE_MASK 0xFFFFF000 +#define HEAP_END 0xC0000000 +#define HEAP_START ((uint32_t) & _kernel_end - HEAP_END) +#define KERNEL_START ((uint32_t) & _kernel_start) +#define KERNEL_END ((uint32_t) & _kernel_end - HEAP_END) +#define PT_START 256 #define GET_PAGE_ADDR(pd_index, pt_index) \ ((((uint32_t)pd_index * 1024) + (uint32_t)pt_index) * 4096) diff --git a/libbozo/headers/utils.h b/libbozo/headers/utils.h index f84c489..156a390 100644 --- a/libbozo/headers/utils.h +++ b/libbozo/headers/utils.h @@ -1,4 +1,6 @@ #pragma once -#define CEIL(x, y) (((x) + (y) - 1) / (y)) -#define ARRAY_SIZE(ptr) (sizeof(ptr) / sizeof(ptr[0])) +#define CEIL(x, y) (((x) + (y) - 1) / (y)) +#define ARRAY_SIZE(ptr) (sizeof(ptr) / sizeof(ptr[0])) +#define ROUND_CEIL(x, y) (CEIL(x, y) * y) +#define ROUND_FLOOR(x, y) ((x / y) * y) diff --git a/src/kernel.c b/src/kernel.c index 5f34f6a..bb0c6fc 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -68,13 +68,16 @@ void kernel_main(multiboot_info_t *mbd, uint32_t magic) "Martin 03:50, 22 March 2009 (UTC)\n"); // PRINT_PTR(alloc_frame()); - /*void *ptr; - while ((ptr = alloc_pages(PAGE_SIZE * 1020))) { - if (ptr) - memset(ptr, ~0, PAGE_SIZE * 1020); - }*/ + if (false) { + void *ptr; + while ((ptr = alloc_pages(PAGE_SIZE * 1))) { + if (ptr) + memset(ptr, ~0, PAGE_SIZE * 1); + } + } else { + while (vmalloc(10)) + ; + } /* vmalloc(10); */ - while (vmalloc(10)) - ; shell_init(); } diff --git a/src/memory/memory.c b/src/memory/memory.c index 18f38cd..db8c3bd 100644 --- a/src/memory/memory.c +++ b/src/memory/memory.c @@ -60,26 +60,46 @@ static void lst_add_back(struct frame_zone **root, struct frame_zone *element) static void add_frame_node(multiboot_memory_map_t *mmmt) { static uint32_t index; - void *zone = (void *)mmmt->addr; - // Kernel code on the block - if (HEAP_START >= zone + mmmt->len) + /** + * # = kernel code + * - = blank + */ + + uint64_t start_addr = mmmt->addr; + uint64_t end_addr = mmmt->addr + mmmt->len; + uint64_t len = mmmt->len; + + /** Kernel code cover all the block + * this situation: + * ####################### + */ + if (KERNEL_START <= start_addr && KERNEL_END >= end_addr) return; - // KERNEL code partially on the block - if (HEAP_START >= zone) { - const uint32_t start_space = - CEIL(HEAP_START, PAGE_SIZE) * PAGE_SIZE; - const uint32_t len = mmmt->len - (start_space - (uint32_t)zone); - mmmt->len = CEIL(len, PAGE_SIZE) * PAGE_SIZE; - zone = (void *)start_space; + /** Kernel code start on the block + * this situation: + * --------############### + */ + if (KERNEL_START > start_addr && KERNEL_START <= end_addr) { + len = ROUND_FLOOR(KERNEL_START - start_addr, PAGE_SIZE); } + /** Kernel code end on the block + * this situation: + * ###############-------- + */ + if (KERNEL_START <= start_addr && KERNEL_END > start_addr && + KERNEL_END <= end_addr) { + len = len - (KERNEL_END - start_addr); + start_addr = ROUND_CEIL(KERNEL_END, PAGE_SIZE); + } + end_addr = ROUND_CEIL(start_addr + len, PAGE_SIZE); init_page_table(frame_zones_page_table, 0); page_directory[1022] = ((uint32_t)frame_zones_page_table - HEAP_END) | 0x03; frame_zones_page_table[index] = - ((uint32_t)zone & PAGE_MASK) | INIT_FLAGS; + ((uint32_t)start_addr & PAGE_MASK) | INIT_FLAGS; struct frame_zone *current = (struct frame_zone *)GET_PAGE_ADDR(1022, index++); @@ -91,7 +111,7 @@ static void add_frame_node(multiboot_memory_map_t *mmmt) cause we are using non decimal number nb_frame = ((size * 8) / (PAGE_SIZE * 8 + 1)) */ - const uint32_t nb_frame = ((mmmt->len * 8) / (PAGE_SIZE * 8 + 1)); + const uint32_t nb_frame = ((len * 8) / (PAGE_SIZE * 8 + 1)); current->first_free_frame = 0; current->next = NULL; @@ -103,8 +123,9 @@ static void add_frame_node(multiboot_memory_map_t *mmmt) uint32_t i = 1; for (; i < CEIL(nb_frame, PAGE_SIZE); i++) frame_zones_page_table[index + i] = - ((uint32_t)zone + i * PAGE_SIZE & PAGE_MASK) | INIT_FLAGS; - current->addr = zone + i * PAGE_SIZE; + ((uint32_t)start_addr + i * PAGE_SIZE & PAGE_MASK) | + INIT_FLAGS; + current->addr = (void *)start_addr + i * PAGE_SIZE; index += i - 1; lst_add_back(&head, current); }