Bug 1316695 - libdwarf not checking whether error is null before attempting to use it for dwarf_srcfiles
Summary: libdwarf not checking whether error is null before attempting to use it for d...
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Fedora
Classification: Fedora
Component: libdwarf
Version: rawhide
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Tom Hughes
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2016-03-10 19:52 UTC by William Cohen
Modified: 2016-05-12 16:13 UTC (History)
2 users (show)

Fixed In Version: libdwarf-20160507-1.fc24
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2016-05-12 16:13:57 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description William Cohen 2016-03-10 19:52:01 UTC
Description of problem:  The dyninst library make a call to dwarf_src with error argument being NULL and libdwarf tries to use it anyway.


Version-Release number of selected component (if applicable):

libdwarf-20160115-2.fc24.x86_64
dyninst-9.1.0-4.fc25.x86_64
systemtap-3.0-0.20160208git40ae3a7.fc24.x86_64


How reproducible:

Always

Steps to Reproduce:
1. yum install "systemtap*" "dyninst*"
2. debuginfo-install dyninst
3. create test.c with:
#include <stdio.h>

int main(int argc, char **argv)
{
  printf("hello\n");
  return 0;
}
4. gcc -g -o hello test.c
5. stap -p4 -m crasher --dyninst -e 'probe process("hello").function("main:3") {log("hit")}' -c ./hello
6. gdb /usr/bin/stapdyn
7. run crasher.so -c ./hello


Actual results:


Starting program: /usr/bin/stapdyn crasher.so -c ./hello
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[New Thread 0x7ffff376c700 (LWP 6316)]
[New Thread 0x7ffff2d61700 (LWP 6317)]
[New Thread 0x7ffff2357700 (LWP 6318)]
Detaching after fork from child process 6319.

Thread 1 "stapdyn" received signal SIGSEGV, Segmentation fault.
dwarf_formstring (attr=0x55555634cb10, return_str=return_str@entry=0x7fffffffd450, error=error@entry=0x0)
    at dwarf_form.c:1183
1183	        if (dwarf_errno(*error) == DW_DLE_NO_TIED_FILE_AVAILABLE) {


Expected results:

The code should print out "hello" and "hit" and then exit without error
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
hello
Starting program: /usr/bin/stapdyn crasher.so -c ./hello
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[New Thread 0x7ffff376c700 (LWP 6332)]
[New Thread 0x7ffff2d61700 (LWP 6333)]
[New Thread 0x7ffff2357700 (LWP 6334)]
Detaching after fork from child process 6335.
[New Thread 0x7fffebfff700 (LWP 6336)]
hello
hit
[Thread 0x7fffebfff700 (LWP 6336) exited]
[Thread 0x7ffff376c700 (LWP 6332) exited]
...



Additional info:

Removing the dyninst-debuginfo rpm allows things to run successfully.

According to /usr/share/doc/libdwarf-devel/libdwarf2.1.pdf there should be  check of error before it is used:

The following lists the processing steps taken upon detection of an error:
1.
Check the error argument; if not a NULL pointer, allocate and initialize a Dwarf_Error
descriptor with information describing the error, place this descriptor in the area pointed to by
error, and return a value indicating an error condition.


Traceback of how it got to the problem code:

(gdb) where
#0  dwarf_formstring (attr=0x555556372a70, return_str=return_str@entry=0x7fffffffd450, error=error@entry=0x0)
    at dwarf_form.c:1183
#1  0x00007ffff3dc41e2 in _dwarf_internal_get_die_comp_dir (die=die@entry=0x5555563729f0, 
    compdir_out=compdir_out@entry=0x7fffffffd4e8, compname_out=compname_out@entry=0x7fffffffd4e0, error=error@entry=0x0)
    at dwarf_util.c:118
#2  0x00007ffff3dbb174 in dwarf_srcfiles (die=die@entry=0x5555563729f0, srcfiles=srcfiles@entry=0x7fffffffd568, 
    srcfilecount=srcfilecount@entry=0x7fffffffd560, error=error@entry=0x0) at ./dwarf_line.c:369
#3  0x00007ffff732b037 in Dyninst::SymtabAPI::DwarfWalker::buildSrcFiles (this=this@entry=0x7fffffffd800, 
    entry=0x5555563729f0) at /usr/src/debug/dyninst-9.1.0/DyninstAPI-9.1.0/symtabAPI/src/dwarfWalker.C:253
#4  0x00007ffff732e3b4 in Dyninst::SymtabAPI::DwarfWalker::parseModule (this=this@entry=0x7fffffffd800, 
    is_info=is_info@entry=1, fixUnknownMod=@0x7fffffffd788: 0x5555558e1ef0)
    at /usr/src/debug/dyninst-9.1.0/DyninstAPI-9.1.0/symtabAPI/src/dwarfWalker.C:237
#5  0x00007ffff732e7be in Dyninst::SymtabAPI::DwarfWalker::parse (this=this@entry=0x7fffffffd800)
    at /usr/src/debug/dyninst-9.1.0/DyninstAPI-9.1.0/symtabAPI/src/dwarfWalker.C:135
#6  0x00007ffff72e2471 in Dyninst::SymtabAPI::Object::parseTypeInfo (this=<optimized out>, obj=obj@entry=0x5555558ac520)
    at /usr/src/debug/dyninst-9.1.0/DyninstAPI-9.1.0/symtabAPI/src/Object-elf.C:5189
