@@ -15,7 +15,6 @@ use sys_common::backtrace::{output, output_fileline};
15
15
16
16
pub fn print ( w : & mut Write , idx : isize , addr : * mut libc:: c_void ,
17
17
symaddr : * mut libc:: c_void ) -> io:: Result < ( ) > {
18
- use env;
19
18
use ffi:: CStr ;
20
19
use ptr;
21
20
@@ -110,46 +109,22 @@ pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void,
110
109
// that is calculated the first time this is requested. Remember that
111
110
// backtracing all happens serially (one global lock).
112
111
//
113
- // An additionally oddity in this function is that we initialize the
114
- // filename via self_exe_name() to pass to libbacktrace. It turns out
115
- // that on Linux libbacktrace seamlessly gets the filename of the
116
- // current executable, but this fails on freebsd. by always providing
117
- // it, we make sure that libbacktrace never has a reason to not look up
118
- // the symbols. The libbacktrace API also states that the filename must
119
- // be in "permanent memory", so we copy it to a static and then use the
120
- // static as the pointer.
112
+ // Things don't work so well on not-Linux since libbacktrace can't track
113
+ // down that executable this is. We at one point used env::current_exe but
114
+ // it turns out that there are some serious security issues with that
115
+ // approach.
121
116
//
122
- // FIXME: We also call self_exe_name() on DragonFly BSD. I haven't
123
- // tested if this is required or not.
117
+ // Specifically, on certain platforms like BSDs, a malicious actor can cause
118
+ // an arbitrary file to be placed at the path returned by current_exe.
119
+ // libbacktrace does not behave defensively in the presence of ill-formed
120
+ // DWARF information, and has been demonstrated to segfault in at least one
121
+ // case. There is no evidence at the moment to suggest that a more carefully
122
+ // constructed file can't cause arbitrary code execution. As a result of all
123
+ // of this, we don't hint libbacktrace with the path to the current process.
124
124
unsafe fn init_state ( ) -> * mut backtrace_state {
125
125
static mut STATE : * mut backtrace_state = ptr:: null_mut ( ) ;
126
- static mut LAST_FILENAME : [ libc:: c_char ; 256 ] = [ 0 ; 256 ] ;
127
126
if !STATE . is_null ( ) { return STATE }
128
- let selfname = if cfg ! ( target_os = "freebsd" ) ||
129
- cfg ! ( target_os = "dragonfly" ) ||
130
- cfg ! ( target_os = "bitrig" ) ||
131
- cfg ! ( target_os = "openbsd" ) ||
132
- cfg ! ( target_os = "windows" ) {
133
- env:: current_exe ( ) . ok ( )
134
- } else {
135
- None
136
- } ;
137
- let filename = match selfname. as_ref ( ) . and_then ( |s| s. to_str ( ) ) {
138
- Some ( path) => {
139
- let bytes = path. as_bytes ( ) ;
140
- if bytes. len ( ) < LAST_FILENAME . len ( ) {
141
- let i = bytes. iter ( ) ;
142
- for ( slot, val) in LAST_FILENAME . iter_mut ( ) . zip ( i) {
143
- * slot = * val as libc:: c_char ;
144
- }
145
- LAST_FILENAME . as_ptr ( )
146
- } else {
147
- ptr:: null ( )
148
- }
149
- }
150
- None => ptr:: null ( ) ,
151
- } ;
152
- STATE = backtrace_create_state ( filename, 0 , error_cb,
127
+ STATE = backtrace_create_state ( ptr:: null ( ) , 0 , error_cb,
153
128
ptr:: null_mut ( ) ) ;
154
129
STATE
155
130
}
0 commit comments