aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2017-02-13 14:52:48 +0000
committerNick Clifton <nickc@redhat.com>2017-02-13 14:52:48 +0000
commitebdf1ebfa551fd4624c3cd05401aa3c01ea2ebbe (patch)
tree87e2c413c7e1b3bfec0146c82309662ca8a16a66 /binutils
parent4aeb00ad3cc6a29b32f0a4e42c2f64d55e25b76d (diff)
downloadgdb-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/ChangeLog11
-rw-r--r--binutils/readelf.c23
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)
{