From 95659639e56a4162c2ff39b49df731390334dced Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 17 Apr 2023 20:11:07 +0200 Subject: [PATCH] kernel: Zero out allocated memory for userspace to avoid leaking sensitive data --- kernel/src/ELF.cpp | 2 +- kernel/src/memory/MemoryManager.cpp | 12 ++++++++++++ kernel/src/memory/MemoryManager.h | 1 + kernel/src/thread/ThreadImage.cpp | 2 +- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/kernel/src/ELF.cpp b/kernel/src/ELF.cpp index 226ca00b..350ac265 100644 --- a/kernel/src/ELF.cpp +++ b/kernel/src/ELF.cpp @@ -101,7 +101,7 @@ namespace ELFLoader if (can_execute_segment(program_header.p_flags)) flags &= ~MMU::NoExecute; // Allocate physical memory for the segment - TRY(MemoryManager::alloc_at( + TRY(MemoryManager::alloc_at_zeroed( base_vaddr, get_blocks_from_size(program_header.p_memsz + vaddr_diff, ARCH_PAGE_SIZE), flags)); // Load the file section of the segment diff --git a/kernel/src/memory/MemoryManager.cpp b/kernel/src/memory/MemoryManager.cpp index 8cf7fddb..8017277c 100644 --- a/kernel/src/memory/MemoryManager.cpp +++ b/kernel/src/memory/MemoryManager.cpp @@ -261,6 +261,18 @@ namespace MemoryManager return start; } + Result alloc_at_zeroed(u64 virt, usize count, int flags) + { + u64 address = TRY(alloc_at(virt, count, MMU::ReadWrite)); + + memset((void*)address, 0, count * ARCH_PAGE_SIZE); + + remap(address, count, flags) + .expect_value("Wait... we just mapped something but it doesn't exist anymore? Confused."); + + return address; + } + Result alloc_for_kernel(usize count, int flags) { const u64 start = TRY(KernelVM::alloc_several_pages(count)); diff --git a/kernel/src/memory/MemoryManager.h b/kernel/src/memory/MemoryManager.h index c22f0c2e..673f4e1c 100644 --- a/kernel/src/memory/MemoryManager.h +++ b/kernel/src/memory/MemoryManager.h @@ -59,6 +59,7 @@ namespace MemoryManager Result map_huge_frames_at(u64 virt, u64 phys, usize count, int flags); Result alloc_at(u64 virt, usize count, int flags); + Result alloc_at_zeroed(u64, usize count, int flags); Result alloc_for_kernel(usize count, int flags); Result get_kernel_mapping_for_frames(u64 phys, usize count, int flags); diff --git a/kernel/src/thread/ThreadImage.cpp b/kernel/src/thread/ThreadImage.cpp index 31d46b1f..19692d70 100644 --- a/kernel/src/thread/ThreadImage.cpp +++ b/kernel/src/thread/ThreadImage.cpp @@ -7,7 +7,7 @@ static Result create_stacks(Stack& user_stack, Stack& kernel_stack) { const u64 THREAD_STACK_BASE = 0x10000; - TRY(MemoryManager::alloc_at(THREAD_STACK_BASE, 4, MMU::ReadWrite | MMU::NoExecute | MMU::User)); + TRY(MemoryManager::alloc_at_zeroed(THREAD_STACK_BASE, 4, MMU::ReadWrite | MMU::NoExecute | MMU::User)); auto guard = make_scope_guard([&] { MemoryManager::unmap_owned(THREAD_STACK_BASE, 4); });