diff options
author | Nick Clifton <nickc@redhat.com> | 2017-02-13 14:52:48 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2017-02-13 14:52:48 +0000 |
commit | ebdf1ebfa551fd4624c3cd05401aa3c01ea2ebbe (patch) | |
tree | 87e2c413c7e1b3bfec0146c82309662ca8a16a66 /binutils | |
parent | 4aeb00ad3cc6a29b32f0a4e42c2f64d55e25b76d (diff) | |
download | gdb-ebdf1ebfa551fd4624c3cd05401aa3c01ea2ebbe.zip gdb-ebdf1ebfa551fd4624c3cd05401aa3c01ea2ebbe.tar.gz gdb-ebdf1ebfa551fd4624c3cd05401aa3c01ea2ebbe.tar.bz2 |
Fix invalid memory access attempting to read the compression header of a too-small compressed section.
PR binutils/21149
* readelf.c (get_compression_header): Add size parameter. Check
size against sizeof compression header before attempting to
extract the header.
(process_section_headers): Pass size to get_compression_header.
(dump_section_as_strings): Likewise.
(dump_section_as_bytes): Likewise.
(load_specific_debug_section): Likewise.
Diffstat (limited to 'binutils')
-rw-r--r-- | binutils/ChangeLog | 11 | ||||
-rw-r--r-- | binutils/readelf.c | 23 |
2 files changed, 29 insertions, 5 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index ebaedcc..10140c2 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,5 +1,16 @@ 2017-02-13 Nick Clifton <nickc@redhat.com> + PR binutils/21149 + * readelf.c (get_compression_header): Add size parameter. Check + size against sizeof compression header before attempting to + extract the header. + (process_section_headers): Pass size to get_compression_header. + (dump_section_as_strings): Likewise. + (dump_section_as_bytes): Likewise. + (load_specific_debug_section): Likewise. + +2017-02-13 Nick Clifton <nickc@redhat.com> + PR binutils/21148 * readelf.c (process_version_sections): Include size of auxillary version information when checking for buffer overflow. diff --git a/binutils/readelf.c b/binutils/readelf.c index a61befe..e6f48b4 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -5715,12 +5715,18 @@ get_elf_section_flags (bfd_vma sh_flags) } static unsigned int -get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf) +get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size) { if (is_32bit_elf) { Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf; + if (size < sizeof (* echdr)) + { + error (_("Compressed section is too small even for a compression header\n")); + return 0; + } + chdr->ch_type = BYTE_GET (echdr->ch_type); chdr->ch_size = BYTE_GET (echdr->ch_size); chdr->ch_addralign = BYTE_GET (echdr->ch_addralign); @@ -5730,6 +5736,12 @@ get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf) { Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf; + if (size < sizeof (* echdr)) + { + error (_("Compressed section is too small even for a compression header\n")); + return 0; + } + chdr->ch_type = BYTE_GET (echdr->ch_type); chdr->ch_size = BYTE_GET (echdr->ch_size); chdr->ch_addralign = BYTE_GET (echdr->ch_addralign); @@ -6311,7 +6323,7 @@ process_section_headers (FILE * file) { Elf_Internal_Chdr chdr; - (void) get_compression_header (&chdr, buf); + (void) get_compression_header (&chdr, buf, sizeof (buf)); if (chdr.ch_type == ELFCOMPRESS_ZLIB) printf (" ZLIB, "); @@ -12643,7 +12655,8 @@ dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file) { Elf_Internal_Chdr chdr; unsigned int compression_header_size - = get_compression_header (& chdr, (unsigned char *) start); + = get_compression_header (& chdr, (unsigned char *) start, + num_bytes); if (chdr.ch_type != ELFCOMPRESS_ZLIB) { @@ -12777,7 +12790,7 @@ dump_section_as_bytes (Elf_Internal_Shdr * section, { Elf_Internal_Chdr chdr; unsigned int compression_header_size - = get_compression_header (& chdr, start); + = get_compression_header (& chdr, start, section_size); if (chdr.ch_type != ELFCOMPRESS_ZLIB) { @@ -12930,7 +12943,7 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, return 0; } - compression_header_size = get_compression_header (&chdr, start); + compression_header_size = get_compression_header (&chdr, start, size); if (chdr.ch_type != ELFCOMPRESS_ZLIB) { |