瀏覽代碼

Kernel: Pass path+length to the stat() and lstat() syscalls

It's not pleasant having to deal with null-terminated strings as input
to syscalls, so let's get rid of them one by one.
Andreas Kling 5 年之前
父節點
當前提交
f231e9ea76
共有 3 個文件被更改,包括 16 次插入10 次删除
  1. 12 6
      Kernel/Process.cpp
  2. 2 2
      Kernel/Process.h
  3. 2 2
      Libraries/LibC/unistd.cpp

+ 12 - 6
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);
 }
 

+ 2 - 2
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);

+ 2 - 2
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);
 }