Auto merge of #50331 - MartinHusemann:master, r=Kimundi

Map the stack guard page with max protection on NetBSD

On NetBSD the initial mmap() protection of a mapping can not be made
less restrictive with mprotect().

So when mapping a stack guard page, use the maximum protection
we ever want to use, then mprotect() it to the permission we
want it to have initially.

Fixes #50313
This commit is contained in:
bors
2018-05-10 21:02:24 +00:00

View File

@@ -326,13 +326,22 @@ pub mod guard {
// 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
// stack overflow. // stack overflow.
let result = mmap(stackaddr, PAGE_SIZE, PROT_NONE, // Systems which enforce strict PAX MPROTECT do not allow
// to mprotect() a mapping with less restrictive permissions
// 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 result = mmap(stackaddr, PAGE_SIZE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0); MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
if result != stackaddr || result == MAP_FAILED { if result != stackaddr || result == MAP_FAILED {
panic!("failed to allocate a guard page"); panic!("failed to allocate a guard page");
} }
let result = mprotect(stackaddr, PAGE_SIZE, PROT_NONE);
if result != 0 {
panic!("failed to protect the guard page");
}
let guardaddr = stackaddr as usize; let guardaddr = stackaddr as usize;
let offset = if cfg!(target_os = "freebsd") { let offset = if cfg!(target_os = "freebsd") {
2 2