소스 검색

Kernel: Enable x86 SMEP (Supervisor Mode Execution Protection)

This prevents the kernel from jumping to code in userspace memory.
Andreas Kling 5 년 전
부모
커밋
8602fa5b49
2개의 변경된 파일23개의 추가작업 그리고 2개의 파일을 삭제
  1. 21 2
      Kernel/VM/MemoryManager.cpp
  2. 2 0
      Kernel/VM/MemoryManager.h

+ 21 - 2
Kernel/VM/MemoryManager.cpp

@@ -21,10 +21,18 @@ MemoryManager& MM
     return *s_the;
 }
 
+void MemoryManager::detect_cpu_features()
+{
+    CPUID extended_processor_info(0x80000001);
+    m_has_nx_support = (extended_processor_info.edx() & (1 << 20)) != 0;
+
+    CPUID extended_features(0x7);
+    m_has_smep_support = (extended_features.ebx() & (1 << 7)) != 0;
+}
+
 MemoryManager::MemoryManager(u32 physical_address_for_kernel_page_tables)
 {
-    CPUID id(0x80000001);
-    m_has_nx_support = (id.edx() & (1 << 20)) != 0;
+    detect_cpu_features();
 
     m_kernel_page_directory = PageDirectory::create_at_fixed_address(PhysicalAddress(physical_address_for_kernel_page_tables));
     for (size_t i = 0; i < 4; ++i) {
@@ -185,6 +193,17 @@ void MemoryManager::initialize_paging()
         "orl $0x20, %eax\n"
         "mov %eax, %cr4\n");
 
+    if (m_has_smep_support) {
+        kprintf("MM: SMEP support detected; enabling\n");
+    // Turn on CR4.SMEP
+    asm volatile(
+        "mov %cr4, %eax\n"
+        "orl $0x100000, %eax\n"
+        "mov %eax, %cr4\n");
+    } else {
+        kprintf("MM: SMEP support not detected\n");
+    }
+
     if (m_has_nx_support) {
         kprintf("MM: NX support detected; enabling NXE flag\n");
 

+ 2 - 0
Kernel/VM/MemoryManager.h

@@ -90,6 +90,7 @@ private:
     void register_region(Region&);
     void unregister_region(Region&);
 
+    void detect_cpu_features();
     void initialize_paging();
     void flush_entire_tlb();
     void flush_tlb(VirtualAddress);
@@ -133,6 +134,7 @@ private:
 
     bool m_quickmap_in_use { false };
     bool m_has_nx_support { false };
+    bool m_has_smep_support { false };
 };
 
 struct ProcessPagingScope {