diff options
author | Marvin Borner | 2021-04-04 00:11:00 +0200 |
---|---|---|
committer | Marvin Borner | 2021-04-04 00:11:00 +0200 |
commit | 7a64bdbbcf14023370b90b22de73c2f61a6f84ac (patch) | |
tree | 7f26778ddcd9f7e213f70e60e04c1805c4f2572f /kernel | |
parent | 9127d8e4d09207d5c9d98024ca6610310a7273ad (diff) |
Implemented basic user program ASLR
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/features/load.c | 28 | ||||
-rw-r--r-- | kernel/features/mm.c | 2 | ||||
-rw-r--r-- | kernel/main.c | 2 |
3 files changed, 21 insertions, 11 deletions
diff --git a/kernel/features/load.c b/kernel/features/load.c index 2b82a44..3dff831 100644 --- a/kernel/features/load.c +++ b/kernel/features/load.c @@ -6,12 +6,11 @@ #include <load.h> #include <mem.h> #include <mm.h> +#include <random.h> #include <str.h> #define PROC_STACK_SIZE 0x4000 -#include <print.h> - res elf_load(const char *path, struct proc *proc) { if (!memory_valid(path)) @@ -45,10 +44,15 @@ res elf_load(const char *path, struct proc *proc) magic[ELF_IDENT_MAG2] == ELF_MAG2 && magic[ELF_IDENT_MAG3] == ELF_MAG3 && magic[ELF_IDENT_CLASS] == ELF_IDENT_CLASS_32 && magic[ELF_IDENT_DATA] == ELF_IDENT_DATA_LSB; - if (!valid_magic || (header.type != ELF_ETYPE_REL && header.type != ELF_ETYPE_EXEC) || + if (!valid_magic || + (header.type != ELF_ETYPE_REL && header.type != ELF_ETYPE_EXEC && + header.type != ELF_ETYPE_DYN) || header.version != 1 || header.machine != ELF_MACHINE_386) return -ENOEXEC; + // ASLR + u32 rand_off = (rand() & 0xffff) * PAGE_SIZE; + // Loop through programs for (u32 i = 0; i < header.phnum; i++) { struct elf_program program = { 0 }; @@ -62,6 +66,9 @@ res elf_load(const char *path, struct proc *proc) } memory_bypass_disable(); + if (program.type == ELF_PROGRAM_TYPE_INTERP) + return -ENOEXEC; + if (program.vaddr == 0 || program.type != ELF_PROGRAM_TYPE_LOAD) continue; @@ -72,13 +79,14 @@ res elf_load(const char *path, struct proc *proc) memory_backup_dir(&prev); memory_switch_dir(proc->page_dir); - struct memory_range vrange = memory_range_around(program.vaddr, program.memsz); + struct memory_range vrange = + memory_range_around(program.vaddr + rand_off, program.memsz); struct memory_range prange = physical_alloc(vrange.size); virtual_map(proc->page_dir, prange, vrange.base, MEMORY_CLEAR | MEMORY_USER); memory_bypass_enable(); - if ((u32)vfs_read(proc->name, (void *)program.vaddr, program.offset, - program.filesz) != program.filesz) { + if ((u32)vfs_read(proc->name, (void *)((u32)program.vaddr + rand_off), + program.offset, program.filesz) != program.filesz) { memory_bypass_disable(); memory_switch_dir(prev); return -ENOEXEC; @@ -133,7 +141,8 @@ res elf_load(const char *path, struct proc *proc) // Remap readonly sections if (!(section.flags & ELF_SECTION_FLAG_WRITE)) { - struct memory_range range = memory_range_around(section.addr, section.size); + struct memory_range range = + memory_range_around(section.addr + rand_off, section.size); virtual_remap_readonly(proc->page_dir, range); } } @@ -152,8 +161,9 @@ res elf_load(const char *path, struct proc *proc) proc->regs.ebp = stack + PROC_STACK_SIZE; proc->regs.useresp = stack + PROC_STACK_SIZE; - proc->regs.eip = header.entry; - proc->entry = header.entry; + proc->regs.eip = header.entry + rand_off; + proc->entry = header.entry + rand_off; + clac(); memory_switch_dir(prev); diff --git a/kernel/features/mm.c b/kernel/features/mm.c index 67a5abf..76049ef 100644 --- a/kernel/features/mm.c +++ b/kernel/features/mm.c @@ -464,7 +464,7 @@ res memory_sys_alloc(struct page_dir *dir, u32 size, u32 *addr, u32 *id, u8 shar return -ENOMEM; struct memory_object *obj = zalloc(sizeof(*obj)); - obj->id = rdrand() + 1; + obj->id = rand() + 1; obj->prange = memory_range(virtual_to_physical(dir, vaddr), size); obj->refs = 1; obj->shared = shared; diff --git a/kernel/main.c b/kernel/main.c index 14a3555..6752fcf 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -31,7 +31,7 @@ void kernel_main(struct mem_info *mem_info, struct vid_info *vid_info) cpu_enable_features(); cpu_print(); - srand(rdseed()); + srand(rand()); // Install drivers vfs_install(); |