summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/API/Syscall.h5
-rw-r--r--Kernel/Process.h48
-rw-r--r--Kernel/StdLib.h14
-rw-r--r--Kernel/Syscalls/read.cpp5
-rw-r--r--Kernel/Syscalls/stat.cpp2
5 files changed, 67 insertions, 7 deletions
diff --git a/Kernel/API/Syscall.h b/Kernel/API/Syscall.h
index 91cd72b960..52cf74e84e 100644
--- a/Kernel/API/Syscall.h
+++ b/Kernel/API/Syscall.h
@@ -27,6 +27,7 @@
#pragma once
#include <AK/Types.h>
+#include <AK/Userspace.h>
#ifdef __serenity__
# include <LibC/fd_set.h>
@@ -230,7 +231,7 @@ inline constexpr const char* to_string(Function function)
#ifdef __serenity__
struct StringArgument {
- const char* characters { nullptr };
+ Userspace<const char*> characters;
size_t length { 0 };
};
@@ -439,7 +440,7 @@ struct SC_waitid_params {
struct SC_stat_params {
StringArgument path;
- struct stat* statbuf;
+ Userspace<struct stat*> statbuf;
bool follow_symlinks;
};
diff --git a/Kernel/Process.h b/Kernel/Process.h
index a49308ed1c..b02cc80e24 100644
--- a/Kernel/Process.h
+++ b/Kernel/Process.h
@@ -32,6 +32,7 @@
#include <AK/InlineLinkedList.h>
#include <AK/NonnullOwnPtrVector.h>
#include <AK/String.h>
+#include <AK/Userspace.h>
#include <AK/WeakPtr.h>
#include <Kernel/API/Syscall.h>
#include <Kernel/FileSystem/InodeMetadata.h>
@@ -209,11 +210,11 @@ public:
mode_t sys$umask(mode_t);
int sys$open(const Syscall::SC_open_params*);
int sys$close(int fd);
- ssize_t sys$read(int fd, u8*, ssize_t);
+ ssize_t sys$read(int fd, Userspace<u8*>, ssize_t);
ssize_t sys$write(int fd, const u8*, ssize_t);
ssize_t sys$writev(int fd, const struct iovec* iov, int iov_count);
int sys$fstat(int fd, stat*);
- int sys$stat(const Syscall::SC_stat_params*);
+ int sys$stat(Userspace<const Syscall::SC_stat_params*>);
int sys$lseek(int fd, off_t, int whence);
int sys$kill(pid_t pid, int sig);
[[noreturn]] void sys$exit(int status);
@@ -357,6 +358,18 @@ public:
[[nodiscard]] bool validate_write(void*, size_t) const;
template<typename T>
+ [[nodiscard]] bool validate_read(Userspace<T*> ptr, size_t size) const
+ {
+ return validate_read((const T*)ptr.ptr(), size);
+ }
+
+ template<typename T>
+ [[nodiscard]] bool validate_write(Userspace<T*> ptr, size_t size) const
+ {
+ return validate_write((T*)ptr.ptr(), size);
+ }
+
+ template<typename T>
[[nodiscard]] bool validate_read_typed(T* value, size_t count = 1)
{
Checked size = sizeof(T);
@@ -377,6 +390,16 @@ public:
}
template<typename T>
+ [[nodiscard]] bool validate_read_and_copy_typed(T* dest, Userspace<const T*> src)
+ {
+ bool validated = validate_read_typed((const T*)src.ptr());
+ if (validated) {
+ copy_from_user(dest, (const T*)src.ptr());
+ }
+ return validated;
+ }
+
+ template<typename T>
[[nodiscard]] bool validate_write_typed(T* value, size_t count = 1)
{
Checked size = sizeof(T);
@@ -385,6 +408,17 @@ public:
return false;
return validate_write(value, size.value());
}
+
+ template<typename T>
+ [[nodiscard]] bool validate_write_typed(Userspace<T*> value, size_t count = 1)
+ {
+ Checked size = sizeof(T);
+ size *= count;
+ if (size.has_overflow())
+ return false;
+ return validate_write((T*)value.ptr(), size.value());
+ }
+
template<typename DataType, typename SizeType>
[[nodiscard]] bool validate(const Syscall::MutableBufferArgument<DataType, SizeType>& buffer)
{
@@ -398,6 +432,12 @@ public:
}
[[nodiscard]] String validate_and_copy_string_from_user(const char*, size_t) const;
+
+ [[nodiscard]] String validate_and_copy_string_from_user(Userspace<const char*> user_characters, size_t size) const
+ {
+ return validate_and_copy_string_from_user((const char*)user_characters.ptr(), size);
+ }
+
[[nodiscard]] String validate_and_copy_string_from_user(const Syscall::StringArgument&) const;
Custody& current_directory();
@@ -545,6 +585,10 @@ private:
KResultOr<siginfo_t> do_waitid(idtype_t idtype, int id, int options);
KResultOr<String> get_syscall_path_argument(const char* user_path, size_t path_length) const;
+ KResultOr<String> get_syscall_path_argument(Userspace<const char*> user_path, size_t path_length) const
+ {
+ return get_syscall_path_argument((const char*)user_path.ptr(), path_length);
+ }
KResultOr<String> get_syscall_path_argument(const Syscall::StringArgument&) const;
bool has_tracee_thread(int tracer_pid) const;
diff --git a/Kernel/StdLib.h b/Kernel/StdLib.h
index f2b896d632..3095557004 100644
--- a/Kernel/StdLib.h
+++ b/Kernel/StdLib.h
@@ -27,6 +27,7 @@
#pragma once
#include <AK/Forward.h>
+#include <AK/Userspace.h>
namespace Syscall {
struct StringArgument;
@@ -69,3 +70,16 @@ inline void copy_to_user(T* dest, const T* src)
{
copy_to_user(dest, src, sizeof(T));
}
+
+
+template<typename T>
+inline void copy_from_user(T* dest, Userspace<const T*> src)
+{
+ copy_from_user(dest, (const T*)src.ptr(), sizeof(T));
+}
+
+template<typename T>
+inline void copy_to_user(Userspace<T*> dest, const T* src)
+{
+ copy_to_user((T*)dest.ptr(), src, sizeof(T));
+}
diff --git a/Kernel/Syscalls/read.cpp b/Kernel/Syscalls/read.cpp
index 2c87dd5297..f76bbe5106 100644
--- a/Kernel/Syscalls/read.cpp
+++ b/Kernel/Syscalls/read.cpp
@@ -29,7 +29,7 @@
namespace Kernel {
-ssize_t Process::sys$read(int fd, u8* buffer, ssize_t size)
+ssize_t Process::sys$read(int fd, Userspace<u8*> buffer, ssize_t size)
{
REQUIRE_PROMISE(stdio);
if (size < 0)
@@ -56,7 +56,8 @@ ssize_t Process::sys$read(int fd, u8* buffer, ssize_t size)
return -EAGAIN;
}
}
- return description->read(buffer, size);
+ // FIXME: We should have a read() that takes a Userspace<u8*>
+ return description->read((u8*)buffer.ptr(), size);
}
}
diff --git a/Kernel/Syscalls/stat.cpp b/Kernel/Syscalls/stat.cpp
index 56f7dcfd2b..33e90443aa 100644
--- a/Kernel/Syscalls/stat.cpp
+++ b/Kernel/Syscalls/stat.cpp
@@ -46,7 +46,7 @@ int Process::sys$fstat(int fd, stat* user_statbuf)
return rc;
}
-int Process::sys$stat(const Syscall::SC_stat_params* user_params)
+int Process::sys$stat(Userspace<const Syscall::SC_stat_params*> user_params)
{
REQUIRE_PROMISE(rpath);
Syscall::SC_stat_params params;