summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/Process.cpp63
-rw-r--r--Kernel/Process.h66
-rw-r--r--Kernel/Syscalls/execve.cpp14
-rw-r--r--Kernel/Syscalls/fork.cpp8
-rw-r--r--Kernel/Syscalls/getuid.cpp13
-rw-r--r--Kernel/Syscalls/kill.cpp8
-rw-r--r--Kernel/Syscalls/pipe.cpp2
-rw-r--r--Kernel/Syscalls/process.cpp2
-rw-r--r--Kernel/Syscalls/profiling.cpp4
-rw-r--r--Kernel/Syscalls/sched.cpp4
-rw-r--r--Kernel/Syscalls/setpgid.cpp22
-rw-r--r--Kernel/Syscalls/setuid.cpp114
12 files changed, 190 insertions, 130 deletions
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp
index e22ca91696..a7d047cadc 100644
--- a/Kernel/Process.cpp
+++ b/Kernel/Process.cpp
@@ -25,7 +25,6 @@
*/
#include <AK/Demangle.h>
-#include <AK/QuickSort.h>
#include <AK/StdLibExtras.h>
#include <AK/StringBuilder.h>
#include <AK/Time.h>
@@ -38,7 +37,6 @@
#include <Kernel/FileSystem/Custody.h>
#include <Kernel/FileSystem/FileDescription.h>
#include <Kernel/FileSystem/VirtualFileSystem.h>
-#include <Kernel/Heap/kmalloc.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/KSyms.h>
#include <Kernel/Module.h>
@@ -51,7 +49,6 @@
#include <Kernel/VM/AnonymousVMObject.h>
#include <Kernel/VM/PageDirectory.h>
#include <Kernel/VM/PrivateInodeVMObject.h>
-#include <Kernel/VM/ProcessPagingScope.h>
#include <Kernel/VM/SharedInodeVMObject.h>
#include <LibC/errno_numbers.h>
#include <LibC/limits.h>
@@ -113,7 +110,7 @@ NonnullRefPtrVector<Process> Process::all_processes()
bool Process::in_group(gid_t gid) const
{
- return m_gid == gid || m_extra_gids.contains_slow(gid);
+ return this->gid() == gid || m_extra_gids.contains_slow(gid);
}
void Process::kill_threads_except_self()
@@ -212,15 +209,31 @@ RefPtr<Process> Process::create_kernel_process(RefPtr<Thread>& first_thread, Str
return process;
}
+const Process::ProtectedData& Process::protected_data() const
+{
+ return *reinterpret_cast<const ProtectedData*>(m_protected_data->data());
+}
+
+void Process::protect_data()
+{
+ auto& region = m_protected_data->impl().region();
+ if (!region.is_writable())
+ return;
+ region.set_writable(false);
+ region.remap();
+}
+
+void Process::unprotect_data()
+{
+ auto& region = m_protected_data->impl().region();
+ if (region.is_writable())
+ return;
+ region.set_writable(true);
+ region.remap();
+}
+
Process::Process(RefPtr<Thread>& first_thread, const String& name, uid_t uid, gid_t gid, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> cwd, RefPtr<Custody> executable, TTY* tty, Process* fork_parent)
: m_name(move(name))
- , m_pid(allocate_pid())
- , m_euid(uid)
- , m_egid(gid)
- , m_uid(uid)
- , m_gid(gid)
- , m_suid(uid)
- , m_sgid(gid)
, m_is_kernel_process(is_kernel_process)
, m_executable(move(executable))
, m_cwd(move(cwd))
@@ -228,7 +241,21 @@ Process::Process(RefPtr<Thread>& first_thread, const String& name, uid_t uid, gi
, m_ppid(ppid)
, m_wait_block_condition(*this)
{
- dbgln_if(PROCESS_DEBUG, "Created new process {}({})", m_name, m_pid.value());
+ m_protected_data = KBuffer::try_create_with_size(sizeof(ProtectedData));
+ VERIFY(m_protected_data);
+
+ {
+ MutableProtectedData protected_data { *this };
+ protected_data->pid = allocate_pid();
+ protected_data->uid = uid;
+ protected_data->gid = gid;
+ protected_data->euid = uid;
+ protected_data->egid = gid;
+ protected_data->suid = uid;
+ protected_data->sgid = gid;
+ }
+
+ dbgln_if(PROCESS_DEBUG, "Created new process {}({})", m_name, this->pid().value());
m_space = Space::create(*this, fork_parent ? &fork_parent->space() : nullptr);
@@ -433,8 +460,8 @@ bool Process::dump_core()
{
VERIFY(is_dumpable());
VERIFY(should_core_dump());
- dbgln("Generating coredump for pid: {}", m_pid.value());
- auto coredump_path = String::formatted("/tmp/coredump/{}_{}_{}", name(), m_pid.value(), RTC::now());
+ dbgln("Generating coredump for pid: {}", pid().value());
+ auto coredump_path = String::formatted("/tmp/coredump/{}_{}_{}", name(), pid().value(), RTC::now());
auto coredump = CoreDump::create(*this, coredump_path);
if (!coredump)
return false;
@@ -445,8 +472,8 @@ bool Process::dump_perfcore()
{
VERIFY(is_dumpable());
VERIFY(m_perf_event_buffer);
- dbgln("Generating perfcore for pid: {}", m_pid.value());
- auto description_or_error = VFS::the().open(String::formatted("perfcore.{}", m_pid.value()), O_CREAT | O_EXCL, 0400, current_directory(), UidAndGid { m_uid, m_gid });
+ dbgln("Generating perfcore for pid: {}", pid().value());
+ auto description_or_error = VFS::the().open(String::formatted("perfcore.{}", pid().value()), O_CREAT | O_EXCL, 0400, current_directory(), UidAndGid { uid(), gid() });
if (description_or_error.is_error())
return false;
auto& description = description_or_error.value();
@@ -547,7 +574,7 @@ void Process::die()
ScopedSpinLock lock(g_processes_lock);
for (auto* process = g_processes->head(); process;) {
auto* next_process = process->next();
- if (process->has_tracee_thread(m_pid)) {
+ if (process->has_tracee_thread(pid())) {
dbgln_if(PROCESS_DEBUG, "Process {} ({}) is attached by {} ({}) which will exit", process->name(), process->pid(), name(), pid());
process->stop_tracing();
auto err = process->send_signal(SIGSTOP, this);
@@ -576,7 +603,7 @@ void Process::terminate_due_to_signal(u8 signal)
KResult Process::send_signal(u8 signal, Process* sender)
{
// Try to send it to the "obvious" main thread:
- auto receiver_thread = Thread::from_tid(m_pid.value());
+ auto receiver_thread = Thread::from_tid(pid().value());
// If the main thread has died, there may still be other threads:
if (!receiver_thread) {
// The first one should be good enough.
diff --git a/Kernel/Process.h b/Kernel/Process.h
index ad8e8a3f82..036ff7cbf5 100644
--- a/Kernel/Process.h
+++ b/Kernel/Process.h
@@ -112,6 +112,33 @@ class Process
friend class Thread;
friend class CoreDump;
+ struct ProtectedData {
+ ProcessID pid { 0 };
+ SessionID sid { 0 };
+ uid_t euid { 0 };
+ gid_t egid { 0 };
+ uid_t uid { 0 };
+ gid_t gid { 0 };
+ uid_t suid { 0 };
+ gid_t sgid { 0 };
+ };
+
+ // Helper class to temporarily unprotect a process's protected data so you can write to it.
+ class MutableProtectedData {
+ public:
+ explicit MutableProtectedData(Process& process)
+ : m_process(process)
+ {
+ m_process.unprotect_data();
+ }
+
+ ~MutableProtectedData() { m_process.protect_data(); }
+ ProtectedData* operator->() { return &const_cast<ProtectedData&>(m_process.protected_data()); }
+
+ private:
+ Process& m_process;
+ };
+
public:
inline static Process* current()
{
@@ -169,18 +196,18 @@ public:
static SessionID get_sid_from_pgid(ProcessGroupID pgid);
const String& name() const { return m_name; }
- ProcessID pid() const { return m_pid; }
- SessionID sid() const { return m_sid; }
- bool is_session_leader() const { return m_sid.value() == m_pid.value(); }
+ ProcessID pid() const { return protected_data().pid; }
+ SessionID sid() const { return protected_data().sid; }
+ bool is_session_leader() const { return protected_data().sid.value() == protected_data().pid.value(); }
ProcessGroupID pgid() const { return m_pg ? m_pg->pgid() : 0; }
- bool is_group_leader() const { return pgid().value() == m_pid.value(); }
+ bool is_group_leader() const { return pgid().value() == protected_data().pid.value(); }
Span<const gid_t> extra_gids() const { return m_extra_gids; }
- uid_t euid() const { return m_euid; }
- gid_t egid() const { return m_egid; }
- uid_t uid() const { return m_uid; }
- gid_t gid() const { return m_gid; }
- uid_t suid() const { return m_suid; }
- gid_t sgid() const { return m_sgid; }
+ uid_t euid() const { return protected_data().euid; }
+ gid_t egid() const { return protected_data().egid; }
+ uid_t uid() const { return protected_data().uid; }
+ gid_t gid() const { return protected_data().gid; }
+ uid_t suid() const { return protected_data().suid; }
+ gid_t sgid() const { return protected_data().sgid; }
ProcessID ppid() const { return m_ppid; }
bool is_dumpable() const { return m_dumpable; }
@@ -392,10 +419,7 @@ public:
KResultOr<LoadResult> load(NonnullRefPtr<FileDescription> main_program_description, RefPtr<FileDescription> interpreter_description, const Elf32_Ehdr& main_program_header);
- bool is_superuser() const
- {
- return m_euid == 0;
- }
+ bool is_superuser() const { return euid() == 0; }
void terminate_due_to_signal(u8 signal);
KResult send_signal(u8 signal, Process* sender);
@@ -510,16 +534,12 @@ private:
OwnPtr<Space> m_space;
VirtualAddress m_signal_trampoline;
- ProcessID m_pid { 0 };
- SessionID m_sid { 0 };
RefPtr<ProcessGroup> m_pg;
- uid_t m_euid { 0 };
- gid_t m_egid { 0 };
- uid_t m_uid { 0 };
- gid_t m_gid { 0 };
- uid_t m_suid { 0 };
- gid_t m_sgid { 0 };
+ const ProtectedData& protected_data() const;
+ void protect_data();
+ void unprotect_data();
+ OwnPtr<KBuffer> m_protected_data;
OwnPtr<ThreadTracer> m_tracer;
@@ -631,7 +651,7 @@ inline void Process::for_each_child(Callback callback)
ScopedSpinLock lock(g_processes_lock);
for (auto* process = g_processes->head(); process;) {
auto* next_process = process->next();
- if (process->ppid() == my_pid || process->has_tracee_thread(m_pid)) {
+ if (process->ppid() == my_pid || process->has_tracee_thread(pid())) {
if (callback(*process) == IterationDecision::Break)
break;
}
diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp
index 03de8d0df6..5aa2e8686e 100644
--- a/Kernel/Syscalls/execve.cpp
+++ b/Kernel/Syscalls/execve.cpp
@@ -507,11 +507,15 @@ KResult Process::do_exec(NonnullRefPtr<FileDescription> main_program_description
if (!(main_program_description->custody()->mount_flags() & MS_NOSUID)) {
if (main_program_metadata.is_setuid()) {
executable_is_setid = true;
- m_euid = m_suid = main_program_metadata.uid;
+ MutableProtectedData protected_data { *this };
+ protected_data->euid = main_program_metadata.uid;
+ protected_data->suid = main_program_metadata.uid;
}
if (main_program_metadata.is_setgid()) {
executable_is_setid = true;
- m_egid = m_sgid = main_program_metadata.gid;
+ MutableProtectedData protected_data { *this };
+ protected_data->egid = main_program_metadata.gid;
+ protected_data->sgid = main_program_metadata.gid;
}
}
@@ -574,7 +578,7 @@ KResult Process::do_exec(NonnullRefPtr<FileDescription> main_program_description
}
VERIFY(new_main_thread);
- auto auxv = generate_auxiliary_vector(load_result.load_base, load_result.entry_eip, m_uid, m_euid, m_gid, m_egid, path, main_program_fd);
+ auto auxv = generate_auxiliary_vector(load_result.load_base, load_result.entry_eip, uid(), euid(), gid(), egid(), path, main_program_fd);
// 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.
@@ -600,7 +604,7 @@ KResult Process::do_exec(NonnullRefPtr<FileDescription> main_program_description
new_main_thread->set_name(m_name);
// FIXME: PID/TID ISSUE
- m_pid = new_main_thread->tid().value();
+ MutableProtectedData(*this)->pid = new_main_thread->tid().value();
auto tsr_result = new_main_thread->make_thread_specific_region({});
if (tsr_result.is_error()) {
// FIXME: We cannot fail this late. Refactor this so the allocation happens before we commit to the new executable.
@@ -618,7 +622,7 @@ KResult Process::do_exec(NonnullRefPtr<FileDescription> main_program_description
tss.eip = load_result.entry_eip;
tss.esp = new_userspace_esp;
tss.cr3 = space().page_directory().cr3();
- tss.ss2 = m_pid.value();
+ tss.ss2 = pid().value();
// Throw away any recorded performance events in this process.
if (m_perf_event_buffer)
diff --git a/Kernel/Syscalls/fork.cpp b/Kernel/Syscalls/fork.cpp
index 054510bbaa..f9f2b4f4d6 100644
--- a/Kernel/Syscalls/fork.cpp
+++ b/Kernel/Syscalls/fork.cpp
@@ -36,7 +36,7 @@ KResultOr<pid_t> Process::sys$fork(RegisterState& regs)
{
REQUIRE_PROMISE(proc);
RefPtr<Thread> child_first_thread;
- auto child = adopt(*new Process(child_first_thread, m_name, m_uid, m_gid, m_pid, m_is_kernel_process, m_cwd, m_executable, m_tty, this));
+ auto child = adopt(*new Process(child_first_thread, m_name, uid(), gid(), pid(), m_is_kernel_process, m_cwd, m_executable, m_tty, this));
if (!child_first_thread)
return ENOMEM;
child->m_root_directory = m_root_directory;
@@ -48,12 +48,16 @@ KResultOr<pid_t> Process::sys$fork(RegisterState& regs)
child->m_veil_state = m_veil_state;
child->m_unveiled_paths = m_unveiled_paths.deep_copy();
child->m_fds = m_fds;
- child->m_sid = m_sid;
child->m_pg = m_pg;
child->m_umask = m_umask;
child->m_extra_gids = m_extra_gids;
child->m_signal_trampoline = m_signal_trampoline;
+ {
+ MutableProtectedData child_data { *child };
+ child_data->sid = this->sid();
+ }
+
dbgln_if(FORK_DEBUG, "fork: child={}", child);
child->space().set_enforces_syscall_regions(space().enforces_syscall_regions());
diff --git a/Kernel/Syscalls/getuid.cpp b/Kernel/Syscalls/getuid.cpp
index 55957026b6..c2c753b9b7 100644
--- a/Kernel/Syscalls/getuid.cpp
+++ b/Kernel/Syscalls/getuid.cpp
@@ -31,31 +31,31 @@ namespace Kernel {
KResultOr<uid_t> Process::sys$getuid()
{
REQUIRE_PROMISE(stdio);
- return m_uid;
+ return uid();
}
KResultOr<gid_t> Process::sys$getgid()
{
REQUIRE_PROMISE(stdio);
- return m_gid;
+ return gid();
}
KResultOr<uid_t> Process::sys$geteuid()
{
REQUIRE_PROMISE(stdio);
- return m_euid;
+ return euid();
}
KResultOr<gid_t> Process::sys$getegid()
{
REQUIRE_PROMISE(stdio);
- return m_egid;
+ return egid();
}
KResultOr<int> Process::sys$getresuid(Userspace<uid_t*> ruid, Userspace<uid_t*> euid, Userspace<uid_t*> suid)
{
REQUIRE_PROMISE(stdio);
- if (!copy_to_user(ruid, &m_uid) || !copy_to_user(euid, &m_euid) || !copy_to_user(suid, &m_suid))
+ if (!copy_to_user(ruid, &protected_data().uid) || !copy_to_user(euid, &protected_data().euid) || !copy_to_user(suid, &protected_data().suid))
return EFAULT;
return 0;
}
@@ -63,7 +63,7 @@ KResultOr<int> Process::sys$getresuid(Userspace<uid_t*> ruid, Userspace<uid_t*>
KResultOr<int> Process::sys$getresgid(Userspace<gid_t*> rgid, Userspace<gid_t*> egid, Userspace<gid_t*> sgid)
{
REQUIRE_PROMISE(stdio);
- if (!copy_to_user(rgid, &m_gid) || !copy_to_user(egid, &m_egid) || !copy_to_user(sgid, &m_sgid))
+ if (!copy_to_user(rgid, &protected_data().gid) || !copy_to_user(egid, &protected_data().egid) || !copy_to_user(sgid, &protected_data().sgid))
return EFAULT;
return 0;
}
@@ -80,6 +80,7 @@ KResultOr<int> Process::sys$getgroups(ssize_t count, Userspace<gid_t*> user_gids
if (!copy_to_user(user_gids, m_extra_gids.data(), sizeof(gid_t) * count))
return EFAULT;
+
return 0;
}
diff --git a/Kernel/Syscalls/kill.cpp b/Kernel/Syscalls/kill.cpp
index 1a75d77c06..c27d056c80 100644
--- a/Kernel/Syscalls/kill.cpp
+++ b/Kernel/Syscalls/kill.cpp
@@ -32,7 +32,7 @@ KResult 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() && m_euid != process.m_uid && m_uid != process.m_uid)
+ if (!is_superuser() && euid() != process.uid() && uid() != process.uid())
return EPERM;
if (process.is_kernel_process() && signal == SIGKILL) {
klog() << "attempted to send SIGKILL to kernel process " << process.name().characters() << "(" << process.pid().value() << ")";
@@ -89,7 +89,7 @@ KResult Process::do_killall(int signal)
ScopedSpinLock lock(g_processes_lock);
for (auto& process : *g_processes) {
KResult res = KSuccess;
- if (process.pid() == m_pid)
+ if (process.pid() == pid())
res = do_killself(signal);
else
res = do_kill(process, signal);
@@ -119,7 +119,7 @@ KResult Process::do_killself(int signal)
KResultOr<int> Process::sys$kill(pid_t pid_or_pgid, int signal)
{
- if (pid_or_pgid == m_pid.value())
+ if (pid_or_pgid == pid().value())
REQUIRE_PROMISE(stdio);
else
REQUIRE_PROMISE(proc);
@@ -133,7 +133,7 @@ KResultOr<int> Process::sys$kill(pid_t pid_or_pgid, int signal)
}
if (pid_or_pgid == -1)
return do_killall(signal);
- if (pid_or_pgid == m_pid.value()) {
+ if (pid_or_pgid == pid().value()) {
return do_killself(signal);
}
VERIFY(pid_or_pgid >= 0);
diff --git a/Kernel/Syscalls/pipe.cpp b/Kernel/Syscalls/pipe.cpp
index 785a4fe9d6..d8c06317f4 100644
--- a/Kernel/Syscalls/pipe.cpp
+++ b/Kernel/Syscalls/pipe.cpp
@@ -40,7 +40,7 @@ KResultOr<int> Process::sys$pipe(int pipefd[2], int flags)
return EINVAL;
u32 fd_flags = (flags & O_CLOEXEC) ? FD_CLOEXEC : 0;
- auto fifo = FIFO::create(m_uid);
+ auto fifo = FIFO::create(uid());
auto open_reader_result = fifo->open_direction(FIFO::Direction::Reader);
if (open_reader_result.is_error())
diff --git a/Kernel/Syscalls/process.cpp b/Kernel/Syscalls/process.cpp
index e604a1e161..e604641965 100644
--- a/Kernel/Syscalls/process.cpp
+++ b/Kernel/Syscalls/process.cpp
@@ -32,7 +32,7 @@ namespace Kernel {
KResultOr<pid_t> Process::sys$getpid()
{
REQUIRE_PROMISE(stdio);
- return m_pid.value();
+ return pid().value();
}
KResultOr<pid_t> Process::sys$getppid()
diff --git a/Kernel/Syscalls/profiling.cpp b/Kernel/Syscalls/profiling.cpp
index 01001fe161..62aa46a443 100644
--- a/Kernel/Syscalls/profiling.cpp
+++ b/Kernel/Syscalls/profiling.cpp
@@ -57,7 +57,7 @@ KResultOr<int> Process::sys$profiling_enable(pid_t pid)
return ESRCH;
if (process->is_dead())
return ESRCH;
- if (!is_superuser() && process->uid() != m_euid)
+ if (!is_superuser() && process->uid() != euid())
return EPERM;
if (!process->create_perf_events_buffer_if_needed())
return ENOMEM;
@@ -79,7 +79,7 @@ KResultOr<int> Process::sys$profiling_disable(pid_t pid)
auto process = Process::from_pid(pid);
if (!process)
return ESRCH;
- if (!is_superuser() && process->uid() != m_euid)
+ if (!is_superuser() && process->uid() != euid())
return EPERM;
if (!process->is_profiling())
return EINVAL;
diff --git a/Kernel/Syscalls/sched.cpp b/Kernel/Syscalls/sched.cpp
index 48a1faadbd..521513a108 100644
--- a/Kernel/Syscalls/sched.cpp
+++ b/Kernel/Syscalls/sched.cpp
@@ -67,7 +67,7 @@ KResultOr<int> Process::sys$sched_setparam(int pid, Userspace<const struct sched
if (!peer)
return ESRCH;
- if (!is_superuser() && m_euid != peer->process().m_uid && m_uid != peer->process().m_uid)
+ if (!is_superuser() && euid() != peer->process().uid() && uid() != peer->process().uid())
return EPERM;
peer->set_priority((u32)desired_param.sched_priority);
@@ -90,7 +90,7 @@ KResultOr<int> Process::sys$sched_getparam(pid_t pid, Userspace<struct sched_par
if (!peer)
return ESRCH;
- if (!is_superuser() && m_euid != peer->process().m_uid && m_uid != peer->process().m_uid)
+ if (!is_superuser() && euid() != peer->process().uid() && uid() != peer->process().uid())
return EPERM;
priority = (int)peer->priority();
diff --git a/Kernel/Syscalls/setpgid.cpp b/Kernel/Syscalls/setpgid.cpp
index f66629b004..f10fec2ebf 100644
--- a/Kernel/Syscalls/setpgid.cpp
+++ b/Kernel/Syscalls/setpgid.cpp
@@ -33,14 +33,14 @@ KResultOr<pid_t> Process::sys$getsid(pid_t pid)
{
REQUIRE_PROMISE(proc);
if (pid == 0)
- return m_sid.value();
+ return sid().value();
ScopedSpinLock lock(g_processes_lock);
auto process = Process::from_pid(pid);
if (!process)
return ESRCH;
- if (m_sid != process->m_sid)
+ if (sid() != process->sid())
return EPERM;
- return process->m_sid.value();
+ return process->sid().value();
}
KResultOr<pid_t> Process::sys$setsid()
@@ -55,10 +55,10 @@ KResultOr<pid_t> Process::sys$setsid()
if (found_process_with_same_pgid_as_my_pid)
return EPERM;
// Create a new Session and a new ProcessGroup.
- m_sid = m_pid.value();
- m_pg = ProcessGroup::create(ProcessGroupID(m_pid.value()));
+ MutableProtectedData(*this)->sid = pid().value();
+ m_pg = ProcessGroup::create(ProcessGroupID(pid().value()));
m_tty = nullptr;
- return m_sid.value();
+ return sid().value();
}
KResultOr<pid_t> Process::sys$getpgid(pid_t pid)
@@ -97,7 +97,7 @@ KResultOr<int> Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid)
{
REQUIRE_PROMISE(proc);
ScopedSpinLock lock(g_processes_lock); // FIXME: Use a ProcessHandle
- ProcessID pid = specified_pid ? ProcessID(specified_pid) : m_pid;
+ ProcessID pid = specified_pid ? ProcessID(specified_pid) : this->pid();
if (specified_pgid < 0) {
// The value of the pgid argument is less than 0, or is not a value supported by the implementation.
return EINVAL;
@@ -105,7 +105,7 @@ KResultOr<int> Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid)
auto process = Process::from_pid(pid);
if (!process)
return ESRCH;
- if (process != this && process->ppid() != m_pid) {
+ if (process != this && process->ppid() != this->pid()) {
// The value of the pid argument does not match the process ID
// of the calling process or of a child process of the calling process.
return ESRCH;
@@ -114,21 +114,21 @@ KResultOr<int> Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid)
// The process indicated by the pid argument is a session leader.
return EPERM;
}
- if (process->ppid() == m_pid && process->sid() != sid()) {
+ if (process->ppid() == this->pid() && process->sid() != sid()) {
// The value of the pid argument matches the process ID of a child
// process of the calling process and the child process is not in
// the same session as the calling process.
return EPERM;
}
- ProcessGroupID new_pgid = specified_pgid ? ProcessGroupID(specified_pgid) : process->m_pid.value();
+ ProcessGroupID new_pgid = specified_pgid ? ProcessGroupID(specified_pgid) : process->pid().value();
SessionID current_sid = sid();
SessionID new_sid = get_sid_from_pgid(new_pgid);
if (new_sid != -1 && current_sid != new_sid) {
// Can't move a process between sessions.
return EPERM;
}
- if (new_sid == -1 && new_pgid != process->m_pid.value()) {
+ if (new_sid == -1 && new_pgid != process->pid().value()) {
// The value of the pgid argument is valid, but is not
// the calling pid, and is not an existing process group.
return EPERM;
diff --git a/Kernel/Syscalls/setuid.cpp b/Kernel/Syscalls/setuid.cpp
index 7426e6cf15..66d333f236 100644
--- a/Kernel/Syscalls/setuid.cpp
+++ b/Kernel/Syscalls/setuid.cpp
@@ -28,110 +28,114 @@
namespace Kernel {
-KResultOr<int> Process::sys$seteuid(uid_t euid)
+KResultOr<int> Process::sys$seteuid(uid_t new_euid)
{
REQUIRE_PROMISE(id);
- if (euid != m_uid && euid != m_suid && !is_superuser())
+ if (new_euid != uid() && new_euid != suid() && !is_superuser())
return EPERM;
- if (m_euid != euid)
+ if (euid() != new_euid)
set_dumpable(false);
- m_euid = euid;
+ MutableProtectedData(*this)->euid = new_euid;
return 0;
}
-KResultOr<int> Process::sys$setegid(gid_t egid)
+KResultOr<int> Process::sys$setegid(gid_t new_egid)
{
REQUIRE_PROMISE(id);
- if (egid != m_gid && egid != m_sgid && !is_superuser())
+ if (new_egid != gid() && new_egid != sgid() && !is_superuser())
return EPERM;
- if (m_egid != egid)
+ if (egid() != new_egid)
set_dumpable(false);
- m_egid = egid;
+ MutableProtectedData(*this)->egid = new_egid;
return 0;
}
-KResultOr<int> Process::sys$setuid(uid_t uid)
+KResultOr<int> Process::sys$setuid(uid_t new_uid)
{
REQUIRE_PROMISE(id);
- if (uid != m_uid && uid != m_euid && !is_superuser())
+ if (new_uid != uid() && new_uid != euid() && !is_superuser())
return EPERM;
- if (m_euid != uid)
+ if (euid() != new_uid)
set_dumpable(false);
- m_uid = uid;
- m_euid = uid;
- m_suid = uid;
+ MutableProtectedData protected_data { *this };
+ protected_data->uid = new_uid;
+ protected_data->euid = new_uid;
+ protected_data->suid = new_uid;
return 0;
}
-KResultOr<int> Process::sys$setgid(gid_t gid)
+KResultOr<int> Process::sys$setgid(gid_t new_gid)
{
REQUIRE_PROMISE(id);
- if (gid != m_gid && gid != m_egid && !is_superuser())
+ if (new_gid != gid() && new_gid != egid() && !is_superuser())
return EPERM;
- if (m_egid != gid)
+ if (egid() != new_gid)
set_dumpable(false);
- m_gid = gid;
- m_egid = gid;
- m_sgid = gid;
+ MutableProtectedData protected_data { *this };
+ protected_data->gid = new_gid;
+ protected_data->egid = new_gid;
+ protected_data->sgid = new_gid;
return 0;
}
-KResultOr<int> Process::sys$setresuid(uid_t ruid, uid_t euid, uid_t suid)
+KResultOr<int> Process::sys$setresuid(uid_t new_ruid, uid_t new_euid, uid_t new_suid)
{
REQUIRE_PROMISE(id);
- if (ruid == (uid_t)-1)
- ruid = m_uid;
- if (euid == (uid_t)-1)
- euid = m_euid;
- if (suid == (uid_t)-1)
- suid = m_suid;
+ if (new_ruid == (uid_t)-1)
+ new_ruid = uid();
+ if (new_euid == (uid_t)-1)
+ new_euid = euid();
+ if (new_suid == (uid_t)-1)
+ new_suid = suid();
- auto ok = [this](uid_t id) { return id == m_uid || id == m_euid || id == m_suid; };
- if ((!ok(ruid) || !ok(euid) || !ok(suid)) && !is_superuser())
+ auto ok = [this](uid_t id) { return id == uid() || id == euid() || id == suid(); };
+ if ((!ok(new_ruid) || !ok(new_euid) || !ok(new_suid)) && !is_superuser())
return EPERM;
- if (m_euid != euid)
+ if (euid() != new_euid)
set_dumpable(false);
- m_uid = ruid;
- m_euid = euid;
- m_suid = suid;
+ MutableProtectedData protected_data { *this };
+ protected_data->uid = new_ruid;
+ protected_data->euid = new_euid;
+ protected_data->suid = new_suid;
return 0;
}
-KResultOr<int> Process::sys$setresgid(gid_t rgid, gid_t egid, gid_t sgid)
+KResultOr<int> Process::sys$setresgid(gid_t new_rgid, gid_t new_egid, gid_t new_sgid)
{
REQUIRE_PROMISE(id);
- if (rgid == (gid_t)-1)
- rgid = m_gid;
- if (egid == (gid_t)-1)
- egid = m_egid;
- if (sgid == (gid_t)-1)
- sgid = m_sgid;
+ if (new_rgid == (gid_t)-1)
+ new_rgid = gid();
+ if (new_egid == (gid_t)-1)
+ new_egid = egid();
+ if (new_sgid == (gid_t)-1)
+ new_sgid = sgid();
- auto ok = [this](gid_t id) { return id == m_gid || id == m_egid || id == m_sgid; };
- if ((!ok(rgid) || !ok(egid) || !ok(sgid)) && !is_superuser())
+ auto ok = [this](gid_t id) { return id == gid() || id == egid() || id == sgid(); };
+ if ((!ok(new_rgid) || !ok(new_egid) || !ok(new_sgid)) && !is_superuser())
return EPERM;
- if (m_egid != egid)
+ if (egid() != new_egid)
set_dumpable(false);
- m_gid = rgid;
- m_egid = egid;
- m_sgid = sgid;
+ MutableProtectedData protected_data { *this };
+ protected_data->gid = new_rgid;
+ protected_data->egid = new_egid;
+ protected_data->sgid = new_sgid;
return 0;
}
@@ -148,23 +152,23 @@ KResultOr<int> Process::sys$setgroups(ssize_t count, Userspace<const gid_t*> use
return 0;
}
- Vector<gid_t> gids;
- gids.resize(count);
- if (!copy_n_from_user(gids.data(), user_gids, count))
+ Vector<gid_t> new_extra_gids;
+ new_extra_gids.resize(count);
+ if (!copy_n_from_user(new_extra_gids.data(), user_gids, count))
return EFAULT;
HashTable<gid_t> unique_extra_gids;
- for (auto& gid : gids) {
- if (gid != m_gid)
- unique_extra_gids.set(gid);
+ for (auto& extra_gid : new_extra_gids) {
+ if (extra_gid != gid())
+ unique_extra_gids.set(extra_gid);
}
m_extra_gids.resize(unique_extra_gids.size());
size_t i = 0;
- for (auto& gid : unique_extra_gids) {
- if (gid == m_gid)
+ for (auto& extra_gid : unique_extra_gids) {
+ if (extra_gid == gid())
continue;
- m_extra_gids[i++] = gid;
+ m_extra_gids[i++] = extra_gid;
}
return 0;
}