From aaa0d1419cca754add76950ac9bae8a3dd526964 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Thu, 5 Aug 2021 22:20:16 +0200 Subject: [PATCH] util: fix unsoundness when dropping ThreadModeMutex outside thread mode. Fixes #283 --- embassy/src/util/mutex.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/embassy/src/util/mutex.rs b/embassy/src/util/mutex.rs index 0506ffe6..9a00a409 100644 --- a/embassy/src/util/mutex.rs +++ b/embassy/src/util/mutex.rs @@ -82,9 +82,7 @@ impl ThreadModeMutex { inner: UnsafeCell::new(value), } } -} -impl ThreadModeMutex { /// Borrows the data pub fn borrow(&self) -> &T { assert!( @@ -107,6 +105,21 @@ impl Mutex for ThreadModeMutex { } } +impl Drop for ThreadModeMutex { + fn drop(&mut self) { + // Only allow dropping from thread mode. Dropping calls drop on the inner `T`, so + // `drop` needs the same guarantees as `lock`. `ThreadModeMutex` is Send even if + // T isn't, so without this check a user could create a ThreadModeMutex in thread mode, + // send it to interrupt context and drop it there, which would "send" a T even if T is not Send. + assert!( + in_thread_mode(), + "ThreadModeMutex can only be dropped from thread mode." + ); + + // Drop of the inner `T` happens after this. + } +} + pub fn in_thread_mode() -> bool { #[cfg(feature = "std")] return Some("main") == std::thread::current().name();