unix: Unsafe-wrap stack_overflow::{drop,make}_handler · model-checking/verify-rust-std@9e11e01 (original) (raw)
`@@ -206,34 +206,48 @@ mod imp {
`
206
206
` libc::stack_t { ss_sp: stackp, ss_flags: 0, ss_size: sigstack_size }
`
207
207
`}
`
208
208
``
``
209
`+
/// # Safety
`
``
210
`+
/// Mutates the alternate signal stack
`
``
211
`+
#[forbid(unsafe_op_in_unsafe_fn)]
`
209
212
`pub unsafe fn make_handler(main_thread: bool) -> Handler {
`
210
213
`if !NEED_ALTSTACK.load(Ordering::Relaxed) {
`
211
214
`return Handler::null();
`
212
215
`}
`
213
216
``
214
217
`if !main_thread {
`
215
218
`// Always write to GUARD to ensure the TLS variable is allocated.
`
216
``
`-
let guard = current_guard().unwrap_or(0..0);
`
``
219
`+
let guard = unsafe { current_guard() }.unwrap_or(0..0);
`
217
220
`GUARD.set((guard.start, guard.end));
`
218
221
`}
`
219
222
``
220
``
`-
let mut stack = mem::zeroed();
`
221
``
`-
sigaltstack(ptr::null(), &mut stack);
`
``
223
`+
// SAFETY: assuming stack_t is zero-initializable
`
``
224
`+
let mut stack = unsafe { mem::zeroed() };
`
``
225
`+
// SAFETY: reads current stack_t into stack
`
``
226
`+
unsafe { sigaltstack(ptr::null(), &mut stack) };
`
222
227
`// Configure alternate signal stack, if one is not already set.
`
223
228
`if stack.ss_flags & SS_DISABLE != 0 {
`
224
``
`-
stack = get_stack();
`
225
``
`-
sigaltstack(&stack, ptr::null_mut());
`
``
229
`+
// SAFETY: We warned our caller this would happen!
`
``
230
`+
unsafe {
`
``
231
`+
stack = get_stack();
`
``
232
`+
sigaltstack(&stack, ptr::null_mut());
`
``
233
`+
}
`
226
234
`Handler { data: stack.ss_sp as *mut libc::c_void }
`
227
235
`} else {
`
228
236
`Handler::null()
`
229
237
`}
`
230
238
`}
`
231
239
``
``
240
`+
/// # Safety
`
``
241
`+
/// Must be called
`
``
242
`+
/// - only with our handler or nullptr
`
``
243
`+
/// - only when done with our altstack
`
``
244
`+
/// This disables the alternate signal stack!
`
``
245
`+
#[forbid(unsafe_op_in_unsafe_fn)]
`
232
246
`pub unsafe fn drop_handler(data: *mut libc::c_void) {
`
233
247
`if !data.is_null() {
`
234
248
`let sigstack_size = sigstack_size();
`
235
249
`let page_size = PAGE_SIZE.load(Ordering::Relaxed);
`
236
``
`-
let stack = libc::stack_t {
`
``
250
`+
let disabling_stack = libc::stack_t {
`
237
251
`ss_sp: ptr::null_mut(),
`
238
252
`ss_flags: SS_DISABLE,
`
239
253
`// Workaround for bug in macOS implementation of sigaltstack
`
`@@ -242,10 +256,11 @@ mod imp {
`
242
256
`// both ss_sp and ss_size should be ignored in this case.
`
243
257
`ss_size: sigstack_size,
`
244
258
`};
`
245
``
`-
sigaltstack(&stack, ptr::null_mut());
`
246
``
`` -
// We know from get_stackp
that the alternate stack we installed is part of a mapping
``
247
``
`-
// that started one page earlier, so walk back a page and unmap from there.
`
248
``
`-
munmap(data.sub(page_size), sigstack_size + page_size);
`
``
259
`+
// SAFETY: we warned the caller this disables the alternate signal stack!
`
``
260
`+
unsafe { sigaltstack(&disabling_stack, ptr::null_mut()) };
`
``
261
`` +
// SAFETY: We know from get_stackp
that the alternate stack we installed is part of
``
``
262
`+
// a mapping that started one page earlier, so walk back a page and unmap from there.
`
``
263
`+
unsafe { munmap(data.sub(page_size), sigstack_size + page_size) };
`
249
264
`}
`
250
265
`}
`
251
266
``
`@@ -446,6 +461,7 @@ mod imp {
`
446
461
`}
`
447
462
``
448
463
`#[cfg(any(target_os = "macos", target_os = "openbsd", target_os = "solaris"))]
`
``
464
`+
// FIXME: I am probably not unsafe.
`
449
465
`unsafe fn current_guard() -> Option<Range> {
`
450
466
`let stackptr = get_stack_start()?;
`
451
467
`let stackaddr = stackptr.addr();
`
`@@ -460,6 +476,7 @@ mod imp {
`
460
476
` target_os = "netbsd",
`
461
477
` target_os = "l4re"
`
462
478
`))]
`
``
479
`+
// FIXME: I am probably not unsafe.
`
463
480
`unsafe fn current_guard() -> Option<Range> {
`
464
481
`let mut ret = None;
`
465
482
`let mut attr: libc::pthread_attr_t = crate::mem::zeroed();
`