Enable stack-overflow detection on musl for non-main threads
This commit is contained in:
@@ -213,7 +213,7 @@ impl Drop for Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
not(all(target_os = "linux", not(target_env = "musl"))),
|
not(target_os = "linux"),
|
||||||
not(target_os = "freebsd"),
|
not(target_os = "freebsd"),
|
||||||
not(target_os = "macos"),
|
not(target_os = "macos"),
|
||||||
not(all(target_os = "netbsd", not(target_vendor = "rumprun"))),
|
not(all(target_os = "netbsd", not(target_vendor = "rumprun"))),
|
||||||
@@ -233,7 +233,7 @@ pub mod guard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
all(target_os = "linux", not(target_env = "musl")),
|
target_os = "linux",
|
||||||
target_os = "freebsd",
|
target_os = "freebsd",
|
||||||
target_os = "macos",
|
target_os = "macos",
|
||||||
all(target_os = "netbsd", not(target_vendor = "rumprun")),
|
all(target_os = "netbsd", not(target_vendor = "rumprun")),
|
||||||
@@ -333,9 +333,7 @@ pub mod guard {
|
|||||||
let page_size = os::page_size();
|
let page_size = os::page_size();
|
||||||
PAGE_SIZE.store(page_size, Ordering::Relaxed);
|
PAGE_SIZE.store(page_size, Ordering::Relaxed);
|
||||||
|
|
||||||
let stackaddr = get_stack_start_aligned()?;
|
if cfg!(all(target_os = "linux", not(target_env = "musl"))) {
|
||||||
|
|
||||||
if cfg!(target_os = "linux") {
|
|
||||||
// Linux doesn't allocate the whole stack right away, and
|
// Linux doesn't allocate the whole stack right away, and
|
||||||
// the kernel has its own stack-guard mechanism to fault
|
// the kernel has its own stack-guard mechanism to fault
|
||||||
// when growing too close to an existing mapping. If we map
|
// when growing too close to an existing mapping. If we map
|
||||||
@@ -346,8 +344,15 @@ pub mod guard {
|
|||||||
// Instead, we'll just note where we expect rlimit to start
|
// Instead, we'll just note where we expect rlimit to start
|
||||||
// faulting, so our handler can report "stack overflow", and
|
// faulting, so our handler can report "stack overflow", and
|
||||||
// trust that the kernel's own stack guard will work.
|
// trust that the kernel's own stack guard will work.
|
||||||
|
let stackaddr = get_stack_start_aligned()?;
|
||||||
let stackaddr = stackaddr as usize;
|
let stackaddr = stackaddr as usize;
|
||||||
Some(stackaddr - page_size..stackaddr)
|
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 {
|
} else {
|
||||||
// Reallocate the last page of the stack.
|
// Reallocate the last page of the stack.
|
||||||
// This ensures SIGBUS will be raised on
|
// This ensures SIGBUS will be raised on
|
||||||
@@ -357,6 +362,7 @@ pub mod guard {
|
|||||||
// than the initial mmap() used, so we mmap() here with
|
// than the initial mmap() used, so we mmap() here with
|
||||||
// read/write permissions and only then mprotect() it to
|
// read/write permissions and only then mprotect() it to
|
||||||
// no permissions at all. See issue #50313.
|
// no permissions at all. See issue #50313.
|
||||||
|
let stackaddr = get_stack_start_aligned()?;
|
||||||
let result = mmap(
|
let result = mmap(
|
||||||
stackaddr,
|
stackaddr,
|
||||||
page_size,
|
page_size,
|
||||||
@@ -406,8 +412,15 @@ pub mod guard {
|
|||||||
let mut guardsize = 0;
|
let mut guardsize = 0;
|
||||||
assert_eq!(libc::pthread_attr_getguardsize(&attr, &mut guardsize), 0);
|
assert_eq!(libc::pthread_attr_getguardsize(&attr, &mut guardsize), 0);
|
||||||
if guardsize == 0 {
|
if guardsize == 0 {
|
||||||
|
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");
|
panic!("there is no guard page");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
let mut stackaddr = crate::ptr::null_mut();
|
let mut stackaddr = crate::ptr::null_mut();
|
||||||
let mut size = 0;
|
let mut size = 0;
|
||||||
assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr, &mut size), 0);
|
assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr, &mut size), 0);
|
||||||
@@ -419,6 +432,8 @@ pub mod guard {
|
|||||||
Some(guardaddr - PAGE_SIZE.load(Ordering::Relaxed)..guardaddr)
|
Some(guardaddr - PAGE_SIZE.load(Ordering::Relaxed)..guardaddr)
|
||||||
} else if cfg!(target_os = "netbsd") {
|
} else if cfg!(target_os = "netbsd") {
|
||||||
Some(stackaddr - guardsize..stackaddr)
|
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")) {
|
} 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
|
// 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
|
// section of `man pthread_attr_getguardsize`. This has been corrected starting
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
// ignore-cloudabi no processes
|
// ignore-cloudabi no processes
|
||||||
// ignore-emscripten no processes
|
// ignore-emscripten no processes
|
||||||
// ignore-sgx no processes
|
// ignore-sgx no processes
|
||||||
// ignore-musl FIXME #31506
|
|
||||||
|
|
||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#![allow(unused_must_use)]
|
#![allow(unused_must_use)]
|
||||||
#![allow(unconditional_recursion)]
|
#![allow(unconditional_recursion)]
|
||||||
// ignore-android: FIXME (#20004)
|
// ignore-android: FIXME (#20004)
|
||||||
// ignore-musl
|
|
||||||
// ignore-cloudabi no processes
|
// ignore-cloudabi no processes
|
||||||
// ignore-emscripten no processes
|
// ignore-emscripten no processes
|
||||||
// ignore-sgx no processes
|
// ignore-sgx no processes
|
||||||
|
|||||||
Reference in New Issue
Block a user