Skip to content

Commit

Permalink
mach-o: out of memory in get_dynamic_reloc_upper_bound
Browse files Browse the repository at this point in the history
	* mach-o.c (bfd_mach_o_canonicalize_dynamic_reloc): Move sanity
	checks..
	(bfd_mach_o_get_dynamic_reloc_upper_bound): ..to here.
  • Loading branch information
amodra committed Mar 17, 2023
1 parent 1d7e244 commit 9237688
Showing 1 changed file with 29 additions and 26 deletions.
55 changes: 29 additions & 26 deletions bfd/mach-o.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down

0 comments on commit 9237688

Please sign in to comment.