diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index b89b8c6a07..b89b22e95c 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -1499,25 +1499,31 @@ int Process::sys$fstat(int fd, stat* statbuf) return description->fstat(*statbuf); } -int Process::sys$lstat(const char* path, stat* statbuf) +int Process::sys$lstat(const char* user_path, size_t path_length, stat* statbuf) { if (!validate_write_typed(statbuf)) return -EFAULT; - SmapDisabler disabler; - auto metadata_or_error = VFS::the().lookup_metadata(StringView(path), current_directory(), O_NOFOLLOW_NOERROR); + if (!validate_read(user_path, path_length)) + return -EFAULT; + auto path = copy_string_from_user(user_path, path_length); + auto metadata_or_error = VFS::the().lookup_metadata(path, current_directory(), O_NOFOLLOW_NOERROR); if (metadata_or_error.is_error()) return metadata_or_error.error(); + SmapDisabler disabler; return metadata_or_error.value().stat(*statbuf); } -int Process::sys$stat(const char* path, stat* statbuf) +int Process::sys$stat(const char* user_path, size_t path_length, stat* statbuf) { if (!validate_write_typed(statbuf)) return -EFAULT; - SmapDisabler disabler; - auto metadata_or_error = VFS::the().lookup_metadata(StringView(path), current_directory()); + if (!validate_read(user_path, path_length)) + return -EFAULT; + auto path = copy_string_from_user(user_path, path_length); + auto metadata_or_error = VFS::the().lookup_metadata(path, current_directory()); if (metadata_or_error.is_error()) return metadata_or_error.error(); + SmapDisabler disabler; return metadata_or_error.value().stat(*statbuf); } diff --git a/Kernel/Process.h b/Kernel/Process.h index ce610aad67..063134be2a 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -127,8 +127,8 @@ public: 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$lstat(const char*, stat*); - int sys$stat(const char*, stat*); + int sys$lstat(const char*, size_t, stat*); + int sys$stat(const char*, size_t, stat*); int sys$lseek(int fd, off_t, int whence); int sys$kill(pid_t pid, int sig); [[noreturn]] void sys$exit(int status); diff --git a/Libraries/LibC/unistd.cpp b/Libraries/LibC/unistd.cpp index f90fca4da2..c15413db04 100644 --- a/Libraries/LibC/unistd.cpp +++ b/Libraries/LibC/unistd.cpp @@ -227,13 +227,13 @@ pid_t waitpid(pid_t waitee, int* wstatus, int options) int lstat(const char* path, struct stat* statbuf) { - int rc = syscall(SC_lstat, path, statbuf); + int rc = syscall(SC_lstat, path, strlen(path), statbuf); __RETURN_WITH_ERRNO(rc, rc, -1); } int stat(const char* path, struct stat* statbuf) { - int rc = syscall(SC_stat, path, statbuf); + int rc = syscall(SC_stat, path, strlen(path), statbuf); __RETURN_WITH_ERRNO(rc, rc, -1); }