Browse Source

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
Tom 4 years ago
parent
commit
9dcc7a67e5
1 changed files with 10 additions and 3 deletions
  1. 10 3
      Kernel/Thread.cpp

+ 10 - 3
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;
 }