diff options
author | Anthony Iacono <anthonyiacono@gmail.com> | 2022-08-20 18:21:01 -0400 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-08-22 12:46:32 +0200 |
commit | f86b671de23a7eb76e8ddb3460369c053f726384 (patch) | |
tree | 59fb1eddeb2cbcae124c31503ab8c10b3be5dd34 /Kernel | |
parent | 8026d8926c703b819ce8384d7abc7fe4dfc42d2b (diff) | |
download | serenity-f86b671de23a7eb76e8ddb3460369c053f726384.zip |
Kernel: Use Process::credentials() and remove user ID/group ID helpers
Move away from using the group ID/user ID helpers in the process to
allow for us to take advantage of the immutable credentials instead.
Diffstat (limited to 'Kernel')
27 files changed, 109 insertions, 94 deletions
diff --git a/Kernel/FileSystem/InodeFile.cpp b/Kernel/FileSystem/InodeFile.cpp index ac61916892..08058d866c 100644 --- a/Kernel/FileSystem/InodeFile.cpp +++ b/Kernel/FileSystem/InodeFile.cpp @@ -62,7 +62,8 @@ ErrorOr<void> InodeFile::ioctl(OpenFileDescription& description, unsigned reques { switch (request) { case FIBMAP: { - if (!Process::current().is_superuser()) + auto current_process_credentials = Process::current().credentials(); + if (!current_process_credentials->is_superuser()) return EPERM; auto user_block_number = static_ptr_cast<int*>(arg); diff --git a/Kernel/GlobalProcessExposed.cpp b/Kernel/GlobalProcessExposed.cpp index 7ef025e8f7..356f1c7dc2 100644 --- a/Kernel/GlobalProcessExposed.cpp +++ b/Kernel/GlobalProcessExposed.cpp @@ -150,7 +150,8 @@ private: TRY(obj.add("bytes_in"sv, socket.bytes_in())); TRY(obj.add("packets_out"sv, socket.packets_out())); TRY(obj.add("bytes_out"sv, socket.bytes_out())); - if (Process::current().is_superuser() || Process::current().uid() == socket.origin_uid()) { + auto current_process_credentials = Process::current().credentials(); + if (current_process_credentials->is_superuser() || current_process_credentials->uid() == socket.origin_uid()) { TRY(obj.add("origin_pid"sv, socket.origin_pid().value())); TRY(obj.add("origin_uid"sv, socket.origin_uid().value())); TRY(obj.add("origin_gid"sv, socket.origin_gid().value())); @@ -206,7 +207,8 @@ private: auto peer_address = TRY(socket.peer_address().to_string()); TRY(obj.add("peer_address"sv, peer_address->view())); TRY(obj.add("peer_port"sv, socket.peer_port())); - if (Process::current().is_superuser() || Process::current().uid() == socket.origin_uid()) { + auto current_process_credentials = Process::current().credentials(); + if (current_process_credentials->is_superuser() || current_process_credentials->uid() == socket.origin_uid()) { TRY(obj.add("origin_pid"sv, socket.origin_pid().value())); TRY(obj.add("origin_uid"sv, socket.origin_uid().value())); TRY(obj.add("origin_gid"sv, socket.origin_gid().value())); @@ -525,8 +527,9 @@ private: TRY(process_object.add("pgid"sv, process.tty() ? process.tty()->pgid().value() : 0)); TRY(process_object.add("pgp"sv, process.pgid().value())); TRY(process_object.add("sid"sv, process.sid().value())); - TRY(process_object.add("uid"sv, process.uid().value())); - TRY(process_object.add("gid"sv, process.gid().value())); + auto credentials = process.credentials(); + TRY(process_object.add("uid"sv, credentials->uid().value())); + TRY(process_object.add("gid"sv, credentials->gid().value())); TRY(process_object.add("ppid"sv, process.ppid().value())); if (process.tty()) { auto tty_pseudo_name = TRY(process.tty()->pseudo_name()); @@ -822,7 +825,8 @@ private: virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override { - if (!Process::current().is_superuser()) + auto current_process_credentials = Process::current().credentials(); + if (!current_process_credentials->is_superuser()) return EPERM; return builder.appendff("{}", kernel_load_base); } diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index 00acbd8eb2..d18a08d795 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -625,7 +625,8 @@ ErrorOr<void> IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspac switch (request) { case SIOCADDRT: { - if (!Process::current().is_superuser()) + auto current_process_credentials = Process::current().credentials(); + if (!current_process_credentials->is_superuser()) return EPERM; if (route.rt_gateway.sa_family != AF_INET) return EAFNOSUPPORT; @@ -639,7 +640,8 @@ ErrorOr<void> IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspac return update_routing_table(destination, gateway, genmask, route.rt_flags, adapter, UpdateTable::Set); } case SIOCDELRT: - if (!Process::current().is_superuser()) + auto current_process_credentials = Process::current().credentials(); + if (!current_process_credentials->is_superuser()) return EPERM; if (route.rt_gateway.sa_family != AF_INET) return EAFNOSUPPORT; @@ -659,9 +661,11 @@ ErrorOr<void> IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspac arpreq arp_req; TRY(copy_from_user(&arp_req, user_req)); + auto current_process_credentials = Process::current().credentials(); + switch (request) { case SIOCSARP: - if (!Process::current().is_superuser()) + if (!current_process_credentials->is_superuser()) return EPERM; if (arp_req.arp_pa.sa_family != AF_INET) return EAFNOSUPPORT; @@ -669,7 +673,7 @@ ErrorOr<void> IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspac return {}; case SIOCDARP: - if (!Process::current().is_superuser()) + if (!current_process_credentials->is_superuser()) return EPERM; if (arp_req.arp_pa.sa_family != AF_INET) return EAFNOSUPPORT; @@ -693,9 +697,11 @@ ErrorOr<void> IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspac if (!adapter) return ENODEV; + auto current_process_credentials = Process::current().credentials(); + switch (request) { case SIOCSIFADDR: - if (!Process::current().is_superuser()) + if (!current_process_credentials->is_superuser()) return EPERM; if (ifr.ifr_addr.sa_family != AF_INET) return EAFNOSUPPORT; @@ -703,7 +709,7 @@ ErrorOr<void> IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspac return {}; case SIOCSIFNETMASK: - if (!Process::current().is_superuser()) + if (!current_process_credentials->is_superuser()) return EPERM; if (ifr.ifr_addr.sa_family != AF_INET) return EAFNOSUPPORT; diff --git a/Kernel/PerformanceEventBuffer.cpp b/Kernel/PerformanceEventBuffer.cpp index b5171daa47..11dfbd8390 100644 --- a/Kernel/PerformanceEventBuffer.cpp +++ b/Kernel/PerformanceEventBuffer.cpp @@ -206,7 +206,8 @@ ErrorOr<void> PerformanceEventBuffer::to_json_impl(Serializer& object) const TRY(strings.finish()); } - bool show_kernel_addresses = Process::current().is_superuser(); + auto current_process_credentials = Process::current().credentials(); + bool show_kernel_addresses = current_process_credentials->is_superuser(); auto array = TRY(object.add_array("events"sv)); bool seen_first_sample = false; for (size_t i = 0; i < m_count; ++i) { diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index a32df9c4e3..25ed65de82 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -522,10 +522,11 @@ Time kgettimeofday() siginfo_t Process::wait_info() const { + auto credentials = this->credentials(); siginfo_t siginfo {}; siginfo.si_signo = SIGCHLD; siginfo.si_pid = pid().value(); - siginfo.si_uid = uid().value(); + siginfo.si_uid = credentials->uid().value(); with_protected_data([&](auto& protected_data) { if (protected_data.termination_signal != 0) { @@ -941,36 +942,6 @@ ErrorOr<void> Process::require_promise(Pledge promise) return EPROMISEVIOLATION; } -UserID Process::uid() const -{ - return credentials()->uid(); -} - -GroupID Process::gid() const -{ - return credentials()->gid(); -} - -UserID Process::euid() const -{ - return credentials()->euid(); -} - -GroupID Process::egid() const -{ - return credentials()->egid(); -} - -UserID Process::suid() const -{ - return credentials()->suid(); -} - -GroupID Process::sgid() const -{ - return credentials()->sgid(); -} - NonnullRefPtr<Credentials> Process::credentials() const { return with_protected_data([&](auto& protected_data) -> NonnullRefPtr<Credentials> { diff --git a/Kernel/Process.h b/Kernel/Process.h index 43c35c463a..fcafbad5f0 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -235,13 +235,6 @@ public: NonnullRefPtr<Credentials> credentials() const; - UserID euid() const; - GroupID egid() const; - UserID uid() const; - GroupID gid() const; - UserID suid() const; - GroupID sgid() const; - bool is_dumpable() const { return with_protected_data([](auto& protected_data) { return protected_data.dumpable; }); @@ -476,8 +469,6 @@ public: ErrorOr<LoadResult> load(NonnullLockRefPtr<OpenFileDescription> main_program_description, LockRefPtr<OpenFileDescription> interpreter_description, const ElfW(Ehdr) & main_program_header); - bool is_superuser() const { return euid() == 0; } - void terminate_due_to_signal(u8 signal); ErrorOr<void> send_signal(u8 signal, Process* sender); diff --git a/Kernel/ProcessProcFSTraits.cpp b/Kernel/ProcessProcFSTraits.cpp index c894fe0667..b664165e47 100644 --- a/Kernel/ProcessProcFSTraits.cpp +++ b/Kernel/ProcessProcFSTraits.cpp @@ -15,7 +15,8 @@ UserID Process::ProcessProcFSTraits::owner_user() const if (!process) return 0; - return process->uid(); + auto credentials = process->credentials(); + return credentials->uid(); } GroupID Process::ProcessProcFSTraits::owner_group() const @@ -24,7 +25,8 @@ GroupID Process::ProcessProcFSTraits::owner_group() const if (!process) return 0; - return process->gid(); + auto credentials = process->credentials(); + return credentials->gid(); } InodeIndex Process::ProcessProcFSTraits::component_index() const diff --git a/Kernel/ProcessSpecificExposed.cpp b/Kernel/ProcessSpecificExposed.cpp index 82fcf6735e..0e39ccb188 100644 --- a/Kernel/ProcessSpecificExposed.cpp +++ b/Kernel/ProcessSpecificExposed.cpp @@ -25,7 +25,8 @@ ErrorOr<void> Process::procfs_get_thread_stack(ThreadID thread_id, KBufferBuilde auto thread = Thread::from_tid(thread_id); if (!thread) return ESRCH; - bool show_kernel_addresses = Process::current().is_superuser(); + auto current_process_credentials = Process::current().credentials(); + bool show_kernel_addresses = current_process_credentials->is_superuser(); bool kernel_address_added = false; for (auto address : TRY(Processor::capture_stack_trace(*thread, 1024))) { if (!show_kernel_addresses && !Memory::is_user_address(VirtualAddress { address })) { @@ -269,7 +270,8 @@ ErrorOr<void> Process::procfs_get_virtual_memory_stats(KBufferBuilder& builder) { SpinlockLocker lock(address_space().get_lock()); for (auto const& region : address_space().regions()) { - if (!region.is_user() && !Process::current().is_superuser()) + auto current_process_credentials = Process::current().credentials(); + if (!region.is_user() && !current_process_credentials->is_superuser()) continue; auto region_object = TRY(array.add_object()); TRY(region_object.add("readable"sv, region.is_readable())); diff --git a/Kernel/Syscalls/clock.cpp b/Kernel/Syscalls/clock.cpp index 6689913e14..ed80b8964b 100644 --- a/Kernel/Syscalls/clock.cpp +++ b/Kernel/Syscalls/clock.cpp @@ -38,7 +38,8 @@ ErrorOr<FlatPtr> Process::sys$clock_settime(clockid_t clock_id, Userspace<timesp VERIFY_NO_PROCESS_BIG_LOCK(this); TRY(require_promise(Pledge::settime)); - if (!is_superuser()) + auto credentials = this->credentials(); + if (!credentials->is_superuser()) return EPERM; auto time = TRY(copy_time_from_user(user_ts)); @@ -120,7 +121,8 @@ ErrorOr<FlatPtr> Process::sys$adjtime(Userspace<timeval const*> user_delta, User if (user_delta) { TRY(require_promise(Pledge::settime)); - if (!is_superuser()) + auto credentials = this->credentials(); + if (!credentials->is_superuser()) return EPERM; auto delta = TRY(copy_time_from_user(user_delta)); diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp index 6cedb9a736..fc281fc4a8 100644 --- a/Kernel/Syscalls/execve.cpp +++ b/Kernel/Syscalls/execve.cpp @@ -598,7 +598,8 @@ ErrorOr<void> Process::do_exec(NonnullLockRefPtr<OpenFileDescription> main_progr } VERIFY(new_main_thread); - auto auxv = generate_auxiliary_vector(load_result.load_base, load_result.entry_eip, uid(), euid(), gid(), egid(), path->view(), main_program_fd_allocation); + auto credentials = this->credentials(); + auto auxv = generate_auxiliary_vector(load_result.load_base, load_result.entry_eip, credentials->uid(), credentials->euid(), credentials->gid(), credentials->egid(), path->view(), main_program_fd_allocation); // NOTE: We create the new stack before disabling interrupts since it will zero-fault // and we don't want to deal with faults after this point. diff --git a/Kernel/Syscalls/fork.cpp b/Kernel/Syscalls/fork.cpp index a0e209fa4a..b4805ff1b8 100644 --- a/Kernel/Syscalls/fork.cpp +++ b/Kernel/Syscalls/fork.cpp @@ -28,7 +28,8 @@ ErrorOr<FlatPtr> Process::sys$fork(RegisterState& regs) }; auto child_name = TRY(m_name->try_clone()); - auto child = TRY(Process::try_create(child_first_thread, move(child_name), uid(), gid(), pid(), m_is_kernel_process, current_directory(), executable(), m_tty, this)); + auto credentials = this->credentials(); + auto child = TRY(Process::try_create(child_first_thread, move(child_name), credentials->uid(), credentials->gid(), pid(), m_is_kernel_process, current_directory(), executable(), m_tty, this)); // NOTE: All user processes have a leaked ref on them. It's balanced by Thread::WaitBlockerSet::finalize(). child->ref(); diff --git a/Kernel/Syscalls/getuid.cpp b/Kernel/Syscalls/getuid.cpp index bb96709a69..a94d1e974a 100644 --- a/Kernel/Syscalls/getuid.cpp +++ b/Kernel/Syscalls/getuid.cpp @@ -12,28 +12,32 @@ ErrorOr<FlatPtr> Process::sys$getuid() { VERIFY_NO_PROCESS_BIG_LOCK(this); TRY(require_promise(Pledge::stdio)); - return uid().value(); + auto credentials = this->credentials(); + return credentials->uid().value(); } ErrorOr<FlatPtr> Process::sys$getgid() { VERIFY_NO_PROCESS_BIG_LOCK(this); TRY(require_promise(Pledge::stdio)); - return gid().value(); + auto credentials = this->credentials(); + return credentials->gid().value(); } ErrorOr<FlatPtr> Process::sys$geteuid() { VERIFY_NO_PROCESS_BIG_LOCK(this); TRY(require_promise(Pledge::stdio)); - return euid().value(); + auto credentials = this->credentials(); + return credentials->euid().value(); } ErrorOr<FlatPtr> Process::sys$getegid() { VERIFY_NO_PROCESS_BIG_LOCK(this); TRY(require_promise(Pledge::stdio)); - return egid().value(); + auto credentials = this->credentials(); + return credentials->egid().value(); } ErrorOr<FlatPtr> Process::sys$getresuid(Userspace<UserID*> user_ruid, Userspace<UserID*> user_euid, Userspace<UserID*> user_suid) diff --git a/Kernel/Syscalls/hostname.cpp b/Kernel/Syscalls/hostname.cpp index fdc74d86a6..6d7ebe09bf 100644 --- a/Kernel/Syscalls/hostname.cpp +++ b/Kernel/Syscalls/hostname.cpp @@ -27,7 +27,8 @@ ErrorOr<FlatPtr> Process::sys$sethostname(Userspace<char const*> buffer, size_t VERIFY_NO_PROCESS_BIG_LOCK(this); TRY(require_no_promises()); - if (!is_superuser()) + auto credentials = this->credentials(); + if (!credentials->is_superuser()) return EPERM; if (length > 64) return ENAMETOOLONG; diff --git a/Kernel/Syscalls/keymap.cpp b/Kernel/Syscalls/keymap.cpp index 81e925b95b..b3561d12ca 100644 --- a/Kernel/Syscalls/keymap.cpp +++ b/Kernel/Syscalls/keymap.cpp @@ -16,7 +16,8 @@ ErrorOr<FlatPtr> Process::sys$setkeymap(Userspace<Syscall::SC_setkeymap_params c VERIFY_NO_PROCESS_BIG_LOCK(this); TRY(require_promise(Pledge::setkeymap)); - if (!is_superuser()) + auto credentials = this->credentials(); + if (!credentials->is_superuser()) return EPERM; auto params = TRY(copy_typed_from_user(user_params)); diff --git a/Kernel/Syscalls/kill.cpp b/Kernel/Syscalls/kill.cpp index 2314610381..5ef4ebc1d8 100644 --- a/Kernel/Syscalls/kill.cpp +++ b/Kernel/Syscalls/kill.cpp @@ -13,7 +13,9 @@ ErrorOr<void> Process::do_kill(Process& process, int signal) { // FIXME: Allow sending SIGCONT to everyone in the process group. // FIXME: Should setuid processes have some special treatment here? - if (!is_superuser() && euid() != process.uid() && uid() != process.uid()) + auto credentials = this->credentials(); + auto kill_process_credentials = process.credentials(); + if (!credentials->is_superuser() && credentials->euid() != kill_process_credentials->uid() && credentials->uid() != kill_process_credentials->uid()) return EPERM; if (process.is_kernel_process()) { dbgln("Attempted to send signal {} to kernel process {} ({})", signal, process.name(), process.pid()); diff --git a/Kernel/Syscalls/mknod.cpp b/Kernel/Syscalls/mknod.cpp index 13c26cc935..3b3b58215e 100644 --- a/Kernel/Syscalls/mknod.cpp +++ b/Kernel/Syscalls/mknod.cpp @@ -16,10 +16,11 @@ ErrorOr<FlatPtr> Process::sys$mknod(Userspace<Syscall::SC_mknod_params const*> u TRY(require_promise(Pledge::dpath)); auto params = TRY(copy_typed_from_user(user_params)); - if (!is_superuser() && !is_regular_file(params.mode) && !is_fifo(params.mode) && !is_socket(params.mode)) + auto credentials = this->credentials(); + if (!credentials->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(credentials(), 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/mount.cpp b/Kernel/Syscalls/mount.cpp index bd428970e2..e82110a7f1 100644 --- a/Kernel/Syscalls/mount.cpp +++ b/Kernel/Syscalls/mount.cpp @@ -70,7 +70,8 @@ ErrorOr<FlatPtr> Process::sys$mount(Userspace<Syscall::SC_mount_params const*> u { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this); TRY(require_no_promises()); - if (!is_superuser()) + auto credentials = this->credentials(); + if (!credentials->is_superuser()) return EPERM; auto params = TRY(copy_typed_from_user(user_params)); @@ -86,7 +87,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(credentials(), 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! @@ -126,13 +127,14 @@ ErrorOr<FlatPtr> Process::sys$mount(Userspace<Syscall::SC_mount_params const*> u ErrorOr<FlatPtr> Process::sys$umount(Userspace<char const*> user_mountpoint, size_t mountpoint_length) { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this); - if (!is_superuser()) + auto credentials = this->credentials(); + if (!credentials->is_superuser()) return EPERM; TRY(require_no_promises()); auto mountpoint = TRY(get_syscall_path_argument(user_mountpoint, mountpoint_length)); - auto custody = TRY(VirtualFileSystem::the().resolve_path(credentials(), 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/pipe.cpp b/Kernel/Syscalls/pipe.cpp index 7cdb0829df..5c164e4737 100644 --- a/Kernel/Syscalls/pipe.cpp +++ b/Kernel/Syscalls/pipe.cpp @@ -19,7 +19,8 @@ ErrorOr<FlatPtr> Process::sys$pipe(Userspace<int*> pipefd, int flags) return EINVAL; u32 fd_flags = (flags & O_CLOEXEC) ? FD_CLOEXEC : 0; - auto fifo = TRY(FIFO::try_create(uid())); + auto credentials = this->credentials(); + auto fifo = TRY(FIFO::try_create(credentials->uid())); auto reader_description = TRY(fifo->open_direction(FIFO::Direction::Reader)); auto writer_description = TRY(fifo->open_direction(FIFO::Direction::Writer)); diff --git a/Kernel/Syscalls/profiling.cpp b/Kernel/Syscalls/profiling.cpp index c2c298085b..efba20f338 100644 --- a/Kernel/Syscalls/profiling.cpp +++ b/Kernel/Syscalls/profiling.cpp @@ -26,7 +26,8 @@ ErrorOr<FlatPtr> Process::sys$profiling_enable(pid_t pid, Userspace<u64 const*> auto const event_mask = TRY(copy_typed_from_user(userspace_event_mask)); if (pid == -1) { - if (!is_superuser()) + auto credentials = this->credentials(); + if (!credentials->is_superuser()) return EPERM; ScopedCritical critical; g_profiling_event_mask = PERF_EVENT_PROCESS_CREATE | PERF_EVENT_THREAD_CREATE | PERF_EVENT_MMAP; @@ -58,7 +59,9 @@ ErrorOr<FlatPtr> Process::sys$profiling_enable(pid_t pid, Userspace<u64 const*> return ESRCH; if (process->is_dead()) return ESRCH; - if (!is_superuser() && process->uid() != euid()) + auto credentials = this->credentials(); + auto profile_process_credentials = process->credentials(); + if (!credentials->is_superuser() && profile_process_credentials->uid() != credentials->euid()) return EPERM; SpinlockLocker lock(g_profiling_lock); g_profiling_event_mask = PERF_EVENT_PROCESS_CREATE | PERF_EVENT_THREAD_CREATE | PERF_EVENT_MMAP; @@ -81,7 +84,8 @@ ErrorOr<FlatPtr> Process::sys$profiling_disable(pid_t pid) TRY(require_no_promises()); if (pid == -1) { - if (!is_superuser()) + auto credentials = this->credentials(); + if (!credentials->is_superuser()) return EPERM; ScopedCritical critical; if (!TimeManagement::the().disable_profile_timer()) @@ -93,7 +97,9 @@ ErrorOr<FlatPtr> Process::sys$profiling_disable(pid_t pid) auto process = Process::from_pid(pid); if (!process) return ESRCH; - if (!is_superuser() && process->uid() != euid()) + auto credentials = this->credentials(); + auto profile_process_credentials = process->credentials(); + if (!credentials->is_superuser() && profile_process_credentials->uid() != credentials->euid()) return EPERM; SpinlockLocker lock(g_profiling_lock); if (!process->is_profiling()) @@ -111,7 +117,8 @@ ErrorOr<FlatPtr> Process::sys$profiling_free_buffer(pid_t pid) TRY(require_no_promises()); if (pid == -1) { - if (!is_superuser()) + auto credentials = this->credentials(); + if (!credentials->is_superuser()) return EPERM; OwnPtr<PerformanceEventBuffer> perf_events; @@ -129,7 +136,9 @@ ErrorOr<FlatPtr> Process::sys$profiling_free_buffer(pid_t pid) auto process = Process::from_pid(pid); if (!process) return ESRCH; - if (!is_superuser() && process->uid() != euid()) + auto credentials = this->credentials(); + auto profile_process_credentials = process->credentials(); + if (!credentials->is_superuser() && profile_process_credentials->uid() != credentials->euid()) return EPERM; SpinlockLocker lock(g_profiling_lock); if (process->is_profiling()) diff --git a/Kernel/Syscalls/ptrace.cpp b/Kernel/Syscalls/ptrace.cpp index 13fdea073f..3915b39c51 100644 --- a/Kernel/Syscalls/ptrace.cpp +++ b/Kernel/Syscalls/ptrace.cpp @@ -40,8 +40,10 @@ static ErrorOr<FlatPtr> handle_ptrace(Kernel::Syscall::SC_ptrace_params const& p MutexLocker ptrace_locker(peer->process().ptrace_lock()); - if ((peer->process().uid() != caller.euid()) - || (peer->process().uid() != peer->process().euid())) // Disallow tracing setuid processes + auto peer_credentials = peer->process().credentials(); + auto caller_credentials = caller.credentials(); + if ((peer_credentials->uid() != caller_credentials->euid()) + || (peer_credentials->uid() != peer_credentials->euid())) // Disallow tracing setuid processes return EACCES; if (!peer->process().is_dumpable()) diff --git a/Kernel/Syscalls/purge.cpp b/Kernel/Syscalls/purge.cpp index 0cf7a5ede2..0512c52f03 100644 --- a/Kernel/Syscalls/purge.cpp +++ b/Kernel/Syscalls/purge.cpp @@ -16,7 +16,8 @@ ErrorOr<FlatPtr> Process::sys$purge(int mode) { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this); TRY(require_no_promises()); - if (!is_superuser()) + auto credentials = this->credentials(); + if (!credentials->is_superuser()) return EPERM; size_t purged_page_count = 0; if (mode & PURGE_ALL_VOLATILE) { diff --git a/Kernel/Syscalls/sched.cpp b/Kernel/Syscalls/sched.cpp index 92814e9caf..d90d935445 100644 --- a/Kernel/Syscalls/sched.cpp +++ b/Kernel/Syscalls/sched.cpp @@ -34,7 +34,9 @@ ErrorOr<FlatPtr> Process::sys$sched_setparam(int pid, Userspace<const struct sch if (!peer) return ESRCH; - if (!is_superuser() && euid() != peer->process().uid() && uid() != peer->process().uid()) + auto credentials = this->credentials(); + auto peer_credentials = peer->process().credentials(); + if (!credentials->is_superuser() && credentials->euid() != peer_credentials->uid() && credentials->uid() != peer_credentials->uid()) return EPERM; peer->set_priority((u32)param.sched_priority); @@ -58,7 +60,9 @@ ErrorOr<FlatPtr> Process::sys$sched_getparam(pid_t pid, Userspace<struct sched_p if (!peer) return ESRCH; - if (!is_superuser() && euid() != peer->process().uid() && uid() != peer->process().uid()) + auto credentials = this->credentials(); + auto peer_credentials = peer->process().credentials(); + if (!credentials->is_superuser() && credentials->euid() != peer_credentials->uid() && credentials->uid() != peer_credentials->uid()) return EPERM; priority = (int)peer->priority(); diff --git a/Kernel/Syscalls/socket.cpp b/Kernel/Syscalls/socket.cpp index d7e292011f..dbff7d7f9e 100644 --- a/Kernel/Syscalls/socket.cpp +++ b/Kernel/Syscalls/socket.cpp @@ -36,7 +36,8 @@ ErrorOr<FlatPtr> Process::sys$socket(int domain, int type, int protocol) VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this); REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(domain); - if ((type & SOCK_TYPE_MASK) == SOCK_RAW && !is_superuser()) + auto credentials = this->credentials(); + if ((type & SOCK_TYPE_MASK) == SOCK_RAW && !credentials->is_superuser()) return EACCES; return m_fds.with_exclusive([&](auto& fds) -> ErrorOr<FlatPtr> { diff --git a/Kernel/TTY/MasterPTY.cpp b/Kernel/TTY/MasterPTY.cpp index c286a1765c..195b62b33b 100644 --- a/Kernel/TTY/MasterPTY.cpp +++ b/Kernel/TTY/MasterPTY.cpp @@ -33,8 +33,9 @@ MasterPTY::MasterPTY(unsigned index, NonnullOwnPtr<DoubleBuffer> buffer) , m_buffer(move(buffer)) { auto& process = Process::current(); - set_uid(process.uid()); - set_gid(process.gid()); + auto credentials = process.credentials(); + set_uid(credentials->uid()); + set_gid(credentials->gid()); m_buffer->set_unblock_callback([this]() { if (m_slave) diff --git a/Kernel/TTY/SlavePTY.cpp b/Kernel/TTY/SlavePTY.cpp index f04cf1bc2d..bf442fae2d 100644 --- a/Kernel/TTY/SlavePTY.cpp +++ b/Kernel/TTY/SlavePTY.cpp @@ -42,8 +42,9 @@ SlavePTY::SlavePTY(MasterPTY& master, unsigned index) , m_index(index) { auto& process = Process::current(); - set_uid(process.uid()); - set_gid(process.gid()); + auto credentials = process.credentials(); + set_uid(credentials->uid()); + set_gid(credentials->gid()); set_size(80, 25); SlavePTY::all_instances().with([&](auto& list) { list.append(*this); }); diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp index 91b38eb34f..fc4ae0b549 100644 --- a/Kernel/Thread.cpp +++ b/Kernel/Thread.cpp @@ -1131,7 +1131,7 @@ DispatchSignalResult Thread::dispatch_signal(u8 signal) // Set for SI_TIMER, we don't have the data here. .si_errno = 0, .si_pid = sender_pid.value(), - .si_uid = sender ? sender->uid().value() : 0, + .si_uid = sender ? sender->credentials()->uid().value() : 0, // Set for SIGILL, SIGFPE, SIGSEGV and SIGBUS // FIXME: We don't generate these signals in a way that can be handled. .si_addr = 0, @@ -1346,7 +1346,8 @@ static ErrorOr<bool> symbolicate(RecognizedSymbol const& symbol, Process& proces if (symbol.address == 0) return false; - bool mask_kernel_addresses = !process.is_superuser(); + auto credentials = process.credentials(); + bool mask_kernel_addresses = !credentials->is_superuser(); if (!symbol.symbol) { if (!Memory::is_user_address(VirtualAddress(symbol.address))) { TRY(builder.try_append("0xdeadc0de\n"sv)); diff --git a/Kernel/ThreadBlockers.cpp b/Kernel/ThreadBlockers.cpp index 15d6789465..a14e5fef46 100644 --- a/Kernel/ThreadBlockers.cpp +++ b/Kernel/ThreadBlockers.cpp @@ -783,10 +783,11 @@ bool Thread::WaitBlocker::unblock(Process& process, UnblockFlags flags, u8 signa siginfo_t siginfo {}; { SpinlockLocker lock(g_scheduler_lock); + auto credentials = process.credentials(); // We need to gather the information before we release the scheduler lock! siginfo.si_signo = SIGCHLD; siginfo.si_pid = process.pid().value(); - siginfo.si_uid = process.uid().value(); + siginfo.si_uid = credentials->uid().value(); siginfo.si_status = signal; switch (flags) { |