From 5c51b82f6a4b8a8988c49049ec8951a8e86d9b4a Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 12 Nov 2022 12:08:26 +0100 Subject: [PATCH] Kernel: Remove obtain_user_ref and add copy_typed_to and from_user --- kernel/include/sys/UserMemory.h | 29 ++++------------------------- kernel/src/sys/clock.cpp | 25 +++++++++---------------- kernel/src/sys/dirent.cpp | 17 ++++++++--------- kernel/src/sys/stat.cpp | 32 ++++++++++++++------------------ 4 files changed, 35 insertions(+), 68 deletions(-) diff --git a/kernel/include/sys/UserMemory.h b/kernel/include/sys/UserMemory.h index 8d33e861..fca1c034 100644 --- a/kernel/include/sys/UserMemory.h +++ b/kernel/include/sys/UserMemory.h @@ -19,33 +19,12 @@ bool validate_user_write(uintptr_t address, size_t size); bool copy_from_user(const void* user_ptr, void* ptr, size_t size); bool copy_to_user(void* user_ptr, const void* ptr, size_t size); -// FIXME: Map the physical addresses into kernel address space. Right now, something overwrites KernelHeap and crashes -// it, so that's not really possible. But it should be done in the future. - -template T* user_address_to_typed_pointer(V address) +template bool copy_typed_from_user(const T* user_ptr, T* ptr) { - uint64_t phys = VMM::get_physical((uint64_t)address); - if (phys == (uint64_t)-1) - { - kinfoln("warning: user pointer is not mapped in its address space"); - return nullptr; - } - // return (T*)MemoryManager::get_unaligned_mappings((void*)phys, Utilities::get_blocks_from_size(PAGE_SIZE, S), - // MAP_READ_WRITE); - return (T*)phys; + return copy_from_user(user_ptr, ptr, sizeof(T)); } -template void free_user_typed_pointer(T*) +template bool copy_typed_to_user(T* user_ptr, const T* ptr) { - // MemoryManager::release_unaligned_mappings(ptr, Utilities::get_blocks_from_size(PAGE_SIZE, S)); -} - -template T* obtain_user_ref(T* user_ptr) -{ - return user_address_to_typed_pointer(user_ptr); -} - -template void release_user_ref(T* ptr) -{ - return free_user_typed_pointer(ptr); + return copy_to_user(user_ptr, ptr, sizeof(T)); } \ No newline at end of file diff --git a/kernel/src/sys/clock.cpp b/kernel/src/sys/clock.cpp index 1d13b879..b4f7f1a8 100644 --- a/kernel/src/sys/clock.cpp +++ b/kernel/src/sys/clock.cpp @@ -33,35 +33,28 @@ static void ms_to_timespec(long ms, struct timespec* tv) void sys_clock_gettime(Context* context, int clock, struct timespec* tp) { - struct timespec* ktp = obtain_user_ref(tp); - if (!ktp) - { - context->rax = -EFAULT; // FIXME: Not sure if clock_gettime can return EFAULT. - return; - } + struct timespec ktp; Task* current_task = Scheduler::current_task(); switch (clock) { case CLOCK_REALTIME: { - ms_to_timespec(PIT::ms_since_boot, ktp); - ktp->tv_sec += unix_boot_time; + ms_to_timespec(PIT::ms_since_boot, &ktp); + ktp.tv_sec += unix_boot_time; break; } case CLOCK_MONOTONIC: { - ms_to_timespec(PIT::ms_since_boot, ktp); + ms_to_timespec(PIT::ms_since_boot, &ktp); break; } case CLOCK_PROCTIME: { - ms_to_timespec(current_task->cpu_time, ktp); + ms_to_timespec(current_task->cpu_time, &ktp); break; } - default: - release_user_ref(ktp); - context->rax = -EINVAL; - return; + default: context->rax = -EINVAL; return; } - release_user_ref(ktp); - context->rax = 0; + if (!copy_typed_to_user(tp, &ktp)) context->rax = -EFAULT; + else + context->rax = 0; return; } diff --git a/kernel/src/sys/dirent.cpp b/kernel/src/sys/dirent.cpp index 89eb16c0..1e205974 100644 --- a/kernel/src/sys/dirent.cpp +++ b/kernel/src/sys/dirent.cpp @@ -38,20 +38,19 @@ void sys_getdents(Context* context, int fd, struct luna_dirent* buf, size_t coun return; } - auto* kdirent = obtain_user_ref(buf); - if (!kdirent) + luna_dirent dirent; + + dirent.total = node->length; + dirent.offset = dir.offset(); + dirent.inode = entry->inode; + strlcpy(dirent.name, entry->name, sizeof(dirent.name)); + + if (!copy_typed_to_user(buf, &dirent)) { context->rax = -EFAULT; return; } - kdirent->total = node->length; - kdirent->offset = dir.offset(); - kdirent->inode = entry->inode; - strlcpy(kdirent->name, entry->name, sizeof(kdirent->name)); - - release_user_ref(kdirent); - dir.seek(dir.offset() + 1); buf++; nread++; diff --git a/kernel/src/sys/stat.cpp b/kernel/src/sys/stat.cpp index 48fdcaf9..5d026633 100644 --- a/kernel/src/sys/stat.cpp +++ b/kernel/src/sys/stat.cpp @@ -24,24 +24,20 @@ struct stat // FIXME: This struct is quite stubbed out. void do_stat(Context* context, VFS::Node* node, struct stat* buf) { - struct stat* kstat = obtain_user_ref(buf); - if (!kstat) - { - context->rax = -EFAULT; // FIXME: The manual doesn't say fstat can return EFAULT, but it seems logical here... - return; - } - kstat->st_ino = node->inode; - kstat->st_mode = node->mode | ((1 << (node->type)) * 010000); - kstat->st_size = node->length; - kstat->st_uid = node->uid; - kstat->st_gid = node->gid; - kstat->st_atime = node->atime; - kstat->st_ctime = node->ctime; - kstat->st_mtime = node->mtime; - kstat->st_dev = 0; - kstat->st_nlink = 0; - release_user_ref(kstat); - context->rax = 0; + struct stat stat; + stat.st_ino = node->inode; + stat.st_mode = node->mode | ((1 << (node->type)) * 010000); + stat.st_size = node->length; + stat.st_uid = node->uid; + stat.st_gid = node->gid; + stat.st_atime = node->atime; + stat.st_ctime = node->ctime; + stat.st_mtime = node->mtime; + stat.st_dev = 0; + stat.st_nlink = 0; + if (!copy_typed_to_user(buf, &stat)) context->rax = -EFAULT; + else + context->rax = 0; } void sys_fstat(Context* context, int fd, struct stat* buf)