@@ -246,10 +246,11 @@ pub mod guard {
246
246
use libc:: { MAP_ANON , MAP_FAILED , MAP_FIXED , MAP_PRIVATE , PROT_NONE , PROT_READ , PROT_WRITE } ;
247
247
248
248
use crate :: ops:: Range ;
249
+ use crate :: sync:: atomic:: { AtomicUsize , Ordering } ;
249
250
use crate :: sys:: os;
250
251
251
252
// This is initialized in init() and only read from after
252
- static mut PAGE_SIZE : usize = 0 ;
253
+ static PAGE_SIZE : AtomicUsize = AtomicUsize :: new ( 0 ) ;
253
254
254
255
pub type Guard = Range < usize > ;
255
256
@@ -275,7 +276,7 @@ pub mod guard {
275
276
276
277
let stackaddr = if libc:: pthread_main_np ( ) == 1 {
277
278
// main thread
278
- current_stack. ss_sp as usize - current_stack. ss_size + PAGE_SIZE
279
+ current_stack. ss_sp as usize - current_stack. ss_size + PAGE_SIZE . load ( Ordering :: Relaxed )
279
280
} else {
280
281
// new thread
281
282
current_stack. ss_sp as usize - current_stack. ss_size
@@ -310,7 +311,8 @@ pub mod guard {
310
311
311
312
// Precondition: PAGE_SIZE is initialized.
312
313
unsafe fn get_stack_start_aligned ( ) -> Option < * mut libc:: c_void > {
313
- assert ! ( PAGE_SIZE != 0 ) ;
314
+ let page_size = PAGE_SIZE . load ( Ordering :: Relaxed ) ;
315
+ assert ! ( page_size != 0 ) ;
314
316
let stackaddr = get_stack_start ( ) ?;
315
317
316
318
// Ensure stackaddr is page aligned! A parent process might
@@ -319,16 +321,17 @@ pub mod guard {
319
321
// stackaddr < stackaddr + stacksize, so if stackaddr is not
320
322
// page-aligned, calculate the fix such that stackaddr <
321
323
// new_page_aligned_stackaddr < stackaddr + stacksize
322
- let remainder = ( stackaddr as usize ) % PAGE_SIZE ;
324
+ let remainder = ( stackaddr as usize ) % page_size ;
323
325
Some ( if remainder == 0 {
324
326
stackaddr
325
327
} else {
326
- ( ( stackaddr as usize ) + PAGE_SIZE - remainder) as * mut libc:: c_void
328
+ ( ( stackaddr as usize ) + page_size - remainder) as * mut libc:: c_void
327
329
} )
328
330
}
329
331
330
332
pub unsafe fn init ( ) -> Option < Guard > {
331
- PAGE_SIZE = os:: page_size ( ) ;
333
+ let page_size = os:: page_size ( ) ;
334
+ PAGE_SIZE . store ( page_size, Ordering :: Relaxed ) ;
332
335
333
336
let stackaddr = get_stack_start_aligned ( ) ?;
334
337
@@ -344,7 +347,7 @@ pub mod guard {
344
347
// faulting, so our handler can report "stack overflow", and
345
348
// trust that the kernel's own stack guard will work.
346
349
let stackaddr = stackaddr as usize ;
347
- Some ( stackaddr - PAGE_SIZE ..stackaddr)
350
+ Some ( stackaddr - page_size ..stackaddr)
348
351
} else {
349
352
// Reallocate the last page of the stack.
350
353
// This ensures SIGBUS will be raised on
@@ -356,7 +359,7 @@ pub mod guard {
356
359
// no permissions at all. See issue #50313.
357
360
let result = mmap (
358
361
stackaddr,
359
- PAGE_SIZE ,
362
+ page_size ,
360
363
PROT_READ | PROT_WRITE ,
361
364
MAP_PRIVATE | MAP_ANON | MAP_FIXED ,
362
365
-1 ,
@@ -366,22 +369,22 @@ pub mod guard {
366
369
panic ! ( "failed to allocate a guard page" ) ;
367
370
}
368
371
369
- let result = mprotect ( stackaddr, PAGE_SIZE , PROT_NONE ) ;
372
+ let result = mprotect ( stackaddr, page_size , PROT_NONE ) ;
370
373
if result != 0 {
371
374
panic ! ( "failed to protect the guard page" ) ;
372
375
}
373
376
374
377
let guardaddr = stackaddr as usize ;
375
378
let offset = if cfg ! ( target_os = "freebsd" ) { 2 } else { 1 } ;
376
379
377
- Some ( guardaddr..guardaddr + offset * PAGE_SIZE )
380
+ Some ( guardaddr..guardaddr + offset * page_size )
378
381
}
379
382
}
380
383
381
384
#[ cfg( any( target_os = "macos" , target_os = "openbsd" , target_os = "solaris" ) ) ]
382
385
pub unsafe fn current ( ) -> Option < Guard > {
383
386
let stackaddr = get_stack_start ( ) ? as usize ;
384
- Some ( stackaddr - PAGE_SIZE ..stackaddr)
387
+ Some ( stackaddr - PAGE_SIZE . load ( Ordering :: Relaxed ) . .stackaddr)
385
388
}
386
389
387
390
#[ cfg( any(
@@ -413,7 +416,7 @@ pub mod guard {
413
416
ret = if cfg ! ( target_os = "freebsd" ) {
414
417
// FIXME does freebsd really fault *below* the guard addr?
415
418
let guardaddr = stackaddr - guardsize;
416
- Some ( guardaddr - PAGE_SIZE ..guardaddr)
419
+ Some ( guardaddr - PAGE_SIZE . load ( Ordering :: Relaxed ) . .guardaddr)
417
420
} else if cfg ! ( target_os = "netbsd" ) {
418
421
Some ( stackaddr - guardsize..stackaddr)
419
422
} else if cfg ! ( all( target_os = "linux" , target_env = "gnu" ) ) {
0 commit comments