From 97ac4601f5dca698550c5080cc8eb163ba01711d Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 3 Apr 2023 15:59:10 +0200 Subject: [PATCH] Kernel: Use custody_for_dirfd() in more syscalls This simplifies a lot of syscalls, some of which were doing very unnecessarily verbose things instead of calling this. --- Kernel/Syscalls/chmod.cpp | 12 +----------- Kernel/Syscalls/chown.cpp | 12 +----------- Kernel/Syscalls/open.cpp | 13 +------------ Kernel/Syscalls/stat.cpp | 13 +------------ Kernel/Syscalls/unlink.cpp | 10 +--------- Kernel/Syscalls/utimensat.cpp | 34 ++-------------------------------- 6 files changed, 7 insertions(+), 87 deletions(-) diff --git a/Kernel/Syscalls/chmod.cpp b/Kernel/Syscalls/chmod.cpp index 76350c8889..e5ddc1530f 100644 --- a/Kernel/Syscalls/chmod.cpp +++ b/Kernel/Syscalls/chmod.cpp @@ -17,17 +17,7 @@ ErrorOr Process::sys$chmod(Userspace u TRY(require_promise(Pledge::fattr)); auto params = TRY(copy_typed_from_user(user_params)); auto path = TRY(get_syscall_path_argument(params.path)); - - RefPtr base; - if (params.dirfd == AT_FDCWD) { - base = current_directory(); - } else { - auto base_description = TRY(open_file_description(params.dirfd)); - if (!base_description->custody()) - return EINVAL; - base = base_description->custody(); - } - + auto base = TRY(custody_for_dirfd(params.dirfd)); TRY(VirtualFileSystem::the().chmod(credentials(), path->view(), params.mode, *base, params.follow_symlinks ? 0 : O_NOFOLLOW_NOERROR)); return 0; } diff --git a/Kernel/Syscalls/chown.cpp b/Kernel/Syscalls/chown.cpp index 69d2934a35..6616ed7999 100644 --- a/Kernel/Syscalls/chown.cpp +++ b/Kernel/Syscalls/chown.cpp @@ -27,17 +27,7 @@ ErrorOr Process::sys$chown(Userspace u TRY(require_promise(Pledge::chown)); auto params = TRY(copy_typed_from_user(user_params)); auto path = TRY(get_syscall_path_argument(params.path)); - - RefPtr base; - if (params.dirfd == AT_FDCWD) { - base = current_directory(); - } else { - auto base_description = TRY(open_file_description(params.dirfd)); - if (!base_description->custody()) - return EINVAL; - base = base_description->custody(); - } - + auto base = TRY(custody_for_dirfd(params.dirfd)); TRY(VirtualFileSystem::the().chown(credentials(), path->view(), params.uid, params.gid, *base, params.follow_symlinks ? 0 : O_NOFOLLOW_NOERROR)); return 0; } diff --git a/Kernel/Syscalls/open.cpp b/Kernel/Syscalls/open.cpp index 59f7af709e..740d5255cd 100644 --- a/Kernel/Syscalls/open.cpp +++ b/Kernel/Syscalls/open.cpp @@ -55,18 +55,7 @@ ErrorOr Process::sys$open(Userspace use dbgln_if(IO_DEBUG, "sys$open(dirfd={}, path='{}', options={}, mode={})", dirfd, path->view(), options, mode); auto fd_allocation = TRY(allocate_fd()); - RefPtr base; - if (dirfd == AT_FDCWD) { - base = current_directory(); - } else { - auto base_description = TRY(open_file_description(dirfd)); - if (!base_description->is_directory()) - return ENOTDIR; - if (!base_description->custody()) - return EINVAL; - base = base_description->custody(); - } - + auto base = TRY(custody_for_dirfd(dirfd)); auto description = TRY(VirtualFileSystem::the().open(credentials(), path->view(), options, mode & ~umask(), *base)); if (description->inode() && description->inode()->bound_socket()) diff --git a/Kernel/Syscalls/stat.cpp b/Kernel/Syscalls/stat.cpp index f2ceeb215b..7299241743 100644 --- a/Kernel/Syscalls/stat.cpp +++ b/Kernel/Syscalls/stat.cpp @@ -28,18 +28,7 @@ ErrorOr Process::sys$stat(Userspace use auto params = TRY(copy_typed_from_user(user_params)); auto path = TRY(get_syscall_path_argument(params.path)); - - RefPtr base; - if (params.dirfd == AT_FDCWD) { - base = current_directory(); - } else { - auto base_description = TRY(open_file_description(params.dirfd)); - if (!base_description->is_directory()) - return ENOTDIR; - if (!base_description->custody()) - return EINVAL; - base = base_description->custody(); - } + auto base = TRY(custody_for_dirfd(params.dirfd)); auto metadata = TRY(VirtualFileSystem::the().lookup_metadata(credentials(), path->view(), *base, params.follow_symlinks ? 0 : O_NOFOLLOW_NOERROR)); auto statbuf = TRY(metadata.stat()); TRY(copy_to_user(params.statbuf, &statbuf)); diff --git a/Kernel/Syscalls/unlink.cpp b/Kernel/Syscalls/unlink.cpp index d545e4ce0b..90a73bdf3e 100644 --- a/Kernel/Syscalls/unlink.cpp +++ b/Kernel/Syscalls/unlink.cpp @@ -19,15 +19,7 @@ ErrorOr Process::sys$unlink(int dirfd, Userspace user_path if (flags & ~AT_REMOVEDIR) return Error::from_errno(EINVAL); - RefPtr base; - if (dirfd == AT_FDCWD) { - base = current_directory(); - } else { - auto base_description = TRY(open_file_description(dirfd)); - if (!base_description->custody()) - return Error::from_errno(EINVAL); - base = base_description->custody(); - } + auto base = TRY(custody_for_dirfd(dirfd)); if (flags & AT_REMOVEDIR) TRY(VirtualFileSystem::the().rmdir(credentials(), path->view(), *base)); diff --git a/Kernel/Syscalls/utimensat.cpp b/Kernel/Syscalls/utimensat.cpp index 4ab0bb600a..14319ab84d 100644 --- a/Kernel/Syscalls/utimensat.cpp +++ b/Kernel/Syscalls/utimensat.cpp @@ -19,8 +19,6 @@ ErrorOr Process::sys$utimensat(Userspace Process::sys$utimensat(Userspace path; - RefPtr description; - RefPtr base; - - auto path_or_error = get_syscall_path_argument(params.path); - if (path_or_error.is_error()) { - // If the path is empty ("") but not a nullptr, attempt to get a path - // from the file descriptor. This allows futimens() to be implemented - // in terms of utimensat(). - if (params.path.characters && params.path.length == 0) { - description = TRY(open_file_description(dirfd)); - path = TRY(description->original_absolute_path()); - base = description->custody(); - } else { - return path_or_error.release_error(); - } - } else { - path = path_or_error.release_value(); - if (dirfd == AT_FDCWD) { - base = current_directory(); - } else { - description = TRY(open_file_description(dirfd)); - if (!KLexicalPath::is_absolute(path->view()) && !description->is_directory()) - return ENOTDIR; - if (!description->custody()) - return EINVAL; - base = description->custody(); - } - } - + auto path = TRY(get_syscall_path_argument(params.path)); + auto base = TRY(custody_for_dirfd(params.dirfd)); auto& atime = times[0]; auto& mtime = times[1]; TRY(VirtualFileSystem::the().utimensat(credentials(), path->view(), *base, atime, mtime, follow_symlink));