#7  0x00007ffff72a1596 in Dyninst::SymtabAPI::Symtab::parseTypes (this=0x5555558ac520)
    at /usr/src/debug/dyninst-9.1.0/DyninstAPI-9.1.0/symtabAPI/src/Symtab.C:2435
#8  0x00007ffff75f379c in BPatch_module::parseTypesIfNecessary (this=0x55555647fb90)
    at /usr/src/debug/dyninst-9.1.0/DyninstAPI-9.1.0/dyninstAPI/src/BPatch_module.C:260
#9  0x00007ffff75d4719 in BPatch_function::constructVarsAndParams (this=this@entry=0x555556478af0)
    at /usr/src/debug/dyninst-9.1.0/DyninstAPI-9.1.0/dyninstAPI/src/BPatch_function.C:792
#10 0x00007ffff75d4aa9 in BPatch_function::getReturnType (this=this@entry=0x555556478af0)
    at /usr/src/debug/dyninst-9.1.0/DyninstAPI-9.1.0/dyninstAPI/src/BPatch_function.C:354
#11 0x00007ffff75e0d77 in BPatch_funcCallExpr::BPatch_funcCallExpr (this=0x7fffffffdc50, func=..., args=...)
    at /usr/src/debug/dyninst-9.1.0/DyninstAPI-9.1.0/dyninstAPI/src/BPatch_snippet.C:819
#12 0x00007ffff75e9fab in BPatch_process::loadLibrary (this=0x5555557c9530, libname=0x5555557c9ab0 "/home/wcohen/crasher.so")
    at /usr/src/debug/dyninst-9.1.0/DyninstAPI-9.1.0/dyninstAPI/src/BPatch_process.C:1041
#13 0x0000555555563cde in mutatee::load_stap_dso(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
#14 0x0000555555562445 in mutator::create_process(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
#15 0x000055555555b732 in main ()

Comment 1 Tom Hughes 2016-03-10 19:57:53 UTC
Have you reported this upstream? There is only one patch applied to the rpm so any bug is almost certainly an upstream issue.

Comment 2 William Cohen 2016-03-10 20:54:17 UTC
The problem was observed in the rawhide version, so it was reported for rawhide.  The issue has not yet been reported upstream.

Comment 3 William Cohen 2016-03-10 21:02:19 UTC
It looks like commit 4130f07d257d3188c8616591271f2e68bb6bfde3 adds the problem code

Author: David Anderson <davea42>  2015-10-15 12:27:28
Committer: David Anderson <davea42>  2015-10-15 12:27:28
Parent: 44bb9d15b163afd4857e99e90b4538e0517f0214 (checkexamples.c.)
Child:  ecf8ab4f520063517e9e8d127477362e6f5058aa (*  print_die.c: Added DW_FORM_strp_sup,)
Branches: master, remotes/origin/carlos_enciso, remotes/origin/master
Follows: 20150915
Precedes: 20151114

    dwarfdump
         * dwarfdump.c: Add enum line_flag_type_e so we can test
           all the srclines interfaces (4 of them). Expand -x
           for that too.
         * print_die.c: Support DW_FORM_GNU_strp_alt.
         * print_lines.c: Update for old and new srclines
           interfaces.
         * globals.h: Added the enum line_flag_e variable for
           recording -x line5= value.
    
    libdwarf
         * checkexamples.c: Fixed data type in the example code.
         * dwarf.h: Updated comment about DW_FORM_GNU_strp_alt
         * dwarf_elf_access.c: Fixed trailing whitespace and
           removed debug printf that got left in.
         * dwarf_error.c: Add new TIED file errors.
           DW_DLE_NO_TIED_FILE_AVAILABLE, DW_DLE_NO_TIED_STRING_AVAILABLE.
         * dwarf_form.c: Added support for DW_FORM_GNU_strp_alt.
         * dwarf_init_finish.c: #if 0 routine all_sig8bits_zero().
        * dwarf_line.c: Now always notice windows-like c: etc
           as start of a full path. Ensure directories with \ are
           turned to / in line tables. (for full such transforms
           configure with --enable-windowspath ) Remove some debug #ifdef
           lines.
           Alter the linecontext interface to pass back table count,
           not linecount.
        * dwarf_line.h: Add commentary and lc_table_count field.
         * dwarf_line_table_reader_common.c: Fix indent/trailing whitespace.
           Now sets lc_table_count;
         * dwarf_opaque.h: Add _dwarf_get_string_from_tied() interface.
         * dwarf_print_lines.c: Remove trailing whitespace and some debug printf..
         * libdwarf.h.in: New error codes. Fix trailing whitespace. Expand
           commentary.

Comment 4 Tom Hughes 2016-03-10 21:15:30 UTC
Thanks - I've reported all that to upstream.

Comment 5 Fedora Update System 2016-05-08 10:27:37 UTC
libdwarf-20160507-1.fc24 has been submitted as an update to Fedora 24. https://bodhi.fedoraproject.org/updates/FEDORA-2016-f36c5935e5

Comment 6 Fedora Update System 2016-05-09 00:55:11 UTC
libdwarf-20160507-1.fc24 has been pushed to the Fedora 24 testing repository. If problems still persist, please make note of it in this bug report.
See https://fedoraproject.org/wiki/QA:Updates_Testing for
instructions on how to install test updates.
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2016-f36c5935e5

Comment 7 Fedora Update System 2016-05-12 16:13:18 UTC
libdwarf-20160507-1.fc24 has been pushed to the Fedora 24 stable repository. If problems still persist, please make note of it in this bug report.


Note You need to log in before you can comment on or make changes to this bug.