summaryrefslogtreecommitdiff
path: root/Kernel/VM
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-12-21 16:21:13 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-12-21 16:21:13 +0100
commitae2d72377dceb95eeaf4901b9371db71ab5b86ab (patch)
tree2eb5f9b63027631aee651cfa78b52aac25f6f85a /Kernel/VM
parent70865e5a5d74ad7039d5de9c63c76ef5fc992f91 (diff)
downloadserenity-ae2d72377dceb95eeaf4901b9371db71ab5b86ab.zip
Kernel: Enable the x86 WP bit to catch invalid memory writes in ring 0
Setting this bit will cause the CPU to generate a page fault when writing to read-only memory, even if we're executing in the kernel. Seemingly the only change needed to make this work was to have the inode-backed page fault handler use a temporary mapping for writing the read-from-disk data into the newly-allocated physical page.
Diffstat (limited to 'Kernel/VM')
-rw-r--r--Kernel/VM/MemoryManager.cpp2
-rw-r--r--Kernel/VM/Region.cpp7
2 files changed, 6 insertions, 3 deletions
diff --git a/Kernel/VM/MemoryManager.cpp b/Kernel/VM/MemoryManager.cpp
index b0bc7fbbe4..d69eb86f66 100644
--- a/Kernel/VM/MemoryManager.cpp
+++ b/Kernel/VM/MemoryManager.cpp
@@ -174,7 +174,7 @@ void MemoryManager::initialize_paging()
asm volatile("movl %%eax, %%cr3" ::"a"(kernel_page_directory().cr3()));
asm volatile(
"movl %%cr0, %%eax\n"
- "orl $0x80000001, %%eax\n"
+ "orl $0x80010001, %%eax\n"
"movl %%eax, %%cr0\n" ::
: "%eax", "memory");
diff --git a/Kernel/VM/Region.cpp b/Kernel/VM/Region.cpp
index 8a6c046625..225095f743 100644
--- a/Kernel/VM/Region.cpp
+++ b/Kernel/VM/Region.cpp
@@ -431,8 +431,11 @@ PageFaultResponse Region::handle_inode_fault(size_t page_index_in_region)
kprintf("MM: handle_inode_fault was unable to allocate a physical page\n");
return PageFaultResponse::ShouldCrash;
}
- remap_page(page_index_in_region);
- u8* dest_ptr = vaddr().offset(page_index_in_region * PAGE_SIZE).as_ptr();
+
+ u8* dest_ptr = MM.quickmap_page(*vmobject_physical_page_entry);
memcpy(dest_ptr, page_buffer, PAGE_SIZE);
+ MM.unquickmap_page();
+
+ remap_page(page_index_in_region);
return PageFaultResponse::Continue;
}