Kernel: Enter new address space before destroying old in sys$execve()

Previously we were assigning to Process::m_space before actually
entering the new address space (assigning it to CR3.)

If a thread was preempted by the scheduler while destroying the old
address space, we'd then attempt to resume the thread with CR3 pointing
at a partially destroyed address space.

We could then crash immediately in write_cr3(), right after assigning
the new value to CR3. I am hopeful that this may have been the bug
haunting our CI for months. :^)
This commit is contained in:
Andreas Kling 2021-12-23 00:42:30 +01:00
parent 601a9321d9
commit 1d08b671ea
Notes: sideshowbarker 2024-07-17 22:20:45 +09:00

View file

@ -503,14 +503,11 @@ ErrorOr<void> Process::do_exec(NonnullRefPtr<OpenFileDescription> main_program_d
set_dumpable(!executable_is_setid);
{
// We must disable global profiling (especially kfree tracing) here because
// we might otherwise end up walking the stack into the process' space that
// is about to be destroyed.
TemporaryChange global_profiling_disabler(g_profiling_all_threads, false);
m_space = load_result.space.release_nonnull();
}
Memory::MemoryManager::enter_address_space(*m_space);
// We make sure to enter the new address space before destroying the old one.
// This ensures that the process always has a valid page directory.
Memory::MemoryManager::enter_address_space(*load_result.space);
m_space = load_result.space.release_nonnull();
m_executable = main_program_description->custody();
m_arguments = move(arguments);