mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 13:38:11 +00:00
Kernel: Don't keep protected Process data in a separate allocation
The previous architecture had a huge flaw: the pointer to the protected data was itself unprotected, allowing you to overwrite it at any time. This patch reorganizes the protected data so it's part of the Process class itself. (Actually, it's a new ProcessBase helper class.) We use the first 4 KB of Process objects themselves as the new storage location for protected data. Then we make Process objects page-aligned using MAKE_ALIGNED_ALLOCATED. This allows us to easily turn on/off write-protection for everything in the ProcessBase portion of Process. :^) Thanks to @bugaevc for pointing out the flaw! This is still not perfect but it's an improvement.
This commit is contained in:
parent
4fcc637e29
commit
90c0f9664e
10 changed files with 125 additions and 125 deletions
|
@ -36,7 +36,8 @@ KResultOr<int> Process::sys$disown(ProcessID pid)
|
|||
return ESRCH;
|
||||
if (process->ppid() != this->pid())
|
||||
return ECHILD;
|
||||
MutableProtectedData(*this)->ppid = 0;
|
||||
ProtectedDataMutationScope scope(*process);
|
||||
process->m_ppid = 0;
|
||||
process->disowned_by_waiter(*this);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -507,15 +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;
|
||||
MutableProtectedData protected_data { *this };
|
||||
protected_data->euid = main_program_metadata.uid;
|
||||
protected_data->suid = main_program_metadata.uid;
|
||||
ProtectedDataMutationScope scope { *this };
|
||||
m_euid = main_program_metadata.uid;
|
||||
m_suid = main_program_metadata.uid;
|
||||
}
|
||||
if (main_program_metadata.is_setgid()) {
|
||||
executable_is_setid = true;
|
||||
MutableProtectedData protected_data { *this };
|
||||
protected_data->egid = main_program_metadata.gid;
|
||||
protected_data->sgid = main_program_metadata.gid;
|
||||
ProtectedDataMutationScope scope { *this };
|
||||
m_egid = main_program_metadata.gid;
|
||||
m_sgid = main_program_metadata.gid;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -598,15 +598,15 @@ KResult Process::do_exec(NonnullRefPtr<FileDescription> main_program_description
|
|||
new_main_thread->set_name(m_name);
|
||||
|
||||
{
|
||||
MutableProtectedData protected_data { *this };
|
||||
protected_data->promises = protected_data->execpromises;
|
||||
protected_data->has_promises = protected_data->has_execpromises;
|
||||
ProtectedDataMutationScope scope { *this };
|
||||
m_promises = m_execpromises;
|
||||
m_has_promises = m_has_execpromises;
|
||||
|
||||
protected_data->execpromises = 0;
|
||||
protected_data->has_execpromises = false;
|
||||
m_execpromises = 0;
|
||||
m_has_execpromises = false;
|
||||
|
||||
// FIXME: PID/TID ISSUE
|
||||
protected_data->pid = new_main_thread->tid().value();
|
||||
m_pid = new_main_thread->tid().value();
|
||||
}
|
||||
|
||||
auto tsr_result = new_main_thread->make_thread_specific_region({});
|
||||
|
|
|
@ -44,18 +44,19 @@ 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_pg = m_pg;
|
||||
child->m_umask = m_umask;
|
||||
child->m_signal_trampoline = m_signal_trampoline;
|
||||
child->m_pg = m_pg;
|
||||
|
||||
{
|
||||
MutableProtectedData child_data { *child };
|
||||
child_data->promises = protected_data().promises;
|
||||
child_data->execpromises = protected_data().execpromises;
|
||||
child_data->has_promises = protected_data().has_promises;
|
||||
child_data->has_execpromises = protected_data().has_execpromises;
|
||||
child_data->sid = this->sid();
|
||||
child_data->extra_gids = this->extra_gids();
|
||||
child->unprotect_data();
|
||||
child->m_promises = m_promises;
|
||||
child->m_execpromises = m_execpromises;
|
||||
child->m_has_promises = m_has_promises;
|
||||
child->m_has_execpromises = m_has_execpromises;
|
||||
child->m_sid = m_sid;
|
||||
child->m_extra_gids = m_extra_gids;
|
||||
child->protect_data();
|
||||
}
|
||||
|
||||
dbgln_if(FORK_DEBUG, "fork: child={}", child);
|
||||
|
|
|
@ -55,7 +55,7 @@ KResultOr<gid_t> Process::sys$getegid()
|
|||
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, &protected_data().uid) || !copy_to_user(euid, &protected_data().euid) || !copy_to_user(suid, &protected_data().suid))
|
||||
if (!copy_to_user(ruid, &m_uid) || !copy_to_user(euid, &m_euid) || !copy_to_user(suid, &m_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, &protected_data().gid) || !copy_to_user(egid, &protected_data().egid) || !copy_to_user(sgid, &protected_data().sgid))
|
||||
if (!copy_to_user(rgid, &m_gid) || !copy_to_user(egid, &m_egid) || !copy_to_user(sgid, &m_sgid))
|
||||
return EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -67,27 +67,27 @@ KResultOr<int> Process::sys$pledge(Userspace<const Syscall::SC_pledge_params*> u
|
|||
return true;
|
||||
};
|
||||
|
||||
MutableProtectedData mutable_protected_data { *this };
|
||||
ProtectedDataMutationScope scope { *this };
|
||||
|
||||
if (!promises.is_null()) {
|
||||
u32 new_promises = 0;
|
||||
if (!parse_pledge(promises, new_promises))
|
||||
return EINVAL;
|
||||
if (protected_data().promises && (!new_promises || new_promises & ~protected_data().promises))
|
||||
if (m_promises && (!new_promises || new_promises & ~m_promises))
|
||||
return EPERM;
|
||||
|
||||
mutable_protected_data->has_promises = true;
|
||||
mutable_protected_data->promises = new_promises;
|
||||
m_has_promises = true;
|
||||
m_promises = new_promises;
|
||||
}
|
||||
|
||||
if (!execpromises.is_null()) {
|
||||
u32 new_execpromises = 0;
|
||||
if (!parse_pledge(execpromises, new_execpromises))
|
||||
return EINVAL;
|
||||
if (protected_data().execpromises && (!new_execpromises || new_execpromises & ~protected_data().execpromises))
|
||||
if (m_execpromises && (!new_execpromises || new_execpromises & ~m_execpromises))
|
||||
return EPERM;
|
||||
mutable_protected_data->has_execpromises = true;
|
||||
mutable_protected_data->execpromises = new_execpromises;
|
||||
m_has_execpromises = true;
|
||||
m_execpromises = new_execpromises;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -38,7 +38,7 @@ KResultOr<pid_t> Process::sys$getpid()
|
|||
KResultOr<pid_t> Process::sys$getppid()
|
||||
{
|
||||
REQUIRE_PROMISE(stdio);
|
||||
return protected_data().ppid.value();
|
||||
return m_ppid.value();
|
||||
}
|
||||
|
||||
KResultOr<int> Process::sys$get_process_name(Userspace<char*> buffer, size_t buffer_size)
|
||||
|
|
|
@ -55,9 +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.
|
||||
MutableProtectedData(*this)->sid = pid().value();
|
||||
m_pg = ProcessGroup::create(ProcessGroupID(pid().value()));
|
||||
m_tty = nullptr;
|
||||
ProtectedDataMutationScope scope { *this };
|
||||
m_sid = pid().value();
|
||||
return sid().value();
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,10 @@ KResultOr<int> Process::sys$seteuid(uid_t new_euid)
|
|||
|
||||
if (euid() != new_euid)
|
||||
set_dumpable(false);
|
||||
MutableProtectedData(*this)->euid = new_euid;
|
||||
|
||||
ProtectedDataMutationScope scope { *this };
|
||||
|
||||
m_euid = new_euid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -51,7 +54,8 @@ KResultOr<int> Process::sys$setegid(gid_t new_egid)
|
|||
if (egid() != new_egid)
|
||||
set_dumpable(false);
|
||||
|
||||
MutableProtectedData(*this)->egid = new_egid;
|
||||
ProtectedDataMutationScope scope { *this };
|
||||
m_egid = new_egid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -65,10 +69,10 @@ KResultOr<int> Process::sys$setuid(uid_t new_uid)
|
|||
if (euid() != new_uid)
|
||||
set_dumpable(false);
|
||||
|
||||
MutableProtectedData protected_data { *this };
|
||||
protected_data->uid = new_uid;
|
||||
protected_data->euid = new_uid;
|
||||
protected_data->suid = new_uid;
|
||||
ProtectedDataMutationScope scope { *this };
|
||||
m_uid = new_uid;
|
||||
m_euid = new_uid;
|
||||
m_suid = new_uid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -82,10 +86,10 @@ KResultOr<int> Process::sys$setgid(gid_t new_gid)
|
|||
if (egid() != new_gid)
|
||||
set_dumpable(false);
|
||||
|
||||
MutableProtectedData protected_data { *this };
|
||||
protected_data->gid = new_gid;
|
||||
protected_data->egid = new_gid;
|
||||
protected_data->sgid = new_gid;
|
||||
ProtectedDataMutationScope scope { *this };
|
||||
m_gid = new_gid;
|
||||
m_egid = new_gid;
|
||||
m_sgid = new_gid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -107,10 +111,10 @@ KResultOr<int> Process::sys$setresuid(uid_t new_ruid, uid_t new_euid, uid_t new_
|
|||
if (euid() != new_euid)
|
||||
set_dumpable(false);
|
||||
|
||||
MutableProtectedData protected_data { *this };
|
||||
protected_data->uid = new_ruid;
|
||||
protected_data->euid = new_euid;
|
||||
protected_data->suid = new_suid;
|
||||
ProtectedDataMutationScope scope { *this };
|
||||
m_uid = new_ruid;
|
||||
m_euid = new_euid;
|
||||
m_suid = new_suid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -132,10 +136,10 @@ KResultOr<int> Process::sys$setresgid(gid_t new_rgid, gid_t new_egid, gid_t new_
|
|||
if (egid() != new_egid)
|
||||
set_dumpable(false);
|
||||
|
||||
MutableProtectedData protected_data { *this };
|
||||
protected_data->gid = new_rgid;
|
||||
protected_data->egid = new_egid;
|
||||
protected_data->sgid = new_sgid;
|
||||
ProtectedDataMutationScope scope { *this };
|
||||
m_gid = new_rgid;
|
||||
m_egid = new_egid;
|
||||
m_sgid = new_sgid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -148,7 +152,8 @@ KResultOr<int> Process::sys$setgroups(ssize_t count, Userspace<const gid_t*> use
|
|||
return EPERM;
|
||||
|
||||
if (!count) {
|
||||
MutableProtectedData(*this)->extra_gids.clear();
|
||||
ProtectedDataMutationScope scope { *this };
|
||||
m_extra_gids.clear();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -163,13 +168,13 @@ KResultOr<int> Process::sys$setgroups(ssize_t count, Userspace<const gid_t*> use
|
|||
unique_extra_gids.set(extra_gid);
|
||||
}
|
||||
|
||||
MutableProtectedData protected_data { *this };
|
||||
protected_data->extra_gids.resize(unique_extra_gids.size());
|
||||
ProtectedDataMutationScope scope { *this };
|
||||
m_extra_gids.resize(unique_extra_gids.size());
|
||||
size_t i = 0;
|
||||
for (auto& extra_gid : unique_extra_gids) {
|
||||
if (extra_gid == gid())
|
||||
continue;
|
||||
protected_data->extra_gids[i++] = extra_gid;
|
||||
m_extra_gids[i++] = extra_gid;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue