From: Alan Modra Date: Mon, 3 Aug 2020 01:31:27 +0000 (+0930) Subject: PR26330, Malloc size error in objdump X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=b5f386d52049067ca081651a460ab4ae85e327d4;p=deliverable%2Fbinutils-gdb.git PR26330, Malloc size error in objdump PR 26330 * elf.c (_bfd_elf_get_symtab_upper_bound): Sanity check symbol table size against file size. Correct LONG_MAX limit check. (_bfd_elf_get_dynamic_symtab_upper_bound): Likewise. (_bfd_elf_get_reloc_upper_bound): Don't check file size if writing. (_bfd_elf_get_dynamic_reloc_upper_bound): Likewise. * elf64-x86-64-.c (elf_x86_64_get_synthetic_symtab): Use bfd_malloc_and_get_section. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d0a5916d37..25cb69fd13 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,14 @@ +2020-08-03 Alan Modra + + PR 26330 + * elf.c (_bfd_elf_get_symtab_upper_bound): Sanity check symbol table + size against file size. Correct LONG_MAX limit check. + (_bfd_elf_get_dynamic_symtab_upper_bound): Likewise. + (_bfd_elf_get_reloc_upper_bound): Don't check file size if writing. + (_bfd_elf_get_dynamic_reloc_upper_bound): Likewise. + * elf64-x86-64-.c (elf_x86_64_get_synthetic_symtab): Use + bfd_malloc_and_get_section. + 2020-07-31 Alan Modra PR 26314 diff --git a/bfd/elf.c b/bfd/elf.c index 5fb1995bad..cc2b46ccc7 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -8446,14 +8446,24 @@ _bfd_elf_get_symtab_upper_bound (bfd *abfd) Elf_Internal_Shdr *hdr = &elf_tdata (abfd)->symtab_hdr; symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym; - if (symcount >= LONG_MAX / sizeof (asymbol *)) + if (symcount > LONG_MAX / sizeof (asymbol *)) { bfd_set_error (bfd_error_file_too_big); return -1; } - symtab_size = (symcount + 1) * (sizeof (asymbol *)); - if (symcount > 0) - symtab_size -= sizeof (asymbol *); + symtab_size = symcount * (sizeof (asymbol *)); + if (symcount == 0) + symtab_size = sizeof (asymbol *); + else if (!bfd_write_p (abfd)) + { + ufile_ptr filesize = bfd_get_file_size (abfd); + + if (filesize != 0 && (unsigned long) symtab_size > filesize) + { + bfd_set_error (bfd_error_file_truncated); + return -1; + } + } return symtab_size; } @@ -8472,14 +8482,24 @@ _bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd) } symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym; - if (symcount >= LONG_MAX / sizeof (asymbol *)) + if (symcount > LONG_MAX / sizeof (asymbol *)) { bfd_set_error (bfd_error_file_too_big); return -1; } - symtab_size = (symcount + 1) * (sizeof (asymbol *)); - if (symcount > 0) - symtab_size -= sizeof (asymbol *); + symtab_size = symcount * (sizeof (asymbol *)); + if (symcount == 0) + symtab_size = sizeof (asymbol *); + else if (!bfd_write_p (abfd)) + { + ufile_ptr filesize = bfd_get_file_size (abfd); + + if (filesize != 0 && (unsigned long) symtab_size > filesize) + { + bfd_set_error (bfd_error_file_truncated); + return -1; + } + } return symtab_size; } @@ -8487,7 +8507,7 @@ _bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd) long _bfd_elf_get_reloc_upper_bound (bfd *abfd, sec_ptr asect) { - if (asect->reloc_count != 0) + if (asect->reloc_count != 0 && !bfd_write_p (abfd)) { /* Sanity check reloc section size. */ struct bfd_elf_section_data *d = elf_section_data (asect); @@ -8596,7 +8616,7 @@ _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd) return -1; } } - if (count > 1) + if (count > 1 && !bfd_write_p (abfd)) { /* Sanity check reloc section sizes. */ ufile_ptr filesize = bfd_get_file_size (abfd); diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index f97a6a05e8..549a8be6a6 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -4810,15 +4810,8 @@ elf_x86_64_get_synthetic_symtab (bfd *abfd, continue; /* Get the PLT section contents. */ - plt_contents = (bfd_byte *) bfd_malloc (plt->size); - if (plt_contents == NULL) + if (!bfd_malloc_and_get_section (abfd, plt, &plt_contents)) break; - if (!bfd_get_section_contents (abfd, (asection *) plt, - plt_contents, 0, plt->size)) - { - free (plt_contents); - break; - } /* Check what kind of PLT it is. */ plt_type = plt_unknown;