mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 07:48:11 +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:
parent
839d2d70a4
commit
cbcf891040
12 changed files with 190 additions and 130 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue