1
0
mirror of https://github.com/SerenityOS/serenity synced 2024-07-09 11:20:46 +00:00

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.
This commit is contained in:
Andreas Kling 2022-08-21 16:02:24 +02:00
parent 9744dedb50
commit c3351d4b9f
33 changed files with 159 additions and 165 deletions

View File

@ -62,19 +62,21 @@ Coredump::Coredump(NonnullLockRefPtr<Process> process, NonnullLockRefPtr<OpenFil
ErrorOr<NonnullLockRefPtr<OpenFileDescription>> 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<void> Coredump::write_elf_header()

View File

@ -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);
}
}

View File

@ -27,6 +27,8 @@ public:
GroupID sgid() const { return m_sgid; }
Span<GroupID const> 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<GroupID> extra_gids);

View File

@ -82,7 +82,7 @@ ErrorOr<NonnullRefPtr<Custody>> Inode::resolve_as_link(Custody& base, RefPtr<Cus
// contents as a path and resolves that. That is, it
// behaves exactly how you would expect a symlink to work.
auto contents = TRY(read_entire());
return VirtualFileSystem::the().resolve_path(StringView { contents->bytes() }, 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)

View File

@ -119,14 +119,14 @@ ErrorOr<void> 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<void> 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);
}
}

View File

@ -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());
}
}

View File

