mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:07:35 +00:00
Kernel: Stop leaking first thread on errors in sys$fork
Until the thread is first set as Runnable at the end of sys$fork, its state is Invalid, and as a result, the Finalizer which is searching for Dying threads will never find it if the syscall short-circuits due to an error condition like OOM. This also meant the parent Process of the thread would be leaked as well.
This commit is contained in:
parent
6901d3dcec
commit
c1fe844da4
1 changed files with 11 additions and 0 deletions
|
@ -18,6 +18,15 @@ ErrorOr<FlatPtr> Process::sys$fork(RegisterState& regs)
|
|||
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
|
||||
TRY(require_promise(Pledge::proc));
|
||||
RefPtr<Thread> child_first_thread;
|
||||
|
||||
ArmedScopeGuard thread_finalizer_guard = [&child_first_thread]() {
|
||||
SpinlockLocker lock(g_scheduler_lock);
|
||||
if (child_first_thread) {
|
||||
child_first_thread->detach();
|
||||
child_first_thread->set_state(Thread::State::Dying);
|
||||
}
|
||||
};
|
||||
|
||||
auto child_name = TRY(m_name->try_clone());
|
||||
auto child = TRY(Process::try_create(child_first_thread, move(child_name), uid(), gid(), pid(), m_is_kernel_process, current_directory(), m_executable, m_tty, this));
|
||||
TRY(m_unveil_data.with([&](auto& parent_unveil_data) -> ErrorOr<void> {
|
||||
|
@ -120,6 +129,8 @@ ErrorOr<FlatPtr> Process::sys$fork(RegisterState& regs)
|
|||
}
|
||||
}
|
||||
|
||||
thread_finalizer_guard.disarm();
|
||||
|
||||
Process::register_new(*child);
|
||||
|
||||
PerformanceManager::add_process_created_event(*child);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue