1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 07:27:45 +00:00

Kernel/Process: Move protected values to the end of the object

The compiler can re-order the structure (class) members if that's
necessary, so if we make Process to inherit from ProcFSExposedComponent,
even if the declaration is to inherit first from ProcessBase, then from
ProcFSExposedComponent and last from Weakable<Process>, the members of
class ProcFSExposedComponent (including the Ref-counted parts) are the
first members of the Process class.

This problem made it impossible to safely use the current toggling
method with the write-protection bit on the ProcessBase members, so
instead of inheriting from it, we make its members the last ones in the
Process class so we can safely locate and modify the corresponding page
write protection bit of these values.

We make sure that the Process class doesn't expand beyond 8192 bytes and
the protected values are always aligned on a page boundary.
This commit is contained in:
Liav A 2021-08-07 22:30:06 +03:00 committed by Andreas Kling
parent e405f436b6
commit 01b79910b3
12 changed files with 130 additions and 128 deletions

View file

@ -18,7 +18,7 @@ KResultOr<FlatPtr> Process::sys$disown(ProcessID pid)
if (process->ppid() != this->pid())
return ECHILD;
ProtectedDataMutationScope scope(*process);
process->m_ppid = 0;
process->m_protected_values.ppid = 0;
process->disowned_by_waiter(*this);
return 0;
}

View file

@ -540,14 +540,14 @@ KResult Process::do_exec(NonnullRefPtr<FileDescription> main_program_description
if (main_program_metadata.is_setuid()) {
executable_is_setid = true;
ProtectedDataMutationScope scope { *this };
m_euid = main_program_metadata.uid;
m_suid = main_program_metadata.uid;
m_protected_values.euid = main_program_metadata.uid;
m_protected_values.suid = main_program_metadata.uid;
}
if (main_program_metadata.is_setgid()) {
executable_is_setid = true;
ProtectedDataMutationScope scope { *this };
m_egid = main_program_metadata.gid;
m_sgid = main_program_metadata.gid;
m_protected_values.egid = main_program_metadata.gid;
m_protected_values.sgid = main_program_metadata.gid;
}
}
@ -641,16 +641,16 @@ KResult Process::do_exec(NonnullRefPtr<FileDescription> main_program_description
{
ProtectedDataMutationScope scope { *this };
m_promises = m_execpromises.load();
m_has_promises = m_has_execpromises.load();
m_protected_values.promises = m_protected_values.execpromises.load();
m_protected_values.has_promises = m_protected_values.has_execpromises.load();
m_execpromises = 0;
m_has_execpromises = false;
m_protected_values.execpromises = 0;
m_protected_values.has_execpromises = false;
m_signal_trampoline = signal_trampoline_region.value()->vaddr();
m_protected_values.signal_trampoline = signal_trampoline_region.value()->vaddr();
// FIXME: PID/TID ISSUE
m_pid = new_main_thread->tid().value();
m_protected_values.pid = new_main_thread->tid().value();
}
auto tsr_result = new_main_thread->make_thread_specific_region({});

View file

@ -20,8 +20,8 @@ void Process::sys$exit(int status)
{
ProtectedDataMutationScope scope { *this };
m_termination_status = status;
m_termination_signal = 0;
m_protected_values.termination_status = status;
m_protected_values.termination_signal = 0;
}
auto* current_thread = Thread::current();

View file

@ -30,15 +30,15 @@ KResultOr<FlatPtr> Process::sys$fork(RegisterState& regs)
{
ProtectedDataMutationScope scope { *child };
child->m_promises = m_promises.load();
child->m_execpromises = m_execpromises.load();
child->m_has_promises = m_has_promises.load();
child->m_has_execpromises = m_has_execpromises.load();
child->m_sid = m_sid;
child->m_extra_gids = m_extra_gids;
child->m_umask = m_umask;
child->m_signal_trampoline = m_signal_trampoline;
child->m_dumpable = m_dumpable;
child->m_protected_values.promises = m_protected_values.promises.load();
child->m_protected_values.execpromises = m_protected_values.execpromises.load();
child->m_protected_values.has_promises = m_protected_values.has_promises.load();
child->m_protected_values.has_execpromises = m_protected_values.has_execpromises.load();
child->m_protected_values.sid = m_protected_values.sid;
child->m_protected_values.extra_gids = m_protected_values.extra_gids;
child->m_protected_values.umask = m_protected_values.umask;
child->m_protected_values.signal_trampoline = m_protected_values.signal_trampoline;
child->m_protected_values.dumpable = m_protected_values.dumpable;
}
dbgln_if(FORK_DEBUG, "fork: child={}", child);

View file

@ -40,7 +40,7 @@ KResultOr<FlatPtr> Process::sys$getresuid(Userspace<uid_t*> ruid, Userspace<uid_
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
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, &m_protected_values.uid) || !copy_to_user(euid, &m_protected_values.euid) || !copy_to_user(suid, &m_protected_values.suid))
return EFAULT;
return 0;
}
@ -49,7 +49,7 @@ KResultOr<FlatPtr> Process::sys$getresgid(Userspace<gid_t*> rgid, Userspace<gid_
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
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, &m_protected_values.gid) || !copy_to_user(egid, &m_protected_values.egid) || !copy_to_user(sgid, &m_protected_values.sgid))
return EFAULT;
return 0;
}

View file

