diff options
| author | Jubilee Young <workingjubilee@gmail.com> | 2024-07-16 21:08:06 -0700 |
|---|---|---|
| committer | Jubilee Young <workingjubilee@gmail.com> | 2024-07-18 15:22:47 -0700 |
| commit | c1740eee1ea8dc046f9195d7578d3079ef423f7b (patch) | |
| tree | 7011def9fa3fafb6b2b8dae20625fef42f585d29 /library/std/src/sys/pal/unix/stack_overflow.rs | |
| parent | fa628ceaff4e24fad699cc651cc6e7d521b642a9 (diff) | |
| download | rust-c1740eee1ea8dc046f9195d7578d3079ef423f7b.tar.gz rust-c1740eee1ea8dc046f9195d7578d3079ef423f7b.zip | |
unix: Unsafe-wrap stack_overflow::{drop,make}_handler
Note that current_guard is probably not unsafe for future work.
Diffstat (limited to 'library/std/src/sys/pal/unix/stack_overflow.rs')
| -rw-r--r-- | library/std/src/sys/pal/unix/stack_overflow.rs | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/library/std/src/sys/pal/unix/stack_overflow.rs b/library/std/src/sys/pal/unix/stack_overflow.rs index e016f3b3ca4..3944e4e1b48 100644 --- a/library/std/src/sys/pal/unix/stack_overflow.rs +++ b/library/std/src/sys/pal/unix/stack_overflow.rs @@ -206,6 +206,9 @@ mod imp { libc::stack_t { ss_sp: stackp, ss_flags: 0, ss_size: sigstack_size } } + /// # Safety + /// Mutates the alternate signal stack + #[forbid(unsafe_op_in_unsafe_fn)] pub unsafe fn make_handler(main_thread: bool) -> Handler { if !NEED_ALTSTACK.load(Ordering::Relaxed) { return Handler::null(); @@ -213,27 +216,38 @@ mod imp { if !main_thread { // Always write to GUARD to ensure the TLS variable is allocated. - let guard = current_guard().unwrap_or(0..0); + let guard = unsafe { current_guard() }.unwrap_or(0..0); GUARD.set((guard.start, guard.end)); } - let mut stack = mem::zeroed(); - sigaltstack(ptr::null(), &mut stack); + // SAFETY: assuming stack_t is zero-initializable + let mut stack = unsafe { mem::zeroed() }; + // SAFETY: reads current stack_t into stack + unsafe { sigaltstack(ptr::null(), &mut stack) }; // Configure alternate signal stack, if one is not already set. if stack.ss_flags & SS_DISABLE != 0 { - stack = get_stack(); - sigaltstack(&stack, ptr::null_mut()); + // SAFETY: We warned our caller this would happen! + unsafe { + stack = get_stack(); + sigaltstack(&stack, ptr::null_mut()); + } Handler { data: stack.ss_sp as *mut libc::c_void } } else { Handler::null() } } + /// # Safety + /// Must be called + /// - only with our handler or nullptr + /// - only when done with our altstack + /// This disables the alternate signal stack! + #[forbid(unsafe_op_in_unsafe_fn)] pub unsafe fn drop_handler(data: *mut libc::c_void) { if !data.is_null() { let sigstack_size = sigstack_size(); let page_size = PAGE_SIZE.load(Ordering::Relaxed); - let stack = libc::stack_t { + let disabling_stack = libc::stack_t { ss_sp: ptr::null_mut(), ss_flags: SS_DISABLE, // Workaround for bug in macOS implementation of sigaltstack @@ -242,10 +256,11 @@ mod imp { // both ss_sp and ss_size should be ignored in this case. ss_size: sigstack_size, }; - sigaltstack(&stack, ptr::null_mut()); - // We know from `get_stackp` that the alternate stack we installed is part of a mapping - // that started one page earlier, so walk back a page and unmap from there. - munmap(data.sub(page_size), sigstack_size + page_size); + // SAFETY: we warned the caller this disables the alternate signal stack! + unsafe { sigaltstack(&disabling_stack, ptr::null_mut()) }; + // SAFETY: We know from `get_stackp` that the alternate stack we installed is part of + // a mapping that started one page earlier, so walk back a page and unmap from there. + unsafe { munmap(data.sub(page_size), sigstack_size + page_size) }; } } @@ -446,6 +461,7 @@ mod imp { } #[cfg(any(target_os = "macos", target_os = "openbsd", target_os = "solaris"))] + // FIXME: I am probably not unsafe. unsafe fn current_guard() -> Option<Range<usize>> { let stackptr = get_stack_start()?; let stackaddr = stackptr.addr(); @@ -460,6 +476,7 @@ mod imp { target_os = "netbsd", target_os = "l4re" ))] + // FIXME: I am probably not unsafe. unsafe fn current_guard() -> Option<Range<usize>> { let mut ret = None; let mut attr: libc::pthread_attr_t = crate::mem::zeroed(); |
