From 3864804113e31e8372cee725aab84047c790e76d Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Mon, 15 Dec 2014 14:56:07 +0100 Subject: [PATCH] libdw: Add bounds checking to dwarf_getpubnames. Signed-off-by: Mark Wielaard --- libdw/ChangeLog | 7 +++++++ libdw/dwarf_getpubnames.c | 16 +++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/libdw/ChangeLog b/libdw/ChangeLog index b1fb582b3..068d45212 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,10 @@ +2014-12-15 Mark Wielaard + + * dwarf_getpubnames.c (get_offsets): Make sure whole unit fall inside + section data. + (dwarf_getpubnames): Make sure section data contains string zero + terminator. + 2014-12-16 Mark Wielaard * memory-access.h (__libdw_get_sleb128): Unroll the first step to help diff --git a/libdw/dwarf_getpubnames.c b/libdw/dwarf_getpubnames.c index 12728a343..c8b9f9f6c 100644 --- a/libdw/dwarf_getpubnames.c +++ b/libdw/dwarf_getpubnames.c @@ -88,9 +88,11 @@ get_offsets (Dwarf *dbg) /* Now we know the offset of the first offset/name pair. */ mem[cnt].set_start = readp + 2 + 2 * len_bytes - startp; mem[cnt].address_len = len_bytes; - if (mem[cnt].set_start >= dbg->sectiondata[IDX_debug_pubnames]->d_size) + size_t max_size = dbg->sectiondata[IDX_debug_pubnames]->d_size; + if (mem[cnt].set_start >= max_size + || len - (2 + 2 * len_bytes) > max_size - mem[cnt].set_start) /* Something wrong, the first entry is beyond the end of - the section. */ + the section. Or the length of the whole unit is too big. */ break; /* Read the version. It better be two for now. */ @@ -184,6 +186,8 @@ dwarf_getpubnames (dbg, callback, arg, offset) unsigned char *startp = (unsigned char *) dbg->sectiondata[IDX_debug_pubnames]->d_buf; + unsigned char *endp + = startp + dbg->sectiondata[IDX_debug_pubnames]->d_size; unsigned char *readp = startp + offset; while (1) { @@ -208,7 +212,13 @@ dwarf_getpubnames (dbg, callback, arg, offset) gl.die_offset += dbg->pubnames_sets[cnt].cu_offset; gl.name = (char *) readp; - readp = (unsigned char *) rawmemchr (gl.name, '\0') + 1; + readp = (unsigned char *) memchr (gl.name, '\0', endp - readp); + if (unlikely (readp == NULL)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1l; + } + readp++; /* We found name and DIE offset. Report it. */ if (callback (dbg, &gl, arg) != DWARF_CB_OK) -- 2.47.3