1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-02 19:42:14 +00:00

Kernel: Move select Process members into protected memory

Process member variable like m_euid are very valuable targets for
kernel exploits and until now they have been writable at all times.

This patch moves m_euid along with a whole bunch of other members
into a new Process::ProtectedData struct. This struct is remapped
as read-only memory whenever we don't need to write to it.

This means that a kernel write primitive is no longer enough to
overwrite a process's effective UID, you must first unprotect the
protected data where the UID is stored. :^)
This commit is contained in:
Andreas Kling 2021-03-10 19:59:46 +01:00
parent 839d2d70a4
commit cbcf891040
12 changed files with 190 additions and 130 deletions

View file

@ -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);