From c3351d4b9fc83c731f122de21adf52ef015aecb1 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 21 Aug 2022 16:02:24 +0200 Subject: [PATCH] Kernel: Make VirtualFileSystem functions take credentials as input Instead of getting credentials from Process::current(), we now require that they be provided as input to the various VFS functions. This ensures that an atomic set of credentials is used throughout an entire VFS operation. --- Kernel/Coredump.cpp | 8 +- Kernel/Credentials.cpp | 5 + Kernel/Credentials.h | 2 + Kernel/FileSystem/Inode.cpp | 2 +- Kernel/FileSystem/InodeFile.cpp | 4 +- Kernel/FileSystem/InodeMetadata.cpp | 15 +- Kernel/FileSystem/InodeMetadata.h | 4 + Kernel/FileSystem/VirtualFileSystem.cpp | 180 +++++++++++------------- Kernel/FileSystem/VirtualFileSystem.h | 40 +++--- Kernel/Net/LocalSocket.cpp | 4 +- Kernel/Process.cpp | 3 +- Kernel/Syscalls/access.cpp | 2 +- Kernel/Syscalls/chdir.cpp | 4 +- Kernel/Syscalls/chmod.cpp | 2 +- Kernel/Syscalls/chown.cpp | 2 +- Kernel/Syscalls/execve.cpp | 4 +- Kernel/Syscalls/inode_watcher.cpp | 2 +- Kernel/Syscalls/link.cpp | 4 +- Kernel/Syscalls/mkdir.cpp | 2 +- Kernel/Syscalls/mknod.cpp | 2 +- Kernel/Syscalls/mmap.cpp | 5 +- Kernel/Syscalls/mount.cpp | 4 +- Kernel/Syscalls/open.cpp | 2 +- Kernel/Syscalls/readlink.cpp | 2 +- Kernel/Syscalls/realpath.cpp | 2 +- Kernel/Syscalls/rename.cpp | 2 +- Kernel/Syscalls/rmdir.cpp | 2 +- Kernel/Syscalls/stat.cpp | 2 +- Kernel/Syscalls/statvfs.cpp | 2 +- Kernel/Syscalls/unlink.cpp | 4 +- Kernel/Syscalls/unveil.cpp | 2 +- Kernel/Syscalls/utime.cpp | 2 +- Kernel/Syscalls/utimensat.cpp | 2 +- 33 files changed, 159 insertions(+), 165 deletions(-) diff --git a/Kernel/Coredump.cpp b/Kernel/Coredump.cpp index 8438d6d4a8..a99b858d74 100644 --- a/Kernel/Coredump.cpp +++ b/Kernel/Coredump.cpp @@ -62,19 +62,21 @@ Coredump::Coredump(NonnullLockRefPtr process, NonnullLockRefPtr> Coredump::try_create_target_file(Process const& process, StringView output_path) { auto output_directory = KLexicalPath::dirname(output_path); - auto dump_directory = TRY(VirtualFileSystem::the().open_directory(output_directory, VirtualFileSystem::the().root_custody())); + auto dump_directory = TRY(VirtualFileSystem::the().open_directory(Process::current().credentials(), output_directory, VirtualFileSystem::the().root_custody())); auto dump_directory_metadata = dump_directory->inode().metadata(); if (dump_directory_metadata.uid != 0 || dump_directory_metadata.gid != 0 || dump_directory_metadata.mode != 040777) { dbgln("Refusing to put coredump in sketchy directory '{}'", output_directory); return EINVAL; } - auto credentials = process.credentials(); + + auto process_credentials = process.credentials(); return TRY(VirtualFileSystem::the().open( + Process::current().credentials(), KLexicalPath::basename(output_path), O_CREAT | O_WRONLY | O_EXCL, S_IFREG, // We will enable reading from userspace when we finish generating the coredump file *dump_directory, - UidAndGid { credentials->uid(), credentials->gid() })); + UidAndGid { process_credentials->uid(), process_credentials->gid() })); } ErrorOr Coredump::write_elf_header() diff --git a/Kernel/Credentials.cpp b/Kernel/Credentials.cpp index 06eea48227..935b4b107f 100644 --- a/Kernel/Credentials.cpp +++ b/Kernel/Credentials.cpp @@ -29,4 +29,9 @@ Credentials::Credentials(UserID uid, GroupID gid, UserID euid, GroupID egid, Use Credentials::~Credentials() = default; +bool Credentials::in_group(Kernel::GroupID gid) const +{ + return m_gid == gid || m_extra_gids.contains_slow(gid); +} + } diff --git a/Kernel/Credentials.h b/Kernel/Credentials.h index 08ebcce1d2..e951d57c21 100644 --- a/Kernel/Credentials.h +++ b/Kernel/Credentials.h @@ -27,6 +27,8 @@ public: GroupID sgid() const { return m_sgid; } Span extra_gids() const { return m_extra_gids.span(); } + bool in_group(GroupID) const; + private: Credentials(UserID uid, GroupID gid, UserID euid, GroupID egid, UserID suid, GroupID sgid, FixedArray extra_gids); diff --git a/Kernel/FileSystem/Inode.cpp b/Kernel/FileSystem/Inode.cpp index 108b47aee7..57f948b9d0 100644 --- a/Kernel/FileSystem/Inode.cpp +++ b/Kernel/FileSystem/Inode.cpp @@ -82,7 +82,7 @@ ErrorOr> Inode::resolve_as_link(Custody& base, RefPtrbytes() }, base, out_parent, options, symlink_recursion_level); + return VirtualFileSystem::the().resolve_path(Process::current().credentials(), StringView { contents->bytes() }, base, out_parent, options, symlink_recursion_level); } Inode::Inode(FileSystem& fs, InodeIndex index) diff --git a/Kernel/FileSystem/InodeFile.cpp b/Kernel/FileSystem/InodeFile.cpp index 260bfd2b25..2696ae6793 100644 --- a/Kernel/FileSystem/InodeFile.cpp +++ b/Kernel/FileSystem/InodeFile.cpp @@ -119,14 +119,14 @@ ErrorOr InodeFile::chown(OpenFileDescription& description, UserID uid, Gro { VERIFY(description.inode() == m_inode); VERIFY(description.custody()); - return VirtualFileSystem::the().chown(*description.custody(), uid, gid); + return VirtualFileSystem::the().chown(Process::current().credentials(), *description.custody(), uid, gid); } ErrorOr InodeFile::chmod(OpenFileDescription& description, mode_t mode) { VERIFY(description.inode() == m_inode); VERIFY(description.custody()); - return VirtualFileSystem::the().chmod(*description.custody(), mode); + return VirtualFileSystem::the().chmod(Process::current().credentials(), *description.custody(), mode); } } diff --git a/Kernel/FileSystem/InodeMetadata.cpp b/Kernel/FileSystem/InodeMetadata.cpp index 35b7074d99..fc70ad8b7f 100644 --- a/Kernel/FileSystem/InodeMetadata.cpp +++ b/Kernel/FileSystem/InodeMetadata.cpp @@ -9,22 +9,19 @@ namespace Kernel { -bool InodeMetadata::may_read(Process const& process) const +bool InodeMetadata::may_read(Credentials const& credentials) const { - auto credentials = process.credentials(); - return may_read(credentials->euid(), credentials->egid(), credentials->extra_gids()); + return may_read(credentials.euid(), credentials.egid(), credentials.extra_gids()); } -bool InodeMetadata::may_write(Process const& process) const +bool InodeMetadata::may_write(Credentials const& credentials) const { - auto credentials = process.credentials(); - return may_write(credentials->euid(), credentials->egid(), credentials->extra_gids()); + return may_write(credentials.euid(), credentials.egid(), credentials.extra_gids()); } -bool InodeMetadata::may_execute(Process const& process) const +bool InodeMetadata::may_execute(Credentials const& credentials) const { - auto credentials = process.credentials(); - return may_execute(credentials->euid(), credentials->egid(), credentials->extra_gids()); + return may_execute(credentials.euid(), credentials.egid(), credentials.extra_gids()); } } diff --git a/Kernel/FileSystem/InodeMetadata.h b/Kernel/FileSystem/InodeMetadata.h index 93e5ed2742..685e38e4aa 100644 --- a/Kernel/FileSystem/InodeMetadata.h +++ b/Kernel/FileSystem/InodeMetadata.h @@ -42,6 +42,10 @@ struct InodeMetadata { bool may_write(Process const&) const; bool may_execute(Process const&) const; + bool may_read(Credentials const&) const; + bool may_write(Credentials const&) const; + bool may_execute(Credentials const&) const; + bool may_read(UserID u, GroupID g, Span eg) const { if (u == 0) diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp index 59f729344f..e51b2c90a9 100644 --- a/Kernel/FileSystem/VirtualFileSystem.cpp +++ b/Kernel/FileSystem/VirtualFileSystem.cpp @@ -204,12 +204,11 @@ ErrorOr VirtualFileSystem::traverse_directory_inode(Inode& dir_inode, Func }); } -ErrorOr VirtualFileSystem::utime(StringView path, Custody& base, time_t atime, time_t mtime) +ErrorOr VirtualFileSystem::utime(Credentials const& credentials, StringView path, Custody& base, time_t atime, time_t mtime) { - auto custody = TRY(resolve_path(path, base)); + auto custody = TRY(resolve_path(credentials, path, base)); auto& inode = custody->inode(); - auto& current_process = Process::current(); - if (!current_process.is_superuser() && inode.metadata().uid != current_process.euid()) + if (!credentials.is_superuser() && inode.metadata().uid != credentials.euid()) return EACCES; if (custody->is_readonly()) return EROFS; @@ -219,12 +218,11 @@ ErrorOr VirtualFileSystem::utime(StringView path, Custody& base, time_t at return {}; } -ErrorOr VirtualFileSystem::utimensat(StringView path, Custody& base, timespec const& atime, timespec const& mtime, int options) +ErrorOr VirtualFileSystem::utimensat(Credentials const& credentials, StringView path, Custody& base, timespec const& atime, timespec const& mtime, int options) { - auto custody = TRY(resolve_path(path, base, nullptr, options)); + auto custody = TRY(resolve_path(credentials, path, base, nullptr, options)); auto& inode = custody->inode(); - auto& current_process = Process::current(); - if (!current_process.is_superuser() && inode.metadata().uid != current_process.euid()) + if (!credentials.is_superuser() && inode.metadata().uid != credentials.euid()) return EACCES; if (custody->is_readonly()) return EROFS; @@ -238,24 +236,24 @@ ErrorOr VirtualFileSystem::utimensat(StringView path, Custody& base, times return {}; } -ErrorOr VirtualFileSystem::lookup_metadata(StringView path, Custody& base, int options) +ErrorOr VirtualFileSystem::lookup_metadata(Credentials const& credentials, StringView path, Custody& base, int options) { - auto custody = TRY(resolve_path(path, base, nullptr, options)); + auto custody = TRY(resolve_path(credentials, path, base, nullptr, options)); return custody->inode().metadata(); } -ErrorOr> VirtualFileSystem::open(StringView path, int options, mode_t mode, Custody& base, Optional owner) +ErrorOr> VirtualFileSystem::open(Credentials const& credentials, StringView path, int options, mode_t mode, Custody& base, Optional owner) { if ((options & O_CREAT) && (options & O_DIRECTORY)) return EINVAL; RefPtr parent_custody; - auto custody_or_error = resolve_path(path, base, &parent_custody, options); + auto custody_or_error = resolve_path(credentials, path, base, &parent_custody, options); if (custody_or_error.is_error()) { // NOTE: ENOENT with a non-null parent custody signals us that the immediate parent // of the file exists, but the file itself does not. if ((options & O_CREAT) && custody_or_error.error().code() == ENOENT && parent_custody) - return create(path, options, mode, *parent_custody, move(owner)); + return create(credentials, path, options, mode, *parent_custody, move(owner)); return custody_or_error.release_error(); } @@ -271,19 +269,18 @@ ErrorOr> VirtualFileSystem::open(StringVi bool should_truncate_file = false; - auto& current_process = Process::current(); - if ((options & O_RDONLY) && !metadata.may_read(current_process)) + if ((options & O_RDONLY) && !metadata.may_read(credentials)) return EACCES; if (options & O_WRONLY) { - if (!metadata.may_write(current_process)) + if (!metadata.may_write(credentials)) return EACCES; if (metadata.is_directory()) return EISDIR; should_truncate_file = options & O_TRUNC; } if (options & O_EXEC) { - if (!metadata.may_execute(current_process) || (custody.mount_flags() & MS_NOEXEC)) + if (!metadata.may_execute(credentials) || (custody.mount_flags() & MS_NOEXEC)) return EACCES; } @@ -332,13 +329,13 @@ ErrorOr> VirtualFileSystem::open(StringVi return description; } -ErrorOr VirtualFileSystem::mknod(StringView path, mode_t mode, dev_t dev, Custody& base) +ErrorOr VirtualFileSystem::mknod(Credentials const& credentials, StringView path, mode_t mode, dev_t dev, Custody& base) { if (!is_regular_file(mode) && !is_block_device(mode) && !is_character_device(mode) && !is_fifo(mode) && !is_socket(mode)) return EINVAL; RefPtr parent_custody; - auto existing_file_or_error = resolve_path(path, base, &parent_custody); + auto existing_file_or_error = resolve_path(credentials, path, base, &parent_custody); if (!existing_file_or_error.is_error()) return EEXIST; if (!parent_custody) @@ -346,20 +343,18 @@ ErrorOr VirtualFileSystem::mknod(StringView path, mode_t mode, dev_t dev, if (existing_file_or_error.error().code() != ENOENT) return existing_file_or_error.release_error(); auto& parent_inode = parent_custody->inode(); - auto& current_process = Process::current(); - auto current_process_credentials = current_process.credentials(); - if (!parent_inode.metadata().may_write(current_process)) + if (!parent_inode.metadata().may_write(credentials)) return EACCES; if (parent_custody->is_readonly()) return EROFS; auto basename = KLexicalPath::basename(path); dbgln_if(VFS_DEBUG, "VirtualFileSystem::mknod: '{}' mode={} dev={} in {}", basename, mode, dev, parent_inode.identifier()); - (void)TRY(parent_inode.create_child(basename, mode, dev, current_process_credentials->euid(), current_process_credentials->egid())); + (void)TRY(parent_inode.create_child(basename, mode, dev, credentials.euid(), credentials.egid())); return {}; } -ErrorOr> VirtualFileSystem::create(StringView path, int options, mode_t mode, Custody& parent_custody, Optional owner) +ErrorOr> VirtualFileSystem::create(Credentials const& credentials, StringView path, int options, mode_t mode, Custody& parent_custody, Optional owner) { auto basename = KLexicalPath::basename(path); auto parent_path = TRY(parent_custody.try_serialize_absolute_path()); @@ -372,16 +367,14 @@ ErrorOr> VirtualFileSystem::create(String } auto& parent_inode = parent_custody.inode(); - auto& current_process = Process::current(); - auto current_process_credentials = current_process.credentials(); - if (!parent_inode.metadata().may_write(current_process)) + if (!parent_inode.metadata().may_write(credentials)) return EACCES; if (parent_custody.is_readonly()) return EROFS; dbgln_if(VFS_DEBUG, "VirtualFileSystem::create: '{}' in {}", basename, parent_inode.identifier()); - auto uid = owner.has_value() ? owner.value().uid : current_process_credentials->euid(); - auto gid = owner.has_value() ? owner.value().gid : current_process_credentials->egid(); + auto uid = owner.has_value() ? owner.value().uid : credentials.euid(); + auto gid = owner.has_value() ? owner.value().gid : credentials.egid(); auto inode = TRY(parent_inode.create_child(basename, mode, 0, uid, gid)); auto custody = TRY(Custody::try_create(&parent_custody, basename, inode, parent_custody.mount_flags())); @@ -392,7 +385,7 @@ ErrorOr> VirtualFileSystem::create(String return description; } -ErrorOr VirtualFileSystem::mkdir(StringView path, mode_t mode, Custody& base) +ErrorOr VirtualFileSystem::mkdir(Credentials const& credentials, StringView path, mode_t mode, Custody& base) { // Unlike in basically every other case, where it's only the last // path component (the one being created) that is allowed not to @@ -407,7 +400,7 @@ ErrorOr VirtualFileSystem::mkdir(StringView path, mode_t mode, Custody& ba RefPtr parent_custody; // FIXME: The errors returned by resolve_path_without_veil can leak information about paths that are not unveiled, // e.g. when the error is EACCESS or similar. - auto result = resolve_path_without_veil(path, base, &parent_custody); + auto result = resolve_path_without_veil(credentials, path, base, &parent_custody); if (!result.is_error()) return EEXIST; else if (!parent_custody) @@ -417,60 +410,56 @@ ErrorOr VirtualFileSystem::mkdir(StringView path, mode_t mode, Custody& ba TRY(validate_path_against_process_veil(*parent_custody, O_CREAT)); auto& parent_inode = parent_custody->inode(); - auto& current_process = Process::current(); - auto current_process_credentials = current_process.credentials(); - if (!parent_inode.metadata().may_write(current_process)) + if (!parent_inode.metadata().may_write(credentials)) return EACCES; if (parent_custody->is_readonly()) return EROFS; auto basename = KLexicalPath::basename(path); dbgln_if(VFS_DEBUG, "VirtualFileSystem::mkdir: '{}' in {}", basename, parent_inode.identifier()); - (void)TRY(parent_inode.create_child(basename, S_IFDIR | mode, 0, current_process_credentials->euid(), current_process_credentials->egid())); + (void)TRY(parent_inode.create_child(basename, S_IFDIR | mode, 0, credentials.euid(), credentials.egid())); return {}; } -ErrorOr VirtualFileSystem::access(StringView path, int mode, Custody& base) +ErrorOr VirtualFileSystem::access(Credentials const& credentials, StringView path, int mode, Custody& base) { - auto custody = TRY(resolve_path(path, base)); + auto custody = TRY(resolve_path(credentials, path, base)); auto& inode = custody->inode(); auto metadata = inode.metadata(); - auto& current_process = Process::current(); if (mode & R_OK) { - if (!metadata.may_read(current_process)) + if (!metadata.may_read(credentials)) return EACCES; } if (mode & W_OK) { - if (!metadata.may_write(current_process)) + if (!metadata.may_write(credentials)) return EACCES; if (custody->is_readonly()) return EROFS; } if (mode & X_OK) { - if (!metadata.may_execute(current_process)) + if (!metadata.may_execute(credentials)) return EACCES; } return {}; } -ErrorOr> VirtualFileSystem::open_directory(StringView path, Custody& base) +ErrorOr> VirtualFileSystem::open_directory(Credentials const& credentials, StringView path, Custody& base) { - auto custody = TRY(resolve_path(path, base)); + auto custody = TRY(resolve_path(credentials, path, base)); auto& inode = custody->inode(); if (!inode.is_directory()) return ENOTDIR; - if (!inode.metadata().may_execute(Process::current())) + if (!inode.metadata().may_execute(credentials)) return EACCES; return custody; } -ErrorOr VirtualFileSystem::chmod(Custody& custody, mode_t mode) +ErrorOr VirtualFileSystem::chmod(Credentials const& credentials, Custody& custody, mode_t mode) { auto& inode = custody.inode(); - auto& current_process = Process::current(); - if (current_process.euid() != inode.metadata().uid && !current_process.is_superuser()) + if (credentials.euid() != inode.metadata().uid && !credentials.is_superuser()) return EPERM; if (custody.is_readonly()) return EROFS; @@ -480,20 +469,20 @@ ErrorOr VirtualFileSystem::chmod(Custody& custody, mode_t mode) return inode.chmod(mode); } -ErrorOr VirtualFileSystem::chmod(StringView path, mode_t mode, Custody& base, int options) +ErrorOr VirtualFileSystem::chmod(Credentials const& credentials, StringView path, mode_t mode, Custody& base, int options) { - auto custody = TRY(resolve_path(path, base, nullptr, options)); - return chmod(custody, mode); + auto custody = TRY(resolve_path(credentials, path, base, nullptr, options)); + return chmod(credentials, custody, mode); } -ErrorOr VirtualFileSystem::rename(StringView old_path, StringView new_path, Custody& base) +ErrorOr VirtualFileSystem::rename(Credentials const& credentials, StringView old_path, StringView new_path, Custody& base) { RefPtr old_parent_custody; - auto old_custody = TRY(resolve_path(old_path, base, &old_parent_custody, O_NOFOLLOW_NOERROR)); + auto old_custody = TRY(resolve_path(credentials, old_path, base, &old_parent_custody, O_NOFOLLOW_NOERROR)); auto& old_inode = old_custody->inode(); RefPtr new_parent_custody; - auto new_custody_or_error = resolve_path(new_path, base, &new_parent_custody); + auto new_custody_or_error = resolve_path(credentials, new_path, base, &new_parent_custody); if (new_custody_or_error.is_error()) { if (new_custody_or_error.error().code() != ENOENT || !new_parent_custody) return new_custody_or_error.release_error(); @@ -528,15 +517,14 @@ ErrorOr VirtualFileSystem::rename(StringView old_path, StringView new_path return EDIRINTOSELF; } - auto& current_process = Process::current(); - if (!new_parent_inode.metadata().may_write(current_process)) + if (!new_parent_inode.metadata().may_write(credentials)) return EACCES; - if (!old_parent_inode.metadata().may_write(current_process)) + if (!old_parent_inode.metadata().may_write(credentials)) return EACCES; if (old_parent_inode.metadata().is_sticky()) { - if (!current_process.is_superuser() && old_inode.metadata().uid != current_process.euid()) + if (!credentials.is_superuser() && old_inode.metadata().uid != credentials.euid()) return EACCES; } @@ -561,7 +549,7 @@ ErrorOr VirtualFileSystem::rename(StringView old_path, StringView new_path if (&new_inode == &old_inode) return {}; if (new_parent_inode.metadata().is_sticky()) { - if (!current_process.is_superuser() && new_inode.metadata().uid != current_process.euid()) + if (!credentials.is_superuser() && new_inode.metadata().uid != credentials.euid()) return EACCES; } if (new_inode.is_directory() && !old_inode.is_directory()) @@ -574,25 +562,24 @@ ErrorOr VirtualFileSystem::rename(StringView old_path, StringView new_path return {}; } -ErrorOr VirtualFileSystem::chown(Custody& custody, UserID a_uid, GroupID a_gid) +ErrorOr VirtualFileSystem::chown(Credentials const& credentials, Custody& custody, UserID a_uid, GroupID a_gid) { auto& inode = custody.inode(); auto metadata = inode.metadata(); - auto& current_process = Process::current(); - if (current_process.euid() != metadata.uid && !current_process.is_superuser()) + if (credentials.euid() != metadata.uid && !credentials.is_superuser()) return EPERM; UserID new_uid = metadata.uid; GroupID new_gid = metadata.gid; if (a_uid != (uid_t)-1) { - if (current_process.euid() != a_uid && !current_process.is_superuser()) + if (credentials.euid() != a_uid && !credentials.is_superuser()) return EPERM; new_uid = a_uid; } if (a_gid != (gid_t)-1) { - if (!current_process.in_group(a_gid) && !current_process.is_superuser()) + if (!credentials.in_group(a_gid) && !credentials.is_superuser()) return EPERM; new_gid = a_gid; } @@ -610,36 +597,36 @@ ErrorOr VirtualFileSystem::chown(Custody& custody, UserID a_uid, GroupID a return inode.chown(new_uid, new_gid); } -ErrorOr VirtualFileSystem::chown(StringView path, UserID a_uid, GroupID a_gid, Custody& base, int options) +ErrorOr VirtualFileSystem::chown(Credentials const& credentials, StringView path, UserID a_uid, GroupID a_gid, Custody& base, int options) { - auto custody = TRY(resolve_path(path, base, nullptr, options)); - return chown(custody, a_uid, a_gid); + auto custody = TRY(resolve_path(credentials, path, base, nullptr, options)); + return chown(credentials, custody, a_uid, a_gid); } -static bool hard_link_allowed(Inode const& inode) +static bool hard_link_allowed(Credentials const& credentials, Inode const& inode) { auto metadata = inode.metadata(); - if (Process::current().euid() == metadata.uid) + if (credentials.euid() == metadata.uid) return true; if (metadata.is_regular_file() && !metadata.is_setuid() && !(metadata.is_setgid() && metadata.mode & S_IXGRP) - && metadata.may_write(Process::current())) { + && metadata.may_write(credentials)) { return true; } return false; } -ErrorOr VirtualFileSystem::link(StringView old_path, StringView new_path, Custody& base) +ErrorOr VirtualFileSystem::link(Credentials const& credentials, StringView old_path, StringView new_path, Custody& base) { - auto old_custody = TRY(resolve_path(old_path, base)); + auto old_custody = TRY(resolve_path(credentials, old_path, base)); auto& old_inode = old_custody->inode(); RefPtr parent_custody; - auto new_custody_or_error = resolve_path(new_path, base, &parent_custody); + auto new_custody_or_error = resolve_path(credentials, new_path, base, &parent_custody); if (!new_custody_or_error.is_error()) return EEXIST; @@ -651,7 +638,7 @@ ErrorOr VirtualFileSystem::link(StringView old_path, StringView new_path, if (parent_inode.fsid() != old_inode.fsid()) return EXDEV; - if (!parent_inode.metadata().may_write(Process::current())) + if (!parent_inode.metadata().may_write(credentials)) return EACCES; if (old_inode.is_directory()) @@ -660,16 +647,16 @@ ErrorOr VirtualFileSystem::link(StringView old_path, StringView new_path, if (parent_custody->is_readonly()) return EROFS; - if (!hard_link_allowed(old_inode)) + if (!hard_link_allowed(credentials, old_inode)) return EPERM; return parent_inode.add_child(old_inode, KLexicalPath::basename(new_path), old_inode.mode()); } -ErrorOr VirtualFileSystem::unlink(StringView path, Custody& base) +ErrorOr VirtualFileSystem::unlink(Credentials const& credentials, StringView path, Custody& base) { RefPtr parent_custody; - auto custody = TRY(resolve_path(path, base, &parent_custody, O_NOFOLLOW_NOERROR | O_UNLINK_INTERNAL)); + auto custody = TRY(resolve_path(credentials, path, base, &parent_custody, O_NOFOLLOW_NOERROR | O_UNLINK_INTERNAL)); auto& inode = custody->inode(); if (inode.is_directory()) @@ -681,12 +668,11 @@ ErrorOr VirtualFileSystem::unlink(StringView path, Custody& base) VERIFY(parent_custody); auto& parent_inode = parent_custody->inode(); - auto& current_process = Process::current(); - if (!parent_inode.metadata().may_write(current_process)) + if (!parent_inode.metadata().may_write(credentials)) return EACCES; if (parent_inode.metadata().is_sticky()) { - if (!current_process.is_superuser() && inode.metadata().uid != current_process.euid()) + if (!credentials.is_superuser() && inode.metadata().uid != credentials.euid()) return EACCES; } @@ -696,10 +682,10 @@ ErrorOr VirtualFileSystem::unlink(StringView path, Custody& base) return parent_inode.remove_child(KLexicalPath::basename(path)); } -ErrorOr VirtualFileSystem::symlink(StringView target, StringView linkpath, Custody& base) +ErrorOr VirtualFileSystem::symlink(Credentials const& credentials, StringView target, StringView linkpath, Custody& base) { RefPtr parent_custody; - auto existing_custody_or_error = resolve_path(linkpath, base, &parent_custody); + auto existing_custody_or_error = resolve_path(credentials, linkpath, base, &parent_custody); if (!existing_custody_or_error.is_error()) return EEXIST; if (!parent_custody) @@ -707,9 +693,7 @@ ErrorOr VirtualFileSystem::symlink(StringView target, StringView linkpath, if (existing_custody_or_error.is_error() && existing_custody_or_error.error().code() != ENOENT) return existing_custody_or_error.release_error(); auto& parent_inode = parent_custody->inode(); - auto& current_process = Process::current(); - auto current_process_credentials = current_process.credentials(); - if (!parent_inode.metadata().may_write(current_process)) + if (!parent_inode.metadata().may_write(credentials)) return EACCES; if (parent_custody->is_readonly()) return EROFS; @@ -717,7 +701,7 @@ ErrorOr VirtualFileSystem::symlink(StringView target, StringView linkpath, auto basename = KLexicalPath::basename(linkpath); dbgln_if(VFS_DEBUG, "VirtualFileSystem::symlink: '{}' (-> '{}') in {}", basename, target, parent_inode.identifier()); - auto inode = TRY(parent_inode.create_child(basename, S_IFLNK | 0644, 0, current_process_credentials->euid(), current_process_credentials->egid())); + auto inode = TRY(parent_inode.create_child(basename, S_IFLNK | 0644, 0, credentials.euid(), credentials.egid())); auto target_buffer = UserOrKernelBuffer::for_kernel_buffer(const_cast((u8 const*)target.characters_without_null_termination())); MutexLocker locker(inode->m_inode_lock); @@ -726,10 +710,10 @@ ErrorOr VirtualFileSystem::symlink(StringView target, StringView linkpath, return {}; } -ErrorOr VirtualFileSystem::rmdir(StringView path, Custody& base) +ErrorOr VirtualFileSystem::rmdir(Credentials const& credentials, StringView path, Custody& base) { RefPtr parent_custody; - auto custody = TRY(resolve_path(path, base, &parent_custody)); + auto custody = TRY(resolve_path(credentials, path, base, &parent_custody)); auto& inode = custody->inode(); // FIXME: We should return EINVAL if the last component of the path is "." @@ -744,12 +728,11 @@ ErrorOr VirtualFileSystem::rmdir(StringView path, Custody& base) auto& parent_inode = parent_custody->inode(); auto parent_metadata = parent_inode.metadata(); - auto& current_process = Process::current(); - if (!parent_metadata.may_write(current_process)) + if (!parent_metadata.may_write(credentials)) return EACCES; if (parent_metadata.is_sticky()) { - if (!current_process.is_superuser() && inode.metadata().uid != current_process.euid()) + if (!credentials.is_superuser() && inode.metadata().uid != credentials.euid()) return EACCES; } @@ -880,11 +863,11 @@ ErrorOr VirtualFileSystem::validate_path_against_process_veil(StringView p return {}; } -ErrorOr> VirtualFileSystem::resolve_path(StringView path, NonnullRefPtr base, RefPtr* out_parent, int options, int symlink_recursion_level) +ErrorOr> VirtualFileSystem::resolve_path(Credentials const& credentials, StringView path, NonnullRefPtr base, RefPtr* out_parent, int options, int symlink_recursion_level) { // FIXME: The errors returned by resolve_path_without_veil can leak information about paths that are not unveiled, // e.g. when the error is EACCESS or similar. - auto custody = TRY(resolve_path_without_veil(path, base, out_parent, options, symlink_recursion_level)); + auto custody = TRY(resolve_path_without_veil(credentials, path, base, out_parent, options, symlink_recursion_level)); if (auto result = validate_path_against_process_veil(*custody, options); result.is_error()) { if (out_parent) out_parent->clear(); @@ -893,10 +876,10 @@ ErrorOr> VirtualFileSystem::resolve_path(StringView path, return custody; } -static bool safe_to_follow_symlink(Inode const& inode, InodeMetadata const& parent_metadata) +static bool safe_to_follow_symlink(Credentials const& credentials, Inode const& inode, InodeMetadata const& parent_metadata) { auto metadata = inode.metadata(); - if (Process::current().euid() == metadata.uid) + if (credentials.euid() == metadata.uid) return true; if (!(parent_metadata.is_sticky() && parent_metadata.mode & S_IWOTH)) @@ -908,7 +891,7 @@ static bool safe_to_follow_symlink(Inode const& inode, InodeMetadata const& pare return false; } -ErrorOr> VirtualFileSystem::resolve_path_without_veil(StringView path, NonnullRefPtr base, RefPtr* out_parent, int options, int symlink_recursion_level) +ErrorOr> VirtualFileSystem::resolve_path_without_veil(Credentials const& credentials, StringView path, NonnullRefPtr base, RefPtr* out_parent, int options, int symlink_recursion_level) { if (symlink_recursion_level >= symlink_recursion_limit) return ELOOP; @@ -917,7 +900,6 @@ ErrorOr> VirtualFileSystem::resolve_path_without_veil(Str return EINVAL; GenericLexer path_lexer(path); - auto& current_process = Process::current(); NonnullRefPtr custody = path[0] == '/' ? root_custody() : base; bool extra_iteration = path[path.length() - 1] == '/'; @@ -933,7 +915,7 @@ ErrorOr> VirtualFileSystem::resolve_path_without_veil(Str if (!parent_metadata.is_directory()) return ENOTDIR; // Ensure the current user is allowed to resolve paths inside this directory. - if (!parent_metadata.may_execute(current_process)) + if (!parent_metadata.may_execute(credentials)) return EACCES; bool have_more_parts = !path_lexer.is_eof() || extra_iteration; @@ -979,7 +961,7 @@ ErrorOr> VirtualFileSystem::resolve_path_without_veil(Str break; } - if (!safe_to_follow_symlink(*child_inode, parent_metadata)) + if (!safe_to_follow_symlink(credentials, *child_inode, parent_metadata)) return EACCES; TRY(validate_path_against_process_veil(*custody, options)); @@ -995,7 +977,7 @@ ErrorOr> VirtualFileSystem::resolve_path_without_veil(Str TRY(remaining_path.try_append('.')); TRY(remaining_path.try_append(path.substring_view_starting_after_substring(part))); - return resolve_path_without_veil(remaining_path.string_view(), symlink_target, out_parent, options, symlink_recursion_level + 1); + return resolve_path_without_veil(credentials, remaining_path.string_view(), symlink_target, out_parent, options, symlink_recursion_level + 1); } } diff --git a/Kernel/FileSystem/VirtualFileSystem.h b/Kernel/FileSystem/VirtualFileSystem.h index 26459474d8..75094b4b1b 100644 --- a/Kernel/FileSystem/VirtualFileSystem.h +++ b/Kernel/FileSystem/VirtualFileSystem.h @@ -50,24 +50,24 @@ public: ErrorOr remount(Custody& mount_point, int new_flags); ErrorOr unmount(Inode& guest_inode); - ErrorOr> open(StringView path, int options, mode_t mode, Custody& base, Optional = {}); - ErrorOr> create(StringView path, int options, mode_t mode, Custody& parent_custody, Optional = {}); - ErrorOr mkdir(StringView path, mode_t mode, Custody& base); - ErrorOr link(StringView old_path, StringView new_path, Custody& base); - ErrorOr unlink(StringView path, Custody& base); - ErrorOr symlink(StringView target, StringView linkpath, Custody& base); - ErrorOr rmdir(StringView path, Custody& base); - ErrorOr chmod(StringView path, mode_t, Custody& base, int options = 0); - ErrorOr chmod(Custody&, mode_t); - ErrorOr chown(StringView path, UserID, GroupID, Custody& base, int options); - ErrorOr chown(Custody&, UserID, GroupID); - ErrorOr access(StringView path, int mode, Custody& base); - ErrorOr lookup_metadata(StringView path, Custody& base, int options = 0); - ErrorOr utime(StringView path, Custody& base, time_t atime, time_t mtime); - ErrorOr utimensat(StringView path, Custody& base, timespec const& atime, timespec const& mtime, int options = 0); - ErrorOr rename(StringView oldpath, StringView newpath, Custody& base); - ErrorOr mknod(StringView path, mode_t, dev_t, Custody& base); - ErrorOr> open_directory(StringView path, Custody& base); + ErrorOr> open(Credentials const&, StringView path, int options, mode_t mode, Custody& base, Optional = {}); + ErrorOr> create(Credentials const&, StringView path, int options, mode_t mode, Custody& parent_custody, Optional = {}); + ErrorOr mkdir(Credentials const&, StringView path, mode_t mode, Custody& base); + ErrorOr link(Credentials const&, StringView old_path, StringView new_path, Custody& base); + ErrorOr unlink(Credentials const&, StringView path, Custody& base); + ErrorOr symlink(Credentials const&, StringView target, StringView linkpath, Custody& base); + ErrorOr rmdir(Credentials const&, StringView path, Custody& base); + ErrorOr chmod(Credentials const&, StringView path, mode_t, Custody& base, int options = 0); + ErrorOr chmod(Credentials const&, Custody&, mode_t); + ErrorOr chown(Credentials const&, StringView path, UserID, GroupID, Custody& base, int options); + ErrorOr chown(Credentials const&, Custody&, UserID, GroupID); + ErrorOr access(Credentials const&, StringView path, int mode, Custody& base); + ErrorOr lookup_metadata(Credentials const&, StringView path, Custody& base, int options = 0); + ErrorOr utime(Credentials const&, StringView path, Custody& base, time_t atime, time_t mtime); + ErrorOr utimensat(Credentials const&, StringView path, Custody& base, timespec const& atime, timespec const& mtime, int options = 0); + ErrorOr rename(Credentials const&, StringView oldpath, StringView newpath, Custody& base); + ErrorOr mknod(Credentials const&, StringView path, mode_t, dev_t, Custody& base); + ErrorOr> open_directory(Credentials const&, StringView path, Custody& base); ErrorOr for_each_mount(Function(Mount const&)>) const; @@ -76,8 +76,8 @@ public: static void sync(); NonnullRefPtr root_custody(); - ErrorOr> resolve_path(StringView path, NonnullRefPtr base, RefPtr* out_parent = nullptr, int options = 0, int symlink_recursion_level = 0); - ErrorOr> resolve_path_without_veil(StringView path, NonnullRefPtr base, RefPtr* out_parent = nullptr, int options = 0, int symlink_recursion_level = 0); + ErrorOr> resolve_path(Credentials const&, StringView path, NonnullRefPtr base, RefPtr* out_parent = nullptr, int options = 0, int symlink_recursion_level = 0); + ErrorOr> resolve_path_without_veil(Credentials const&, StringView path, NonnullRefPtr base, RefPtr* out_parent = nullptr, int options = 0, int symlink_recursion_level = 0); private: friend class OpenFileDescription; diff --git a/Kernel/Net/LocalSocket.cpp b/Kernel/Net/LocalSocket.cpp index eaf23cc66b..c6c4e7e457 100644 --- a/Kernel/Net/LocalSocket.cpp +++ b/Kernel/Net/LocalSocket.cpp @@ -139,7 +139,7 @@ ErrorOr LocalSocket::bind(Userspace user_address, socklen mode_t mode = S_IFSOCK | (m_prebind_mode & 0777); UidAndGid owner { m_prebind_uid, m_prebind_gid }; - auto result = VirtualFileSystem::the().open(path->view(), O_CREAT | O_EXCL | O_NOFOLLOW_NOERROR, mode, Process::current().current_directory(), owner); + auto result = VirtualFileSystem::the().open(Process::current().credentials(), path->view(), O_CREAT | O_EXCL | O_NOFOLLOW_NOERROR, mode, Process::current().current_directory(), owner); if (result.is_error()) { if (result.error().code() == EEXIST) return set_so_error(EADDRINUSE); @@ -179,7 +179,7 @@ ErrorOr LocalSocket::connect(OpenFileDescription& description, Userspaceview(), O_RDWR, 0, Process::current().current_directory())); + auto file = SOCKET_TRY(VirtualFileSystem::the().open(Process::current().credentials(), path->view(), O_RDWR, 0, Process::current().current_directory())); auto inode = file->inode(); m_inode = inode; diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 5d922a3552..a32df9c4e3 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -583,8 +583,9 @@ ErrorOr Process::dump_perfcore() auto base_filename = TRY(KString::formatted("{}_{}", name(), pid().value())); auto perfcore_filename = TRY(KString::formatted("{}.profile", base_filename)); LockRefPtr description; + auto credentials = this->credentials(); for (size_t attempt = 1; attempt <= 10; ++attempt) { - auto description_or_error = VirtualFileSystem::the().open(perfcore_filename->view(), O_CREAT | O_EXCL, 0400, current_directory(), UidAndGid { 0, 0 }); + auto description_or_error = VirtualFileSystem::the().open(credentials, perfcore_filename->view(), O_CREAT | O_EXCL, 0400, current_directory(), UidAndGid { 0, 0 }); if (!description_or_error.is_error()) { description = description_or_error.release_value(); break; diff --git a/Kernel/Syscalls/access.cpp b/Kernel/Syscalls/access.cpp index 08177de6c1..6a2a246e48 100644 --- a/Kernel/Syscalls/access.cpp +++ b/Kernel/Syscalls/access.cpp @@ -15,7 +15,7 @@ ErrorOr Process::sys$access(Userspace user_path, size_t pa VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this); TRY(require_promise(Pledge::rpath)); auto path = TRY(get_syscall_path_argument(user_path, path_length)); - TRY(VirtualFileSystem::the().access(path->view(), mode, current_directory())); + TRY(VirtualFileSystem::the().access(credentials(), path->view(), mode, current_directory())); return 0; } diff --git a/Kernel/Syscalls/chdir.cpp b/Kernel/Syscalls/chdir.cpp index a10a7cbc5b..0df61f7e1d 100644 --- a/Kernel/Syscalls/chdir.cpp +++ b/Kernel/Syscalls/chdir.cpp @@ -19,7 +19,7 @@ ErrorOr Process::sys$chdir(Userspace user_path, size_t pat auto current_directory = m_current_directory.with([](auto& current_directory) -> NonnullRefPtr { return *current_directory; }); - RefPtr new_directory = TRY(VirtualFileSystem::the().open_directory(path->view(), *current_directory)); + RefPtr new_directory = TRY(VirtualFileSystem::the().open_directory(credentials(), path->view(), *current_directory)); m_current_directory.with([&](auto& current_directory) { // NOTE: We use swap() here to avoid manipulating the ref counts while holding the lock. swap(current_directory, new_directory); @@ -34,7 +34,7 @@ ErrorOr Process::sys$fchdir(int fd) auto description = TRY(open_file_description(fd)); if (!description->is_directory()) return ENOTDIR; - if (!description->metadata().may_execute(*this)) + if (!description->metadata().may_execute(credentials())) return EACCES; m_current_directory.with([&](auto& current_directory) { current_directory = description->custody(); diff --git a/Kernel/Syscalls/chmod.cpp b/Kernel/Syscalls/chmod.cpp index c1f2e2fc8d..0b5db76bd3 100644 --- a/Kernel/Syscalls/chmod.cpp +++ b/Kernel/Syscalls/chmod.cpp @@ -28,7 +28,7 @@ ErrorOr Process::sys$chmod(Userspace u base = base_description->custody(); } - TRY(VirtualFileSystem::the().chmod(path->view(), params.mode, *base, params.follow_symlinks ? 0 : O_NOFOLLOW_NOERROR)); + 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 4a72df16a2..29ab8c8703 100644 --- a/Kernel/Syscalls/chown.cpp +++ b/Kernel/Syscalls/chown.cpp @@ -38,7 +38,7 @@ ErrorOr Process::sys$chown(Userspace u base = base_description->custody(); } - TRY(VirtualFileSystem::the().chown(path->view(), params.uid, params.gid, *base, params.follow_symlinks ? 0 : O_NOFOLLOW_NOERROR)); + 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/execve.cpp b/Kernel/Syscalls/execve.cpp index ff4c1cb718..6cedb9a736 100644 --- a/Kernel/Syscalls/execve.cpp +++ b/Kernel/Syscalls/execve.cpp @@ -758,7 +758,7 @@ ErrorOr> Process::find_elf_interpreter_for_execu if (!interpreter_path.is_empty()) { dbgln_if(EXEC_DEBUG, "exec({}): Using program interpreter {}", path, interpreter_path); - auto interpreter_description = TRY(VirtualFileSystem::the().open(interpreter_path, O_EXEC, 0, current_directory())); + auto interpreter_description = TRY(VirtualFileSystem::the().open(credentials(), interpreter_path, O_EXEC, 0, current_directory())); auto interp_metadata = interpreter_description->metadata(); VERIFY(interpreter_description->inode()); @@ -827,7 +827,7 @@ ErrorOr Process::exec(NonnullOwnPtr path, NonnullOwnPtrVectorview(), O_EXEC, 0, current_directory())); + auto description = TRY(VirtualFileSystem::the().open(credentials(), path->view(), O_EXEC, 0, current_directory())); auto metadata = description->metadata(); if (!metadata.is_regular_file()) diff --git a/Kernel/Syscalls/inode_watcher.cpp b/Kernel/Syscalls/inode_watcher.cpp index 2ff70ca498..51d6fdb04a 100644 --- a/Kernel/Syscalls/inode_watcher.cpp +++ b/Kernel/Syscalls/inode_watcher.cpp @@ -47,7 +47,7 @@ ErrorOr Process::sys$inode_watcher_add_watch(Userspaceinode_watcher(); auto path = TRY(get_syscall_path_argument(params.user_path)); - auto custody = TRY(VirtualFileSystem::the().resolve_path(path->view(), current_directory())); + auto custody = TRY(VirtualFileSystem::the().resolve_path(credentials(), path->view(), current_directory())); if (!custody->inode().fs().supports_watchers()) return ENOTSUP; diff --git a/Kernel/Syscalls/link.cpp b/Kernel/Syscalls/link.cpp index 19da805cb1..5cc048caa8 100644 --- a/Kernel/Syscalls/link.cpp +++ b/Kernel/Syscalls/link.cpp @@ -17,7 +17,7 @@ ErrorOr Process::sys$link(Userspace use auto params = TRY(copy_typed_from_user(user_params)); auto old_path = TRY(try_copy_kstring_from_user(params.old_path)); auto new_path = TRY(try_copy_kstring_from_user(params.new_path)); - TRY(VirtualFileSystem::the().link(old_path->view(), new_path->view(), current_directory())); + TRY(VirtualFileSystem::the().link(credentials(), old_path->view(), new_path->view(), current_directory())); return 0; } @@ -29,7 +29,7 @@ ErrorOr Process::sys$symlink(Userspaceview(), linkpath->view(), current_directory())); + TRY(VirtualFileSystem::the().symlink(credentials(), target->view(), linkpath->view(), current_directory())); return 0; } diff --git a/Kernel/Syscalls/mkdir.cpp b/Kernel/Syscalls/mkdir.cpp index 46451a6f3c..7cd0de8cbd 100644 --- a/Kernel/Syscalls/mkdir.cpp +++ b/Kernel/Syscalls/mkdir.cpp @@ -15,7 +15,7 @@ ErrorOr Process::sys$mkdir(Userspace user_path, size_t pat VERIFY_NO_PROCESS_BIG_LOCK(this); TRY(require_promise(Pledge::cpath)); auto path = TRY(get_syscall_path_argument(user_path, path_length)); - TRY(VirtualFileSystem::the().mkdir(path->view(), mode & ~umask(), current_directory())); + TRY(VirtualFileSystem::the().mkdir(credentials(), path->view(), mode & ~umask(), current_directory())); return 0; } } diff --git a/Kernel/Syscalls/mknod.cpp b/Kernel/Syscalls/mknod.cpp index ba07f2142b..13c26cc935 100644 --- a/Kernel/Syscalls/mknod.cpp +++ b/Kernel/Syscalls/mknod.cpp @@ -19,7 +19,7 @@ ErrorOr Process::sys$mknod(Userspace u if (!is_superuser() && !is_regular_file(params.mode) && !is_fifo(params.mode) && !is_socket(params.mode)) return EPERM; auto path = TRY(get_syscall_path_argument(params.path)); - TRY(VirtualFileSystem::the().mknod(path->view(), params.mode & ~umask(), params.dev, current_directory())); + TRY(VirtualFileSystem::the().mknod(credentials(), path->view(), params.mode & ~umask(), params.dev, current_directory())); return 0; } diff --git a/Kernel/Syscalls/mmap.cpp b/Kernel/Syscalls/mmap.cpp index aab05f47c2..c5afee7b7b 100644 --- a/Kernel/Syscalls/mmap.cpp +++ b/Kernel/Syscalls/mmap.cpp @@ -105,15 +105,16 @@ ErrorOr Process::validate_mmap_prot(int prot, bool map_stack, bool map_ano ErrorOr Process::validate_inode_mmap_prot(int prot, Inode const& inode, bool map_shared) const { + auto credentials = this->credentials(); auto metadata = inode.metadata(); - if ((prot & PROT_READ) && !metadata.may_read(*this)) + if ((prot & PROT_READ) && !metadata.may_read(credentials)) return EACCES; if (map_shared) { // FIXME: What about readonly filesystem mounts? We cannot make a // decision here without knowing the mount flags, so we would need to // keep a Custody or something from mmap time. - if ((prot & PROT_WRITE) && !metadata.may_write(*this)) + if ((prot & PROT_WRITE) && !metadata.may_write(credentials)) return EACCES; if (auto shared_vmobject = inode.shared_vmobject()) { if ((prot & PROT_EXEC) && shared_vmobject->writable_mappings()) diff --git a/Kernel/Syscalls/mount.cpp b/Kernel/Syscalls/mount.cpp index 5443e30e8e..bd428970e2 100644 --- a/Kernel/Syscalls/mount.cpp +++ b/Kernel/Syscalls/mount.cpp @@ -86,7 +86,7 @@ ErrorOr Process::sys$mount(Userspace u else dbgln("mount {} @ {}", fs_type, target); - auto target_custody = TRY(VirtualFileSystem::the().resolve_path(target->view(), current_directory())); + auto target_custody = TRY(VirtualFileSystem::the().resolve_path(credentials(), target->view(), current_directory())); if (params.flags & MS_REMOUNT) { // We're not creating a new mount, we're updating an existing one! @@ -132,7 +132,7 @@ ErrorOr Process::sys$umount(Userspace user_mountpoint, siz TRY(require_no_promises()); auto mountpoint = TRY(get_syscall_path_argument(user_mountpoint, mountpoint_length)); - auto custody = TRY(VirtualFileSystem::the().resolve_path(mountpoint->view(), current_directory())); + auto custody = TRY(VirtualFileSystem::the().resolve_path(credentials(), mountpoint->view(), current_directory())); auto& guest_inode = custody->inode(); TRY(VirtualFileSystem::the().unmount(guest_inode)); return 0; diff --git a/Kernel/Syscalls/open.cpp b/Kernel/Syscalls/open.cpp index 2a0c773255..59f7af709e 100644 --- a/Kernel/Syscalls/open.cpp +++ b/Kernel/Syscalls/open.cpp @@ -67,7 +67,7 @@ ErrorOr Process::sys$open(Userspace use base = base_description->custody(); } - auto description = TRY(VirtualFileSystem::the().open(path->view(), options, mode & ~umask(), *base)); + auto description = TRY(VirtualFileSystem::the().open(credentials(), path->view(), options, mode & ~umask(), *base)); if (description->inode() && description->inode()->bound_socket()) return ENXIO; diff --git a/Kernel/Syscalls/readlink.cpp b/Kernel/Syscalls/readlink.cpp index 540073ea9a..593eb862d3 100644 --- a/Kernel/Syscalls/readlink.cpp +++ b/Kernel/Syscalls/readlink.cpp @@ -17,7 +17,7 @@ ErrorOr Process::sys$readlink(Userspaceview(), O_RDONLY | O_NOFOLLOW_NOERROR, 0, current_directory())); + auto description = TRY(VirtualFileSystem::the().open(credentials(), path->view(), O_RDONLY | O_NOFOLLOW_NOERROR, 0, current_directory())); if (!description->metadata().is_symlink()) return EINVAL; diff --git a/Kernel/Syscalls/realpath.cpp b/Kernel/Syscalls/realpath.cpp index 1412761310..a6c7f6df7f 100644 --- a/Kernel/Syscalls/realpath.cpp +++ b/Kernel/Syscalls/realpath.cpp @@ -18,7 +18,7 @@ ErrorOr Process::sys$realpath(Userspaceview(), current_directory())); + auto custody = TRY(VirtualFileSystem::the().resolve_path(credentials(), path->view(), current_directory())); auto absolute_path = TRY(custody->try_serialize_absolute_path()); size_t ideal_size = absolute_path->length() + 1; diff --git a/Kernel/Syscalls/rename.cpp b/Kernel/Syscalls/rename.cpp index 8da237d1dd..7ebcb3d4d0 100644 --- a/Kernel/Syscalls/rename.cpp +++ b/Kernel/Syscalls/rename.cpp @@ -17,7 +17,7 @@ ErrorOr Process::sys$rename(Userspace auto params = TRY(copy_typed_from_user(user_params)); auto old_path = TRY(get_syscall_path_argument(params.old_path)); auto new_path = TRY(get_syscall_path_argument(params.new_path)); - TRY(VirtualFileSystem::the().rename(old_path->view(), new_path->view(), current_directory())); + TRY(VirtualFileSystem::the().rename(credentials(), old_path->view(), new_path->view(), current_directory())); return 0; } diff --git a/Kernel/Syscalls/rmdir.cpp b/Kernel/Syscalls/rmdir.cpp index 0db5ee57f1..42e77a33fa 100644 --- a/Kernel/Syscalls/rmdir.cpp +++ b/Kernel/Syscalls/rmdir.cpp @@ -15,7 +15,7 @@ ErrorOr Process::sys$rmdir(Userspace user_path, size_t pat VERIFY_NO_PROCESS_BIG_LOCK(this); TRY(require_promise(Pledge::cpath)); auto path = TRY(get_syscall_path_argument(user_path, path_length)); - TRY(VirtualFileSystem::the().rmdir(path->view(), current_directory())); + TRY(VirtualFileSystem::the().rmdir(credentials(), path->view(), current_directory())); return 0; } diff --git a/Kernel/Syscalls/stat.cpp b/Kernel/Syscalls/stat.cpp index 89194d32d0..650c88eb83 100644 --- a/Kernel/Syscalls/stat.cpp +++ b/Kernel/Syscalls/stat.cpp @@ -41,7 +41,7 @@ ErrorOr Process::sys$stat(Userspace use return EINVAL; base = base_description->custody(); } - auto metadata = TRY(VirtualFileSystem::the().lookup_metadata(path->view(), *base, params.follow_symlinks ? 0 : O_NOFOLLOW_NOERROR)); + 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)); return 0; diff --git a/Kernel/Syscalls/statvfs.cpp b/Kernel/Syscalls/statvfs.cpp index 856b0752bf..c72799d070 100644 --- a/Kernel/Syscalls/statvfs.cpp +++ b/Kernel/Syscalls/statvfs.cpp @@ -47,7 +47,7 @@ ErrorOr Process::sys$statvfs(Userspaceview(), current_directory(), nullptr, 0)); + auto custody = TRY(VirtualFileSystem::the().resolve_path(credentials(), path->view(), current_directory(), nullptr, 0)); auto& inode = custody->inode(); auto const& fs = inode.fs(); diff --git a/Kernel/Syscalls/unlink.cpp b/Kernel/Syscalls/unlink.cpp index 5f3a62330e..d545e4ce0b 100644 --- a/Kernel/Syscalls/unlink.cpp +++ b/Kernel/Syscalls/unlink.cpp @@ -30,9 +30,9 @@ ErrorOr Process::sys$unlink(int dirfd, Userspace user_path } if (flags & AT_REMOVEDIR) - TRY(VirtualFileSystem::the().rmdir(path->view(), *base)); + TRY(VirtualFileSystem::the().rmdir(credentials(), path->view(), *base)); else - TRY(VirtualFileSystem::the().unlink(path->view(), *base)); + TRY(VirtualFileSystem::the().unlink(credentials(), path->view(), *base)); return 0; } diff --git a/Kernel/Syscalls/unveil.cpp b/Kernel/Syscalls/unveil.cpp index a27ebefbbb..496791b03f 100644 --- a/Kernel/Syscalls/unveil.cpp +++ b/Kernel/Syscalls/unveil.cpp @@ -82,7 +82,7 @@ ErrorOr Process::sys$unveil(Userspace // If this case is encountered, the parent node of the path is returned and the custody of that inode is used instead. RefPtr parent_custody; // Parent inode in case of ENOENT OwnPtr new_unveiled_path; - auto custody_or_error = VirtualFileSystem::the().resolve_path_without_veil(path->view(), VirtualFileSystem::the().root_custody(), &parent_custody); + auto custody_or_error = VirtualFileSystem::the().resolve_path_without_veil(credentials(), path->view(), VirtualFileSystem::the().root_custody(), &parent_custody); if (!custody_or_error.is_error()) { new_unveiled_path = TRY(custody_or_error.value()->try_serialize_absolute_path()); } else if (custody_or_error.error().code() == ENOENT && parent_custody && (new_permissions & UnveilAccess::CreateOrRemove)) { diff --git a/Kernel/Syscalls/utime.cpp b/Kernel/Syscalls/utime.cpp index 1e1bb4144f..a0e4d2a188 100644 --- a/Kernel/Syscalls/utime.cpp +++ b/Kernel/Syscalls/utime.cpp @@ -23,7 +23,7 @@ ErrorOr Process::sys$utime(Userspace user_path, size_t pat // Not a bug! buf = { now, now }; } - TRY(VirtualFileSystem::the().utime(path->view(), current_directory(), buf.actime, buf.modtime)); + TRY(VirtualFileSystem::the().utime(credentials(), path->view(), current_directory(), buf.actime, buf.modtime)); return 0; } diff --git a/Kernel/Syscalls/utimensat.cpp b/Kernel/Syscalls/utimensat.cpp index 73b13ecb2e..26d8a4704f 100644 --- a/Kernel/Syscalls/utimensat.cpp +++ b/Kernel/Syscalls/utimensat.cpp @@ -71,7 +71,7 @@ ErrorOr Process::sys$utimensat(Userspaceview(), *base, atime, mtime, follow_symlink)); + TRY(VirtualFileSystem::the().utimensat(credentials(), path->view(), *base, atime, mtime, follow_symlink)); return 0; }