aboutsummaryrefslogtreecommitdiff
path: root/kernel/features
diff options
context:
space:
mode:
authorMarvin Borner2021-04-02 23:26:28 +0200
committerMarvin Borner2021-04-02 23:26:28 +0200
commitce98400f8a9ebd4e62e76b9e292b7598d0d66cc0 (patch)
tree823f06c2c325ead611863eeb3ac974c1ae562878 /kernel/features
parentfe468b476d567b6aa0695a030c408ccf46278c7d (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.c10
-rw-r--r--kernel/features/mm.c47
-rw-r--r--kernel/features/proc.c14
-rw-r--r--kernel/features/syscall.c5
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);