Make kernel rodata and data not executable

This commit is contained in:
apio 2022-11-16 20:02:04 +01:00
parent 7f15ba0ac5
commit 7fc5a6b753
7 changed files with 82 additions and 4 deletions

View File

@ -31,7 +31,7 @@ target_compile_definitions(moon PRIVATE IN_MOON)
target_compile_options(moon PRIVATE -Os)
target_compile_options(moon PRIVATE -pedantic -Wall -Wextra -Werror -Wvla)
target_compile_options(moon PRIVATE -Wall -Wextra -Werror -Wvla)
target_compile_options(moon PRIVATE -Wdisabled-optimization -Wformat=2 -Winit-self)
target_compile_options(moon PRIVATE -Wmissing-include-dirs -Wswitch-default -Wcast-qual -Wundef)
target_compile_options(moon PRIVATE -Wcast-align -Wwrite-strings -Wlogical-op -Wredundant-decls -Wshadow -Wconversion)

View File

@ -16,13 +16,16 @@ SECTIONS
kernel_start = .;
.text : {
KEEP(*(.text.boot)) *(.text .text.*) /* code */
. = ALIGN(0x1000);
start_of_kernel_rodata = .;
*(.rodata .rodata.*) /* data */
*(.rodata .rodata.*) /* read-only data */
end_of_kernel_rodata = .;
. = ALIGN(0x1000);
start_of_kernel_data = .;
start_of_kernel_data = .; /* data */
*(.data .data.*)
} :boot
.bss (NOLOAD) : { /* bss */
*(.bss .bss.*)

View File

@ -24,4 +24,6 @@ void Init::early_init()
MemoryManager::init();
CPU::platform_init();
check(MemoryManager::protect_kernel_sections().has_value());
}

View File

@ -2,6 +2,7 @@
#include "arch/MMU.h"
#include "arch/Serial.h"
#include "bootboot.h"
#include <Alignment.h>
#include <String.h>
#include <Types.h>
@ -40,6 +41,17 @@ static void page_bitmap_set(u64 index, bool value)
namespace MemoryManager
{
Result<void> protect_kernel_sections()
{
u64 rodata_pages = get_blocks_from_size((u64)(end_of_kernel_rodata - start_of_kernel_rodata), MMU::page_size());
TRY(remap((u64)start_of_kernel_rodata, rodata_pages, MMU::NoExecute));
u64 data_pages = get_blocks_from_size((u64)(end_of_kernel_data - start_of_kernel_data), MMU::page_size());
TRY(remap((u64)start_of_kernel_data, data_pages, MMU::NoExecute | MMU::ReadWrite));
return {};
}
void init_physical_allocator()
{
u64 total_mem = 0;
@ -145,6 +157,33 @@ namespace MemoryManager
return {};
}
Result<void> remap(u64 address, size_t count, int flags)
{
check(is_aligned(address, MMU::page_size()));
while (count--)
{
TRY(MMU::remap(address, flags));
address += MMU::page_size();
}
return {};
}
Result<void> remap_unaligned(u64 address, size_t count, int flags)
{
if (!is_aligned(address, MMU::page_size())) count++;
address = align_down(address, MMU::page_size());
while (count--)
{
TRY(MMU::remap(address, flags));
address += MMU::page_size();
}
return {};
}
u64 free()
{
return free_mem;

View File

@ -6,12 +6,17 @@ namespace MemoryManager
{
void init();
Result<void> protect_kernel_sections();
Result<u64> alloc_physical_page();
Result<void> free_physical_page(u64 page);
void lock_page(u64 page);
void lock_pages(u64 pages, u64 count);
Result<void> remap(u64 address, size_t count, int flags);
Result<void> remap_unaligned(u64 address, size_t count, int flags);
u64 free();
u64 used();
u64 reserved();

22
luna/Alignment.h Normal file
View File

@ -0,0 +1,22 @@
#pragma once
template <typename T> constexpr T is_aligned(T value, T align_base)
{
return (value % align_base == 0);
}
template <typename T> constexpr T align_down(T value, T align_base)
{
return value - (value % align_base);
}
template <typename T> constexpr T align_up(T value, T align_base)
{
if (is_aligned(value, align_base)) return value;
return align_down(value, align_base) + align_base;
}
template <typename T> constexpr T get_blocks_from_size(T value, T block_size)
{
return (value + (block_size - 1)) / block_size;
}

View File

@ -237,3 +237,10 @@ template <> class Result<void>
// clang-format off
#define err Error{0}
// clang-format on
#define TRY(expr) \
({ \
auto _expr_rc = (expr); \
if (_expr_rc.has_error()) return _expr_rc.release_error(); \
_expr_rc.release_value(); \
})