diff options
author | Alan Modra <amodra@gmail.com> | 2023-03-17 21:07:17 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2023-03-17 21:14:46 +1030 |
commit | 92376883a9a18e478228ae14ac8f3b03398fdefa (patch) | |
tree | 25bdacee745eda994a4a9f2c52f46383a9bcec2b /bfd/mach-o.c | |
parent | 1d7e244fc54e1d825e851d8af13a24136ae8cd79 (diff) | |
download | gdb-92376883a9a18e478228ae14ac8f3b03398fdefa.zip gdb-92376883a9a18e478228ae14ac8f3b03398fdefa.tar.gz gdb-92376883a9a18e478228ae14ac8f3b03398fdefa.tar.bz2 |
mach-o: out of memory in get_dynamic_reloc_upper_bound
* mach-o.c (bfd_mach_o_canonicalize_dynamic_reloc): Move sanity
checks..
(bfd_mach_o_get_dynamic_reloc_upper_bound): ..to here.
Diffstat (limited to 'bfd/mach-o.c')
-rw-r--r-- | bfd/mach-o.c | 55 |
1 files changed, 29 insertions, 26 deletions
diff --git a/bfd/mach-o.c b/bfd/mach-o.c index 0a91095..9b9aba5 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -1701,11 +1701,36 @@ long bfd_mach_o_get_dynamic_reloc_upper_bound (bfd *abfd) { bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); + bfd_mach_o_dysymtab_command *dysymtab = mdata->dysymtab; - if (mdata->dysymtab == NULL) + if (dysymtab == NULL) return 1; - return (mdata->dysymtab->nextrel + mdata->dysymtab->nlocrel + 1) - * sizeof (arelent *); + + ufile_ptr filesize = bfd_get_file_size (abfd); + size_t amt; + + if (filesize != 0) + { + if (dysymtab->extreloff > filesize + || dysymtab->nextrel > ((filesize - dysymtab->extreloff) + / BFD_MACH_O_RELENT_SIZE) + || dysymtab->locreloff > filesize + || dysymtab->nlocrel > ((filesize - dysymtab->locreloff) + / BFD_MACH_O_RELENT_SIZE)) + { + bfd_set_error (bfd_error_file_truncated); + return -1; + } + } + if (dysymtab->nextrel + dysymtab->nlocrel < dysymtab->nextrel + || _bfd_mul_overflow (dysymtab->nextrel + dysymtab->nlocrel, + sizeof (arelent), &amt)) + { + bfd_set_error (bfd_error_file_too_big); + return -1; + } + + return (dysymtab->nextrel + dysymtab->nlocrel + 1) * sizeof (arelent *); } long @@ -1729,29 +1754,7 @@ bfd_mach_o_canonicalize_dynamic_reloc (bfd *abfd, arelent **rels, if (mdata->dyn_reloc_cache == NULL) { - ufile_ptr filesize = bfd_get_file_size (abfd); - size_t amt; - - if (filesize != 0) - { - if (dysymtab->extreloff > filesize - || dysymtab->nextrel > ((filesize - dysymtab->extreloff) - / BFD_MACH_O_RELENT_SIZE) - || dysymtab->locreloff > filesize - || dysymtab->nlocrel > ((filesize - dysymtab->locreloff) - / BFD_MACH_O_RELENT_SIZE)) - { - bfd_set_error (bfd_error_file_truncated); - return -1; - } - } - if (_bfd_mul_overflow (dysymtab->nextrel + dysymtab->nlocrel, - sizeof (arelent), &amt)) - { - bfd_set_error (bfd_error_file_too_big); - return -1; - } - + size_t amt = (dysymtab->nextrel + dysymtab->nlocrel) * sizeof (arelent); res = bfd_malloc (amt); if (res == NULL) return -1; |