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/Spinlock.h>
|
||||||
#include <luna/SystemError.h>
|
#include <luna/SystemError.h>
|
||||||
#include <luna/Types.h>
|
#include <luna/Types.h>
|
||||||
|
#include <luna/Vector.h>
|
||||||
|
|
||||||
extern const u8 start_of_kernel_rodata[1];
|
extern const u8 start_of_kernel_rodata[1];
|
||||||
extern const u8 end_of_kernel_rodata[1];
|
extern const u8 end_of_kernel_rodata[1];
|
||||||
@ -420,6 +421,28 @@ namespace MemoryManager
|
|||||||
return true;
|
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)
|
bool validate_user_write(void* user, usize size)
|
||||||
{
|
{
|
||||||
uintptr_t user_ptr = (uintptr_t)user;
|
uintptr_t user_ptr = (uintptr_t)user;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <luna/OwnedStringView.h>
|
||||||
#include <luna/Result.h>
|
#include <luna/Result.h>
|
||||||
#include <luna/Types.h>
|
#include <luna/Types.h>
|
||||||
|
|
||||||
@ -24,6 +25,7 @@ namespace MemoryManager
|
|||||||
bool validate_user_writable_page(u64 address);
|
bool validate_user_writable_page(u64 address);
|
||||||
|
|
||||||
bool validate_userspace_string(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_write(void* user, usize size);
|
||||||
bool validate_user_read(const void* user, usize size);
|
bool validate_user_read(const void* user, usize size);
|
||||||
|
@ -5,14 +5,11 @@
|
|||||||
|
|
||||||
Result<u64> sys_mkdir(Registers*, SyscallArgs args)
|
Result<u64> sys_mkdir(Registers*, SyscallArgs args)
|
||||||
{
|
{
|
||||||
u64 path_address = args[0];
|
auto path = TRY(MemoryManager::strdup_from_user(args[0]));
|
||||||
if (!MemoryManager::validate_userspace_string(path_address)) return err(EFAULT);
|
|
||||||
|
|
||||||
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.chars()));
|
||||||
|
|
||||||
TRY(VFS::create_directory(path));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -10,25 +10,22 @@ constexpr int FLAGS_TO_KEEP = O_RDWR | O_APPEND;
|
|||||||
|
|
||||||
Result<u64> sys_open(Registers*, SyscallArgs args)
|
Result<u64> sys_open(Registers*, SyscallArgs args)
|
||||||
{
|
{
|
||||||
u64 path_address = args[0];
|
auto path = TRY(MemoryManager::strdup_from_user(args[0]));
|
||||||
if (!MemoryManager::validate_userspace_string(path_address)) return err(EFAULT);
|
|
||||||
|
|
||||||
const char* path = (const char*)path_address;
|
|
||||||
int flags = (int)args[1];
|
int flags = (int)args[1];
|
||||||
|
|
||||||
Thread* current = Scheduler::current();
|
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;
|
SharedPtr<VFS::Inode> inode;
|
||||||
|
|
||||||
// Caller did not pass either O_RDONLY, O_WRONLY or O_RDWR
|
// Caller did not pass either O_RDONLY, O_WRONLY or O_RDWR
|
||||||
if ((flags & O_RDWR) == 0) { return err(EINVAL); }
|
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.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
|
else
|
||||||
return maybe_inode.release_error();
|
return maybe_inode.release_error();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user