diff options
author | Alan Modra <amodra@gmail.com> | 2017-10-17 16:43:47 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2017-10-17 16:47:44 +1030 |
commit | 0301ce1486b1450f219202677f30d0fa97335419 (patch) | |
tree | 7bb39c6316333bafe33c8d97857c0beba657ae54 /bfd/aoutx.h | |
parent | e6e2dfbdc1e0df3844401f7a8be64e98823a7846 (diff) | |
download | gdb-0301ce1486b1450f219202677f30d0fa97335419.zip gdb-0301ce1486b1450f219202677f30d0fa97335419.tar.gz gdb-0301ce1486b1450f219202677f30d0fa97335419.tar.bz2 |
PR22306, Invalid free() in slurp_symtab()
PR 22306
* aoutx.h (aout_get_external_symbols): Handle stringsize of zero,
and error for any other size that doesn't cover the header word.
Diffstat (limited to 'bfd/aoutx.h')
-rw-r--r-- | bfd/aoutx.h | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/bfd/aoutx.h b/bfd/aoutx.h index 3d38fda..d096ed5 100644 --- a/bfd/aoutx.h +++ b/bfd/aoutx.h @@ -1351,27 +1351,42 @@ aout_get_external_symbols (bfd *abfd) || bfd_bread ((void *) string_chars, amt, abfd) != amt) return FALSE; stringsize = GET_WORD (abfd, string_chars); + if (stringsize == 0) + stringsize = 1; + else if (stringsize < BYTES_IN_WORD + || (size_t) stringsize != stringsize) + { + bfd_set_error (bfd_error_bad_value); + return FALSE; + } #ifdef USE_MMAP - if (! bfd_get_file_window (abfd, obj_str_filepos (abfd), stringsize, - &obj_aout_string_window (abfd), TRUE)) - return FALSE; - strings = (char *) obj_aout_string_window (abfd).data; -#else - strings = (char *) bfd_malloc (stringsize + 1); - if (strings == NULL) - return FALSE; - - /* Skip space for the string count in the buffer for convenience - when using indexes. */ - amt = stringsize - BYTES_IN_WORD; - if (bfd_bread (strings + BYTES_IN_WORD, amt, abfd) != amt) + if (stringsize >= BYTES_IN_WORD) { - free (strings); - return FALSE; + if (! bfd_get_file_window (abfd, obj_str_filepos (abfd), stringsize, + &obj_aout_string_window (abfd), TRUE)) + return FALSE; + strings = (char *) obj_aout_string_window (abfd).data; } + else #endif + { + strings = (char *) bfd_malloc (stringsize); + if (strings == NULL) + return FALSE; + if (stringsize >= BYTES_IN_WORD) + { + /* Keep the string count in the buffer for convenience + when indexing with e_strx. */ + amt = stringsize - BYTES_IN_WORD; + if (bfd_bread (strings + BYTES_IN_WORD, amt, abfd) != amt) + { + free (strings); + return FALSE; + } + } + } /* Ensure that a zero index yields an empty string. */ strings[0] = '\0'; |