summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2019-02-01 14:03:38 +0100
committerMark Wielaard <mark@klomp.org>2019-02-01 14:06:18 +0100
commite8f8dc465a1fa496aa627a330886c0f70f98d4c0 (patch)
tree6497369576303a187089b194bbcf9a1264b5eb21
parentcad9595592730fd8c9d0d9236d38f62ec8cfbcef (diff)
downloadelfutils-e8f8dc465a1fa496aa627a330886c0f70f98d4c0.tar.gz
libdw: Check there is enough space for CU 64bit length, version and type.
We only checked we could read the initial length and after knowing the version and type whether the unit header was the right size. Also check there are at least enough bytes to read the 64bit length, version and unit type bytes. https://sourceware.org/bugzilla/show_bug.cgi?id=24140 Signed-off-by: Mark Wielaard <mark@klomp.org>
-rw-r--r--libdw/ChangeLog6
-rw-r--r--libdw/dwarf_nextcu.c17
2 files changed, 20 insertions, 3 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index ff3880df..aaa62960 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,9 @@
+2019-02-02 Mark Wielaard <mark@klomp.org>
+
+ * dwarf_nextcu.c (__libdw_next_unit): Define bytes_end.
+ Check there are enough bytes to read extended lenght, version
+ and unit.
+
2019-01-20 Mark Wielaard <mark@klomp.org>
* dwarf_getsrclines.c (read_srclines): Check terminating NUL byte
diff --git a/libdw/dwarf_nextcu.c b/libdw/dwarf_nextcu.c
index be113270..67cec449 100644
--- a/libdw/dwarf_nextcu.c
+++ b/libdw/dwarf_nextcu.c
@@ -85,6 +85,7 @@ __libdw_next_unit (Dwarf *dwarf, bool v4_debug_types, Dwarf_Off off,
beginning of the CU entry. */
const unsigned char *data = dwarf->sectiondata[sec_idx]->d_buf;
const unsigned char *bytes = data + off;
+ const unsigned char *bytes_end = data + dwarf->sectiondata[sec_idx]->d_size;
/* The format of the CU header is described in dwarf2p1 7.5.1 and
changed in DWARFv5 (to include unit type, switch location of some
@@ -164,17 +165,27 @@ __libdw_next_unit (Dwarf *dwarf, bool v4_debug_types, Dwarf_Off off,
}
if (length == DWARF3_LENGTH_64_BIT)
- /* This is a 64-bit DWARF format. */
- length = read_8ubyte_unaligned_inc (dwarf, bytes);
+ {
+ /* This is a 64-bit DWARF format. */
+ if (bytes_end - bytes < 8)
+ goto invalid;
+ length = read_8ubyte_unaligned_inc (dwarf, bytes);
+ }
/* Read the version stamp. Always a 16-bit value. */
+ if (bytes_end - bytes < 2)
+ goto invalid;
uint_fast16_t version = read_2ubyte_unaligned_inc (dwarf, bytes);
/* We keep unit_type at zero for older DWARF since we cannot
easily guess whether it is a compile or partial unit. */
uint8_t unit_type = 0;
if (version >= 5)
- unit_type = *bytes++;
+ {
+ if (bytes_end - bytes < 1)
+ goto invalid;
+ unit_type = *bytes++;
+ }
/* All these are optional. */
Dwarf_Off subdie_off = 0;