@@ -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 < usize > > {
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 < usize > > {
464
481
let mut ret = None ;
465
482
let mut attr: libc:: pthread_attr_t = crate :: mem:: zeroed ( ) ;
0 commit comments