From 7e56c51c7932cfdb178e9457011d09d53e98937b Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Fri, 28 Jun 2019 15:30:43 +0100 Subject: [PATCH] Prevent attempts to allocate excessive amounts of memory when parsing corrupt ELF files. PR 24708 * elf.c (_bfd_elf_slurp_version_tables): Check for an excessively large version reference section. * compress.c (bfd_get_full_section_contents): Check for an uncompressed section whose size is larger than the file size. --- bfd/ChangeLog | 8 ++++++++ bfd/compress.c | 17 +++++++++++++++++ bfd/elf.c | 12 ++++++++++++ binutils/ChangeLog | 3 ++- binutils/objdump.c | 6 +++++- 5 files changed, 44 insertions(+), 2 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 04bdb786076..31d4eee240a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2019-06-28 Nick Clifton + + PR 24708 + * elf.c (_bfd_elf_slurp_version_tables): Check for an excessively + large version reference section. + * compress.c (bfd_get_full_section_contents): Check for an + uncompressed section whose size is larger than the file size. + 2019-06-28 Alan Modra * format.c (bfd_check_format_matches): Don't match plugin target diff --git a/bfd/compress.c b/bfd/compress.c index b5db7a76bed..cba281dca49 100644 --- a/bfd/compress.c +++ b/bfd/compress.c @@ -250,6 +250,23 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr) case COMPRESS_SECTION_NONE: if (p == NULL) { + ufile_ptr filesize = bfd_get_file_size (abfd); + if (filesize > 0 + && filesize < sz + /* The MMO file format supports its own special compression + technique, but it uses COMPRESS_SECTION_NONE when loading + a section's contents. */ + && bfd_get_flavour (abfd) != bfd_target_mmo_flavour) + { + /* PR 24708: Avoid attempts to allocate a ridiculous amount + of memory. */ + bfd_set_error (bfd_error_no_memory); + _bfd_error_handler + /* xgettext:c-format */ + (_("error: %pB(%pA) section size (%#" PRIx64 " bytes) is larger than file size (%#" PRIx64 " bytes)"), + abfd, sec, (uint64_t) sz, (uint64_t) filesize); + return FALSE; + } p = (bfd_byte *) bfd_malloc (sz); if (p == NULL) { diff --git a/bfd/elf.c b/bfd/elf.c index 2094fca1ff5..75efcc6f105 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -8443,6 +8443,18 @@ error_return_verref: goto error_return; } + ufile_ptr filesize = bfd_get_file_size (abfd); + if (filesize > 0 && filesize < hdr->sh_size) + { + /* PR 24708: Avoid attempts to allocate a ridiculous amount + of memory. */ + bfd_set_error (bfd_error_no_memory); + _bfd_error_handler + /* xgettext:c-format */ + (_("error: %pB version reference section is too large (%#" PRIx64 " bytes)"), + abfd, (uint64_t) hdr->sh_size); + goto error_return_verref; + } contents = (bfd_byte *) bfd_malloc (hdr->sh_size); if (contents == NULL) goto error_return_verref; diff --git a/binutils/ChangeLog b/binutils/ChangeLog index e9f83e6413f..d7231713e7a 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -2,7 +2,8 @@ PR 24707 * objdump.c (slurp_symtab): Fail with a helpful error message if - the symbol table is too large. + the symbol table is too large. Skip this check for MMO format + files. 2019-06-26 Nick Clifton diff --git a/binutils/objdump.c b/binutils/objdump.c index 32e6f24f7b4..6812ba7853d 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -708,7 +708,11 @@ slurp_symtab (bfd *abfd) off_t filesize = bfd_get_file_size (abfd); /* qv PR 24707. */ - if (filesize > 0 && filesize < storage) + if (filesize > 0 + && filesize < storage + /* The MMO file format supports its own special compression + technique, so its sections can be larger than the file size. */ + && bfd_get_flavour (abfd) != bfd_target_mmo_flavour) { bfd_nonfatal_message (bfd_get_filename (abfd), abfd, NULL, _("error: symbol table size (%#lx) is larger than filesize (%#lx)"), -- 2.30.2