@@ -206,34 +206,45 @@ 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 only be called with our handler or nullptr, and only when done with our altstack
242
+ #[ forbid( unsafe_op_in_unsafe_fn) ]
232
243
pub unsafe fn drop_handler ( data : * mut libc:: c_void ) {
233
244
if !data. is_null ( ) {
234
245
let sigstack_size = sigstack_size ( ) ;
235
246
let page_size = PAGE_SIZE . load ( Ordering :: Relaxed ) ;
236
- let stack = libc:: stack_t {
247
+ let disabling_stack = libc:: stack_t {
237
248
ss_sp : ptr:: null_mut ( ) ,
238
249
ss_flags : SS_DISABLE ,
239
250
// Workaround for bug in macOS implementation of sigaltstack
@@ -242,10 +253,11 @@ mod imp {
242
253
// both ss_sp and ss_size should be ignored in this case.
243
254
ss_size : sigstack_size,
244
255
} ;
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) ;
256
+ // SAFETY: we warned the caller this disables the alternate signal stack!
257
+ unsafe { sigaltstack ( & disabling_stack, ptr:: null_mut ( ) ) } ;
258
+ // SAFETY: We know from `get_stackp` that the alternate stack we installed is part of
259
+ // a mapping that started one page earlier, so walk back a page and unmap from there.
260
+ unsafe { munmap ( data. sub ( page_size) , sigstack_size + page_size) } ;
249
261
}
250
262
}
251
263
0 commit comments