Bug 1392305

Summary: possible uninitialized data use in _elf_cook_shdr of cook.c in libelf
Product: Red Hat Enterprise Linux 7 Reporter: puzzor <puzzorsj>
Component: elfutilsAssignee: Mark Wielaard <mjw>
Status: CLOSED CANTFIX QA Contact: qe-baseos-tools-bugs
Severity: medium Docs Contact:
Priority: unspecified    
Version: 7.4CC: mbenitez, mjw
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2016-11-07 09:05:20 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Attachments:
Description Flags
poc and description none

Description puzzor 2016-11-07 07:21:23 UTC
Created attachment 1217877 [details]
poc and description

# Vulnerability
possible uninitialized data use in _elf_cook_shdr of cook.c in libelf

# Version
libelf 0.8.13

# SIGSEGV Output
Program received signal SIGSEGV, Segmentation fault.
0xb7fa763e in _elf_free_scns (elf=0xb5e02f80, scn=0xb60007b0) at end.c:48
48        tmp = sd->sd_link;
(gdb) bt
#0  0xb7fa763e in _elf_free_scns (elf=0xb5e02f80, scn=0xb60007b0) at end.c:48
#1  0xb7fa780a in elf_end (elf=0xb5e02f80) at end.c:107
#2  0x080e3b9b in main (argv=<optimized out>, argc=<optimized out>) at dwarfdump.c:660
(gdb) print sd
$1 = (Scn_Data *) 0x2ffffff
(gdb) print sd.sd_link
Cannot access memory at address 0x3000017


# PoC
See poc

# Analysis
In fact, this crash was detected under libdwarf20161021 version(https://www.prevanders.net/libdwarf-20161021.tar.gz). With this PoC, I can crash dwarfdump, at first I thought it was a bug in libdwarf, but after analysis, I considered the bug was in the libelf. The vulnerable function is _elf_cook_shdr in cook.c in libelf0.8.13. 
First, assume an Elf32_Ehdr struct has a 0 value of e_shnum.
At line 239, a struct is defined as "head".
At line 318, something interesting goes here, as the "num" is 0, "head" will be a value of malloc(0), but as the description in man page: "If size is 0, then malloc() returns either NULL, or a unique pointer value that can later be successfully passed to free()". 
Malloc may return a non-zero value, then the function will not return.
At line 456, the crafted value("&head[0].scn") will be passed to elf->e_scn_1,
if other function use this value, something unexcepted may occur.
In our case(libdwarf), this crafted value causes the final crash.
I think it is an uninitialized data deference.

# Report Timeline
2016.11.01: Shi Ji(@Puzzor) discovered this issue

# Credit
Shi Ji(@Puzzor) of VARAS@IIE

# Repro
compile the libdwarf20161021 with asan and run dwarfdump with ./dwarfdump poc

Comment 1 Mark Wielaard 2016-11-07 09:05:20 UTC
RHEL does not ship with libelf 0.8.13. It ships with elfutils-libelf-0.166-2.el7.
The code is completely different.