mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 06:57:46 +00:00
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.
This commit is contained in:
parent
8026d8926c
commit
f86b671de2
27 changed files with 109 additions and 94 deletions
|
@ -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));
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue