1
+ // FIXME(strict_provenance_magic): system API wants us to pass a pointer as ulong :(
2
+ #![ cfg_attr( not( bootstrap) , allow( fuzzy_provenance_casts) ) ]
3
+
1
4
use crate :: cmp;
2
5
use crate :: ffi:: CStr ;
3
6
use crate :: io;
@@ -505,24 +508,24 @@ pub mod guard {
505
508
#[ cfg( target_os = "macos" ) ]
506
509
unsafe fn get_stack_start ( ) -> Option < * mut libc:: c_void > {
507
510
let th = libc:: pthread_self ( ) ;
508
- let stackaddr =
509
- libc:: pthread_get_stackaddr_np ( th) as usize - libc:: pthread_get_stacksize_np ( th) ;
510
- Some ( stackaddr as * mut libc:: c_void )
511
+ let stackptr = libc:: pthread_get_stackaddr_np ( th) ;
512
+ Some ( stackptr. with_addr ( stackptr. with_addr ( ) - libc:: pthread_get_stacksize_np ( th) ) )
511
513
}
512
514
513
515
#[ cfg( target_os = "openbsd" ) ]
514
516
unsafe fn get_stack_start ( ) -> Option < * mut libc:: c_void > {
515
517
let mut current_stack: libc:: stack_t = crate :: mem:: zeroed ( ) ;
516
518
assert_eq ! ( libc:: pthread_stackseg_np( libc:: pthread_self( ) , & mut current_stack) , 0 ) ;
517
519
520
+ let stack_ptr = current_stack. ss_sp ;
518
521
let stackaddr = if libc:: pthread_main_np ( ) == 1 {
519
522
// main thread
520
- current_stack . ss_sp as usize - current_stack. ss_size + PAGE_SIZE . load ( Ordering :: Relaxed )
523
+ stack_ptr . addr ( ) - current_stack. ss_size + PAGE_SIZE . load ( Ordering :: Relaxed )
521
524
} else {
522
525
// new thread
523
- current_stack . ss_sp as usize - current_stack. ss_size
526
+ stack_ptr . addr ( ) - current_stack. ss_size
524
527
} ;
525
- Some ( stackaddr as * mut libc :: c_void )
528
+ Some ( stack_ptr . with_addr ( stack_addr ) )
526
529
}
527
530
528
531
#[ cfg( any(
@@ -557,19 +560,20 @@ pub mod guard {
557
560
unsafe fn get_stack_start_aligned ( ) -> Option < * mut libc:: c_void > {
558
561
let page_size = PAGE_SIZE . load ( Ordering :: Relaxed ) ;
559
562
assert ! ( page_size != 0 ) ;
560
- let stackaddr = get_stack_start ( ) ?;
563
+ let stackptr = get_stack_start ( ) ?;
564
+ let stackaddr = stackptr. addr ( ) ;
561
565
562
566
// Ensure stackaddr is page aligned! A parent process might
563
567
// have reset RLIMIT_STACK to be non-page aligned. The
564
568
// pthread_attr_getstack() reports the usable stack area
565
569
// stackaddr < stackaddr + stacksize, so if stackaddr is not
566
570
// page-aligned, calculate the fix such that stackaddr <
567
571
// new_page_aligned_stackaddr < stackaddr + stacksize
568
- let remainder = ( stackaddr as usize ) % page_size;
572
+ let remainder = ( stackaddr) % page_size;
569
573
Some ( if remainder == 0 {
570
- stackaddr
574
+ stackptr
571
575
} else {
572
- ( ( stackaddr as usize ) + page_size - remainder) as * mut libc :: c_void
576
+ stackptr . with_addr ( stackaddr + page_size - remainder)
573
577
} )
574
578
}
575
579
@@ -588,8 +592,8 @@ pub mod guard {
588
592
// Instead, we'll just note where we expect rlimit to start
589
593
// faulting, so our handler can report "stack overflow", and
590
594
// trust that the kernel's own stack guard will work.
591
- let stackaddr = get_stack_start_aligned ( ) ?;
592
- let stackaddr = stackaddr as usize ;
595
+ let stackptr = get_stack_start_aligned ( ) ?;
596
+ let stackaddr = stackptr . addr ( ) ;
593
597
Some ( stackaddr - page_size..stackaddr)
594
598
} else if cfg ! ( all( target_os = "linux" , target_env = "musl" ) ) {
595
599
// For the main thread, the musl's pthread_attr_getstack
@@ -602,8 +606,8 @@ pub mod guard {
602
606
// at the bottom. If we try to remap the bottom of the stack
603
607
// ourselves, FreeBSD's guard page moves upwards. So we'll just use
604
608
// the builtin guard page.
605
- let stackaddr = get_stack_start_aligned ( ) ?;
606
- let guardaddr = stackaddr as usize ;
609
+ let stackptr = get_stack_start_aligned ( ) ?;
610
+ let guardaddr = stackptr . addr ( ) ;
607
611
// Technically the number of guard pages is tunable and controlled
608
612
// by the security.bsd.stack_guard_page sysctl, but there are
609
613
// few reasons to change it from the default. The default value has
@@ -620,33 +624,34 @@ pub mod guard {
620
624
// than the initial mmap() used, so we mmap() here with
621
625
// read/write permissions and only then mprotect() it to
622
626
// no permissions at all. See issue #50313.
623
- let stackaddr = get_stack_start_aligned ( ) ?;
627
+ let stackptr = get_stack_start_aligned ( ) ?;
624
628
let result = mmap (
625
- stackaddr ,
629
+ stackptr ,
626
630
page_size,
627
631
PROT_READ | PROT_WRITE ,
628
632
MAP_PRIVATE | MAP_ANON | MAP_FIXED ,
629
633
-1 ,
630
634
0 ,
631
635
) ;
632
- if result != stackaddr || result == MAP_FAILED {
636
+ if result != stackptr || result == MAP_FAILED {
633
637
panic ! ( "failed to allocate a guard page: {}" , io:: Error :: last_os_error( ) ) ;
634
638
}
635
639
636
- let result = mprotect ( stackaddr , page_size, PROT_NONE ) ;
640
+ let result = mprotect ( stackptr , page_size, PROT_NONE ) ;
637
641
if result != 0 {
638
642
panic ! ( "failed to protect the guard page: {}" , io:: Error :: last_os_error( ) ) ;
639
643
}
640
644
641
- let guardaddr = stackaddr as usize ;
645
+ let guardaddr = stackptr . addr ( ) ;
642
646
643
647
Some ( guardaddr..guardaddr + page_size)
644
648
}
645
649
}
646
650
647
651
#[ cfg( any( target_os = "macos" , target_os = "openbsd" , target_os = "solaris" ) ) ]
648
652
pub unsafe fn current ( ) -> Option < Guard > {
649
- let stackaddr = get_stack_start ( ) ? as usize ;
653
+ let stackptr = get_stack_start ( ) ?;
654
+ let stackaddr = stackptr. addr ( ) ;
650
655
Some ( stackaddr - PAGE_SIZE . load ( Ordering :: Relaxed ) ..stackaddr)
651
656
}
652
657
@@ -679,11 +684,11 @@ pub mod guard {
679
684
panic ! ( "there is no guard page" ) ;
680
685
}
681
686
}
682
- let mut stackaddr = crate :: ptr:: null_mut ( ) ;
687
+ let mut stackptr = crate :: ptr:: null_mut :: < libc :: c_void > ( ) ;
683
688
let mut size = 0 ;
684
- assert_eq ! ( libc:: pthread_attr_getstack( & attr, & mut stackaddr , & mut size) , 0 ) ;
689
+ assert_eq ! ( libc:: pthread_attr_getstack( & attr, & mut stackptr , & mut size) , 0 ) ;
685
690
686
- let stackaddr = stackaddr as usize ;
691
+ let stackaddr = stackptr . addr ( ) ;
687
692
ret = if cfg ! ( any( target_os = "freebsd" , target_os = "netbsd" ) ) {
688
693
Some ( stackaddr - guardsize..stackaddr)
689
694
} else if cfg ! ( all( target_os = "linux" , target_env = "musl" ) ) {
0 commit comments