Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 369afc8

Browse files
authoredMar 9, 2020
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 2f59631 + 676b9bc commit 369afc8

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)
Please sign in to comment.