1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 18:47:34 +00:00

Kernel: Enable x86 UMIP (User Mode Instruction Prevention) if supported

This prevents code running outside of kernel mode from using the
following instructions:

* SGDT - Store Global Descriptor Table
* SIDT - Store Interrupt Descriptor Table
* SLDT - Store Local Descriptor Table
* SMSW - Store Machine Status Word
* STR - Store Task Register

There's no need for userspace to be able to use these instructions so
let's just disable them to prevent information leakage.
This commit is contained in:
Andreas Kling 2020-01-01 13:02:32 +01:00
parent 5aeaab601e
commit 9c0836ce97
5 changed files with 23 additions and 1 deletions

View file

@ -32,6 +32,7 @@ kinds of crashes.
* `-x`: Read from recently freed memory. (Tests an opportunistic malloc guard.) * `-x`: Read from recently freed memory. (Tests an opportunistic malloc guard.)
* `-y`: Write to recently freed memory. (Tests an opportunistic malloc guard.) * `-y`: Write to recently freed memory. (Tests an opportunistic malloc guard.)
* `-X`: Attempt to execute non-executable memory. (Not mapped with PROT\_EXEC.) * `-X`: Attempt to execute non-executable memory. (Not mapped with PROT\_EXEC.)
* `-U`: Attempt to trigger an x86 User Mode Instruction Prevention fault.
## Examples ## Examples

View file

@ -549,6 +549,7 @@ bool g_cpu_supports_pae;
bool g_cpu_supports_pge; bool g_cpu_supports_pge;
bool g_cpu_supports_smep; bool g_cpu_supports_smep;
bool g_cpu_supports_sse; bool g_cpu_supports_sse;
bool g_cpu_supports_umip;
void detect_cpu_features() void detect_cpu_features()
{ {
@ -562,4 +563,5 @@ void detect_cpu_features()
CPUID extended_features(0x7); CPUID extended_features(0x7);
g_cpu_supports_smep = (extended_features.ebx() & (1 << 7)); g_cpu_supports_smep = (extended_features.ebx() & (1 << 7));
g_cpu_supports_umip = (extended_features.ecx() & (1 << 2));
} }

View file

@ -513,3 +513,4 @@ extern bool g_cpu_supports_pae;
extern bool g_cpu_supports_pge; extern bool g_cpu_supports_pge;
extern bool g_cpu_supports_smep; extern bool g_cpu_supports_smep;
extern bool g_cpu_supports_sse; extern bool g_cpu_supports_sse;
extern bool g_cpu_supports_umip;

View file

@ -258,6 +258,14 @@ extern "C" [[noreturn]] void init(u32 physical_address_for_kernel_page_tables)
kprintf("x86: SSE support enabled\n"); kprintf("x86: SSE support enabled\n");
} }
if (g_cpu_supports_umip) {
asm volatile(
"mov %cr4, %eax\n"
"orl $0x800, %eax\n"
"mov %eax, %cr4\n");
kprintf("x86: UMIP support enabled\n");
}
RTC::initialize(); RTC::initialize();
PIC::initialize(); PIC::initialize();
gdt_init(); gdt_init();

View file

@ -10,7 +10,7 @@
static void print_usage_and_exit() static void print_usage_and_exit()
{ {
printf("usage: crash -[AsdiamfMFTtSxyX]\n"); printf("usage: crash -[AsdiamfMFTtSxyXU]\n");
exit(0); exit(0);
} }
@ -98,6 +98,7 @@ int main(int argc, char** argv)
WriteToFreedMemoryStillCachedByMalloc, WriteToFreedMemoryStillCachedByMalloc,
ReadFromFreedMemoryStillCachedByMalloc, ReadFromFreedMemoryStillCachedByMalloc,
ExecuteNonExecutableMemory, ExecuteNonExecutableMemory,
TriggerUserModeInstructionPrevention,
}; };
Mode mode = SegmentationViolation; Mode mode = SegmentationViolation;
@ -136,6 +137,8 @@ int main(int argc, char** argv)
mode = WriteToFreedMemoryStillCachedByMalloc; mode = WriteToFreedMemoryStillCachedByMalloc;
else if (String(argv[1]) == "-X") else if (String(argv[1]) == "-X")
mode = ExecuteNonExecutableMemory; mode = ExecuteNonExecutableMemory;
else if (String(argv[1]) == "-U")
mode = TriggerUserModeInstructionPrevention;
else else
print_usage_and_exit(); print_usage_and_exit();
@ -320,6 +323,13 @@ int main(int argc, char** argv)
}).run(run_type); }).run(run_type);
} }
if (mode == TriggerUserModeInstructionPrevention || mode == TestAllCrashTypes) {
Crash("Trigger x86 User Mode Instruction Prevention", []() {
asm volatile("str %eax");
return Crash::Failure::DidNotCrash;
}).run(run_type);
}
return 0; return 0;
} }