diff options
author | Alan Modra <amodra@gmail.com> | 2020-08-03 11:01:27 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2020-08-03 14:07:31 +0930 |
commit | b5f386d52049067ca081651a460ab4ae85e327d4 (patch) | |
tree | c3e7492c0f10b8c152599fe572e40f88933b0dc2 /bfd | |
parent | ee44c2ac7b3efdfd28c41cd32d7fb935b0582a97 (diff) | |
download | gdb-b5f386d52049067ca081651a460ab4ae85e327d4.zip gdb-b5f386d52049067ca081651a460ab4ae85e327d4.tar.gz gdb-b5f386d52049067ca081651a460ab4ae85e327d4.tar.bz2 |
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.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 11 | ||||
-rw-r--r-- | bfd/elf.c | 40 | ||||
-rw-r--r-- | bfd/elf64-x86-64.c | 9 |
3 files changed, 42 insertions, 18 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d0a5916..25cb69f 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,14 @@ +2020-08-03 Alan Modra <amodra@gmail.com> + + 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 <amodra@gmail.com> PR 26314 @@ -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 f97a6a0..549a8be 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; |