kernel: Make the stack and loaded program code regions persistent
All checks were successful
continuous-integration/drone/push Build is passing
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:
parent
54a1998d42
commit
3d157b760c
@ -91,7 +91,7 @@ Result<u64> UserVM::alloc_region(usize count, bool persistent)
|
|||||||
return err(ENOMEM);
|
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);
|
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)
|
if (region->start >= address && region->end <= end)
|
||||||
{
|
{
|
||||||
region->used = used;
|
region->used = used;
|
||||||
|
region->persistent = persistent;
|
||||||
if (region->start == address && region->end == end)
|
if (region->start == address && region->end == end)
|
||||||
{
|
{
|
||||||
try_merge_region_with_neighbors(region);
|
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));
|
auto* middle_region = TRY(split_region(region, address));
|
||||||
TRY(split_region(middle_region, end));
|
TRY(split_region(middle_region, end));
|
||||||
middle_region->used = used;
|
middle_region->used = used;
|
||||||
|
middle_region->persistent = persistent;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,6 +135,7 @@ Result<bool> UserVM::set_region(u64 address, usize count, bool used)
|
|||||||
bool finished = region->end == end;
|
bool finished = region->end == end;
|
||||||
auto* split = TRY(split_region(region, address));
|
auto* split = TRY(split_region(region, address));
|
||||||
split->used = used;
|
split->used = used;
|
||||||
|
split->persistent = persistent;
|
||||||
try_merge_region_with_neighbors(split);
|
try_merge_region_with_neighbors(split);
|
||||||
if (!finished) continue;
|
if (!finished) continue;
|
||||||
return true;
|
return true;
|
||||||
@ -142,6 +145,7 @@ Result<bool> UserVM::set_region(u64 address, usize count, bool used)
|
|||||||
{
|
{
|
||||||
TRY(split_region(region, end));
|
TRY(split_region(region, end));
|
||||||
region->used = used;
|
region->used = used;
|
||||||
|
region->persistent = persistent;
|
||||||
try_merge_region_with_neighbors(region);
|
try_merge_region_with_neighbors(region);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -21,14 +21,14 @@ class UserVM
|
|||||||
|
|
||||||
Result<u64> alloc_region(usize count, bool persistent = false);
|
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)
|
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();
|
static Result<OwnedPtr<UserVM>> try_create();
|
||||||
@ -36,7 +36,7 @@ class UserVM
|
|||||||
Result<OwnedPtr<UserVM>> clone();
|
Result<OwnedPtr<UserVM>> clone();
|
||||||
|
|
||||||
private:
|
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_default_region();
|
||||||
Result<void> create_null_region();
|
Result<void> create_null_region();
|
||||||
void try_merge_region_with_neighbors(VMRegion* region);
|
void try_merge_region_with_neighbors(VMRegion* region);
|
||||||
|
@ -102,9 +102,8 @@ namespace ELFLoader
|
|||||||
if (can_write_segment(program_header.p_flags)) flags |= MMU::ReadWrite;
|
if (can_write_segment(program_header.p_flags)) flags |= MMU::ReadWrite;
|
||||||
if (can_execute_segment(program_header.p_flags)) flags &= ~MMU::NoExecute;
|
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(
|
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);
|
return err(ENOMEM);
|
||||||
|
|
||||||
// Allocate physical memory for the segment
|
// Allocate physical memory for the segment
|
||||||
|
@ -11,8 +11,7 @@ static Result<void> create_stacks(Stack& user_stack, Stack& kernel_stack, UserVM
|
|||||||
{
|
{
|
||||||
const u64 THREAD_STACK_BASE = 0x10000;
|
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, true))) return err(ENOMEM);
|
||||||
if (!TRY(vm->test_and_alloc_region(THREAD_STACK_BASE, DEFAULT_USER_STACK_PAGES))) return err(ENOMEM);
|
|
||||||
|
|
||||||
TRY(MemoryManager::alloc_at_zeroed(THREAD_STACK_BASE, DEFAULT_USER_STACK_PAGES,
|
TRY(MemoryManager::alloc_at_zeroed(THREAD_STACK_BASE, DEFAULT_USER_STACK_PAGES,
|
||||||
MMU::ReadWrite | MMU::NoExecute | MMU::User));
|
MMU::ReadWrite | MMU::NoExecute | MMU::User));
|
||||||
|
Loading…
Reference in New Issue
Block a user