Skip to content

Commit 676b9bc

Browse files
committed
unix: Don't override existing SIGSEGV/BUS handlers
Although `stack_overflow::init` runs very early in the process, even before `main`, there may already be signal handlers installed for things like the address sanitizer. In that case, just leave it alone, and don't bother trying to allocate our own signal stacks either.
1 parent 2cb0b85 commit 676b9bc

File tree

2 files changed

+39
-8
lines changed

2 files changed

+39
-8
lines changed

src/libstd/sys/unix/stack_overflow.rs

+20-8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ impl Handler {
1313
pub unsafe fn new() -> Handler {
1414
make_handler()
1515
}
16+
17+
fn null() -> Handler {
18+
Handler { _data: crate::ptr::null_mut() }
19+
}
1620
}
1721

1822
impl Drop for Handler {
@@ -108,13 +112,20 @@ mod imp {
108112
}
109113

110114
static mut MAIN_ALTSTACK: *mut libc::c_void = ptr::null_mut();
115+
static mut NEED_ALTSTACK: bool = false;
111116

112117
pub unsafe fn init() {
113118
let mut action: sigaction = mem::zeroed();
114-
action.sa_flags = SA_SIGINFO | SA_ONSTACK;
115-
action.sa_sigaction = signal_handler as sighandler_t;
116-
sigaction(SIGSEGV, &action, ptr::null_mut());
117-
sigaction(SIGBUS, &action, ptr::null_mut());
119+
for &signal in &[SIGSEGV, SIGBUS] {
120+
sigaction(signal, ptr::null_mut(), &mut action);
121+
// Configure our signal handler if one is not already set.
122+
if action.sa_sigaction == SIG_DFL {
123+
action.sa_flags = SA_SIGINFO | SA_ONSTACK;
124+
action.sa_sigaction = signal_handler as sighandler_t;
125+
sigaction(signal, &action, ptr::null_mut());
126+
NEED_ALTSTACK = true;
127+
}
128+
}
118129

119130
let handler = make_handler();
120131
MAIN_ALTSTACK = handler._data;
@@ -152,6 +163,9 @@ mod imp {
152163
}
153164

154165
pub unsafe fn make_handler() -> Handler {
166+
if !NEED_ALTSTACK {
167+
return Handler::null();
168+
}
155169
let mut stack = mem::zeroed();
156170
sigaltstack(ptr::null(), &mut stack);
157171
// Configure alternate signal stack, if one is not already set.
@@ -160,7 +174,7 @@ mod imp {
160174
sigaltstack(&stack, ptr::null_mut());
161175
Handler { _data: stack.ss_sp as *mut libc::c_void }
162176
} else {
163-
Handler { _data: ptr::null_mut() }
177+
Handler::null()
164178
}
165179
}
166180

@@ -191,14 +205,12 @@ mod imp {
191205
target_os = "openbsd"
192206
)))]
193207
mod imp {
194-
use crate::ptr;
195-
196208
pub unsafe fn init() {}
197209

198210
pub unsafe fn cleanup() {}
199211

200212
pub unsafe fn make_handler() -> super::Handler {
201-
super::Handler { _data: ptr::null_mut() }
213+
super::Handler::null()
202214
}
203215

204216
pub unsafe fn drop_handler(_handler: &mut super::Handler) {}

src/test/ui/sanitize/badfree.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// needs-sanitizer-support
2+
// only-x86_64
3+
//
4+
// compile-flags: -Z sanitizer=address -O
5+
//
6+
// run-fail
7+
// error-pattern: AddressSanitizer: SEGV
8+
9+
use std::ffi::c_void;
10+
11+
extern "C" {
12+
fn free(ptr: *mut c_void);
13+
}
14+
15+
fn main() {
16+
unsafe {
17+
free(1 as *mut c_void);
18+
}
19+
}

0 commit comments

Comments
 (0)