diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/features/load.c | 59 | ||||
-rw-r--r-- | kernel/features/mm.c | 13 | ||||
-rw-r--r-- | kernel/features/proc.c | 3 | ||||
-rw-r--r-- | kernel/inc/load.h | 1 | ||||
-rw-r--r-- | kernel/inc/mm.h | 1 |
5 files changed, 23 insertions, 54 deletions
diff --git a/kernel/features/load.c b/kernel/features/load.c index 3430a75..1795efb 100644 --- a/kernel/features/load.c +++ b/kernel/features/load.c @@ -7,16 +7,10 @@ #include <mm.h> #include <str.h> -#include <print.h> - #define PROC_STACK_SIZE 0x4000 -s32 bin_load(const char *path, struct proc *proc) +s32 elf_load(const char *path, struct proc *proc) { - UNUSED(path); - UNUSED(proc); - panic("Deprecated!\n"); -#if 0 if (!path || !memory_valid(path) || !proc) return -EFAULT; @@ -27,46 +21,10 @@ s32 bin_load(const char *path, struct proc *proc) if (stat != 0) return stat; - strcpy(proc->name, path); - - struct page_dir *prev; - memory_backup_dir(&prev); - memory_switch_dir(proc->page_dir); - - u32 size = PAGE_ALIGN_UP(s.size); - u32 data = (u32)memory_alloc(proc->page_dir, size, MEMORY_USER | MEMORY_CLEAR); - - memory_bypass_enable(); - s32 read = vfs_read(proc->name, (void *)data, 0, s.size); - memory_bypass_disable(); - if (read <= 0) { - memory_switch_dir(prev); - return read; - } - - u32 stack = (u32)memory_alloc(proc->page_dir, PROC_STACK_SIZE, MEMORY_USER | MEMORY_CLEAR); - proc->regs.ebp = stack; - proc->regs.useresp = stack; - proc->regs.eip = data; - proc->entry = data; - - memory_switch_dir(prev); - return 0; -#endif -} - -s32 elf_load(const char *path, struct proc *proc) -{ - if (!path || !memory_valid(path) || !proc) - return -EFAULT; - - struct stat s = { 0 }; - s32 stat = vfs_stat(path, &s); - if (stat != 0) - return stat; - struct elf_header header = { 0 }; + memory_bypass_enable(); s32 read = vfs_read(path, &header, 0, sizeof(header)); + memory_bypass_disable(); if (read < 0) return read; if (read != sizeof(header)) @@ -86,14 +44,18 @@ s32 elf_load(const char *path, struct proc *proc) for (u32 i = 0; i < header.phnum; i++) { struct elf_program program = { 0 }; + memory_bypass_enable(); if (vfs_read(path, &program, header.phoff + header.phentsize * i, - sizeof(program)) != sizeof(program)) + sizeof(program)) != sizeof(program)) { + memory_bypass_disable(); return -ENOEXEC; + } + memory_bypass_disable(); if (program.vaddr == 0) continue; - if (program.vaddr <= 0x100000) + if (!memory_is_user(program.vaddr)) return -ENOEXEC; struct page_dir *prev; @@ -104,11 +66,14 @@ s32 elf_load(const char *path, struct proc *proc) 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) { + memory_bypass_disable(); memory_switch_dir(prev); return -ENOEXEC; } + memory_bypass_disable(); memory_switch_dir(prev); } diff --git a/kernel/features/mm.c b/kernel/features/mm.c index b804076..d14bd81 100644 --- a/kernel/features/mm.c +++ b/kernel/features/mm.c @@ -412,24 +412,27 @@ void memory_backup_dir(struct page_dir **backup) *backup = dir; } -// TODO: Verify that this isn't a huge security risk static u8 memory_bypass_validity = 0; void memory_bypass_enable(void) { - /* memory_bypass_validity = 1; */ + memory_bypass_validity = 1; } void memory_bypass_disable(void) { - /* memory_bypass_validity = 0; */ + memory_bypass_validity = 0; +} + +u8 memory_is_user(u32 addr) +{ + return PDI(addr) >= PAGE_KERNEL_COUNT; } // TODO: Limit by proc stack and data range u8 memory_valid(const void *addr) { - /* return ((u32)addr) / PAGE_SIZE / PAGE_COUNT >= PAGE_KERNEL_COUNT; */ if (proc_current() && !memory_bypass_validity) - return (u32)addr >= 0x100000; + return memory_is_user((u32)addr); else return 1; } diff --git a/kernel/features/proc.c b/kernel/features/proc.c index 5d3c8aa..ff4638b 100644 --- a/kernel/features/proc.c +++ b/kernel/features/proc.c @@ -144,7 +144,8 @@ void proc_exit(struct proc *proc, int status) current = NULL; if (res) - printf("Process %s exited with status %d (%s)\n", proc->name, status, + printf("Process %s (%d) exited with status %d (%s)\n", + proc->name[0] ? proc->name : "UNKNOWN", proc->pid, status, status == 0 ? "success" : "error"); virtual_destroy_dir(proc->page_dir); diff --git a/kernel/inc/load.h b/kernel/inc/load.h index 28bdc54..54ace4e 100644 --- a/kernel/inc/load.h +++ b/kernel/inc/load.h @@ -105,7 +105,6 @@ struct elf_program { u32 align; }; -s32 bin_load(const char *path, struct proc *proc); s32 elf_load(const char *path, struct proc *proc); #endif diff --git a/kernel/inc/mm.h b/kernel/inc/mm.h index 5a307b2..e506331 100644 --- a/kernel/inc/mm.h +++ b/kernel/inc/mm.h @@ -112,6 +112,7 @@ void memory_backup_dir(struct page_dir **backup); // Bypass should almost never be used void memory_bypass_enable(void); void memory_bypass_disable(void); +u8 memory_is_user(u32 addr); u8 memory_valid(const void *addr); void memory_install(struct mem_info *mem_info, struct vid_info *vid_info); |