diff --git a/kernel-src/arch/x86-64/cpu.c b/kernel-src/arch/x86-64/cpu.c index 2d60115e..34670acb 100644 --- a/kernel-src/arch/x86-64/cpu.c +++ b/kernel-src/arch/x86-64/cpu.c @@ -17,6 +17,7 @@ static bool has_smap; static bool has_smap_detected; +static bool has_smep; void arch_syscall_entry(); static void illisr(isr_t *self, context_t *ctx) { @@ -79,6 +80,7 @@ static void enable_smep_if_available(void) { asm volatile("mov %%cr4, %0" : "=r"(cr4)); cr4 |= CR4_SMEP; asm volatile("mov %0, %%cr4" : : "r"(cr4) : "memory"); + has_smep = true; } static bool detect_smap(void) { @@ -115,6 +117,14 @@ void arch_cpu_user_access_end(void) { asm volatile("clac" : : : "memory"); } +bool arch_cpu_smep_enabled(void) { + return has_smep; +} + +bool arch_cpu_smap_enabled(void) { + return has_smap; +} + void arch_nmi_isr(context_t *ctx) { // we are in an NMI context, running on IST0 // first load the proper gsbase to get access to cpu-local variables. diff --git a/kernel-src/arch/x86-64/mmu.c b/kernel-src/arch/x86-64/mmu.c index 928b62e1..89ca9a5a 100644 --- a/kernel-src/arch/x86-64/mmu.c +++ b/kernel-src/arch/x86-64/mmu.c @@ -324,8 +324,14 @@ static volatile struct limine_executable_address_request kaddrreq = { #define ERROR_FETCH 16 static void pfisr(isr_t *self, context_t *ctx) { - if ((ctx->rflags & ARCH_CONTEXT_RFLAGS_AC) == 0 && IS_USER_ADDRESS((void *)ctx->cr2) && !IS_USER_ADDRESS((void *)ctx->rip)) { - _panic("SMAP/SMEP violation", ctx); + if (!ARCH_CONTEXT_ISUSER(ctx) && IS_USER_ADDRESS((void *)ctx->cr2)) { + if ((ctx->error & ERROR_FETCH) && arch_cpu_smep_enabled()) { + _panic("SMEP violation", ctx); + } + + if ((ctx->error & ERROR_FETCH) == 0 && (ctx->rflags & ARCH_CONTEXT_RFLAGS_AC) == 0 && arch_cpu_smap_enabled()) { + _panic("SMAP violation", ctx); + } } thread_t *thread = current_thread(); diff --git a/kernel-src/include/x86-64/arch/cpu.h b/kernel-src/include/x86-64/arch/cpu.h index 14f23555..3f239c2a 100644 --- a/kernel-src/include/x86-64/arch/cpu.h +++ b/kernel-src/include/x86-64/arch/cpu.h @@ -116,6 +116,8 @@ static inline uint16_t be_to_cpu_w(uint16_t w) { cpu_t *get_bsp(void); void arch_cpu_user_access_begin(void); void arch_cpu_user_access_end(void); +bool arch_cpu_smep_enabled(void); +bool arch_cpu_smap_enabled(void); static inline thread_t *current_thread(void) { thread_t *thread; diff --git a/recipes/astral b/recipes/astral index 6e3a54e1..a738d414 100644 --- a/recipes/astral +++ b/recipes/astral @@ -1,5 +1,5 @@ name=astral -revision=5 +revision=6 from_source=astral imagedeps="build-essential nasm" hostdeps="xgcc xbinutils limine"