about summary refs log tree commit diff
path: root/src/libstd/sys
diff options
context:
space:
mode:
authorMartin Husemann <martin@NetBSD.org>2018-04-30 08:04:53 +0200
committerMartin Husemann <martin@NetBSD.org>2018-04-30 08:04:53 +0200
commit7c2304ddc6d716883415ac883f02256db6318644 (patch)
treecaada13bda1dd1bd380b7f61dc1c2e5e942990e0 /src/libstd/sys
parentf900bcf35c9ed4b8f911a37df3949f82669b9bd8 (diff)
downloadrust-7c2304ddc6d716883415ac883f02256db6318644.tar.gz
rust-7c2304ddc6d716883415ac883f02256db6318644.zip
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.
Diffstat (limited to 'src/libstd/sys')
-rw-r--r--src/libstd/sys/unix/thread.rs20
1 files changed, 16 insertions, 4 deletions
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index 9e388808030..f32016ce1d6 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -326,11 +326,23 @@ 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,
-                              MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
+            if cfg!(target_os = "netbsd") {
+                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, 0);
 
-            if result != stackaddr || result == MAP_FAILED {
-                panic!("failed to allocate a guard page");
+                if result != 0 {
+                    panic!("unable 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;