kernel: Make the stack and loaded program code regions persistent
All checks were successful
continuous-integration/drone/push Build is passing

This way, they can't be modified by mmap() or munmap().
This commit is contained in:
apio 2023-06-19 12:44:49 +02:00
parent 54a1998d42
commit 3d157b760c
Signed by: apio
GPG Key ID: B8A7D06E42258954
4 changed files with 11 additions and 9 deletions

View File

@ -91,7 +91,7 @@ Result<u64> UserVM::alloc_region(usize count, bool persistent)
return err(ENOMEM);
}
Result<bool> UserVM::set_region(u64 address, usize count, bool used)
Result<bool> UserVM::set_region(u64 address, usize count, bool used, bool persistent)
{
if (address >= VM_END) return err(EINVAL);
@ -112,6 +112,7 @@ Result<bool> UserVM::set_region(u64 address, usize count, bool used)
if (region->start >= address && region->end <= end)
{
region->used = used;
region->persistent = persistent;
if (region->start == address && region->end == end)
{
try_merge_region_with_neighbors(region);
@ -125,6 +126,7 @@ Result<bool> UserVM::set_region(u64 address, usize count, bool used)
auto* middle_region = TRY(split_region(region, address));
TRY(split_region(middle_region, end));
middle_region->used = used;
middle_region->persistent = persistent;
return true;
}
@ -133,6 +135,7 @@ Result<bool> UserVM::set_region(u64 address, usize count, bool used)
bool finished = region->end == end;
auto* split = TRY(split_region(region, address));
split->used = used;
split->persistent = persistent;
try_merge_region_with_neighbors(split);
if (!finished) continue;
return true;
@ -142,6 +145,7 @@ Result<bool> UserVM::set_region(u64 address, usize count, bool used)
{
TRY(split_region(region, end));
region->used = used;
region->persistent = persistent;
try_merge_region_with_neighbors(region);
return true;
}

View File

@ -21,14 +21,14 @@ class UserVM
Result<u64> alloc_region(usize count, bool persistent = false);
Result<bool> test_and_alloc_region(u64 address, usize count)
Result<bool> test_and_alloc_region(u64 address, usize count, bool persistent = false)
{
return set_region(address, count, true);
return set_region(address, count, true, persistent);
}
Result<bool> free_region(u64 address, usize count)
{
return set_region(address, count, false);
return set_region(address, count, false, false);
}
static Result<OwnedPtr<UserVM>> try_create();
@ -36,7 +36,7 @@ class UserVM
Result<OwnedPtr<UserVM>> clone();
private:
Result<bool> set_region(u64 address, usize count, bool used);
Result<bool> set_region(u64 address, usize count, bool used, bool persistent);
Result<void> create_default_region();
Result<void> create_null_region();
void try_merge_region_with_neighbors(VMRegion* region);

View File

@ -102,9 +102,8 @@ namespace ELFLoader
if (can_write_segment(program_header.p_flags)) flags |= MMU::ReadWrite;
if (can_execute_segment(program_header.p_flags)) flags &= ~MMU::NoExecute;
// FIXME: Set this memory range to persistent so that munmap() cannot remove it.
if (!TRY(vm->test_and_alloc_region(
base_vaddr, get_blocks_from_size(program_header.p_memsz + vaddr_diff, ARCH_PAGE_SIZE))))
base_vaddr, get_blocks_from_size(program_header.p_memsz + vaddr_diff, ARCH_PAGE_SIZE), true)))
return err(ENOMEM);
// Allocate physical memory for the segment

View File

@ -11,8 +11,7 @@ static Result<void> create_stacks(Stack& user_stack, Stack& kernel_stack, UserVM
{
const u64 THREAD_STACK_BASE = 0x10000;
// FIXME: Set this memory range to persistent so that munmap() cannot remove it.
if (!TRY(vm->test_and_alloc_region(THREAD_STACK_BASE, DEFAULT_USER_STACK_PAGES))) return err(ENOMEM);
if (!TRY(vm->test_and_alloc_region(THREAD_STACK_BASE, DEFAULT_USER_STACK_PAGES, true))) return err(ENOMEM);
TRY(MemoryManager::alloc_at_zeroed(THREAD_STACK_BASE, DEFAULT_USER_STACK_PAGES,
MMU::ReadWrite | MMU::NoExecute | MMU::User));