diff options
author | Alan Modra <amodra@gmail.com> | 2019-07-26 12:58:52 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2019-07-26 13:05:16 +0930 |
commit | 8e2e3c6c346c1c8142e714715e5a86b32f7e31ea (patch) | |
tree | f37c408660f255113544c75cda01fd0d8dc4580d /binutils/dwarf.c | |
parent | 6dd17ae0f9b0d9fc230e75ce345da9793498554d (diff) | |
download | gdb-8e2e3c6c346c1c8142e714715e5a86b32f7e31ea.zip gdb-8e2e3c6c346c1c8142e714715e5a86b32f7e31ea.tar.gz gdb-8e2e3c6c346c1c8142e714715e5a86b32f7e31ea.tar.bz2 |
PR24798, buffer overflow in process_cu_tu_index
PR 24798
* dwarf.c (process_cu_tu_index): Avoid integer overflow on 64-bit
systems by casting ncols and nslots expressions to size_t. Display
number of columns and slots before giving up due to buffer overflow.
Use %u to display unsigned ints. Perform more pointer wrap tests.
Diffstat (limited to 'binutils/dwarf.c')
-rw-r--r-- | binutils/dwarf.c | 53 |
1 files changed, 24 insertions, 29 deletions
diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 94c8a03..d633832 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -9314,33 +9314,29 @@ process_cu_tu_index (struct dwarf_section *section, int do_display) SAFE_BYTE_GET (nslots, phdr + 12, 4, limit); phash = phdr + 16; - pindex = phash + nslots * 8; - ppool = pindex + nslots * 4; - - /* PR 17531: file: 45d69832. */ - if (pindex < phash || ppool < phdr || (pindex == phash && nslots != 0)) - { - warn (ngettext ("Section %s is too small for %d slot\n", - "Section %s is too small for %d slots\n", - nslots), - section->name, nslots); - return 0; - } + pindex = phash + (size_t) nslots * 8; + ppool = pindex + (size_t) nslots * 4; if (do_display) { introduce (section, FALSE); - printf (_(" Version: %d\n"), version); + printf (_(" Version: %u\n"), version); if (version >= 2) - printf (_(" Number of columns: %d\n"), ncols); - printf (_(" Number of used entries: %d\n"), nused); - printf (_(" Number of slots: %d\n\n"), nslots); + printf (_(" Number of columns: %u\n"), ncols); + printf (_(" Number of used entries: %u\n"), nused); + printf (_(" Number of slots: %u\n\n"), nslots); } - if (ppool > limit || ppool < phdr) + /* PR 17531: file: 45d69832. */ + if ((size_t) nslots * 8 / 8 != nslots + || phash < phdr || phash > limit + || pindex < phash || pindex > limit + || ppool < pindex || ppool > limit) { - warn (_("Section %s too small for %d hash table entries\n"), + warn (ngettext ("Section %s is too small for %u slot\n", + "Section %s is too small for %u slots\n", + nslots), section->name, nslots); return 0; } @@ -9402,9 +9398,9 @@ process_cu_tu_index (struct dwarf_section *section, int do_display) unsigned int dw_sect; unsigned char *ph = phash; unsigned char *pi = pindex; - unsigned char *poffsets = ppool + ncols * 4; - unsigned char *psizes = poffsets + nused * ncols * 4; - unsigned char *pend = psizes + nused * ncols * 4; + unsigned char *poffsets = ppool + (size_t) ncols * 4; + unsigned char *psizes = poffsets + (size_t) nused * ncols * 4; + unsigned char *pend = psizes + (size_t) nused * ncols * 4; bfd_boolean is_tu_index; struct cu_tu_set *this_set = NULL; unsigned int row; @@ -9413,14 +9409,13 @@ process_cu_tu_index (struct dwarf_section *section, int do_display) is_tu_index = strcmp (section->name, ".debug_tu_index") == 0; /* PR 17531: file: 0dd159bf. - Check for wraparound with an overlarge ncols value. */ - if (poffsets < ppool || (unsigned int) ((poffsets - ppool) / 4) != ncols) - { - warn (_("Overlarge number of columns: %x\n"), ncols); - return 0; - } - - if (pend > limit) + Check for integer overflow (can occur when size_t is 32-bit) + with overlarge ncols or nused values. */ + if ((size_t) ncols * 4 / 4 != ncols + || (size_t) nused * ncols * 4 / ((size_t) ncols * 4) != nused + || poffsets < ppool || poffsets > limit + || psizes < poffsets || psizes > limit + || pend < psizes || pend > limit) { warn (_("Section %s too small for offset and size tables\n"), section->name); |