mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 20:37:35 +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:
parent
9744dedb50
commit
c3351d4b9f
33 changed files with 159 additions and 165 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue