diff options
| author | Mark Wielaard <[email protected]> | 2014-12-19 00:06:26 +0100 |
|---|---|---|
| committer | Mark Wielaard <[email protected]> | 2014-12-19 00:06:26 +0100 |
| commit | bd0434b61e0317718eb159fe7b5dc9ea870a0b79 (patch) | |
| tree | 825a373c2233a59b5156b219013e32f8f241aacc /libdw/dwarf_getpubnames.c | |
| parent | e18bf66ce8070f96195880e83a50c9d98006b832 (diff) | |
| parent | 898ed261444cdd817c2d9b3656209a291eb5e807 (diff) | |
Merge branch 'master' into portable
Diffstat (limited to 'libdw/dwarf_getpubnames.c')
| -rw-r--r-- | libdw/dwarf_getpubnames.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/libdw/dwarf_getpubnames.c b/libdw/dwarf_getpubnames.c index 12728a34..19f4eae1 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. */ @@ -123,7 +125,7 @@ get_offsets (Dwarf *dbg) readp += len; } - if (mem == NULL) + if (mem == NULL || cnt == 0) { __libdw_seterrno (DWARF_E_NO_ENTRY); return -1; @@ -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) { @@ -195,6 +199,8 @@ dwarf_getpubnames (dbg, callback, arg, offset) while (1) { /* READP points to the next offset/name pair. */ + if (readp + dbg->pubnames_sets[cnt].address_len > endp) + goto invalid_dwarf; if (dbg->pubnames_sets[cnt].address_len == 4) gl.die_offset = read_4ubyte_unaligned_inc (dbg, readp); else @@ -208,7 +214,14 @@ 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)) + { + invalid_dwarf: + __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) |
