diff mbox

[Libbacktrace] Fix possible SEGV when handling stripped PIE binaries.

Message ID 56D6A981.8070102@partner.samsung.com
State New
Headers show

Commit Message

max March 2, 2016, 8:51 a.m. UTC
Hi!

When testing ASan on large system, I've noticed that sometimes it 
crashes with SEGV in Libbacktrace when trying to symbolize stripped PIE 
(compiled with -pie -fPIC) binaries in fully stripped environment (this 
means that all dependent libraries are also stripped). Here a scenario 
I've observed:

1) _asan_backtrace_initialize calls elf_add passing &elf_fileline_fn as 
output parameter to properly initialize it.
2) elf_add doesn't elf_fileline_fn initialize and returns -1 for 
stripped PIE binary.
3) _asan_backtrace_initialize calls phdr_callback on each dependent 
library via dl_iterate_phdr.
4) phdr_callback initializes elf_fileline_fn iff it found debug info in 
some library (found_dwarf == 1), but this is false since all libs are 
stripped. So, we still have uninitialized elf_fileline_fn value.
5) _asan_backtrace_initialize uses elf_fileline_fn to initialize proper 
fileline_fn callback.
6) Libbacktrace uses fileline_fn callback later and crashes because it 
contains garbage.

This patch fixes the issue by simply initializing elf_fileline_fn via 
elf_nodebug in _asan_backtrace_initialize prologue.

Tested on x86_64-linux-gnu and arm-linux-gnueabi, OK for trunk?

-Maxim

Comments

Ian Lance Taylor March 2, 2016, 1:59 p.m. UTC | #1
On Wed, Mar 2, 2016 at 12:51 AM, Maxim Ostapenko
<m.ostapenko@partner.samsung.com> wrote:
>
> When testing ASan on large system, I've noticed that sometimes it crashes
> with SEGV in Libbacktrace when trying to symbolize stripped PIE (compiled
> with -pie -fPIC) binaries in fully stripped environment (this means that all
> dependent libraries are also stripped). Here a scenario I've observed:
>
> 1) _asan_backtrace_initialize calls elf_add passing &elf_fileline_fn as
> output parameter to properly initialize it.
> 2) elf_add doesn't elf_fileline_fn initialize and returns -1 for stripped
> PIE binary.
> 3) _asan_backtrace_initialize calls phdr_callback on each dependent library
> via dl_iterate_phdr.
> 4) phdr_callback initializes elf_fileline_fn iff it found debug info in some
> library (found_dwarf == 1), but this is false since all libs are stripped.
> So, we still have uninitialized elf_fileline_fn value.
> 5) _asan_backtrace_initialize uses elf_fileline_fn to initialize proper
> fileline_fn callback.
> 6) Libbacktrace uses fileline_fn callback later and crashes because it
> contains garbage.
>
> This patch fixes the issue by simply initializing elf_fileline_fn via
> elf_nodebug in _asan_backtrace_initialize prologue.
>
> Tested on x86_64-linux-gnu and arm-linux-gnueabi, OK for trunk?

Thanks for the analysis.  I would rather set *fileline_fn in the case
where elf_add returns -1.  Or, remove the setting of *fileline_fn =
elf_nodebug in elf_add, since that would become the default.

Ian
diff mbox

Patch

libbacktrace/ChangeLog:

2016-03-02  Maxim Ostapenko  <m.ostapenko@partner.samsung.com>

	* elf.c (backtrace_initialize): Properly initialize elf_fileline_fn to
	avoid possible crash.

diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index 05cc5c0..c7168c6 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -925,7 +925,7 @@  backtrace_initialize (struct backtrace_state *state, int descriptor,
   int ret;
   int found_sym;
   int found_dwarf;
-  fileline elf_fileline_fn;
+  fileline elf_fileline_fn = elf_nodebug;
   struct phdr_data pd;
 
   ret = elf_add (state, descriptor, 0, error_callback, data, &elf_fileline_fn,