Bug 1316695 - libdwarf not checking whether error is null before attempting to use it for dwarf_srcfiles
libdwarf not checking whether error is null before attempting to use it for d...
Product: Fedora
Classification: Fedora
Component: libdwarf (Show other bugs)
Unspecified Unspecified
unspecified Severity unspecified
: ---
: ---
Assigned To: Tom Hughes
Fedora Extras Quality Assurance
Depends On:
  Show dependency treegraph
Reported: 2016-03-10 14:52 EST by William Cohen
Modified: 2016-05-12 12:13 EDT (History)
2 users (show)

See Also:
Fixed In Version: libdwarf-20160507-1.fc24
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2016-05-12 12:13:57 EDT
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)

  None (edit)
Description William Cohen 2016-03-10 14:52:01 EST
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):


How reproducible:


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)
  return 0;
4. gcc -g -o hello test.c
5. stap -p4 -m crasher --dyninst -e 'probe process("hello").function("main@test.c: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
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)]
[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:
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 14:57:53 EST
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 15:54:17 EST
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 16:02:19 EST
It looks like commit 4130f07d257d3188c8616591271f2e68bb6bfde3 adds the problem code

Author: David Anderson <davea42@earthlink.net>  2015-10-15 12:27:28
Committer: David Anderson <davea42@earthlink.net>  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.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
         * globals.h: Added the enum line_flag_e variable for
           recording -x line5= value.
         * 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.
         * 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
           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
Comment 4 Tom Hughes 2016-03-10 16:15:30 EST
Thanks - I've reported all that to upstream.
Comment 5 Fedora Update System 2016-05-08 06:27:37 EDT
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-08 20:55:11 EDT
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 12:13:18 EDT
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.