diff options
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/API/Syscall.h | 5 | ||||
-rw-r--r-- | Kernel/Process.h | 48 | ||||
-rw-r--r-- | Kernel/StdLib.h | 14 | ||||
-rw-r--r-- | Kernel/Syscalls/read.cpp | 5 | ||||
-rw-r--r-- | Kernel/Syscalls/stat.cpp | 2 |
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; |