about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2020-09-09 10:16:03 -0400
committerTavian Barnes <tavianator@tavianator.com>2020-09-09 10:21:50 -0400
commita06edda3ad9abd4f07d07bbe46cb488efeebbbd0 (patch)
treeeecd9afb5dd25011443ea5305dc8e9a1030eed19
parent683d1bcd405727fcc9209f64845bd3b9104878b8 (diff)
downloadrust-a06edda3ad9abd4f07d07bbe46cb488efeebbbd0.tar.gz
rust-a06edda3ad9abd4f07d07bbe46cb488efeebbbd0.zip
Fix segfault if pthread_getattr_np fails
glibc destroys[1] the passed pthread_attr_t if pthread_getattr_np()
fails.  Destroying it again leads to a segfault.  Fix it by only
destroying it on success for glibc.

[1]: https://sourceware.org/git/?p=glibc.git;a=blob;f=nptl/pthread_getattr_np.c;h=ce437205e41dc05653e435f6188768cccdd91c99;hb=HEAD#l205
-rw-r--r--library/std/src/sys/unix/thread.rs8
1 files changed, 6 insertions, 2 deletions
diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs
index 04da9812ddc..569aedd7411 100644
--- a/library/std/src/sys/unix/thread.rs
+++ b/library/std/src/sys/unix/thread.rs
@@ -305,7 +305,9 @@ pub mod guard {
             assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr, &mut stacksize), 0);
             ret = Some(stackaddr);
         }
-        assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
+        if e == 0 || cfg!(not(target_env = "gnu")) {
+            assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
+        }
         ret
     }
 
@@ -446,7 +448,9 @@ pub mod guard {
                 Some(stackaddr..stackaddr + guardsize)
             };
         }
-        assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
+        if e == 0 || cfg!(not(target_env = "gnu")) {
+            assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
+        }
         ret
     }
 }