diff options
author | circl <circl.lastname@gmail.com> | 2021-12-31 19:20:17 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-01-01 15:08:49 +0100 |
commit | 63760603f3adec2fb696018f6c1c77feeb0dbdd0 (patch) | |
tree | 3d96a31951e538ab9cdc3c99b025ff5c9a41bb42 /Kernel | |
parent | 344cfa0db4a76601754aead153fa52d2cde6db1e (diff) | |
download | serenity-63760603f3adec2fb696018f6c1c77feeb0dbdd0.zip |
Kernel+LibC+LibCore: Add lchown and fchownat functions
This modifies sys$chown to allow specifying whether or not to follow
symlinks and in which directory.
This was then used to implement lchown and fchownat in LibC and LibCore.
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/API/Syscall.h | 2 | ||||
-rw-r--r-- | Kernel/FileSystem/VirtualFileSystem.cpp | 4 | ||||
-rw-r--r-- | Kernel/FileSystem/VirtualFileSystem.h | 2 | ||||
-rw-r--r-- | Kernel/Syscalls/chown.cpp | 15 |
4 files changed, 19 insertions, 4 deletions
diff --git a/Kernel/API/Syscall.h b/Kernel/API/Syscall.h index 6372efb165..d02184fdfd 100644 --- a/Kernel/API/Syscall.h +++ b/Kernel/API/Syscall.h @@ -400,6 +400,8 @@ struct SC_chown_params { StringArgument path; u32 uid; u32 gid; + int dirfd; + int follow_symlinks; }; struct SC_mknod_params { diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp index 3855182999..2bcf342329 100644 --- a/Kernel/FileSystem/VirtualFileSystem.cpp +++ b/Kernel/FileSystem/VirtualFileSystem.cpp @@ -564,9 +564,9 @@ ErrorOr<void> VirtualFileSystem::chown(Custody& custody, UserID a_uid, GroupID a return inode.chown(new_uid, new_gid); } -ErrorOr<void> VirtualFileSystem::chown(StringView path, UserID a_uid, GroupID a_gid, Custody& base) +ErrorOr<void> VirtualFileSystem::chown(StringView path, UserID a_uid, GroupID a_gid, Custody& base, int options) { - auto custody = TRY(resolve_path(path, base)); + auto custody = TRY(resolve_path(path, base, nullptr, options)); return chown(custody, a_uid, a_gid); } diff --git a/Kernel/FileSystem/VirtualFileSystem.h b/Kernel/FileSystem/VirtualFileSystem.h index bee3f1504f..a1386dbb14 100644 --- a/Kernel/FileSystem/VirtualFileSystem.h +++ b/Kernel/FileSystem/VirtualFileSystem.h @@ -59,7 +59,7 @@ public: ErrorOr<void> rmdir(StringView path, Custody& base); ErrorOr<void> chmod(StringView path, mode_t, Custody& base); ErrorOr<void> chmod(Custody&, mode_t); - ErrorOr<void> chown(StringView path, UserID, GroupID, Custody& base); + ErrorOr<void> chown(StringView path, UserID, GroupID, Custody& base, int options); ErrorOr<void> chown(Custody&, UserID, GroupID); ErrorOr<void> access(StringView path, int mode, Custody& base); ErrorOr<InodeMetadata> lookup_metadata(StringView path, Custody& base, int options = 0); diff --git a/Kernel/Syscalls/chown.cpp b/Kernel/Syscalls/chown.cpp index 92172fed61..0db2c9cccc 100644 --- a/Kernel/Syscalls/chown.cpp +++ b/Kernel/Syscalls/chown.cpp @@ -4,6 +4,8 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <AK/NonnullRefPtrVector.h> +#include <Kernel/FileSystem/Custody.h> #include <Kernel/FileSystem/OpenFileDescription.h> #include <Kernel/Process.h> @@ -24,7 +26,18 @@ ErrorOr<FlatPtr> Process::sys$chown(Userspace<const Syscall::SC_chown_params*> u TRY(require_promise(Pledge::chown)); auto params = TRY(copy_typed_from_user(user_params)); auto path = TRY(get_syscall_path_argument(params.path)); - TRY(VirtualFileSystem::the().chown(path->view(), params.uid, params.gid, current_directory())); + + RefPtr<Custody> base; + if (params.dirfd == AT_FDCWD) { + base = current_directory(); + } else { + auto base_description = TRY(fds().open_file_description(params.dirfd)); + if (!base_description->custody()) + return EINVAL; + base = base_description->custody(); + } + + TRY(VirtualFileSystem::the().chown(path->view(), params.uid, params.gid, *base, params.follow_symlinks ? 0 : O_NOFOLLOW_NOERROR)); return 0; } |