From 6e9b4491a6846703a113be1660fa98acfd09ee80 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 7 Jan 2023 00:17:16 +0100 Subject: [PATCH] MemoryManager: Add copy_to_user() and copy_to_user_typed() --- kernel/src/memory/MemoryManager.cpp | 29 +++++++++++++++++++++++++++++ kernel/src/memory/MemoryManager.h | 7 +++++++ 2 files changed, 36 insertions(+) diff --git a/kernel/src/memory/MemoryManager.cpp b/kernel/src/memory/MemoryManager.cpp index 9a834af2..5c73c96a 100644 --- a/kernel/src/memory/MemoryManager.cpp +++ b/kernel/src/memory/MemoryManager.cpp @@ -364,6 +364,35 @@ namespace MemoryManager return true; } + bool copy_to_user(void* user, const void* kernel, usize size) + { + uintptr_t user_ptr = (uintptr_t)user; + uintptr_t user_page = align_down(user_ptr); + + const char* kernel_ptr = (const char*)kernel; + + // Userspace pointer not aligned on page boundary + if (user_ptr != user_page) + { + // FIXME: Validate that this page is writable by the user, not just the kernel. + if (!validate_writable_page(user_page)) return false; + } + + while (size--) + { + // Crossed a page boundary, gotta check the page tables again before touching any memory!! + if (user_ptr % ARCH_PAGE_SIZE) + { + if (!validate_writable_page(user_ptr)) return false; + } + + *(char*)user_ptr = *kernel_ptr++; + user_ptr++; + } + + return true; + } + usize free() { return free_mem; diff --git a/kernel/src/memory/MemoryManager.h b/kernel/src/memory/MemoryManager.h index b2f72a84..6ce8d001 100644 --- a/kernel/src/memory/MemoryManager.h +++ b/kernel/src/memory/MemoryManager.h @@ -22,6 +22,13 @@ namespace MemoryManager bool validate_userspace_string(u64 address); + bool copy_to_user(void* user, const void* kernel, usize size); + + template bool copy_to_user_typed(T* user, const T* kernel) + { + return copy_to_user(user, kernel, sizeof(T)); + } + Result map_frames_at(u64 virt, u64 phys, usize count, int flags); Result alloc_at(u64 virt, usize count, int flags);