Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable stack-overflow detection on musl for non-main threads #75703

Merged
merged 1 commit into from
Aug 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions library/std/src/sys/unix/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ impl Drop for Thread {
}

#[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"))),
Expand All @@ -233,7 +233,7 @@ pub mod guard {
}

#[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")),
Expand Down Expand Up @@ -333,9 +333,7 @@ pub mod guard {
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
Expand All @@ -346,8 +344,15 @@ pub mod guard {
// 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
Expand All @@ -357,6 +362,7 @@ pub mod guard {
// 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,
Expand Down Expand Up @@ -406,7 +412,14 @@ pub mod guard {
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;
Expand All @@ -419,6 +432,8 @@ pub mod guard {
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
Expand Down
1 change: 0 additions & 1 deletion src/test/ui/abi/stack-probes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion src/test/ui/out-of-stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down