Browse Source

Kernel: Pass a parameter struct to mknod()

Andreas Kling 5 years ago
parent
commit
c97bfbd609
5 changed files with 35 additions and 11 deletions
  1. 10 9
      Kernel/Process.cpp
  2. 1 1
      Kernel/Process.h
  3. 12 0
      Kernel/StdLib.h
  4. 6 0
      Kernel/Syscall.h
  5. 6 1
      Libraries/LibC/unistd.cpp

+ 10 - 9
Kernel/Process.cpp

@@ -3667,17 +3667,18 @@ void Process::FileDescriptionAndFlags::set(NonnullRefPtr<FileDescription>&& d, u
     flags = f;
 }
 
-int Process::sys$mknod(const char* pathname, mode_t mode, dev_t dev)
+int Process::sys$mknod(const Syscall::SC_mknod_params* user_params)
 {
-    if (!validate_read_str(pathname))
+    if (!validate_read_typed(user_params))
         return -EFAULT;
-
-    if (!is_superuser()) {
-        if (!is_regular_file(mode) && !is_fifo(mode) && !is_socket(mode))
-            return -EPERM;
-    }
-
-    return VFS::the().mknod(StringView(pathname), mode & ~umask(), dev, current_directory());
+    Syscall::SC_mknod_params params;
+    copy_from_user(&params, user_params);
+    if (!is_superuser() && !is_regular_file(params.mode) && !is_fifo(params.mode) && !is_socket(params.mode))
+        return -EPERM;
+    auto path = get_syscall_path_argument(params.path.characters, params.path.length);
+    if (path.is_error())
+        return path.error();
+    return VFS::the().mknod(path.value(), params.mode & ~umask(), params.dev, current_directory());
 }
 
 int Process::sys$dump_backtrace()

+ 1 - 1
Kernel/Process.h

@@ -206,7 +206,7 @@ public:
     int sys$get_thread_name(int tid, char* buffer, int buffer_size);
     int sys$rename(const char* oldpath, const char* newpath);
     int sys$systrace(pid_t);
-    int sys$mknod(const char* pathname, mode_t, dev_t);
+    int sys$mknod(const Syscall::SC_mknod_params*);
     int sys$create_shared_buffer(int, void** buffer);
     int sys$share_buffer_with(int, pid_t peer_pid);
     int sys$share_buffer_globally(int);

+ 12 - 0
Kernel/StdLib.h

@@ -36,3 +36,15 @@ void* memmove(void* dest, const void* src, size_t n);
 inline u16 ntohs(u16 w) { return (w & 0xff) << 8 | ((w >> 8) & 0xff); }
 inline u16 htons(u16 w) { return (w & 0xff) << 8 | ((w >> 8) & 0xff); }
 }
+
+template<typename T>
+inline void copy_from_user(T* dest, const T* src)
+{
+    copy_from_user(dest, src, sizeof(T));
+}
+
+template<typename T>
+inline void copy_to_user(T* dest, const T* src)
+{
+    copy_to_user(dest, src, sizeof(T));
+}

+ 6 - 0
Kernel/Syscall.h

@@ -339,6 +339,12 @@ struct SC_chown_params {
      u32 gid;
 };
 
+struct SC_mknod_params {
+    StringArgument path;
+    u16 mode;
+    u32 dev;
+};
+
 void initialize();
 int sync();
 

+ 6 - 1
Libraries/LibC/unistd.cpp

@@ -451,7 +451,12 @@ int access(const char* pathname, int mode)
 
 int mknod(const char* pathname, mode_t mode, dev_t dev)
 {
-    int rc = syscall(SC_mknod, pathname, mode, dev);
+    if (!pathname) {
+        errno = EFAULT;
+        return -1;
+    }
+    Syscall::SC_mknod_params params { { pathname, strlen(pathname) }, mode, dev };
+    int rc = syscall(SC_mknod, &params);
     __RETURN_WITH_ERRNO(rc, rc, -1);
 }