@ -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<GroupID const> eg) const
{
if (u == 0)

View File

@ -204,12 +204,11 @@ ErrorOr<void> VirtualFileSystem::traverse_directory_inode(Inode& dir_inode, Func
});
}
ErrorOr<void> VirtualFileSystem::utime(StringView path, Custody& base, time_t atime, time_t mtime)
ErrorOr<void> 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<void> VirtualFileSystem::utime(StringView path, Custody& base, time_t at
return {};
}
ErrorOr<void> VirtualFileSystem::utimensat(StringView path, Custody& base, timespec const& atime, timespec const& mtime, int options)
ErrorOr<void> 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<void> VirtualFileSystem::utimensat(StringView path, Custody& base, times
return {};
}
ErrorOr<InodeMetadata> VirtualFileSystem::lookup_metadata(StringView path, Custody& base, int options)
ErrorOr<InodeMetadata> 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<NonnullLockRefPtr<OpenFileDescription>> VirtualFileSystem::open(StringView path, int options, mode_t mode, Custody& base, Optional<UidAndGid> owner)
ErrorOr<NonnullLockRefPtr<OpenFileDescription>> VirtualFileSystem::open(Credentials const& credentials, StringView path, int options, mode_t mode, Custody& base, Optional<UidAndGid> owner)
{
if ((options & O_CREAT) && (options & O_DIRECTORY))
return EINVAL;
RefPtr<Custody> 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<NonnullLockRefPtr<OpenFileDescription>> 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<NonnullLockRefPtr<OpenFileDescription>> VirtualFileSystem::open(StringVi
return description;
}
ErrorOr<void> VirtualFileSystem::mknod(StringView path, mode_t mode, dev_t dev, Custody& base)
ErrorOr<void> 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<Custody> 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<void> 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<NonnullLockRefPtr<OpenFileDescription>> VirtualFileSystem::create(StringView path, int options, mode_t mode, Custody& parent_custody, Optional<UidAndGid> owner)
ErrorOr<NonnullLockRefPtr<OpenFileDescription>> VirtualFileSystem::create(Credentials const& credentials, StringView path, int options, mode_t mode, Custody& parent_custody, Optional<UidAndGid> owner)
{
auto basename = KLexicalPath::basename(path);
auto parent_path = TRY(parent_custody.try_serialize_absolute_path());
@ -372,16 +367,14 @@ ErrorOr<NonnullLockRefPtr<OpenFileDescription>> 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<NonnullLockRefPtr<OpenFileDescription>> VirtualFileSystem::create(String
return description;
}
ErrorOr<void> VirtualFileSystem::mkdir(StringView path, mode_t mode, Custody& base)
ErrorOr<void> 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<void> VirtualFileSystem::mkdir(StringView path, mode_t mode, Custody& ba
RefPtr<Custody> 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<void> 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<void> VirtualFileSystem::access(StringView path, int mode, Custody& base)
ErrorOr<void> 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<NonnullRefPtr<Custody>> VirtualFileSystem::open_directory(StringView path, Custody& base)
ErrorOr<NonnullRefPtr<Custody>> 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<void> VirtualFileSystem::chmod(Custody& custody, mode_t mode)
ErrorOr<void> 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<void> VirtualFileSystem::chmod(Custody& custody, mode_t mode)
return inode.chmod(mode);
}
ErrorOr<void> VirtualFileSystem::chmod(StringView path, mode_t mode, Custody& base, int options)
ErrorOr<void> 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<void> VirtualFileSystem::rename(StringView old_path, StringView new_path, Custody& base)
ErrorOr<void> VirtualFileSystem::rename(Credentials const& credentials, StringView old_path, StringView new_path, Custody& base)
{
RefPtr<Custody> 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<Custody> 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<void> 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<void> 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<void> VirtualFileSystem::rename(StringView old_path, StringView new_path
return {};
}
ErrorOr<void> VirtualFileSystem::chown(Custody& custody, UserID a_uid, GroupID a_gid)
ErrorOr<void> 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<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, int options)
ErrorOr<void> 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<void> VirtualFileSystem::link(StringView old_path, StringView new_path, Custody& base)
ErrorOr<void> 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<Custody> 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<void> 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<void> 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<void> VirtualFileSystem::unlink(StringView path, Custody& base)
ErrorOr<void> VirtualFileSystem::unlink(Credentials const& credentials, StringView path, Custody& base)
{
RefPtr<Custody> 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<void> 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<void> VirtualFileSystem::unlink(StringView path, Custody& base)
return parent_inode.remove_child(KLexicalPath::basename(path));
}
ErrorOr<void> VirtualFileSystem::symlink(StringView target, StringView linkpath, Custody& base)
ErrorOr<void> VirtualFileSystem::symlink(Credentials const& credentials, StringView target, StringView linkpath, Custody& base)
{
RefPtr<Custody> 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<void> 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<void> 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*>((u8 const*)target.characters_without_null_termination()));
MutexLocker locker(inode->m_inode_lock);
@ -726,10 +710,10 @@ ErrorOr<void> VirtualFileSystem::symlink(StringView target, StringView linkpath,
return {};
}
ErrorOr<void> VirtualFileSystem::rmdir(StringView path, Custody& base)
ErrorOr<void> VirtualFileSystem::rmdir(Credentials const& credentials, StringView path, Custody& base)
{
RefPtr<Custody> 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<void> 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<void> VirtualFileSystem::validate_path_against_process_veil(StringView p
return {};
}
ErrorOr<NonnullRefPtr<Custody>> VirtualFileSystem::resolve_path(StringView path, NonnullRefPtr<Custody> base, RefPtr<Custody>* out_parent, int options, int symlink_recursion_level)
ErrorOr<NonnullRefPtr<Custody>> VirtualFileSystem::resolve_path(Credentials const& credentials, StringView path, NonnullRefPtr<Custody> base, RefPtr<Custody>* 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<NonnullRefPtr<Custody>> 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<NonnullRefPtr<Custody>> VirtualFileSystem::resolve_path_without_veil(StringView path, NonnullRefPtr<Custody> base, RefPtr<Custody>* out_parent, int options, int symlink_recursion_level)
ErrorOr<NonnullRefPtr<Custody>> VirtualFileSystem::resolve_path_without_veil(Credentials const& credentials, StringView path, NonnullRefPtr<Custody> base, RefPtr<Custody>* out_parent, int options, int symlink_recursion_level)
{
if (symlink_recursion_level >= symlink_recursion_limit)
return ELOOP;
@ -917,7 +900,6 @@ ErrorOr<NonnullRefPtr<Custody>> VirtualFileSystem::resolve_path_without_veil(Str
return EINVAL;
GenericLexer path_lexer(path);
auto& current_process = Process::current();
NonnullRefPtr<Custody> custody = path[0] == '/' ? root_custody() : base;
bool extra_iteration = path[path.length() - 1] == '/';
@ -933,7 +915,7 @@ ErrorOr<NonnullRefPtr<Custody>> 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<NonnullRefPtr<Custody>> 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<NonnullRefPtr<Custody>> 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);
}
}

View File

@ -50,24 +50,24 @@ public:
ErrorOr<void> remount(Custody& mount_point, int new_flags);
ErrorOr<void> unmount(Inode& guest_inode);
ErrorOr<NonnullLockRefPtr<OpenFileDescription>> open(StringView path, int options, mode_t mode, Custody& base, Optional<UidAndGid> = {});
ErrorOr<NonnullLockRefPtr<OpenFileDescription>> create(StringView path, int options, mode_t mode, Custody& parent_custody, Optional<UidAndGid> = {});
ErrorOr<void> mkdir(StringView path, mode_t mode, Custody& base);
ErrorOr<void> link(StringView old_path, StringView new_path, Custody& base);
ErrorOr<void> unlink(StringView path, Custody& base);
ErrorOr<void> symlink(StringView target, StringView linkpath, Custody& base);
ErrorOr<void> rmdir(StringView path, Custody& base);
ErrorOr<void> chmod(StringView path, mode_t, Custody& base, int options = 0);
ErrorOr<void> chmod(Custody&, mode_t);
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);
ErrorOr<void> utime(StringView path, Custody& base, time_t atime, time_t mtime);
ErrorOr<void> utimensat(StringView path, Custody& base, timespec const& atime, timespec const& mtime, int options = 0);
ErrorOr<void> rename(StringView oldpath, StringView newpath, Custody& base);
ErrorOr<void> mknod(StringView path, mode_t, dev_t, Custody& base);
ErrorOr<NonnullRefPtr<Custody>> open_directory(StringView path, Custody& base);
ErrorOr<NonnullLockRefPtr<OpenFileDescription>> open(Credentials const&, StringView path, int options, mode_t mode, Custody& base, Optional<UidAndGid> = {});
ErrorOr<NonnullLockRefPtr<OpenFileDescription>> create(Credentials const&, StringView path, int options, mode_t mode, Custody& parent_custody, Optional<UidAndGid> = {});
ErrorOr<void> mkdir(Credentials const&, StringView path, mode_t mode, Custody& base);
ErrorOr<void> link(Credentials const&, StringView old_path, StringView new_path, Custody& base);
ErrorOr<void> unlink(Credentials const&, StringView path, Custody& base);
ErrorOr<void> symlink(Credentials const&, StringView target, StringView linkpath, Custody& base);
ErrorOr<void> rmdir(Credentials const&, StringView path, Custody& base);
ErrorOr<void> chmod(Credentials const&, StringView path, mode_t, Custody& base, int options = 0);
ErrorOr<void> chmod(Credentials const&, Custody&, mode_t);
ErrorOr<void> chown(Credentials const&, StringView path, UserID, GroupID, Custody& base, int options);
ErrorOr<void> chown(Credentials const&, Custody&, UserID, GroupID);
ErrorOr<void> access(Credentials const&, StringView path, int mode, Custody& base);
ErrorOr<InodeMetadata> lookup_metadata(Credentials const&, StringView path, Custody& base, int options = 0);
ErrorOr<void> utime(Credentials const&, StringView path, Custody& base, time_t atime, time_t mtime);
ErrorOr<void> utimensat(Credentials const&, StringView path, Custody& base, timespec const& atime, timespec const& mtime, int options = 0);
ErrorOr<void> rename(Credentials const&, StringView oldpath, StringView newpath, Custody& base);
ErrorOr<void> mknod(Credentials const&, StringView path, mode_t, dev_t, Custody& base);
ErrorOr<NonnullRefPtr<Custody>> open_directory(Credentials const&, StringView path, Custody& base);
ErrorOr<void> for_each_mount(Function<ErrorOr<void>(Mount const&)>) const;
@ -76,8 +76,8 @@ public:
static void sync();
NonnullRefPtr<Custody> root_custody();
ErrorOr<NonnullRefPtr<Custody>> resolve_path(StringView path, NonnullRefPtr<Custody> base, RefPtr<Custody>* out_parent = nullptr, int options = 0, int symlink_recursion_level = 0);
ErrorOr<NonnullRefPtr<Custody>> resolve_path_without_veil(StringView path, NonnullRefPtr<Custody> base, RefPtr<Custody>* out_parent = nullptr, int options = 0, int symlink_recursion_level = 0);
ErrorOr<NonnullRefPtr<Custody>> resolve_path(Credentials const&, StringView path, NonnullRefPtr<Custody> base, RefPtr<Custody>* out_parent = nullptr, int options = 0, int symlink_recursion_level = 0);
ErrorOr<NonnullRefPtr<Custody>> resolve_path_without_veil(Credentials const&, StringView path, NonnullRefPtr<Custody> base, RefPtr<Custody>* out_parent = nullptr, int options = 0, int symlink_recursion_level = 0);
private:
friend class OpenFileDescription;

View File

@ -139,7 +139,7 @@ ErrorOr<void> LocalSocket::bind(Userspace<sockaddr const*> 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<void> LocalSocket::connect(OpenFileDescription& description, Userspace<s
auto path = SOCKET_TRY(KString::try_create(StringView { address.sun_path, strnlen(address.sun_path, sizeof(address.sun_path)) }));
dbgln_if(LOCAL_SOCKET_DEBUG, "LocalSocket({}) connect({})", this, *path);
auto file = SOCKET_TRY(VirtualFileSystem::the().open(path->view(), 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;

View File

@ -583,8 +583,9 @@ ErrorOr<void> Process::dump_perfcore()
auto base_filename = TRY(KString::formatted("{}_{}", name(), pid().value()));
auto perfcore_filename = TRY(KString::formatted("{}.profile", base_filename));
LockRefPtr<OpenFileDescription> 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;

View File

@ -15,7 +15,7 @@ ErrorOr<FlatPtr> Process::sys$access(Userspace<char const*> 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;
}

View File

@ -19,7 +19,7 @@ ErrorOr<FlatPtr> Process::sys$chdir(Userspace<char const*> user_path, size_t pat
auto current_directory = m_current_directory.with([](auto& current_directory) -> NonnullRefPtr<Custody> {
return *current_directory;
});
RefPtr<Custody> new_directory = TRY(VirtualFileSystem::the().open_directory(path->view(), *current_directory));
RefPtr<Custody> 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<FlatPtr> 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();

View File

@ -28,7 +28,7 @@ ErrorOr<FlatPtr> Process::sys$chmod(Userspace<Syscall::SC_chmod_params const*> 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;
}

View File

@ -38,7 +38,7 @@ ErrorOr<FlatPtr> Process::sys$chown(Userspace<Syscall::SC_chown_params const*> 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;
}

View File

@ -758,7 +758,7 @@ ErrorOr<LockRefPtr<OpenFileDescription>> 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<void> Process::exec(NonnullOwnPtr<KString> path, NonnullOwnPtrVector<KSt
// * ET_EXEC binary that just gets loaded
// * ET_DYN binary that requires a program interpreter
//
auto description = TRY(VirtualFileSystem::the().open(path->view(), 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())

View File

@ -47,7 +47,7 @@ ErrorOr<FlatPtr> Process::sys$inode_watcher_add_watch(Userspace<Syscall::SC_inod
return EBADF;
auto* inode_watcher = description->inode_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;

View File

@ -17,7 +17,7 @@ ErrorOr<FlatPtr> Process::sys$link(Userspace<Syscall::SC_link_params const*> 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<FlatPtr> Process::sys$symlink(Userspace<Syscall::SC_symlink_params const
auto target = TRY(get_syscall_path_argument(params.target));
auto linkpath = TRY(get_syscall_path_argument(params.linkpath));
TRY(VirtualFileSystem::the().symlink(target->view(), linkpath->view(), current_directory()));
TRY(VirtualFileSystem::the().symlink(credentials(), target->view(), linkpath->view(), current_directory()));
return 0;
}

View File

@ -15,7 +15,7 @@ ErrorOr<FlatPtr> Process::sys$mkdir(Userspace<char const*> 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;
}
}

View File

@ -19,7 +19,7 @@ ErrorOr<FlatPtr> Process::sys$mknod(Userspace<Syscall::SC_mknod_params const*> 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;
}

View File

@ -105,15 +105,16 @@ ErrorOr<void> Process::validate_mmap_prot(int prot, bool map_stack, bool map_ano
ErrorOr<void> 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())

View File

@ -86,7 +86,7 @@ ErrorOr<FlatPtr> Process::sys$mount(Userspace<Syscall::SC_mount_params const*> 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<FlatPtr> Process::sys$umount(Userspace<char const*> 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;

View File

@ -67,7 +67,7 @@ ErrorOr<FlatPtr> Process::sys$open(Userspace<Syscall::SC_open_params const*> 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;

View File

@ -17,7 +17,7 @@ ErrorOr<FlatPtr> Process::sys$readlink(Userspace<Syscall::SC_readlink_params con
auto params = TRY(copy_typed_from_user(user_params));
auto path = TRY(get_syscall_path_argument(params.path));
auto description = TRY(VirtualFileSystem::the().open(path->view(), 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;

View File

@ -18,7 +18,7 @@ ErrorOr<FlatPtr> Process::sys$realpath(Userspace<Syscall::SC_realpath_params con
auto params = TRY(copy_typed_from_user(user_params));
auto path = TRY(get_syscall_path_argument(params.path));
auto custody = TRY(VirtualFileSystem::the().resolve_path(path->view(), 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;

View File

@ -17,7 +17,7 @@ ErrorOr<FlatPtr> Process::sys$rename(Userspace<Syscall::SC_rename_params const*>
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;
}

View File

@ -15,7 +15,7 @@ ErrorOr<FlatPtr> Process::sys$rmdir(Userspace<char const*> 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;
}

View File

@ -41,7 +41,7 @@ ErrorOr<FlatPtr> Process::sys$stat(Userspace<Syscall::SC_stat_params const*> 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;

View File

@ -47,7 +47,7 @@ ErrorOr<FlatPtr> Process::sys$statvfs(Userspace<Syscall::SC_statvfs_params const
auto path = TRY(get_syscall_path_argument(params.path));
auto custody = TRY(VirtualFileSystem::the().resolve_path(path->view(), 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();

View File

@ -30,9 +30,9 @@ ErrorOr<FlatPtr> Process::sys$unlink(int dirfd, Userspace<char const*> 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;
}

View File

@ -82,7 +82,7 @@ ErrorOr<FlatPtr> Process::sys$unveil(Userspace<Syscall::SC_unveil_params const*>
// If this case is encountered, the parent node of the path is returned and the custody of that inode is used instead.
RefPtr<Custody> parent_custody; // Parent inode in case of ENOENT
OwnPtr<KString> 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)) {

View File

@ -23,7 +23,7 @@ ErrorOr<FlatPtr> Process::sys$utime(Userspace<char const*> 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;
}

View File

@ -71,7 +71,7 @@ ErrorOr<FlatPtr> Process::sys$utimensat(Userspace<Syscall::SC_utimensat_params c
auto& atime = times[0];
auto& mtime = times[1];
TRY(VirtualFileSystem::the().utimensat(path->view(), *base, atime, mtime, follow_symlink));
TRY(VirtualFileSystem::the().utimensat(credentials(), path->view(), *base, atime, mtime, follow_symlink));
return 0;
}