bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug binutils/23531] New: crash accessing address 0 in readelf (binutils


From: l.simon at samsung dot com
Subject: [Bug binutils/23531] New: crash accessing address 0 in readelf (binutils-2.2.7a)
Date: Wed, 15 Aug 2018 11:30:04 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=23531

            Bug ID: 23531
           Summary: crash accessing address 0 in readelf (binutils-2.2.7a)
           Product: binutils
           Version: unspecified
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: binutils
          Assignee: unassigned at sourceware dot org
          Reporter: l.simon at samsung dot com
  Target Milestone: ---

Created attachment 11187
  --> https://sourceware.org/bugzilla/attachment.cgi?id=11187&action=edit
input to reproduce the crash

Hi

I've come across an issue in readelf (binutils-2.2.7a), as follows:


Problem: 
-------
"readelf -a input" crashes trying to access uninitialised memory (0) if given
the file attached.

Reproduce:
---------
        $ CFLAGS="-g -fsanitize=address" CC=clang ../configure --disable-shared
--disable-nls --disable-werror --disable-gdb --disable-libdecnumber
--disable-readline --disable-sim
        $ ASAN_SYMBOLIZER_PATH=`which llvm-symbolizer` ./build/binutils/readelf
-a input

        ==30209==ERROR: AddressSanitizer: SEGV on unknown address
0x000000000000 (pc 0x00000055c484 sp 0x7ffc692c6520 bp 0x7ffc692c6c50 T0)
    #0 0x55c483 in dump_hppa_unwind
/path/binutils-2.2.7a.asan/build/binutils/../../binutils/readelf.c:7849
    #1 0x553415 in hppa_process_unwind
/path/binutils-2.2.7a.asan/build/binutils/../../binutils/readelf.c:8129
    #2 0x4b29f7 in process_unwind
/path/binutils-2.2.7a.asan/build/binutils/../../binutils/readelf.c:9262
    #3 0x48c2d8 in process_object
/path/binutils-2.2.7a.asan/build/binutils/../../binutils/readelf.c:18751
    #4 0x487870 in process_file
/path/binutils-2.2.7a.asan/build/binutils/../../binutils/readelf.c:19188
    #5 0x485916 in main
/path/binutils-2.2.7a.asan/build/binutils/../../binutils/readelf.c:19247
    #6 0x7f95f0d03f44 (/lib/x86_64-linux-gnu/libc.so.6+0x21f44)
    #7 0x47e01c in _start
(/path/binutils-2.2.7a.asan/build/binutils/readelf+0x47e01c)


Details:
-------
in file readelf.c, function hppa_process_unwind():

        if (! slurp_hppa_unwind_table (filedata, &aux, sec))
            res = FALSE;

          if (aux.table_len > 0)
            {
              if (! dump_hppa_unwind (filedata, &aux))
                res = FALSE;
            }
            [...]


Even if the function slurp_hppa_unwind_table() fails, the function
dump_hppa_unwind() is executed. In dump_hppa_unwind():

        for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
    {
      bfd_vma offset;
      const char * procname;
      find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
                               aux->strtab_size, tp->start, &procname,
                               &offset);
          [...]

Because slurp_hppa_unwind_table() failed, aux->table_len may be non-zero but
aux->table
is still 0. So tp is NULL and the program tries to access address 0x0.

I don't think this is exploitable because 0 is not controllable by user input:
it's the value
set in function hppa_process_unwind() thru: 

        memset (& aux, 0, sizeof (aux));

Suggested fix:
----
Change:

        if ( aux.table_len > 0)

to:

        if ( res && aux.table_len > 0)

Note: I reported this bug by email, and Nick Clifton <address@hidden>
suggested the following fix:

diff --git a/binutils/readelf.c b/binutils/readelf.c
index 90dbdf7e2b..34acf6346a 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -7934,6 +7934,8 @@ slurp_hppa_unwind_table (Filedata *                 
filedata,
   Elf_Internal_Sym * sym;
   const char * relname;

+  aux->table_len = 0;
+
   /* First, find the starting address of the segment that includes
      this section.  */
   if (filedata->file_header.e_phnum)

However I don't think this fixes the problem, because:
1. The code I'm using already has the suggested fix
2. The length is updated in slurp_hppa_unwind_table(), but the function returns
FALSE before aux->table is populated with the corresponding entries. That's
where the mismatch comes from. 

So the loop "for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)" is
executed because the "aux->table_len" is non-zero. But aux->table is 0.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]