kernel: support for Intel SMAP and SMEP on x86_64.

SMAP will generated page faults when the kernel tries to access user pages unless overriden.
If SMAP is enabled, the override instructions are written where needed in memory with
binary "altcodepatches".
Support is enabled by default, might be disabled per safemode setting.

Change-Id: Ife26cd765056aeaf65b2ffa3cadd0dcf4e273a96
This commit is contained in:
Jérôme Duval
2018-01-30 20:05:39 +00:00
parent 43e75989a6
commit 9dd4d2dd05
19 changed files with 214 additions and 15 deletions
@@ -1,4 +1,5 @@
/*
* Copyright 2018, Jérôme Duval, [email protected].
* Copyright 2014, Paweł Dziepak, [email protected].
* Distributed under the terms of the MIT License.
*/
@@ -50,7 +51,9 @@ bool user_access(Function function)
// destructor.
auto fail = setjmp(thread_get_current_thread()->fault_handler_state);
if (fail == 0) {
set_ac();
function();
clear_ac();
return true;
}
return false;
@@ -20,6 +20,10 @@
#define ASM_NOP9 .byte 0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00
#define ALTCODEPATCH_TAG_STAC 1
#define ALTCODEPATCH_TAG_CLAC 2
#ifdef _ASSEMBLER
#define CODEPATCH_START 990:
@@ -30,6 +34,14 @@
.short tag ; \
.popsection
#define ASM_STAC CODEPATCH_START \
ASM_NOP3 ; \
CODEPATCH_END(ALTCODEPATCH_TAG_STAC)
#define ASM_CLAC CODEPATCH_START \
ASM_NOP3 ; \
CODEPATCH_END(ALTCODEPATCH_TAG_CLAC)
#else
#define _STRINGIFY(x...) #x
@@ -43,6 +55,15 @@
".short " STRINGIFY(tag) " \n" \
".popsection"
#define ASM_STAC CODEPATCH_START \
STRINGIFY(ASM_NOP3) "\n" \
CODEPATCH_END(ALTCODEPATCH_TAG_STAC)
#define ASM_CLAC CODEPATCH_START \
STRINGIFY(ASM_NOP3) "\n"\
CODEPATCH_END(ALTCODEPATCH_TAG_CLAC)
void arch_altcodepatch_replace(uint16 tag, void* newcodepatch, size_t length);
+19 -5
View File
@@ -17,6 +17,7 @@
#include <arch_thread_types.h>
#include <arch/x86/arch_altcodepatch.h>
#include <arch/x86/descriptors.h>
#ifdef __x86_64__
@@ -272,10 +273,6 @@
#define IA32_FEATURE_AMD_EXT_IBPB (1 << 12) /* IBPB Support only (no IBRS) */
// cr4 flags
#define IA32_CR4_PAE (1UL << 5)
#define IA32_CR4_GLOBAL_PAGES (1UL << 7)
// Memory type ranges
#define IA32_MTR_UNCACHED 0
#define IA32_MTR_WRITE_COMBINING 1
@@ -299,7 +296,7 @@
#define X86_EFLAGS_NESTED_TASK 0x00004000
#define X86_EFLAGS_RESUME 0x00010000
#define X86_EFLAGS_V86_MODE 0x00020000
#define X86_EFLAGS_ALIGNMENT_CHECK 0x00040000
#define X86_EFLAGS_ALIGNMENT_CHECK 0x00040000 // also SMAP status
#define X86_EFLAGS_VIRTUAL_INTERRUPT 0x00080000
#define X86_EFLAGS_VIRTUAL_INTERRUPT_PENDING 0x00100000
#define X86_EFLAGS_ID 0x00200000
@@ -313,9 +310,20 @@
#define CR0_FPU_EMULATION (1UL << 2)
#define CR0_MONITOR_FPU (1UL << 1)
// cr4 flags
#define IA32_CR4_PAE (1UL << 5)
#define IA32_CR4_GLOBAL_PAGES (1UL << 7)
#define CR4_OS_FXSR (1UL << 9)
#define CR4_OS_XMM_EXCEPTION (1UL << 10)
#define IA32_CR4_SMEP (1UL << 20)
#define IA32_CR4_SMAP (1UL << 21)
// page fault error codes (http://wiki.osdev.org/Page_Fault)
#define PGFAULT_P 0x01 // Protection violation
#define PGFAULT_W 0x02 // Write
#define PGFAULT_U 0x04 // Usermode
#define PGFAULT_RSVD 0x08 // Reserved bits
#define PGFAULT_I 0x10 // Instruction fetch
// iframe types
#define IFRAME_TYPE_SYSCALL 0x1
@@ -461,6 +469,12 @@ typedef struct arch_cpu_info {
#define wbinvd() \
__asm__("wbinvd")
#define set_ac() \
__asm__ volatile (ASM_STAC : : : "memory")
#define clear_ac() \
__asm__ volatile (ASM_CLAC : : : "memory")
#define out8(value,port) \
__asm__ ("outb %%al,%%dx" : : "a" (value), "d" (port))
+1
View File
@@ -12,6 +12,7 @@
#define B_SAFEMODE_DISABLE_ACPI "disable_acpi"
#define B_SAFEMODE_DISABLE_APIC "disable_apic"
#define B_SAFEMODE_ENABLE_X2APIC "enable_x2apic"
#define B_SAFEMODE_DISABLE_SMEP_SMAP "disable_smep_smap"
#define B_SAFEMODE_DISABLE_APM "disable_apm"
#define B_SAFEMODE_DISABLE_SMP "disable_smp"
#define B_SAFEMODE_DISABLE_HYPER_THREADING "disable_hyperthreading"