summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorTom <tomut@yahoo.com>2021-05-20 13:58:36 -0600
committerAndreas Kling <kling@serenityos.org>2021-05-20 22:08:36 +0200
commit9dcc7a67e5d9bc584d732df14f8e9296f792425f (patch)
tree1743e674a751226f47d66c822d513bd2bd3e7c6f /Kernel
parentadfdfd6aba58f378b00319ac5fc6cdcf78b40a84 (diff)
downloadserenity-9dcc7a67e5d9bc584d732df14f8e9296f792425f.zip
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
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/Thread.cpp13
1 files 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> Thread::from_tid(ThreadID tid)
RefPtr<Thread> 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;
}