1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 00:57:36 +00:00

Kernel: Harden memory mapping of the kernel image

We now map the kernel's text and rodata segments read+execute.
We also make the data and bss segments non-executable.

Thanks to q3k for the idea! :^)
This commit is contained in:
Andreas Kling 2020-01-06 13:53:30 +01:00
parent 47cc3e68c6
commit 8e7420ddf2
2 changed files with 26 additions and 5 deletions

View file

@ -68,20 +68,35 @@ void MemoryManager::initialize_paging()
auto& pte = ensure_pte(kernel_page_directory(), VirtualAddress(i)); auto& pte = ensure_pte(kernel_page_directory(), VirtualAddress(i));
pte.set_execute_disabled(true); pte.set_execute_disabled(true);
} }
// Disable execution from 2MB through 8MB (kmalloc, kmalloc_eternal, slabs, page tables, ...)
for (size_t i = 1; i < 4; ++i) {
auto& pte = kernel_page_directory().table().directory(0)[i];
pte.set_execute_disabled(true);
}
} }
// Disable execution from 2MB through 8MB (kmalloc, kmalloc_eternal, slabs, page tables, ...) // Disable writing to the kernel text and rodata segments.
for (size_t i = 1; i < 4; ++i) { extern u32 start_of_kernel_text;
auto& pte = kernel_page_directory().table().directory(0)[i]; extern u32 start_of_kernel_data;
if (g_cpu_supports_nx) for (size_t i = (u32)&start_of_kernel_text; i < (u32)&start_of_kernel_data; i += PAGE_SIZE) {
auto& pte = ensure_pte(kernel_page_directory(), VirtualAddress(i));
pte.set_writable(false);
}
if (g_cpu_supports_nx) {
// Disable execution of the kernel data and bss segments.
extern u32 end_of_kernel_bss;
for (size_t i = (u32)&start_of_kernel_data; i < (u32)&end_of_kernel_bss; i += PAGE_SIZE) {
auto& pte = ensure_pte(kernel_page_directory(), VirtualAddress(i));
pte.set_execute_disabled(true); pte.set_execute_disabled(true);
}
} }
// FIXME: We should move everything kernel-related above the 0xc0000000 virtual mark. // FIXME: We should move everything kernel-related above the 0xc0000000 virtual mark.
// Basic physical memory map: // Basic physical memory map:
// 0 -> 1 MB We're just leaving this alone for now. // 0 -> 1 MB We're just leaving this alone for now.
// 1 -> 3 MB Kernel image. // 1 -> 2 MB Kernel image.
// (last page before 2MB) Used by quickmap_page(). // (last page before 2MB) Used by quickmap_page().
// 2 MB -> 4 MB kmalloc_eternal() space. // 2 MB -> 4 MB kmalloc_eternal() space.
// 4 MB -> 7 MB kmalloc() space. // 4 MB -> 7 MB kmalloc() space.

View file

@ -9,8 +9,10 @@ SECTIONS
Arch/i386/Boot/boot.ao Arch/i386/Boot/boot.ao
*(.multiboot) *(.multiboot)
*(.page_tables) *(.page_tables)
start_of_kernel_text = .;
*(.text) *(.text)
*(.text.startup) *(.text.startup)
end_of_kernel_text = .;
} }
.rodata BLOCK(4K) : ALIGN(4K) .rodata BLOCK(4K) : ALIGN(4K)
@ -24,12 +26,16 @@ SECTIONS
.data BLOCK(4K) : ALIGN(4K) .data BLOCK(4K) : ALIGN(4K)
{ {
start_of_kernel_data = .;
*(.data) *(.data)
end_of_kernel_data = .;
} }
.bss BLOCK(4K) : ALIGN(4K) .bss BLOCK(4K) : ALIGN(4K)
{ {
start_of_kernel_bss = .;
*(COMMON) *(COMMON)
*(.bss) *(.bss)
end_of_kernel_bss = .;
} }
} }