From a185b56b7caca17c7aa9d6f702fe1b2209c82e4e Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Sun, 18 Mar 2018 23:02:06 +0900 Subject: Address review comments --- src/libstd/sys/unix/thread.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'src/libstd/sys') diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 72cdb9440b8..d94e11a5207 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -222,7 +222,7 @@ pub mod guard { #[cfg_attr(test, allow(dead_code))] pub mod guard { use libc; - use libc::mmap; + use libc::{mmap, munmap}; use libc::{PROT_NONE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED}; use ops::Range; use sys::os; @@ -336,6 +336,24 @@ pub mod guard { } } + pub unsafe fn deinit() { + if !cfg!(target_os = "linux") { + if let Some(mut stackaddr) = get_stack_start() { + // Ensure address is aligned. Same as above. + let remainder = (stackaddr as usize) % PAGE_SIZE; + if remainder != 0 { + stackaddr = ((stackaddr as usize) + PAGE_SIZE - remainder) + as *mut libc::c_void; + } + + // Undo the guard page mapping. + if munmap(stackaddr, PAGE_SIZE) != 0 { + panic!("unable to deallocate the guard page"); + } + } + } + } + #[cfg(any(target_os = "macos", target_os = "bitrig", target_os = "openbsd", -- cgit 1.4.1-3-g733a5 From 2928c7a8a253b655132ac9f2beb4ca74540f0e14 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Tue, 20 Mar 2018 21:22:45 +0900 Subject: Refactor the stack addr aligning code into a function --- src/libstd/sys/unix/thread.rs | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'src/libstd/sys') diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index d94e11a5207..4364089a181 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -284,10 +284,10 @@ pub mod guard { ret } - pub unsafe fn init() -> Option { - PAGE_SIZE = os::page_size(); - - let mut stackaddr = get_stack_start()?; + // Precondition: PAGE_SIZE is initialized. + unsafe fn get_stack_start_aligned() -> Option<*mut libc::c_void> { + assert!(PAGE_SIZE != 0); + let stackaddr = get_stack_start()?; // Ensure stackaddr is page aligned! A parent process might // have reset RLIMIT_STACK to be non-page aligned. The @@ -296,10 +296,17 @@ pub mod guard { // page-aligned, calculate the fix such that stackaddr < // new_page_aligned_stackaddr < stackaddr + stacksize let remainder = (stackaddr as usize) % PAGE_SIZE; - if remainder != 0 { - stackaddr = ((stackaddr as usize) + PAGE_SIZE - remainder) - as *mut libc::c_void; - } + Some(if remainder == 0 { + stackaddr + } else { + ((stackaddr as usize) + PAGE_SIZE - remainder) as *mut libc::c_void + }) + } + + pub unsafe fn init() -> Option { + PAGE_SIZE = os::page_size(); + + let stackaddr = get_stack_start_aligned()?; if cfg!(target_os = "linux") { // Linux doesn't allocate the whole stack right away, and @@ -338,14 +345,7 @@ pub mod guard { pub unsafe fn deinit() { if !cfg!(target_os = "linux") { - if let Some(mut stackaddr) = get_stack_start() { - // Ensure address is aligned. Same as above. - let remainder = (stackaddr as usize) % PAGE_SIZE; - if remainder != 0 { - stackaddr = ((stackaddr as usize) + PAGE_SIZE - remainder) - as *mut libc::c_void; - } - + if let Some(stackaddr) = get_stack_start_aligned() { // Undo the guard page mapping. if munmap(stackaddr, PAGE_SIZE) != 0 { panic!("unable to deallocate the guard page"); -- cgit 1.4.1-3-g733a5 From 91279904345e2ecd3f52b17339183bbe3bd11203 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Sat, 24 Mar 2018 13:47:36 +0900 Subject: Fix build on non-Unix platforms --- src/libstd/sys/cloudabi/thread.rs | 1 + src/libstd/sys/redox/thread.rs | 1 + src/libstd/sys/unix/thread.rs | 1 + src/libstd/sys/wasm/thread.rs | 1 + src/libstd/sys/windows/thread.rs | 1 + 5 files changed, 5 insertions(+) (limited to 'src/libstd/sys') diff --git a/src/libstd/sys/cloudabi/thread.rs b/src/libstd/sys/cloudabi/thread.rs index 78a3b82546e..a22d9053b69 100644 --- a/src/libstd/sys/cloudabi/thread.rs +++ b/src/libstd/sys/cloudabi/thread.rs @@ -118,6 +118,7 @@ pub mod guard { pub unsafe fn init() -> Option { None } + pub unsafe fn deinit() {} } fn min_stack_size(_: *const libc::pthread_attr_t) -> usize { diff --git a/src/libstd/sys/redox/thread.rs b/src/libstd/sys/redox/thread.rs index c4719a94c7e..f20350269b7 100644 --- a/src/libstd/sys/redox/thread.rs +++ b/src/libstd/sys/redox/thread.rs @@ -91,4 +91,5 @@ pub mod guard { pub type Guard = !; pub unsafe fn current() -> Option { None } pub unsafe fn init() -> Option { None } + pub unsafe fn deinit() {} } diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 4364089a181..b9ec0d4a403 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -209,6 +209,7 @@ pub mod guard { pub type Guard = Range; pub unsafe fn current() -> Option { None } pub unsafe fn init() -> Option { None } + pub unsafe fn deinit() {} } diff --git a/src/libstd/sys/wasm/thread.rs b/src/libstd/sys/wasm/thread.rs index 6a066509b49..7345843b975 100644 --- a/src/libstd/sys/wasm/thread.rs +++ b/src/libstd/sys/wasm/thread.rs @@ -46,4 +46,5 @@ pub mod guard { pub type Guard = !; pub unsafe fn current() -> Option { None } pub unsafe fn init() -> Option { None } + pub unsafe fn deinit() {} } diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs index 43abfbb1f64..4b3d1b586b5 100644 --- a/src/libstd/sys/windows/thread.rs +++ b/src/libstd/sys/windows/thread.rs @@ -96,4 +96,5 @@ pub mod guard { pub type Guard = !; pub unsafe fn current() -> Option { None } pub unsafe fn init() -> Option { None } + pub unsafe fn deinit() {} } -- cgit 1.4.1-3-g733a5 From d39b02c2c9e8aa472ab47ccfb5de63bc616daf62 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Sun, 25 Mar 2018 16:08:03 +0900 Subject: Use a more conservative way to deinit stack guard --- src/libstd/sys/unix/thread.rs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src/libstd/sys') diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index b9ec0d4a403..6064b55489e 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -223,8 +223,8 @@ pub mod guard { #[cfg_attr(test, allow(dead_code))] pub mod guard { use libc; - use libc::{mmap, munmap}; - use libc::{PROT_NONE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED}; + use libc::mmap; + use libc::{PROT_NONE, PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED}; use ops::Range; use sys::os; @@ -347,9 +347,19 @@ pub mod guard { pub unsafe fn deinit() { if !cfg!(target_os = "linux") { if let Some(stackaddr) = get_stack_start_aligned() { - // Undo the guard page mapping. - if munmap(stackaddr, PAGE_SIZE) != 0 { - panic!("unable to deallocate the guard page"); + // Remove the protection on the guard page. + // FIXME: we cannot unmap the page, because when we mmap() + // above it may be already mapped by the OS, which we can't + // detect from mmap()'s return value. If we unmap this page, + // it will lead to failure growing stack size on platforms like + // macOS. Instead, just restore the page to a writable state. + // This ain't Linux, so we probably don't need to care about + // execstack. + 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!("unable to reset the guard page"); } } } -- cgit 1.4.1-3-g733a5 From 8ecbec1dba048bf55461dbff772f18a72311ecc2 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Wed, 28 Mar 2018 18:47:16 +0900 Subject: Use mprotect instead of mmap --- src/libstd/sys/unix/thread.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/libstd/sys') diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 6064b55489e..775289f393b 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -355,10 +355,9 @@ pub mod guard { // macOS. Instead, just restore the page to a writable state. // This ain't Linux, so we probably don't need to care about // execstack. - let result = mmap(stackaddr, PAGE_SIZE, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0); + let result = mprotect(stackaddr, PAGE_SIZE, PROT_READ | PROT_WRITE); - if result != stackaddr || result == MAP_FAILED { + if result != 0 { panic!("unable to reset the guard page"); } } -- cgit 1.4.1-3-g733a5 From 7db854b36f9598e44fb4d61428d42d7769233e19 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Tue, 3 Apr 2018 12:42:36 +0900 Subject: Fix imports --- src/libstd/sys/unix/thread.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libstd/sys') diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 775289f393b..2db3d4a5744 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -223,7 +223,7 @@ pub mod guard { #[cfg_attr(test, allow(dead_code))] pub mod guard { use libc; - use libc::mmap; + use libc::{mmap, mprotect}; use libc::{PROT_NONE, PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED}; use ops::Range; use sys::os; -- cgit 1.4.1-3-g733a5