diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 52d860fe14..896457bdec 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -2640,12 +2640,16 @@ int Process::sys$fchown(int fd, uid_t uid, gid_t gid) return description->chown(uid, gid); } -int Process::sys$chown(const char* pathname, uid_t uid, gid_t gid) +int Process::sys$chown(const Syscall::SC_chown_params* user_params) { - SmapDisabler disabler; - if (!validate_read_str(pathname)) + if (!validate_read_typed(user_params)) return -EFAULT; - return VFS::the().chown(StringView(pathname), uid, gid, current_directory()); + Syscall::SC_chown_params params; + copy_from_user(¶ms, user_params, sizeof(params)); + auto path = get_syscall_path_argument(params.path.characters, params.path.length); + if (path.is_error()) + return path.error(); + return VFS::the().chown(path.value(), params.uid, params.gid, current_directory()); } void Process::finalize() diff --git a/Kernel/Process.h b/Kernel/Process.h index f2c9e79f12..e1af793214 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -183,7 +183,7 @@ public: int sys$umount(const char* mountpoint, size_t mountpoint_length); int sys$chmod(const char* pathname, size_t path_length, mode_t); int sys$fchmod(int fd, mode_t); - int sys$chown(const char* pathname, uid_t, gid_t); + int sys$chown(const Syscall::SC_chown_params*); int sys$fchown(int fd, uid_t, gid_t); int sys$socket(int domain, int type, int protocol); int sys$bind(int sockfd, const sockaddr* addr, socklen_t); diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index 6cdf3d31bd..41ed4f6fed 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -333,6 +333,12 @@ struct SC_link_params { StringArgument new_path; }; +struct SC_chown_params { + StringArgument path; + u32 uid; + u32 gid; +}; + void initialize(); int sync(); diff --git a/Libraries/LibC/unistd.cpp b/Libraries/LibC/unistd.cpp index 2feb69c16f..9ad0eb7462 100644 --- a/Libraries/LibC/unistd.cpp +++ b/Libraries/LibC/unistd.cpp @@ -27,7 +27,12 @@ int systrace(pid_t pid) int chown(const char* pathname, uid_t uid, gid_t gid) { - int rc = syscall(SC_chown, pathname, uid, gid); + if (!pathname) { + errno = EFAULT; + return -1; + } + Syscall::SC_chown_params params { { pathname, strlen(pathname) }, uid, gid }; + int rc = syscall(SC_chown, ¶ms); __RETURN_WITH_ERRNO(rc, rc, -1); }