@@ -223,8 +223,8 @@ pub mod guard {
223
223
#[ cfg_attr( test, allow( dead_code) ) ]
224
224
pub mod guard {
225
225
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 } ;
228
228
use ops:: Range ;
229
229
use sys:: os;
230
230
@@ -347,9 +347,19 @@ pub mod guard {
347
347
pub unsafe fn deinit ( ) {
348
348
if !cfg ! ( target_os = "linux" ) {
349
349
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" ) ;
353
363
}
354
364
}
355
365
}
0 commit comments