Skip to content

Commit d39b02c

Browse files
committed
Use a more conservative way to deinit stack guard
1 parent 9127990 commit d39b02c

File tree

1 file changed

+15
-5
lines changed

1 file changed

+15
-5
lines changed

src/libstd/sys/unix/thread.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,8 @@ pub mod guard {
223223
#[cfg_attr(test, allow(dead_code))]
224224
pub mod guard {
225225
use libc;
226-
use libc::{mmap, munmap};
227-
use libc::{PROT_NONE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED};
226+
use libc::mmap;
227+
use libc::{PROT_NONE, PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED};
228228
use ops::Range;
229229
use sys::os;
230230

@@ -347,9 +347,19 @@ pub mod guard {
347347
pub unsafe fn deinit() {
348348
if !cfg!(target_os = "linux") {
349349
if let Some(stackaddr) = get_stack_start_aligned() {
350-
// Undo the guard page mapping.
351-
if munmap(stackaddr, PAGE_SIZE) != 0 {
352-
panic!("unable to deallocate the guard page");
350+
// Remove the protection on the guard page.
351+
// FIXME: we cannot unmap the page, because when we mmap()
352+
// above it may be already mapped by the OS, which we can't
353+
// detect from mmap()'s return value. If we unmap this page,
354+
// it will lead to failure growing stack size on platforms like
355+
// macOS. Instead, just restore the page to a writable state.
356+
// This ain't Linux, so we probably don't need to care about
357+
// execstack.
358+
let result = mmap(stackaddr, PAGE_SIZE, PROT_READ | PROT_WRITE,
359+
MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
360+
361+
if result != stackaddr || result == MAP_FAILED {
362+
panic!("unable to reset the guard page");
353363
}
354364
}
355365
}

0 commit comments

Comments
 (0)