diff options
author | Marvin Borner | 2021-04-02 23:26:28 +0200 |
---|---|---|
committer | Marvin Borner | 2021-04-02 23:26:28 +0200 |
commit | ce98400f8a9ebd4e62e76b9e292b7598d0d66cc0 (patch) | |
tree | 823f06c2c325ead611863eeb3ac974c1ae562878 /kernel/features | |
parent | fe468b476d567b6aa0695a030c408ccf46278c7d (diff) |
Added kernel section clear/protect after init
This is a huge security improvement as it prevents potential exploits
of using or modifying internal kernel functions or data.
Diffstat (limited to 'kernel/features')
-rw-r--r-- | kernel/features/fs.c | 10 | ||||
-rw-r--r-- | kernel/features/mm.c | 47 | ||||
-rw-r--r-- | kernel/features/proc.c | 14 | ||||
-rw-r--r-- | kernel/features/syscall.c | 5 |
4 files changed, 54 insertions, 22 deletions
diff --git a/kernel/features/fs.c b/kernel/features/fs.c index 0ffe80f..cc9949e 100644 --- a/kernel/features/fs.c +++ b/kernel/features/fs.c @@ -16,7 +16,7 @@ * VFS */ -static struct list *mount_points = NULL; +PROTECTED static struct list *mount_points = NULL; static char *vfs_normalize_path(const char *path) { @@ -293,7 +293,7 @@ res vfs_ready(const char *path) return m->dev->vfs->ready(path, m->dev); } -void vfs_install(void) +CLEAR void vfs_install(void) { mount_points = list_new(); } @@ -302,9 +302,9 @@ void vfs_install(void) * Device */ -static struct list *devices = NULL; +PROTECTED static struct list *devices = NULL; -void device_add(struct device *dev) +CLEAR void device_add(struct device *dev) { dev->id = rand() + 1; list_add(devices, dev); @@ -373,7 +373,7 @@ static res devfs_ready(const char *path, struct device *dev) return target->ready(); } -void device_install(void) +CLEAR void device_install(void) { devices = list_new(); diff --git a/kernel/features/mm.c b/kernel/features/mm.c index 3be798a..86d33c7 100644 --- a/kernel/features/mm.c +++ b/kernel/features/mm.c @@ -11,7 +11,7 @@ #include <print.h> #include <random.h> -static struct page_dir kernel_dir ALIGNED(PAGE_SIZE) = { 0 }; +PROTECTED static struct page_dir kernel_dir ALIGNED(PAGE_SIZE) = { 0 }; static struct page_table kernel_tables[PAGE_KERNEL_COUNT] ALIGNED(PAGE_SIZE) = { 0 }; /** @@ -23,14 +23,14 @@ static void paging_switch_dir(u32 dir) cr3_set(dir); } -extern void paging_invalidate_tlb(void); +CLEAR extern void paging_invalidate_tlb(void); -void paging_disable(void) +CLEAR void paging_disable(void) { cr0_set(cr0_get() | 0x7fffffff); } -void paging_enable(void) +CLEAR void paging_enable(void) { cr0_set(cr0_get() | 0x80010000); } @@ -70,7 +70,7 @@ void page_fault_handler(struct regs *r) */ static u32 memory_used = 0; -static u32 memory_total = 0; +PROTECTED static u32 memory_total = 0; static u32 best_bet = 0; static u8 memory[PAGE_COUNT * PAGE_COUNT / 8] = { 0 }; @@ -563,7 +563,7 @@ struct memory_range memory_range_around(u32 base, u32 size) extern u32 kernel_rw_start; extern u32 kernel_rw_end; -static struct memory_range kernel_rw_memory_range(void) +CLEAR static struct memory_range kernel_rw_memory_range(void) { return memory_range_around((u32)&kernel_rw_start, (u32)&kernel_rw_end - (u32)&kernel_rw_start); @@ -571,13 +571,44 @@ static struct memory_range kernel_rw_memory_range(void) extern u32 kernel_ro_start; extern u32 kernel_ro_end; -static struct memory_range kernel_ro_memory_range(void) +CLEAR static struct memory_range kernel_ro_memory_range(void) { return memory_range_around((u32)&kernel_ro_start, (u32)&kernel_ro_end - (u32)&kernel_ro_start); } -void memory_install(struct mem_info *mem_info, struct vid_info *vid_info) +extern u32 kernel_temp_clear_start; +extern u32 kernel_temp_clear_end; +static void memory_temp_clear(void) +{ + u8 *data = (u8 *)&kernel_temp_clear_start; + u32 size = (u32)&kernel_temp_clear_end - (u32)&kernel_temp_clear_start; + memset(data, 0, size); + memory_free(&kernel_dir, memory_range_around((u32)data, size)); + printf("Cleared %dKiB\n", size >> 10); +} + +extern u32 kernel_temp_protect_start; +extern u32 kernel_temp_protect_end; +CLEAR static void memory_temp_protect(void) +{ + u32 data = (u32)&kernel_temp_protect_start; + u32 size = (u32)&kernel_temp_protect_end - (u32)&kernel_temp_protect_start; + memory_map_identity(&kernel_dir, memory_range_around((u32)data, size), MEMORY_READONLY); + printf("Protected %dKiB\n", size >> 10); +} + +void memory_user_hook(void) +{ + PROTECTED static u8 called = 0; + if (!called) { + called = 1; + memory_temp_protect(); + memory_temp_clear(); + } +} + +CLEAR void memory_install(struct mem_info *mem_info, struct vid_info *vid_info) { for (struct mmap_boot *p = mem_info->start; (u32)(p - mem_info->start) < mem_info->size; p++) { diff --git a/kernel/features/proc.c b/kernel/features/proc.c index 8625e7d..6d07945 100644 --- a/kernel/features/proc.c +++ b/kernel/features/proc.c @@ -18,12 +18,12 @@ static u32 locked = 0; static u32 current_pid = 0; -static struct node *idle_proc = NULL; static struct node *current = NULL; +PROTECTED static struct node *idle_proc = NULL; -static struct list *proc_list_running = NULL; -static struct list *proc_list_blocked = NULL; -static struct list *proc_list_idle = NULL; +PROTECTED static struct list *proc_list_running = NULL; +PROTECTED static struct list *proc_list_blocked = NULL; +PROTECTED static struct list *proc_list_idle = NULL; // TODO: Use less memcpy and only copy relevant registers // TODO: 20 priority queues (https://www.kernel.org/doc/html/latest/scheduler/sched-nice-design.html) @@ -111,7 +111,7 @@ struct proc *proc_from_pid(u32 pid) return NULL; } -void proc_set_quantum(struct proc *proc, u32 value) +CLEAR void proc_set_quantum(struct proc *proc, u32 value) { proc->quantum.val = value; } @@ -552,8 +552,10 @@ NORETURN void proc_init(void) _eip = init->regs.eip; _esp = init->regs.useresp; - memory_switch_dir(init->page_dir); + // We'll shortly jump to usermode. Clear and protect every secret! + memory_user_hook(); + memory_switch_dir(init->page_dir); printf("Jumping to userspace!\n"); // You're waiting for a train. A train that will take you far away... diff --git a/kernel/features/syscall.c b/kernel/features/syscall.c index ab14539..6a64996 100644 --- a/kernel/features/syscall.c +++ b/kernel/features/syscall.c @@ -24,8 +24,7 @@ static void syscall_handler(struct regs *r) switch (num) { case SYS_LOOP: { - loop(); - panic("Fell out of the looping!\n"); + panic("Loop is deprecated!\n"); break; } case SYS_ALLOC: { @@ -134,7 +133,7 @@ static void syscall_handler(struct regs *r) } } -void syscall_init(void) +CLEAR void syscall_init(void) { idt_set_gate(0x80, (u32)isr128, 0x08, 0x8E); isr_install_handler(0x80, syscall_handler); |