From 5226395d6faef77a5f1dadb6235bcd99352e1843 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sat, 5 Mar 2022 17:19:04 +0100 Subject: [PATCH] Fix soundness issue in scoped threads. --- library/std/src/thread/mod.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 5ffc86b4560..56baa7e4455 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -1293,6 +1293,23 @@ fn drop(&mut self) { // panicked, and nobody consumed the panic payload, we make sure // the scope function will panic. let unhandled_panic = matches!(self.result.get_mut(), Some(Err(_))); + // Drop the result before decrementing the number of running + // threads, because the Drop implementation might still use things + // it borrowed from 'scope. + // This is only relevant for threads that aren't join()ed, as + // join() will take the `result` and set it to None, such that + // there is nothing left to drop here. + // If this drop panics, that just results in an abort, because + // we're outside of the outermost `catch_unwind` of our thread. + // The same happens for detached non-scoped threads when dropping + // their ignored return value (or panic payload) panics, so + // there's no need to try to do anything better. + // (And even if we tried to handle it, we'd also need to handle + // the case where the panic payload we get out of it also panics + // on drop, and so on. See issue #86027.) + *self.result.get_mut() = None; + // Now that there will be no more user code running on this thread + // that can use 'scope, mark the thread as 'finished'. scope.decrement_num_running_threads(unhandled_panic); } }