about summary refs log tree commit diff
path: root/src/libstd/sys
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-05-10 21:02:24 +0000
committerbors <bors@rust-lang.org>2018-05-10 21:02:24 +0000
commitacd3871ba17316419c644e17547887787628ec2f (patch)
treeb1557c8e01f5bdb3556bfcdc10ef5e73563edace /src/libstd/sys
parent9e3caa23f99816caf3c2fb69ff5c88b512fb1b38 (diff)
parent244e24a312925779f6c62ce7d6b315fa2c120a7c (diff)
downloadrust-acd3871ba17316419c644e17547887787628ec2f.tar.gz
rust-acd3871ba17316419c644e17547887787628ec2f.zip
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
Diffstat (limited to 'src/libstd/sys')
-rw-r--r--src/libstd/sys/unix/thread.rs13
1 files changed, 11 insertions, 2 deletions
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index 9e388808030..7fdecc9c0c0 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -326,13 +326,22 @@ pub mod guard {
             // Reallocate the last page of the stack.
             // This ensures SIGBUS will be raised on
             // 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);
-
             if result != stackaddr || result == MAP_FAILED {
                 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 offset = if cfg!(target_os = "freebsd") {
                 2