@@ -15,7 +15,6 @@ use sys_common::backtrace::{output, output_fileline};
1515
1616pub fn print ( w : & mut Write , idx : isize , addr : * mut libc:: c_void ,
1717 symaddr : * mut libc:: c_void ) -> io:: Result < ( ) > {
18- use env;
1918 use ffi:: CStr ;
2019 use ptr;
2120
@@ -110,46 +109,22 @@ pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void,
110109 // that is calculated the first time this is requested. Remember that
111110 // backtracing all happens serially (one global lock).
112111 //
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.
121116 //
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.
124124 unsafe fn init_state ( ) -> * mut backtrace_state {
125125 static mut STATE : * mut backtrace_state = ptr:: null_mut ( ) ;
126- static mut LAST_FILENAME : [ libc:: c_char ; 256 ] = [ 0 ; 256 ] ;
127126 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,
153128 ptr:: null_mut ( ) ) ;
154129 STATE
155130 }
0 commit comments