diff options
author | Marvin Borner | 2021-04-03 14:04:23 +0200 |
---|---|---|
committer | Marvin Borner | 2021-04-03 14:04:23 +0200 |
commit | 394ee169ea6eb4dd5c8fa778d1c2769e26e52f01 (patch) | |
tree | 70440fb0d9eeb09e1aeec7eba6f2319d34b4918c /kernel/drivers | |
parent | ce98400f8a9ebd4e62e76b9e292b7598d0d66cc0 (diff) |
Enabled SMAP/SMEP protections
Diffstat (limited to 'kernel/drivers')
-rw-r--r-- | kernel/drivers/cpu.c | 112 | ||||
-rw-r--r-- | kernel/drivers/fb.c | 3 | ||||
-rw-r--r-- | kernel/drivers/keyboard.c | 2 | ||||
-rw-r--r-- | kernel/drivers/mouse.c | 2 |
4 files changed, 79 insertions, 40 deletions
diff --git a/kernel/drivers/cpu.c b/kernel/drivers/cpu.c index 774d9f7..86ae2be 100644 --- a/kernel/drivers/cpu.c +++ b/kernel/drivers/cpu.c @@ -1,8 +1,10 @@ // MIT License, Copyright (c) 2020 Marvin Borner // This file is a wrapper around some CPU asm calls +#include <assert.h> #include <cpu.h> #include <def.h> +#include <mem.h> #include <print.h> u8 inb(u16 port) @@ -41,26 +43,6 @@ void outl(u16 port, u32 data) __asm__ volatile("outl %0, %1" ::"a"(data), "Nd"(port)); } -CLEAR static void cpuid(int code, u32 *a, u32 *b, u32 *c, u32 *d) -{ - __asm__ volatile("cpuid" : "=a"(*a), "=b"(*b), "=c"(*c), "=d"(*d) : "a"(code)); -} - -CLEAR static char *cpu_string(char buf[16]) -{ - // wtf - cpuid(CPUID_VENDOR_STRING, (u32 *)(buf + 12), (u32 *)(buf), (u32 *)(buf + 8), - (u32 *)(buf + 4)); - - return buf; -} - -CLEAR void cpu_print(void) -{ - char buf[16] = { 0 }; - printf("CPU vendor: %s\n", cpu_string(buf)); -} - CLEAR u32 cr0_get(void) { u32 cr0; @@ -97,18 +79,6 @@ CLEAR void cr4_set(u32 cr4) __asm__ volatile("movl %%eax, %%cr4" ::"a"(cr4)); } -static u32 cpu_cfeatures = 0; -u8 cpu_has_cfeature(enum cpuid_features feature) -{ - return (cpu_cfeatures & feature) != 0; -} - -static u32 cpu_dfeatures = 0; -u8 cpu_has_dfeature(enum cpuid_features feature) -{ - return (cpu_dfeatures & feature) != 0; -} - static void fpu_handler(struct regs *r) { UNUSED(r); @@ -121,13 +91,44 @@ void fpu_restore(void) __asm__ volatile("fxrstor (%0)" ::"r"(fpu_state)); } -CLEAR void cpu_enable_features(void) +CLEAR static struct cpuid cpuid(u32 code) { u32 a, b, c, d; - cpuid(CPUID_FEATURES, &a, &b, &c, &d); - cpu_cfeatures = c; - cpu_dfeatures = d; - if (cpu_has_dfeature(CPUID_FEAT_EDX_SSE)) { + __asm__ volatile("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "a"(code), "c"(0)); + return (struct cpuid){ a, b, c, d }; +} + +CLEAR static char *cpu_string(char buf[16]) +{ + // wtf + struct cpuid id = cpuid(CPUID_VENDOR_STRING); + memcpy((u32 *)(buf + 12), &id.eax, 4); + memcpy((u32 *)(buf + 0), &id.ebx, 4); + memcpy((u32 *)(buf + 8), &id.ecx, 4); + memcpy((u32 *)(buf + 4), &id.edx, 4); + return buf; +} + +CLEAR void cpu_print(void) +{ + char buf[16] = { 0 }; + printf("CPU vendor: %s\n", cpu_string(buf)); +} + +PROTECTED struct cpuid cpu_features = { 0 }; +PROTECTED struct cpuid cpu_extended_information = { 0 }; +PROTECTED struct cpuid cpu_extended_features = { 0 }; + +CLEAR void cpu_enable_features(void) +{ + cpu_features = cpuid(CPUID_FEATURES); + u32 max = cpuid(0x80000000).eax; + assert(max >= 0x80000001); + cpu_extended_information = cpuid(0x80000001); + cpu_extended_features = cpuid(0x7); + + // Enable SSE + if (cpu_features.edx & CPUID_FEAT_EDX_SSE) { cr0_set(cr0_get() & ~(1 << 2)); cr0_set(cr0_get() | (1 << 1)); cr4_set(cr4_get() | (3 << 9)); @@ -135,13 +136,48 @@ CLEAR void cpu_enable_features(void) panic("No SSE support!\n"); } - if (cpu_has_dfeature(CPUID_FEAT_EDX_FPU)) { + // Enable FPU + if (cpu_features.edx & CPUID_FEAT_EDX_FPU) { __asm__ volatile("fninit"); __asm__ volatile("fxsave %0" : "=m"(fpu_state)); irq_install_handler(7, fpu_handler); } else { panic("No FPU support!\n"); } + + // Enable NX (IA32_EFER.NXE) + if (cpu_extended_information.edx & CPUID_EXT_INFO_EDX_NX) { + __asm__ volatile("movl $0xc0000080, %ecx\n" + "rdmsr\n" + "orl $0x800, %eax\n" + "wrmsr\n"); + } else { + print("No NX support :(\n"); + } + + // Enable SMEP + if (cpu_extended_features.ebx & CPUID_EXT_FEAT_EBX_SMEP) { + cr4_set(cr4_get() | 0x100000); + } else { + print("No SMEP support :(\n"); + } + + // Enable SMAP + if (cpu_extended_features.ebx & CPUID_EXT_FEAT_EBX_SMAP) { + cr4_set(cr4_get() | 0x200000); + } else { + print("No SMAP support :(\n"); + } +} + +void clac(void) +{ + __asm__ volatile("clac" ::: "cc"); +} + +void stac(void) +{ + __asm__ volatile("stac" ::: "cc"); } CLEAR void cli(void) diff --git a/kernel/drivers/fb.c b/kernel/drivers/fb.c index 577debf..3e333e8 100644 --- a/kernel/drivers/fb.c +++ b/kernel/drivers/fb.c @@ -1,6 +1,7 @@ // MIT License, Copyright (c) 2021 Marvin Borner #include <assert.h> +#include <cpu.h> #include <def.h> #include <errno.h> #include <fb.h> @@ -44,7 +45,9 @@ static res fb_ioctl(u32 request, void *arg1, void *arg2, void *arg3, struct devi else fb_owner = proc_current()->pid; + stac(); memcpy(arg1, info->vbe, sizeof(struct vbe_basic)); + clac(); fb_map_buffer(proc_current()->page_dir, info); return EOK; } diff --git a/kernel/drivers/keyboard.c b/kernel/drivers/keyboard.c index b917e4e..95b8a21 100644 --- a/kernel/drivers/keyboard.c +++ b/kernel/drivers/keyboard.c @@ -68,7 +68,7 @@ static res keyboard_read(void *buf, u32 offset, u32 count, struct device *dev) return -EINVAL; struct event_keyboard *e = stack_pop(queue); - memcpy(buf, (u8 *)e + offset, MIN(count, sizeof(*e))); + memcpy_user(buf, (u8 *)e + offset, MIN(count, sizeof(*e))); free(e); return MIN(count, sizeof(*e)); } diff --git a/kernel/drivers/mouse.c b/kernel/drivers/mouse.c index eb05d08..0440057 100644 --- a/kernel/drivers/mouse.c +++ b/kernel/drivers/mouse.c @@ -95,7 +95,7 @@ static res mouse_read(void *buf, u32 offset, u32 count, struct device *dev) return -EINVAL; struct event_mouse *e = stack_pop(queue); - memcpy(buf, (u8 *)e + offset, MIN(count, sizeof(*e))); + memcpy_user(buf, (u8 *)e + offset, MIN(count, sizeof(*e))); free(e); return MIN(count, sizeof(*e)); } |