-
Notifications
You must be signed in to change notification settings - Fork 367
Description
Description
bloaty crashes with a stack overflow (AddressSanitizer: stack-overflow) when running with -d compileunits on binaries where a .dwo file refers to itself via the DW_AT_GNU_dwo_name attribute. This causes infinite recursion in ReadDWARFDebugInfo and ReadDWARFCompileUnits.
Reproduction Steps
-
Build
bloatywith ASAN enabled:cmake -B build/main -G Ninja -S . \ -DCMAKE_BUILD_TYPE=Debug \ -DBLOATY_ENABLE_ASAN=ON cmake --build build/main -
Run against a binary with recursive DWO references (e.g., Chrome debug build):
cd /path/to/chrome-build /path/to/bloaty/build/main/bloaty -d compileunits ./chrome
Analysis
ASAN Output
The application crashes with a stack overflow.
AddressSanitizer:DEADLYSIGNAL
=================================================================
==3401789==ERROR: AddressSanitizer: stack-overflow on address 0x7bf03b3ffff8 (pc 0x7ff03fc3e888 bp 0x000000000000 sp 0x7bf03b3ffff0 T1)
Thread T1 created by T0 here:
#0 0x7ff03fd11612 in pthread_create ../../../../src/libsanitizer/asan/asan_interceptors.cpp:250
#1 0x7ff03f8e6e38 in std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) (/lib/x86_64-linux-gnu/libstdc++.so.6+0xe6e38)
#2 0x55743569d987 in bloaty::Bloaty::ScanAndRollupFiles(...) src/bloaty.cc:1926
...
GDB Backtrace
Running under GDB confirms infinite recursion between ReadDWARFCompileUnits and ReadDWARFDebugInfo.
Command used:
gdb -batch -ex "run" -ex "bt 20" --args /path/to/bloaty/build/main/bloaty -d compileunits ./chromeOutput:
#12 0x000055555668a9b0 in bloaty::dwarf::CU::ReadHeader (...) at src/dwarf/debug_info.cc:175
#13 0x00005555566898e3 in bloaty::dwarf::CUIter::NextCU (...) at src/dwarf/debug_info.cc:121
#14 0x0000555556508446 in bloaty::ReadDWARFDebugInfo (...) at src/dwarf.cc:643
#15 0x0000555556508b20 in bloaty::ReadDWARFCompileUnits (...) at src/dwarf.cc:722
#16 0x0000555556507ceb in bloaty::ReadDWARFDebugInfo (...) at src/dwarf.cc:674
#17 0x0000555556508b20 in bloaty::ReadDWARFCompileUnits (...) at src/dwarf.cc:722
#18 0x0000555556507ceb in bloaty::ReadDWARFDebugInfo (...) at src/dwarf.cc:674
#19 0x0000555556508b20 in bloaty::ReadDWARFCompileUnits (...) at src/dwarf.cc:722
...
Identifying the Offending File
To determine which file caused the recursion, I temporarily instrumented src/dwarf.cc to print the DWO path before recursing:
std::string dwo_path = ConstructDwoPath(dwo_info);
if (!dwo_path.empty()) {
fprintf(stderr, "Processing DWO: %s\n", dwo_path.c_str()); // Added this line
auto file = MmapInputFileFactory().OpenFile(dwo_path);Re-running bloaty produced the following output immediately before the stack overflow:
Processing DWO: obj/chrome/chrome_initial/chrome_exe_main_aura.dwo
Processing DWO: obj/chrome/chrome_initial/chrome_exe_main_aura.dwo
Processing DWO: obj/chrome/chrome_initial/chrome_exe_main_aura.dwo
...
Binary Analysis
Inspecting obj/chrome/chrome_initial/chrome_exe_main_aura.dwo with readelf confirmed the self-reference:
$ readelf -wi chrome-build/obj/chrome/chrome_initial/chrome_exe_main_aura.dwo | grep dwo_name
<10> DW_AT_GNU_dwo_name: (indexed string: 0x7): obj/chrome/chrome_initial/chrome_exe_main_aura.dwoBecause the DWO name points to the file itself, Bloaty recursively attempts to parse it indefinitely.
Affected Code
The issue lies in src/dwarf.cc where dwo_path is processed without checking if it has already been visited or if it refers to the current file.
// src/dwarf.cc
std::string dwo_path = ConstructDwoPath(dwo_info);
if (!dwo_path.empty()) {
auto file = MmapInputFileFactory().OpenFile(dwo_path);
dwarf::File dwo_dwarf;
cu.dwarf().open(*file, &dwo_dwarf, sink);
// RECURSION HAPPENS HERE
ReadDWARFCompileUnits(dwo_dwarf, symbol_map, &cu, sink);
}Minimal Reproduction
A minimal reproduction can be created using yaml2obj.
-
Create
recursive.yaml:--- !ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_DYN Machine: EM_X86_64 Sections: - Name: .text Type: SHT_PROGBITS Flags: [ SHF_ALLOC, SHF_EXECINSTR ] Address: 0x400000 AddressAlign: 0x10 Size: 0x100 DWARF: debug_str: - recursive.o - "." debug_abbrev: - ID: 0 Table: - Code: 0x1 Tag: DW_TAG_compile_unit Children: DW_CHILDREN_no Attributes: - Attribute: DW_AT_GNU_dwo_name Form: DW_FORM_strp - Attribute: DW_AT_comp_dir Form: DW_FORM_strp debug_info: - Version: 4 AbbrevTableID: 0 AbbrOffset: 0x0 AddrSize: 8 Entries: - AbbrCode: 0x1 Values: - Value: 0x0 # points to "recursive.o" - Value: 0xc # points to "."
-
Generate the object file:
yaml2obj recursive.yaml -o recursive.o
-
Run Bloaty:
./bloaty -d compileunits recursive.o
This will trigger the stack overflow.