about summary refs log tree commit diff
path: root/library/std/src/sys
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-06-25 15:14:09 +0200
committerGitHub <noreply@github.com>2022-06-25 15:14:09 +0200
commitecefccd8d2859c6715760861c7dacfcdf816992a (patch)
tree85e8c78d6b37d2c1be7f2bce20c05fe7280cae87 /library/std/src/sys
parent45ef23d78e54ff2d12db78c6445f766f61972c86 (diff)
parente642c5987e1885a6ea9b0f1527810a72bdcdeb3f (diff)
downloadrust-ecefccd8d2859c6715760861c7dacfcdf816992a.tar.gz
rust-ecefccd8d2859c6715760861c7dacfcdf816992a.zip
Rollup merge of #98194 - m-ou-se:leak-locked-pthread-mutex, r=Amanieu
Leak pthread_{mutex,rwlock}_t if it's dropped while locked.

Fixes https://github.com/rust-lang/rust/issues/85434.
Diffstat (limited to 'library/std/src/sys')
-rw-r--r--library/std/src/sys/unix/locks/pthread_mutex.rs20
-rw-r--r--library/std/src/sys/unix/locks/pthread_rwlock.rs16
2 files changed, 35 insertions, 1 deletions
diff --git a/library/std/src/sys/unix/locks/pthread_mutex.rs b/library/std/src/sys/unix/locks/pthread_mutex.rs
index 916e898d890..98afee69ba6 100644
--- a/library/std/src/sys/unix/locks/pthread_mutex.rs
+++ b/library/std/src/sys/unix/locks/pthread_mutex.rs
@@ -1,5 +1,5 @@
 use crate::cell::UnsafeCell;
-use crate::mem::MaybeUninit;
+use crate::mem::{forget, MaybeUninit};
 use crate::sys::cvt_nz;
 use crate::sys_common::lazy_box::{LazyBox, LazyInit};
 
@@ -23,6 +23,24 @@ impl LazyInit for Mutex {
         unsafe { mutex.init() };
         mutex
     }
+
+    fn destroy(mutex: Box<Self>) {
+        // We're not allowed to pthread_mutex_destroy a locked mutex,
+        // so check first if it's unlocked.
+        if unsafe { mutex.try_lock() } {
+            unsafe { mutex.unlock() };
+            drop(mutex);
+        } else {
+            // The mutex is locked. This happens if a MutexGuard is leaked.
+            // In this case, we just leak the Mutex too.
+            forget(mutex);
+        }
+    }
+
+    fn cancel_init(_: Box<Self>) {
+        // In this case, we can just drop it without any checks,
+        // since it cannot have been locked yet.
+    }
 }
 
 impl Mutex {
diff --git a/library/std/src/sys/unix/locks/pthread_rwlock.rs b/library/std/src/sys/unix/locks/pthread_rwlock.rs
index 75e5759c787..adfe2a88338 100644
--- a/library/std/src/sys/unix/locks/pthread_rwlock.rs
+++ b/library/std/src/sys/unix/locks/pthread_rwlock.rs
@@ -1,4 +1,5 @@
 use crate::cell::UnsafeCell;
+use crate::mem::forget;
 use crate::sync::atomic::{AtomicUsize, Ordering};
 use crate::sys_common::lazy_box::{LazyBox, LazyInit};
 
@@ -17,6 +18,21 @@ impl LazyInit for RwLock {
     fn init() -> Box<Self> {
         Box::new(Self::new())
     }
+
+    fn destroy(mut rwlock: Box<Self>) {
+        // We're not allowed to pthread_rwlock_destroy a locked rwlock,
+        // so check first if it's unlocked.
+        if *rwlock.write_locked.get_mut() || *rwlock.num_readers.get_mut() != 0 {
+            // The rwlock is locked. This happens if a RwLock{Read,Write}Guard is leaked.
+            // In this case, we just leak the RwLock too.
+            forget(rwlock);
+        }
+    }
+
+    fn cancel_init(_: Box<Self>) {
+        // In this case, we can just drop it without any checks,
+        // since it cannot have been locked yet.
+    }
 }
 
 impl RwLock {