summaryrefslogtreecommitdiffstats
path: root/libdw/dwarf_getpubnames.c
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2014-12-19 00:06:26 +0100
committerMark Wielaard <[email protected]>2014-12-19 00:06:26 +0100
commitbd0434b61e0317718eb159fe7b5dc9ea870a0b79 (patch)
tree825a373c2233a59b5156b219013e32f8f241aacc /libdw/dwarf_getpubnames.c
parente18bf66ce8070f96195880e83a50c9d98006b832 (diff)
parent898ed261444cdd817c2d9b3656209a291eb5e807 (diff)
Merge branch 'master' into portable
Diffstat (limited to 'libdw/dwarf_getpubnames.c')
-rw-r--r--libdw/dwarf_getpubnames.c21
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)