diff options
| author | Alexis Beingessner <a.beingessner@gmail.com> | 2022-03-22 21:29:38 -0400 |
|---|---|---|
| committer | Aria Beingessner <a.beingessner@gmail.com> | 2022-03-29 20:18:27 -0400 |
| commit | 09395f626b2ff7378fb250300654b1817953a390 (patch) | |
| tree | 92ff9d059a640e5638062b633f1e62a2665701a9 /library/std/src/sys/unix/thread.rs | |
| parent | 68643603ad00900d6a91a0dae90bb2ebb4f0db48 (diff) | |
| download | rust-09395f626b2ff7378fb250300654b1817953a390.tar.gz rust-09395f626b2ff7378fb250300654b1817953a390.zip | |
Make some linux/unix APIs better conform to strict provenance.
This largely makes the stdlib conform to strict provenance on Ubuntu. Some hairier things have been left alone for now.
Diffstat (limited to 'library/std/src/sys/unix/thread.rs')
| -rw-r--r-- | library/std/src/sys/unix/thread.rs | 48 |
1 files changed, 25 insertions, 23 deletions
diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index 2d5d306ed62..be70d00cb1a 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -505,9 +505,8 @@ pub mod guard { #[cfg(target_os = "macos")] unsafe fn get_stack_start() -> Option<*mut libc::c_void> { let th = libc::pthread_self(); - let stackaddr = - libc::pthread_get_stackaddr_np(th) as usize - libc::pthread_get_stacksize_np(th); - Some(stackaddr as *mut libc::c_void) + let stackptr = libc::pthread_get_stackaddr_np(th); + Some(stackptr.map_addr(|addr| addr - libc::pthread_get_stacksize_np(th))) } #[cfg(target_os = "openbsd")] @@ -515,14 +514,15 @@ pub mod guard { let mut current_stack: libc::stack_t = crate::mem::zeroed(); assert_eq!(libc::pthread_stackseg_np(libc::pthread_self(), &mut current_stack), 0); + let stack_ptr = current_stack.ss_sp; let stackaddr = if libc::pthread_main_np() == 1 { // main thread - current_stack.ss_sp as usize - current_stack.ss_size + PAGE_SIZE.load(Ordering::Relaxed) + stack_ptr.addr() - current_stack.ss_size + PAGE_SIZE.load(Ordering::Relaxed) } else { // new thread - current_stack.ss_sp as usize - current_stack.ss_size + stack_ptr.addr() - current_stack.ss_size }; - Some(stackaddr as *mut libc::c_void) + Some(stack_ptr.with_addr(stack_addr)) } #[cfg(any( @@ -557,7 +557,8 @@ pub mod guard { unsafe fn get_stack_start_aligned() -> Option<*mut libc::c_void> { let page_size = PAGE_SIZE.load(Ordering::Relaxed); assert!(page_size != 0); - let stackaddr = get_stack_start()?; + let stackptr = get_stack_start()?; + let stackaddr = stackptr.addr(); // Ensure stackaddr is page aligned! A parent process might // have reset RLIMIT_STACK to be non-page aligned. The @@ -565,11 +566,11 @@ pub mod guard { // stackaddr < stackaddr + stacksize, so if stackaddr is not // page-aligned, calculate the fix such that stackaddr < // new_page_aligned_stackaddr < stackaddr + stacksize - let remainder = (stackaddr as usize) % page_size; + let remainder = stackaddr % page_size; Some(if remainder == 0 { - stackaddr + stackptr } else { - ((stackaddr as usize) + page_size - remainder) as *mut libc::c_void + stackptr.with_addr(stackaddr + page_size - remainder) }) } @@ -588,8 +589,8 @@ pub mod guard { // Instead, we'll just note where we expect rlimit to start // faulting, so our handler can report "stack overflow", and // trust that the kernel's own stack guard will work. - let stackaddr = get_stack_start_aligned()?; - let stackaddr = stackaddr as usize; + let stackptr = get_stack_start_aligned()?; + let stackaddr = stackptr.addr(); Some(stackaddr - page_size..stackaddr) } else if cfg!(all(target_os = "linux", target_env = "musl")) { // For the main thread, the musl's pthread_attr_getstack @@ -602,8 +603,8 @@ pub mod guard { // at the bottom. If we try to remap the bottom of the stack // ourselves, FreeBSD's guard page moves upwards. So we'll just use // the builtin guard page. - let stackaddr = get_stack_start_aligned()?; - let guardaddr = stackaddr as usize; + let stackptr = get_stack_start_aligned()?; + let guardaddr = stackptr.addr(); // Technically the number of guard pages is tunable and controlled // by the security.bsd.stack_guard_page sysctl, but there are // few reasons to change it from the default. The default value has @@ -620,25 +621,25 @@ pub mod guard { // than the initial mmap() used, so we mmap() here with // read/write permissions and only then mprotect() it to // no permissions at all. See issue #50313. - let stackaddr = get_stack_start_aligned()?; + let stackptr = get_stack_start_aligned()?; let result = mmap( - stackaddr, + stackptr, page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0, ); - if result != stackaddr || result == MAP_FAILED { + if result != stackptr || result == MAP_FAILED { panic!("failed to allocate a guard page: {}", io::Error::last_os_error()); } - let result = mprotect(stackaddr, page_size, PROT_NONE); + let result = mprotect(stackptr, page_size, PROT_NONE); if result != 0 { panic!("failed to protect the guard page: {}", io::Error::last_os_error()); } - let guardaddr = stackaddr as usize; + let guardaddr = stackptr.addr(); Some(guardaddr..guardaddr + page_size) } @@ -646,7 +647,8 @@ pub mod guard { #[cfg(any(target_os = "macos", target_os = "openbsd", target_os = "solaris"))] pub unsafe fn current() -> Option<Guard> { - let stackaddr = get_stack_start()? as usize; + let stackptr = get_stack_start()?; + let stackaddr = stackptr.addr(); Some(stackaddr - PAGE_SIZE.load(Ordering::Relaxed)..stackaddr) } @@ -679,11 +681,11 @@ pub mod guard { panic!("there is no guard page"); } } - let mut stackaddr = crate::ptr::null_mut(); + let mut stackptr = crate::ptr::null_mut::<libc::c_void>(); let mut size = 0; - assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr, &mut size), 0); + assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackptr, &mut size), 0); - let stackaddr = stackaddr as usize; + let stackaddr = stackptr.addr(); ret = if cfg!(any(target_os = "freebsd", target_os = "netbsd")) { Some(stackaddr - guardsize..stackaddr) } else if cfg!(all(target_os = "linux", target_env = "musl")) { |
