https://sourceware.org/bugzilla/show_bug.cgi?id=34934
Bug ID: 34934
Summary: libdw: out-of-bounds read in DWARF 5 location list
parsing with a wrapped block length
Product: elfutils
Version: unspecified
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: libdw
Assignee: unassigned at sourceware dot org
Reporter: vivekjha7424 at gmail dot com
CC: elfutils-devel at sourceware dot org
Target Milestone: ---
elfutils-0.197 (tag elfutils-0.197, commit 9f0a0fd0), built with
AddressSanitizer and UBSan, reports a heap-buffer-overflow read when
dwarf_getlocation_addr() is called on a crafted DWARF 5 .debug_loclists entry.
Where: __libdw_read_begin_end_pair_inc() reads the entry's code byte at
libdw/dwarf_ranges.c:270. It is called from getlocations_addr() at
libdw/dwarf_getlocation.c:858.
Cause: the block length of the entry is read as a ULEB128 at
libdw/dwarf_getlocation.c:889. The check at line 892 compares it as a signed
value, so a length of 2^63 or more passes. The read position is then advanced
by the unchecked addition at line 894, which wraps it below the start of the
section. The code byte at dwarf_ranges.c:270 is then read from memory before
the section data.
Reproduction (ASan, elfutils-0.197):
- Control, benign length: no report, dwarf_getlocation_addr() returns 0 or 1 as
expected.
- Entry with block length 2^64 - (77 + k), called with address 0x1000: READ of
size 1 at dwarf_ranges.c:270, located k bytes before the allocated section
image. Tested with k = 1, 2 and 8.
- The same entry with address -1: no report, returns -1.
Impact: an out-of-bounds read at an address derived from the input file. A
crash is the expected result. I have not shown information disclosure.
Scope: the reproduction covers the block-length route only. Two related routes
were found by reading the code and are not yet reproduced: a DWARF64 entry
using DW_FORM_loclistx (dwarf_getlocation.c:813-838), and the rnglistx read at
dwarf_ranges.c:447-543. Neither checks the lower bound.
Current main: dwarf_ranges.c and dwarf_getlocation.c are unchanged between
elfutils-0.197 and origin/main (656c58e1), so the defect is present there too.
Suggested fix: reject a block length larger than the bytes remaining before the
position update at dwarf_getlocation.c:894, and check the lower bound before
reads at dwarf_ranges.c lines 160 and 267.
--
You are receiving this mail because:
You are on the CC list for the bug.