Skip to content

Commit d9b718f

Browse files
authored
Rollup merge of rust-lang#69685 - cuviper:soft-segv, r=sfackler
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. Fixes rust-lang#69524.
2 parents 8a30198 + db75c97 commit d9b718f

File tree

2 files changed

+39
-6
lines changed

2 files changed

+39
-6
lines changed

src/libstd/sys/unix/stack_overflow.rs

+20-6
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

@@ -198,7 +212,7 @@ mod imp {
198212
pub unsafe fn cleanup() {}
199213

200214
pub unsafe fn make_handler() -> super::Handler {
201-
super::Handler { _data: ptr::null_mut() }
215+
super::Handler::null()
202216
}
203217

204218
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)