aboutsummaryrefslogtreecommitdiff
path: root/kernel/features
diff options
context:
space:
mode:
authorMarvin Borner2021-03-20 21:55:52 +0100
committerMarvin Borner2021-03-20 21:55:52 +0100
commit535018ae7247ede06606e4d8aced2d12c761f28f (patch)
tree7713c8e02ca26b2a51370e26cbc2a37437c53179 /kernel/features
parent5132bac014d63331acf61bb60b9254023f76b869 (diff)
Reimplemented memory range validation
Diffstat (limited to 'kernel/features')
-rw-r--r--kernel/features/load.c59
-rw-r--r--kernel/features/mm.c13
-rw-r--r--kernel/features/proc.c3
3 files changed, 22 insertions, 53 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);