From 9dcc7a67e5d9bc584d732df14f8e9296f792425f Mon Sep 17 00:00:00 2001 From: Tom Date: Thu, 20 May 2021 13:58:36 -0600 Subject: [PATCH] Kernel: Close a Thread tid lookup race There is a window between dropping a thread's last reference and it being removed from the list. Found in #5541 --- Kernel/Thread.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp index 5cf5718530..e08ea0a2d9 100644 --- a/Kernel/Thread.cpp +++ b/Kernel/Thread.cpp @@ -1034,9 +1034,16 @@ RefPtr Thread::from_tid(ThreadID tid) RefPtr found_thread; { ScopedSpinLock lock(g_tid_map_lock); - auto it = g_tid_map->find(tid); - if (it != g_tid_map->end()) - found_thread = it->value; + if (auto it = g_tid_map->find(tid); it != g_tid_map->end()) { + // We need to call try_ref() here as there is a window between + // dropping the last reference and calling the Thread's destructor! + // We shouldn't remove the threads from that list until it is truly + // destructed as it may stick around past finalization in order to + // be able to wait() on it! + if (it->value->try_ref()) { + found_thread = adopt_ref(*it->value); + } + } } return found_thread; }