diff options
author | Tom <tomut@yahoo.com> | 2021-05-20 13:58:36 -0600 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-05-20 22:08:36 +0200 |
commit | 9dcc7a67e5d9bc584d732df14f8e9296f792425f (patch) | |
tree | 1743e674a751226f47d66c822d513bd2bd3e7c6f /Kernel | |
parent | adfdfd6aba58f378b00319ac5fc6cdcf78b40a84 (diff) | |
download | serenity-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.cpp | 13 |
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; } |