@ -56,7 +56,7 @@ KResultOr<FlatPtr> Process::sys$pledge(Userspace<const Syscall::SC_pledge_params
if (promises) {
if (!parse_pledge(promises->view(), new_promises))
return EINVAL;
if (m_has_promises && (new_promises & ~m_promises))
if (m_protected_values.has_promises && (new_promises & ~m_protected_values.promises))
return EPERM;
}
@ -64,7 +64,7 @@ KResultOr<FlatPtr> Process::sys$pledge(Userspace<const Syscall::SC_pledge_params
if (execpromises) {
if (!parse_pledge(execpromises->view(), new_execpromises))
return EINVAL;
if (m_has_execpromises && (new_execpromises & ~m_execpromises))
if (m_protected_values.has_execpromises && (new_execpromises & ~m_protected_values.execpromises))
return EPERM;
}
@ -74,13 +74,13 @@ KResultOr<FlatPtr> Process::sys$pledge(Userspace<const Syscall::SC_pledge_params
// leave the caller in an unexpected state.
if (promises) {
m_promises = new_promises;
m_has_promises = true;
m_protected_values.has_promises = true;
m_protected_values.promises = new_promises;
}
if (execpromises) {
m_execpromises = new_execpromises;
m_has_execpromises = true;
m_protected_values.has_execpromises = true;
m_protected_values.execpromises = new_execpromises;
}
return 0;

View file

@ -20,7 +20,7 @@ KResultOr<FlatPtr> Process::sys$getppid()
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
REQUIRE_PROMISE(stdio);
return m_ppid.value();
return m_protected_values.ppid.value();
}
KResultOr<FlatPtr> Process::sys$get_process_name(Userspace<char*> buffer, size_t buffer_size)

View file

@ -40,7 +40,7 @@ KResultOr<FlatPtr> Process::sys$setsid()
m_pg = ProcessGroup::create(ProcessGroupID(pid().value()));
m_tty = nullptr;
ProtectedDataMutationScope scope { *this };
m_sid = pid().value();
m_protected_values.sid = pid().value();
return sid().value();
}

View file

@ -21,7 +21,7 @@ KResultOr<FlatPtr> Process::sys$seteuid(uid_t new_euid)
ProtectedDataMutationScope scope { *this };
m_euid = new_euid;
m_protected_values.euid = new_euid;
return 0;
}
@ -37,7 +37,7 @@ KResultOr<FlatPtr> Process::sys$setegid(gid_t new_egid)
set_dumpable(false);
ProtectedDataMutationScope scope { *this };
m_egid = new_egid;
m_protected_values.egid = new_egid;
return 0;
}
@ -53,9 +53,9 @@ KResultOr<FlatPtr> Process::sys$setuid(uid_t new_uid)
set_dumpable(false);
ProtectedDataMutationScope scope { *this };
m_uid = new_uid;
m_euid = new_uid;
m_suid = new_uid;
m_protected_values.uid = new_uid;
m_protected_values.euid = new_uid;
m_protected_values.suid = new_uid;
return 0;
}
@ -71,9 +71,9 @@ KResultOr<FlatPtr> Process::sys$setgid(gid_t new_gid)
set_dumpable(false);
ProtectedDataMutationScope scope { *this };
m_gid = new_gid;
m_egid = new_gid;
m_sgid = new_gid;
m_protected_values.gid = new_gid;
m_protected_values.egid = new_gid;
m_protected_values.sgid = new_gid;
return 0;
}
@ -98,8 +98,8 @@ KResultOr<FlatPtr> Process::sys$setreuid(uid_t new_ruid, uid_t new_euid)
set_dumpable(false);
ProtectedDataMutationScope scope { *this };
m_uid = new_ruid;
m_euid = new_euid;
m_protected_values.uid = new_ruid;
m_protected_values.euid = new_euid;
return 0;
}
@ -123,9 +123,9 @@ KResultOr<FlatPtr> Process::sys$setresuid(uid_t new_ruid, uid_t new_euid, uid_t
set_dumpable(false);
ProtectedDataMutationScope scope { *this };
m_uid = new_ruid;
m_euid = new_euid;
m_suid = new_suid;
m_protected_values.uid = new_ruid;
m_protected_values.euid = new_euid;
m_protected_values.suid = new_suid;
return 0;
}
@ -149,9 +149,9 @@ KResultOr<FlatPtr> Process::sys$setresgid(gid_t new_rgid, gid_t new_egid, gid_t
set_dumpable(false);
ProtectedDataMutationScope scope { *this };
m_gid = new_rgid;
m_egid = new_egid;
m_sgid = new_sgid;
m_protected_values.gid = new_rgid;
m_protected_values.egid = new_egid;
m_protected_values.sgid = new_sgid;
return 0;
}
@ -164,7 +164,7 @@ KResultOr<FlatPtr> Process::sys$setgroups(size_t count, Userspace<const gid_t*>
if (!count) {
ProtectedDataMutationScope scope { *this };
m_extra_gids.clear();
m_protected_values.extra_gids.clear();
return 0;
}
@ -181,13 +181,13 @@ KResultOr<FlatPtr> Process::sys$setgroups(size_t count, Userspace<const gid_t*>
}
ProtectedDataMutationScope scope { *this };
if (!m_extra_gids.try_resize(unique_extra_gids.size()))
if (!m_protected_values.extra_gids.try_resize(unique_extra_gids.size()))
return ENOMEM;
size_t i = 0;
for (auto& extra_gid : unique_extra_gids) {
if (extra_gid == gid())
continue;
m_extra_gids[i++] = extra_gid;
m_protected_values.extra_gids[i++] = extra_gid;
}
return 0;
}

View file

@ -12,9 +12,9 @@ KResultOr<FlatPtr> Process::sys$umask(mode_t mask)
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
REQUIRE_PROMISE(stdio);
auto old_mask = m_umask;
auto old_mask = m_protected_values.umask;
ProtectedDataMutationScope scope { *this };
m_umask = mask & 0777;
m_protected_values.umask = mask & 0777;
return old_mask;
}