aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2021-04-04 00:11:00 +0200
committerMarvin Borner2021-04-04 00:11:00 +0200
commit7a64bdbbcf14023370b90b22de73c2f61a6f84ac (patch)
tree7f26778ddcd9f7e213f70e60e04c1805c4f2572f
parent9127d8e4d09207d5c9d98024ca6610310a7273ad (diff)
Implemented basic user program ASLR
-rw-r--r--apps/Makefile4
-rw-r--r--kernel/features/load.c28
-rw-r--r--kernel/features/mm.c2
-rw-r--r--kernel/main.c2
-rw-r--r--libs/libc/Makefile10
-rw-r--r--libs/libc/inc/random.h4
-rw-r--r--libs/libc/random.c48
-rw-r--r--libs/libgui/Makefile2
-rw-r--r--libs/libnet/Makefile2
-rw-r--r--libs/libtxt/Makefile2
10 files changed, 53 insertions, 51 deletions
diff --git a/apps/Makefile b/apps/Makefile
index c015d18..1afa879 100644
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -6,14 +6,14 @@ LD = ccache ../cross/opt/bin/i686-elf-ld
OC = ccache ../cross/opt/bin/i686-elf-objcopy
ST = ccache ../cross/opt/bin/i686-elf-strip
-CFLAGS = $(CFLAGS_DEFAULT) -I../libs/ -I../libs/libc/inc/ -DUSER
+CFLAGS = $(CFLAGS_DEFAULT) -I../libs/ -I../libs/libc/inc/ -pie -fPIE -fPIC -DUSER
all: $(COBJS)
%.o: %.c
@mkdir -p ../build/apps/
@$(CC) -c $(CFLAGS) $< -o $@
- @$(LD) -o $(@:.o=.elf) --section-start=.text=0x42000000 -L../build/ -static $@ -lgui -ltxt -lc
+ @$(LD) -o $(@:.o=.elf) --section-start=.text=0x42000000 -L../build/ -pie -no-dynamic-linker $@ -lgui -ltxt -lc
@cp $(@:.o=.elf) ../build/apps/$(@:.o=)
#@$(ST) --strip-all ../build/apps/$(@:.o=)
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();
diff --git a/libs/libc/Makefile b/libs/libc/Makefile
index 24970d8..cc1b836 100644
--- a/libs/libc/Makefile
+++ b/libs/libc/Makefile
@@ -1,7 +1,8 @@
# MIT License, Copyright (c) 2020 Marvin Borner
# TODO: Remove cpu from libc?
-COBJS = sanitize.o \
+COBJS = crt/crt0.o \
+ sanitize.o \
errno.o \
str.o \
alloc.o \
@@ -26,11 +27,12 @@ ASFLAGS = -f elf32
%.o: %.c
@$(CC) -c $(CFLAGS) $< -o $@
-libc: CFLAGS += -DUSER
+libc: CFLAGS += -pie -fPIE -fPIC -DUSER
libc: $(COBJS)
- @$(AS) $(ASFLAGS) crt/crt0.asm -o crt0.o
@mkdir -p ../../build/
- @$(AR) rcs ../../build/libc.a crt0.o $+
+ @$(AS) $(ASFLAGS) crt/crti.asm -o ../../build/crti.o
+ @$(AS) $(ASFLAGS) crt/crtn.asm -o ../../build/crtn.o
+ @$(AR) rcs ../../build/libc.a ../../build/crti.o ../../build/crti.o $+
libk: CFLAGS += -DKERNEL -ffreestanding -I../../kernel/inc/ $(CFLAGS_EXTRA)
libk: $(COBJS)
diff --git a/libs/libc/inc/random.h b/libs/libc/inc/random.h
index a82524c..6360625 100644
--- a/libs/libc/inc/random.h
+++ b/libs/libc/inc/random.h
@@ -5,9 +5,9 @@
#include <def.h>
+#define rand_range(min, max) (rand() % ((max) + 1 - (min)) + (min))
+
void srand(u32 seed);
-u32 rdrand(void);
-u32 rdseed(void);
u32 rand(void);
char *randstr(u32 size);
diff --git a/libs/libc/random.c b/libs/libc/random.c
index 6296407..983357f 100644
--- a/libs/libc/random.c
+++ b/libs/libc/random.c
@@ -15,46 +15,36 @@ void srand(u32 seed)
g_seed = seed;
}
-u32 rdrand(void)
+static u32 default_rand(void)
{
-#ifdef KERNEL
- if (!(cpu_features.ecx & CPUID_FEAT_ECX_RDRND))
- return rand();
-
- u32 rd;
- __asm__ volatile("1:\n"
- "rdrand %0\n"
- "jnc 1b\n"
- : "=r"(rd));
- return rd;
-#else
- return rand();
-#endif
+ g_seed = g_seed * 1103515245 + 12345;
+ return (g_seed >> 16) & 0x7FFF;
}
-u32 rdseed(void)
+u32 rand(void)
{
#ifdef KERNEL
- if (!(cpu_extended_features.ebx & CPUID_EXT_FEAT_EBX_RDSEED))
- return rand();
-
u32 rd;
- __asm__ volatile("1:\n"
- "rdseed %0\n"
- "jnc 1b\n"
- : "=r"(rd));
+ if (cpu_extended_features.ebx & CPUID_EXT_FEAT_EBX_RDSEED) {
+ __asm__ volatile("1:\n"
+ "rdseed %0\n"
+ "jnc 1b\n"
+ : "=r"(rd));
+ } else if (cpu_features.ecx & CPUID_FEAT_ECX_RDRND) {
+ __asm__ volatile("1:\n"
+ "rdrand %0\n"
+ "jnc 1b\n"
+ : "=r"(rd));
+ } else {
+ rd = default_rand();
+ }
+
return rd;
#else
- return rand();
+ return default_rand();
#endif
}
-u32 rand(void)
-{
- g_seed = g_seed * 1103515245 + 12345;
- return (g_seed >> 16) & 0x7FFF;
-}
-
char *randstr(u32 size)
{
if (!size)
diff --git a/libs/libgui/Makefile b/libs/libgui/Makefile
index e04b703..47e2556 100644
--- a/libs/libgui/Makefile
+++ b/libs/libgui/Makefile
@@ -10,7 +10,7 @@ CC = ccache ../../cross/opt/bin/i686-elf-gcc
LD = ccache ../../cross/opt/bin/i686-elf-ld
AR = ccache ../../cross/opt/bin/i686-elf-ar
-CFLAGS = $(CFLAGS_DEFAULT) -I../ -I../libc/inc/ -DUSER
+CFLAGS = $(CFLAGS_DEFAULT) -I../ -I../libc/inc/ -pie -fPIE -fPIC -DUSER
all: libgui
diff --git a/libs/libnet/Makefile b/libs/libnet/Makefile
index 69c899d..7094875 100644
--- a/libs/libnet/Makefile
+++ b/libs/libnet/Makefile
@@ -5,7 +5,7 @@ CC = ccache ../../cross/opt/bin/i686-elf-gcc
LD = ccache ../../cross/opt/bin/i686-elf-ld
AR = ccache ../../cross/opt/bin/i686-elf-ar
-CFLAGS = $(CFLAGS_DEFAULT) -I../ -I../libc/inc/ -DUSER
+CFLAGS = $(CFLAGS_DEFAULT) -I../ -I../libc/inc/ -pie -fPIE -fPIC -DUSER
all: libtxt
diff --git a/libs/libtxt/Makefile b/libs/libtxt/Makefile
index 6d06502..38fe01f 100644
--- a/libs/libtxt/Makefile
+++ b/libs/libtxt/Makefile
@@ -5,7 +5,7 @@ CC = ccache ../../cross/opt/bin/i686-elf-gcc
LD = ccache ../../cross/opt/bin/i686-elf-ld
AR = ccache ../../cross/opt/bin/i686-elf-ar
-CFLAGS = $(CFLAGS_DEFAULT) -I../ -I../libc/inc/ -DUSER
+CFLAGS = $(CFLAGS_DEFAULT) -I../ -I../libc/inc/ -pie -fPIE -fPIC -DUSER
all: libtxt