kernel: Add strdup_from_user()
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
apio 2023-03-12 16:30:36 +01:00
parent 682d3c753e
commit 02dbcbbfa1
Signed by: apio
GPG Key ID: B8A7D06E42258954
4 changed files with 32 additions and 13 deletions

View File

@ -8,6 +8,7 @@
#include <luna/Spinlock.h>
#include <luna/SystemError.h>
#include <luna/Types.h>
#include <luna/Vector.h>
extern const u8 start_of_kernel_rodata[1];
extern const u8 end_of_kernel_rodata[1];
@ -420,6 +421,28 @@ namespace MemoryManager
return true;
}
// FIXME: Make this more efficient.
Result<OwnedStringView> strdup_from_user(u64 address)
{
if (!validate_user_readable_page(address)) return err(EFAULT);
Vector<char> result;
while (*(char*)address != 0)
{
TRY(result.try_append(*(char*)address));
address++;
if (address % ARCH_PAGE_SIZE)
{
if (!validate_user_readable_page(address)) return err(EFAULT);
}
}
TRY(result.try_append(0)); // null terminator
return OwnedStringView::from_string_literal(result.data());
}
bool validate_user_write(void* user, usize size)
{
uintptr_t user_ptr = (uintptr_t)user;

View File

@ -1,4 +1,5 @@
#pragma once
#include <luna/OwnedStringView.h>
#include <luna/Result.h>
#include <luna/Types.h>
@ -24,6 +25,7 @@ namespace MemoryManager
bool validate_user_writable_page(u64 address);
bool validate_userspace_string(u64 address);
Result<OwnedStringView> strdup_from_user(u64 address);
bool validate_user_write(void* user, usize size);
bool validate_user_read(const void* user, usize size);

View File

@ -5,14 +5,11 @@
Result<u64> sys_mkdir(Registers*, SyscallArgs args)
{
u64 path_address = args[0];
if (!MemoryManager::validate_userspace_string(path_address)) return err(EFAULT);
auto path = TRY(MemoryManager::strdup_from_user(args[0]));
const char* path = (const char*)path_address;
kinfoln("mkdir: attempting to create %s", path.chars());
kinfoln("mkdir: attempting to create %s", path);
TRY(VFS::create_directory(path));
TRY(VFS::create_directory(path.chars()));
return 0;
}

View File

@ -10,25 +10,22 @@ constexpr int FLAGS_TO_KEEP = O_RDWR | O_APPEND;
Result<u64> sys_open(Registers*, SyscallArgs args)
{
u64 path_address = args[0];
if (!MemoryManager::validate_userspace_string(path_address)) return err(EFAULT);
const char* path = (const char*)path_address;
auto path = TRY(MemoryManager::strdup_from_user(args[0]));
int flags = (int)args[1];
Thread* current = Scheduler::current();
kinfoln("open: trying to open file %s, flags %d", path, flags);
kinfoln("open: trying to open file %s, flags %d", path.chars(), flags);
SharedPtr<VFS::Inode> inode;
// Caller did not pass either O_RDONLY, O_WRONLY or O_RDWR
if ((flags & O_RDWR) == 0) { return err(EINVAL); }
auto maybe_inode = VFS::resolve_path(path);
auto maybe_inode = VFS::resolve_path(path.chars());
if (maybe_inode.has_error())
{
if (maybe_inode.error() == ENOENT && (flags & O_CREAT)) inode = TRY(VFS::create_file(path));
if (maybe_inode.error() == ENOENT && (flags & O_CREAT)) inode = TRY(VFS::create_file(path.chars()));
else
return maybe_inode.release_error();
}