kernel: Add strdup_from_user()
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
682d3c753e
commit
02dbcbbfa1
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user