diff options
author | Mark Wielaard <mark@klomp.org> | 2019-02-01 14:03:38 +0100 |
---|---|---|
committer | Mark Wielaard <mark@klomp.org> | 2019-02-01 14:06:18 +0100 |
commit | e8f8dc465a1fa496aa627a330886c0f70f98d4c0 (patch) | |
tree | 6497369576303a187089b194bbcf9a1264b5eb21 | |
parent | cad9595592730fd8c9d0d9236d38f62ec8cfbcef (diff) | |
download | elfutils-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/ChangeLog | 6 | ||||
-rw-r--r-- | libdw/dwarf_nextcu.c | 17 |
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; |