Add comments and unify guard page setup.

While currently only NetBSD seems to be affected, all systems
implementing PAX MPROTECT in strict mode need this treatment,
and it does not hurt others.
This commit is contained in:
Martin Husemann
2018-05-02 10:00:33 +02:00
parent 7c2304ddc6
commit 244e24a312

View File

@@ -326,23 +326,20 @@ 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.
if cfg!(target_os = "netbsd") { // Systems which enforce strict PAX MPROTECT do not allow
let result = mmap(stackaddr, PAGE_SIZE, PROT_READ | PROT_WRITE, // to mprotect() a mapping with less restrictive permissions
MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0); // than the initial mmap() used, so we mmap() here with
if result != stackaddr || result == MAP_FAILED { // read/write permissions and only then mprotect() it to
panic!("failed to allocate a guard page"); // no permissions at all. See issue #50313.
} let result = mmap(stackaddr, PAGE_SIZE, PROT_READ | PROT_WRITE,
let result = mprotect(stackaddr, PAGE_SIZE, 0); MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
if result != stackaddr || result == MAP_FAILED {
panic!("failed to allocate a guard page");
}
if result != 0 { let result = mprotect(stackaddr, PAGE_SIZE, PROT_NONE);
panic!("unable to protect the guard page"); if result != 0 {
} panic!("failed to protect the guard page");
} else {
let result = mmap(stackaddr, PAGE_SIZE, PROT_NONE,
MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
if result != stackaddr || result == MAP_FAILED {
panic!("failed to allocate a guard page");
}
} }
let guardaddr = stackaddr as usize; let guardaddr = stackaddr as usize;