From 6a80b1387fe01b6a350d123a7ad0c7a8130827cc Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tomasz=20Mi=C4=85sko?= Date: Wed, 19 Aug 2020 00:00:00 +0000 Subject: [PATCH] Enable stack-overflow detection on musl for non-main threads --- library/std/src/sys/unix/thread.rs | 27 +++++++++++++++++++++------ src/test/ui/abi/stack-probes.rs | 1 - src/test/ui/out-of-stack.rs | 1 - 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index c1bda6b430e..04da9812ddc 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -213,7 +213,7 @@ fn drop(&mut self) { } #[cfg(all( - not(all(target_os = "linux", not(target_env = "musl"))), + not(target_os = "linux"), not(target_os = "freebsd"), not(target_os = "macos"), not(all(target_os = "netbsd", not(target_vendor = "rumprun"))), @@ -233,7 +233,7 @@ pub unsafe fn init() -> Option { } #[cfg(any( - all(target_os = "linux", not(target_env = "musl")), + target_os = "linux", target_os = "freebsd", target_os = "macos", all(target_os = "netbsd", not(target_vendor = "rumprun")), @@ -333,9 +333,7 @@ pub unsafe fn init() -> Option { let page_size = os::page_size(); PAGE_SIZE.store(page_size, Ordering::Relaxed); - let stackaddr = get_stack_start_aligned()?; - - if cfg!(target_os = "linux") { + if cfg!(all(target_os = "linux", not(target_env = "musl"))) { // Linux doesn't allocate the whole stack right away, and // the kernel has its own stack-guard mechanism to fault // when growing too close to an existing mapping. If we map @@ -346,8 +344,15 @@ pub unsafe fn init() -> Option { // Instead, we'll just note where we expect rlimit to start // faulting, so our handler can report "stack overflow", and // trust that the kernel's own stack guard will work. + let stackaddr = get_stack_start_aligned()?; let stackaddr = stackaddr as usize; Some(stackaddr - page_size..stackaddr) + } else if cfg!(all(target_os = "linux", target_env = "musl")) { + // For the main thread, the musl's pthread_attr_getstack + // returns the current stack size, rather than maximum size + // it can eventually grow to. It cannot be used to determine + // the position of kernel's stack guard. + None } else { // Reallocate the last page of the stack. // This ensures SIGBUS will be raised on @@ -357,6 +362,7 @@ pub unsafe fn init() -> Option { // than the initial mmap() used, so we mmap() here with // read/write permissions and only then mprotect() it to // no permissions at all. See issue #50313. + let stackaddr = get_stack_start_aligned()?; let result = mmap( stackaddr, page_size, @@ -406,7 +412,14 @@ pub unsafe fn current() -> Option { let mut guardsize = 0; assert_eq!(libc::pthread_attr_getguardsize(&attr, &mut guardsize), 0); if guardsize == 0 { - panic!("there is no guard page"); + if cfg!(all(target_os = "linux", target_env = "musl")) { + // musl versions before 1.1.19 always reported guard + // size obtained from pthread_attr_get_np as zero. + // Use page size as a fallback. + guardsize = PAGE_SIZE.load(Ordering::Relaxed); + } else { + panic!("there is no guard page"); + } } let mut stackaddr = crate::ptr::null_mut(); let mut size = 0; @@ -419,6 +432,8 @@ pub unsafe fn current() -> Option { Some(guardaddr - PAGE_SIZE.load(Ordering::Relaxed)..guardaddr) } else if cfg!(target_os = "netbsd") { Some(stackaddr - guardsize..stackaddr) + } else if cfg!(all(target_os = "linux", target_env = "musl")) { + Some(stackaddr - guardsize..stackaddr) } else if cfg!(all(target_os = "linux", target_env = "gnu")) { // glibc used to include the guard area within the stack, as noted in the BUGS // section of `man pthread_attr_getguardsize`. This has been corrected starting diff --git a/src/test/ui/abi/stack-probes.rs b/src/test/ui/abi/stack-probes.rs index 1d5b362e29d..a52c285f9f0 100644 --- a/src/test/ui/abi/stack-probes.rs +++ b/src/test/ui/abi/stack-probes.rs @@ -11,7 +11,6 @@ // ignore-cloudabi no processes // ignore-emscripten no processes // ignore-sgx no processes -// ignore-musl FIXME #31506 use std::mem::MaybeUninit; use std::process::Command; diff --git a/src/test/ui/out-of-stack.rs b/src/test/ui/out-of-stack.rs index d04b0c1a630..6beafc0732b 100644 --- a/src/test/ui/out-of-stack.rs +++ b/src/test/ui/out-of-stack.rs @@ -3,7 +3,6 @@ #![allow(unused_must_use)] #![allow(unconditional_recursion)] // ignore-android: FIXME (#20004) -// ignore-musl // ignore-cloudabi no processes // ignore-emscripten no processes // ignore-sgx no processes -- 2.44.0