Browse Source

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.
Anthony Iacono 2 năm trước cách đây
mục cha
commit
f86b671de2

+ 2 - 1
Kernel/FileSystem/InodeFile.cpp

@@ -62,7 +62,8 @@ ErrorOr<void> InodeFile::ioctl(OpenFileDescription& description, unsigned reques
 {
 {
     switch (request) {
     switch (request) {
     case FIBMAP: {
     case FIBMAP: {
-        if (!Process::current().is_superuser())
+        auto current_process_credentials = Process::current().credentials();
+        if (!current_process_credentials->is_superuser())
             return EPERM;
             return EPERM;
 
 
         auto user_block_number = static_ptr_cast<int*>(arg);
         auto user_block_number = static_ptr_cast<int*>(arg);

+ 9 - 5
Kernel/GlobalProcessExposed.cpp

@@ -150,7 +150,8 @@ private:
             TRY(obj.add("bytes_in"sv, socket.bytes_in()));
             TRY(obj.add("bytes_in"sv, socket.bytes_in()));
             TRY(obj.add("packets_out"sv, socket.packets_out()));
             TRY(obj.add("packets_out"sv, socket.packets_out()));
             TRY(obj.add("bytes_out"sv, socket.bytes_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_pid"sv, socket.origin_pid().value()));
                 TRY(obj.add("origin_uid"sv, socket.origin_uid().value()));
                 TRY(obj.add("origin_uid"sv, socket.origin_uid().value()));
                 TRY(obj.add("origin_gid"sv, socket.origin_gid().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());
             auto peer_address = TRY(socket.peer_address().to_string());
             TRY(obj.add("peer_address"sv, peer_address->view()));
             TRY(obj.add("peer_address"sv, peer_address->view()));
             TRY(obj.add("peer_port"sv, socket.peer_port()));
             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_pid"sv, socket.origin_pid().value()));
                 TRY(obj.add("origin_uid"sv, socket.origin_uid().value()));
                 TRY(obj.add("origin_uid"sv, socket.origin_uid().value()));
                 TRY(obj.add("origin_gid"sv, socket.origin_gid().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("pgid"sv, process.tty() ? process.tty()->pgid().value() : 0));
             TRY(process_object.add("pgp"sv, process.pgid().value()));
             TRY(process_object.add("pgp"sv, process.pgid().value()));
             TRY(process_object.add("sid"sv, process.sid().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()));
             TRY(process_object.add("ppid"sv, process.ppid().value()));
             if (process.tty()) {
             if (process.tty()) {
                 auto tty_pseudo_name = TRY(process.tty()->pseudo_name());
                 auto tty_pseudo_name = TRY(process.tty()->pseudo_name());
@@ -822,7 +825,8 @@ private:
 
 
     virtual ErrorOr<void> try_generate(KBufferBuilder& builder) override
     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 EPERM;
         return builder.appendff("{}", kernel_load_base);
         return builder.appendff("{}", kernel_load_base);
     }
     }

+ 12 - 6
Kernel/Net/IPv4Socket.cpp

@@ -625,7 +625,8 @@ ErrorOr<void> IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspac
 
 
         switch (request) {
         switch (request) {
         case SIOCADDRT: {
         case SIOCADDRT: {
-            if (!Process::current().is_superuser())
+            auto current_process_credentials = Process::current().credentials();
+            if (!current_process_credentials->is_superuser())
                 return EPERM;
                 return EPERM;
             if (route.rt_gateway.sa_family != AF_INET)
             if (route.rt_gateway.sa_family != AF_INET)
                 return EAFNOSUPPORT;
                 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);
             return update_routing_table(destination, gateway, genmask, route.rt_flags, adapter, UpdateTable::Set);
         }
         }
         case SIOCDELRT:
         case SIOCDELRT:
-            if (!Process::current().is_superuser())
+            auto current_process_credentials = Process::current().credentials();
+            if (!current_process_credentials->is_superuser())
                 return EPERM;
                 return EPERM;
             if (route.rt_gateway.sa_family != AF_INET)
             if (route.rt_gateway.sa_family != AF_INET)
                 return EAFNOSUPPORT;
                 return EAFNOSUPPORT;
@@ -659,9 +661,11 @@ ErrorOr<void> IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspac
         arpreq arp_req;
         arpreq arp_req;
         TRY(copy_from_user(&arp_req, user_req));
         TRY(copy_from_user(&arp_req, user_req));
 
 
+        auto current_process_credentials = Process::current().credentials();
+
         switch (request) {
         switch (request) {
         case SIOCSARP:
         case SIOCSARP:
-            if (!Process::current().is_superuser())
+            if (!current_process_credentials->is_superuser())
                 return EPERM;
                 return EPERM;
             if (arp_req.arp_pa.sa_family != AF_INET)
             if (arp_req.arp_pa.sa_family != AF_INET)
                 return EAFNOSUPPORT;
                 return EAFNOSUPPORT;
@@ -669,7 +673,7 @@ ErrorOr<void> IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspac
             return {};
             return {};
 
 
         case SIOCDARP:
         case SIOCDARP:
-            if (!Process::current().is_superuser())
+            if (!current_process_credentials->is_superuser())
                 return EPERM;
                 return EPERM;
             if (arp_req.arp_pa.sa_family != AF_INET)
             if (arp_req.arp_pa.sa_family != AF_INET)
                 return EAFNOSUPPORT;
                 return EAFNOSUPPORT;
@@ -693,9 +697,11 @@ ErrorOr<void> IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspac
         if (!adapter)
         if (!adapter)
             return ENODEV;
             return ENODEV;
 
 
+        auto current_process_credentials = Process::current().credentials();
+
         switch (request) {
         switch (request) {
         case SIOCSIFADDR:
         case SIOCSIFADDR:
-            if (!Process::current().is_superuser())
+            if (!current_process_credentials->is_superuser())
                 return EPERM;
                 return EPERM;
             if (ifr.ifr_addr.sa_family != AF_INET)
             if (ifr.ifr_addr.sa_family != AF_INET)
                 return EAFNOSUPPORT;
                 return EAFNOSUPPORT;
@@ -703,7 +709,7 @@ ErrorOr<void> IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspac
             return {};
             return {};
 
 
         case SIOCSIFNETMASK:
         case SIOCSIFNETMASK:
-            if (!Process::current().is_superuser())
+            if (!current_process_credentials->is_superuser())
                 return EPERM;
                 return EPERM;
             if (ifr.ifr_addr.sa_family != AF_INET)
             if (ifr.ifr_addr.sa_family != AF_INET)
                 return EAFNOSUPPORT;
                 return EAFNOSUPPORT;

+ 2 - 1
Kernel/PerformanceEventBuffer.cpp

@@ -206,7 +206,8 @@ ErrorOr<void> PerformanceEventBuffer::to_json_impl(Serializer& object) const
         TRY(strings.finish());
         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));
     auto array = TRY(object.add_array("events"sv));
     bool seen_first_sample = false;
     bool seen_first_sample = false;
     for (size_t i = 0; i < m_count; ++i) {
     for (size_t i = 0; i < m_count; ++i) {

+ 2 - 31
Kernel/Process.cpp

@@ -522,10 +522,11 @@ Time kgettimeofday()
 
 
 siginfo_t Process::wait_info() const
 siginfo_t Process::wait_info() const
 {
 {
+    auto credentials = this->credentials();
     siginfo_t siginfo {};
     siginfo_t siginfo {};
     siginfo.si_signo = SIGCHLD;
     siginfo.si_signo = SIGCHLD;
     siginfo.si_pid = pid().value();
     siginfo.si_pid = pid().value();
-    siginfo.si_uid = uid().value();
+    siginfo.si_uid = credentials->uid().value();
 
 
     with_protected_data([&](auto& protected_data) {
     with_protected_data([&](auto& protected_data) {
         if (protected_data.termination_signal != 0) {
         if (protected_data.termination_signal != 0) {
@@ -941,36 +942,6 @@ ErrorOr<void> Process::require_promise(Pledge promise)
     return EPROMISEVIOLATION;
     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
 NonnullRefPtr<Credentials> Process::credentials() const
 {
 {
     return with_protected_data([&](auto& protected_data) -> NonnullRefPtr<Credentials> {
     return with_protected_data([&](auto& protected_data) -> NonnullRefPtr<Credentials> {

+ 0 - 9
Kernel/Process.h

@@ -235,13 +235,6 @@ public:
 
 
     NonnullRefPtr<Credentials> credentials() const;
     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
     bool is_dumpable() const
     {
     {
         return with_protected_data([](auto& protected_data) { return protected_data.dumpable; });
         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);
     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);
     void terminate_due_to_signal(u8 signal);
     ErrorOr<void> send_signal(u8 signal, Process* sender);
     ErrorOr<void> send_signal(u8 signal, Process* sender);
 
 

+ 4 - 2
Kernel/ProcessProcFSTraits.cpp

@@ -15,7 +15,8 @@ UserID Process::ProcessProcFSTraits::owner_user() const
     if (!process)
     if (!process)
         return 0;
         return 0;
 
 
-    return process->uid();
+    auto credentials = process->credentials();
+    return credentials->uid();
 }
 }
 
 
 GroupID Process::ProcessProcFSTraits::owner_group() const
 GroupID Process::ProcessProcFSTraits::owner_group() const
@@ -24,7 +25,8 @@ GroupID Process::ProcessProcFSTraits::owner_group() const
     if (!process)
     if (!process)
         return 0;
         return 0;
 
 
-    return process->gid();
+    auto credentials = process->credentials();
+    return credentials->gid();
 }
 }
 
 
 InodeIndex Process::ProcessProcFSTraits::component_index() const
 InodeIndex Process::ProcessProcFSTraits::component_index() const

+ 4 - 2
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);
     auto thread = Thread::from_tid(thread_id);
     if (!thread)
     if (!thread)
         return ESRCH;
         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;
     bool kernel_address_added = false;
     for (auto address : TRY(Processor::capture_stack_trace(*thread, 1024))) {
     for (auto address : TRY(Processor::capture_stack_trace(*thread, 1024))) {
         if (!show_kernel_addresses && !Memory::is_user_address(VirtualAddress { address })) {
         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());
         SpinlockLocker lock(address_space().get_lock());
         for (auto const& region : address_space().regions()) {
         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;
                 continue;
             auto region_object = TRY(array.add_object());
             auto region_object = TRY(array.add_object());
             TRY(region_object.add("readable"sv, region.is_readable()));
             TRY(region_object.add("readable"sv, region.is_readable()));

+ 4 - 2
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);
     VERIFY_NO_PROCESS_BIG_LOCK(this);
     TRY(require_promise(Pledge::settime));
     TRY(require_promise(Pledge::settime));
 
 
-    if (!is_superuser())
+    auto credentials = this->credentials();
+    if (!credentials->is_superuser())
         return EPERM;
         return EPERM;
 
 
     auto time = TRY(copy_time_from_user(user_ts));
     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) {
     if (user_delta) {
         TRY(require_promise(Pledge::settime));
         TRY(require_promise(Pledge::settime));
-        if (!is_superuser())
+        auto credentials = this->credentials();
+        if (!credentials->is_superuser())
             return EPERM;
             return EPERM;
         auto delta = TRY(copy_time_from_user(user_delta));
         auto delta = TRY(copy_time_from_user(user_delta));
 
 

+ 2 - 1
Kernel/Syscalls/execve.cpp

@@ -598,7 +598,8 @@ ErrorOr<void> Process::do_exec(NonnullLockRefPtr<OpenFileDescription> main_progr
     }
     }
     VERIFY(new_main_thread);
     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
     // 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.
     //       and we don't want to deal with faults after this point.

+ 2 - 1
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_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().
     // NOTE: All user processes have a leaked ref on them. It's balanced by Thread::WaitBlockerSet::finalize().
     child->ref();
     child->ref();

+ 8 - 4
Kernel/Syscalls/getuid.cpp

@@ -12,28 +12,32 @@ ErrorOr<FlatPtr> Process::sys$getuid()
 {
 {
     VERIFY_NO_PROCESS_BIG_LOCK(this);
     VERIFY_NO_PROCESS_BIG_LOCK(this);
     TRY(require_promise(Pledge::stdio));
     TRY(require_promise(Pledge::stdio));
-    return uid().value();
+    auto credentials = this->credentials();
+    return credentials->uid().value();
 }
 }
 
 
 ErrorOr<FlatPtr> Process::sys$getgid()
 ErrorOr<FlatPtr> Process::sys$getgid()
 {
 {
     VERIFY_NO_PROCESS_BIG_LOCK(this);
     VERIFY_NO_PROCESS_BIG_LOCK(this);
     TRY(require_promise(Pledge::stdio));
     TRY(require_promise(Pledge::stdio));
-    return gid().value();
+    auto credentials = this->credentials();
+    return credentials->gid().value();
 }
 }
 
 
 ErrorOr<FlatPtr> Process::sys$geteuid()
 ErrorOr<FlatPtr> Process::sys$geteuid()
 {
 {
     VERIFY_NO_PROCESS_BIG_LOCK(this);
     VERIFY_NO_PROCESS_BIG_LOCK(this);
     TRY(require_promise(Pledge::stdio));
     TRY(require_promise(Pledge::stdio));
-    return euid().value();
+    auto credentials = this->credentials();
+    return credentials->euid().value();
 }
 }
 
 
 ErrorOr<FlatPtr> Process::sys$getegid()
 ErrorOr<FlatPtr> Process::sys$getegid()
 {
 {
     VERIFY_NO_PROCESS_BIG_LOCK(this);
     VERIFY_NO_PROCESS_BIG_LOCK(this);
     TRY(require_promise(Pledge::stdio));
     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)
 ErrorOr<FlatPtr> Process::sys$getresuid(Userspace<UserID*> user_ruid, Userspace<UserID*> user_euid, Userspace<UserID*> user_suid)

+ 2 - 1
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);
     VERIFY_NO_PROCESS_BIG_LOCK(this);
     TRY(require_no_promises());
     TRY(require_no_promises());
 
 
-    if (!is_superuser())
+    auto credentials = this->credentials();
+    if (!credentials->is_superuser())
         return EPERM;
         return EPERM;
     if (length > 64)
     if (length > 64)
         return ENAMETOOLONG;
         return ENAMETOOLONG;

+ 2 - 1
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);
     VERIFY_NO_PROCESS_BIG_LOCK(this);
     TRY(require_promise(Pledge::setkeymap));
     TRY(require_promise(Pledge::setkeymap));
 
 
-    if (!is_superuser())
+    auto credentials = this->credentials();
+    if (!credentials->is_superuser())
         return EPERM;
         return EPERM;
 
 
     auto params = TRY(copy_typed_from_user(user_params));
     auto params = TRY(copy_typed_from_user(user_params));

+ 3 - 1
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: Allow sending SIGCONT to everyone in the process group.
     // FIXME: Should setuid processes have some special treatment here?
     // 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;
         return EPERM;
     if (process.is_kernel_process()) {
     if (process.is_kernel_process()) {
         dbgln("Attempted to send signal {} to kernel process {} ({})", signal, process.name(), process.pid());
         dbgln("Attempted to send signal {} to kernel process {} ({})", signal, process.name(), process.pid());

+ 3 - 2
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));
     TRY(require_promise(Pledge::dpath));
     auto params = TRY(copy_typed_from_user(user_params));
     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;
         return EPERM;
     auto path = TRY(get_syscall_path_argument(params.path));
     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;
     return 0;
 }
 }
 
 

+ 6 - 4
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);
     VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
     TRY(require_no_promises());
     TRY(require_no_promises());
-    if (!is_superuser())
+    auto credentials = this->credentials();
+    if (!credentials->is_superuser())
         return EPERM;
         return EPERM;
 
 
     auto params = TRY(copy_typed_from_user(user_params));
     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
     else
         dbgln("mount {} @ {}", fs_type, target);
         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) {
     if (params.flags & MS_REMOUNT) {
         // We're not creating a new mount, we're updating an existing one!
         // 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)
 ErrorOr<FlatPtr> Process::sys$umount(Userspace<char const*> user_mountpoint, size_t mountpoint_length)
 {
 {
     VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
     VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
-    if (!is_superuser())
+    auto credentials = this->credentials();
+    if (!credentials->is_superuser())
         return EPERM;
         return EPERM;
 
 
     TRY(require_no_promises());
     TRY(require_no_promises());
 
 
     auto mountpoint = TRY(get_syscall_path_argument(user_mountpoint, mountpoint_length));
     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();
     auto& guest_inode = custody->inode();
     TRY(VirtualFileSystem::the().unmount(guest_inode));
     TRY(VirtualFileSystem::the().unmount(guest_inode));
     return 0;
     return 0;

+ 2 - 1
Kernel/Syscalls/pipe.cpp

@@ -19,7 +19,8 @@ ErrorOr<FlatPtr> Process::sys$pipe(Userspace<int*> pipefd, int flags)
         return EINVAL;
         return EINVAL;
 
 
     u32 fd_flags = (flags & O_CLOEXEC) ? FD_CLOEXEC : 0;
     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 reader_description = TRY(fifo->open_direction(FIFO::Direction::Reader));
     auto writer_description = TRY(fifo->open_direction(FIFO::Direction::Writer));
     auto writer_description = TRY(fifo->open_direction(FIFO::Direction::Writer));

+ 15 - 6
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));
     auto const event_mask = TRY(copy_typed_from_user(userspace_event_mask));
 
 
     if (pid == -1) {
     if (pid == -1) {
-        if (!is_superuser())
+        auto credentials = this->credentials();
+        if (!credentials->is_superuser())
             return EPERM;
             return EPERM;
         ScopedCritical critical;
         ScopedCritical critical;
         g_profiling_event_mask = PERF_EVENT_PROCESS_CREATE | PERF_EVENT_THREAD_CREATE | PERF_EVENT_MMAP;
         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;
         return ESRCH;
     if (process->is_dead())
     if (process->is_dead())
         return ESRCH;
         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;
         return EPERM;
     SpinlockLocker lock(g_profiling_lock);
     SpinlockLocker lock(g_profiling_lock);
     g_profiling_event_mask = PERF_EVENT_PROCESS_CREATE | PERF_EVENT_THREAD_CREATE | PERF_EVENT_MMAP;
     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());
     TRY(require_no_promises());
 
 
     if (pid == -1) {
     if (pid == -1) {
-        if (!is_superuser())
+        auto credentials = this->credentials();
+        if (!credentials->is_superuser())
             return EPERM;
             return EPERM;
         ScopedCritical critical;
         ScopedCritical critical;
         if (!TimeManagement::the().disable_profile_timer())
         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);
     auto process = Process::from_pid(pid);
     if (!process)
     if (!process)
         return ESRCH;
         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;
         return EPERM;
     SpinlockLocker lock(g_profiling_lock);
     SpinlockLocker lock(g_profiling_lock);
     if (!process->is_profiling())
     if (!process->is_profiling())
@@ -111,7 +117,8 @@ ErrorOr<FlatPtr> Process::sys$profiling_free_buffer(pid_t pid)
     TRY(require_no_promises());
     TRY(require_no_promises());
 
 
     if (pid == -1) {
     if (pid == -1) {
-        if (!is_superuser())
+        auto credentials = this->credentials();
+        if (!credentials->is_superuser())
             return EPERM;
             return EPERM;
 
 
         OwnPtr<PerformanceEventBuffer> perf_events;
         OwnPtr<PerformanceEventBuffer> perf_events;
@@ -129,7 +136,9 @@ ErrorOr<FlatPtr> Process::sys$profiling_free_buffer(pid_t pid)
     auto process = Process::from_pid(pid);
     auto process = Process::from_pid(pid);
     if (!process)
     if (!process)
         return ESRCH;
         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;
         return EPERM;
     SpinlockLocker lock(g_profiling_lock);
     SpinlockLocker lock(g_profiling_lock);
     if (process->is_profiling())
     if (process->is_profiling())

+ 4 - 2
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());
     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;
         return EACCES;
 
 
     if (!peer->process().is_dumpable())
     if (!peer->process().is_dumpable())

+ 2 - 1
Kernel/Syscalls/purge.cpp

@@ -16,7 +16,8 @@ ErrorOr<FlatPtr> Process::sys$purge(int mode)
 {
 {
     VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
     VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
     TRY(require_no_promises());
     TRY(require_no_promises());
-    if (!is_superuser())
+    auto credentials = this->credentials();
+    if (!credentials->is_superuser())
         return EPERM;
         return EPERM;
     size_t purged_page_count = 0;
     size_t purged_page_count = 0;
     if (mode & PURGE_ALL_VOLATILE) {
     if (mode & PURGE_ALL_VOLATILE) {

+ 6 - 2
Kernel/Syscalls/sched.cpp

@@ -34,7 +34,9 @@ ErrorOr<FlatPtr> Process::sys$sched_setparam(int pid, Userspace<const struct sch
     if (!peer)
     if (!peer)
         return ESRCH;
         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;
         return EPERM;
 
 
     peer->set_priority((u32)param.sched_priority);
     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)
         if (!peer)
             return ESRCH;
             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;
             return EPERM;
 
 
         priority = (int)peer->priority();
         priority = (int)peer->priority();

+ 2 - 1
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);
     VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
     REQUIRE_PROMISE_FOR_SOCKET_DOMAIN(domain);
     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 EACCES;
 
 
     return m_fds.with_exclusive([&](auto& fds) -> ErrorOr<FlatPtr> {
     return m_fds.with_exclusive([&](auto& fds) -> ErrorOr<FlatPtr> {

+ 3 - 2
Kernel/TTY/MasterPTY.cpp

@@ -33,8 +33,9 @@ MasterPTY::MasterPTY(unsigned index, NonnullOwnPtr<DoubleBuffer> buffer)
     , m_buffer(move(buffer))
     , m_buffer(move(buffer))
 {
 {
     auto& process = Process::current();
     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]() {
     m_buffer->set_unblock_callback([this]() {
         if (m_slave)
         if (m_slave)

+ 3 - 2
Kernel/TTY/SlavePTY.cpp

@@ -42,8 +42,9 @@ SlavePTY::SlavePTY(MasterPTY& master, unsigned index)
     , m_index(index)
     , m_index(index)
 {
 {
     auto& process = Process::current();
     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);
     set_size(80, 25);
 
 
     SlavePTY::all_instances().with([&](auto& list) { list.append(*this); });
     SlavePTY::all_instances().with([&](auto& list) { list.append(*this); });

+ 3 - 2
Kernel/Thread.cpp

@@ -1131,7 +1131,7 @@ DispatchSignalResult Thread::dispatch_signal(u8 signal)
             // Set for SI_TIMER, we don't have the data here.
             // Set for SI_TIMER, we don't have the data here.
             .si_errno = 0,
             .si_errno = 0,
             .si_pid = sender_pid.value(),
             .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
             // Set for SIGILL, SIGFPE, SIGSEGV and SIGBUS
             // FIXME: We don't generate these signals in a way that can be handled.
             // FIXME: We don't generate these signals in a way that can be handled.
             .si_addr = 0,
             .si_addr = 0,
@@ -1346,7 +1346,8 @@ static ErrorOr<bool> symbolicate(RecognizedSymbol const& symbol, Process& proces
     if (symbol.address == 0)
     if (symbol.address == 0)
         return false;
         return false;
 
 
-    bool mask_kernel_addresses = !process.is_superuser();
+    auto credentials = process.credentials();
+    bool mask_kernel_addresses = !credentials->is_superuser();
     if (!symbol.symbol) {
     if (!symbol.symbol) {
         if (!Memory::is_user_address(VirtualAddress(symbol.address))) {
         if (!Memory::is_user_address(VirtualAddress(symbol.address))) {
             TRY(builder.try_append("0xdeadc0de\n"sv));
             TRY(builder.try_append("0xdeadc0de\n"sv));

+ 2 - 1
Kernel/ThreadBlockers.cpp

@@ -783,10 +783,11 @@ bool Thread::WaitBlocker::unblock(Process& process, UnblockFlags flags, u8 signa
         siginfo_t siginfo {};
         siginfo_t siginfo {};
         {
         {
             SpinlockLocker lock(g_scheduler_lock);
             SpinlockLocker lock(g_scheduler_lock);
+            auto credentials = process.credentials();
             // We need to gather the information before we release the scheduler lock!
             // We need to gather the information before we release the scheduler lock!
             siginfo.si_signo = SIGCHLD;
             siginfo.si_signo = SIGCHLD;
             siginfo.si_pid = process.pid().value();
             siginfo.si_pid = process.pid().value();
-            siginfo.si_uid = process.uid().value();
+            siginfo.si_uid = credentials->uid().value();
             siginfo.si_status = signal;
             siginfo.si_status = signal;
 
 
             switch (flags) {
             switch (flags) {