Bladeren bron

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. :^)
Andreas Kling 3 jaren geleden
bovenliggende
commit
1d08b671ea
1 gewijzigde bestanden met toevoegingen van 5 en 8 verwijderingen
  1. 5 8
      Kernel/Syscalls/execve.cpp

+ 5 - 8
Kernel/Syscalls/execve.cpp

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