Yet another out-of-memory fuzzed object

Do I care about out of memory conditions triggered by fuzzers?  Not
much.  Your operating system ought to be able to handle it by killing
the memory hog.  Oh well, this one was an element of a coff-alpha
archive that said it was a little less that 2**64 in size.  The
coff-alpha compression scheme expands at most 8 times, so we can do
better in bfd_get_file_size.

	* bfdio.c (bfd_get_file_size): Assume elements in compressed
	archive can only expand a maximum of eight times.
	* coffgen.c (_bfd_coff_get_external_symbols): Sanity check
	size of symbol table agains file size.
This commit is contained in:
Alan Modra
2023-04-19 22:32:15 +09:30
parent 685b44ee81
commit 3b37f0f1b8
2 changed files with 15 additions and 4 deletions
+5 -4
View File
@@ -524,6 +524,7 @@ ufile_ptr
bfd_get_file_size (bfd *abfd)
{
ufile_ptr file_size, archive_size = (ufile_ptr) -1;
unsigned int compression_p2 = 0;
if (abfd->my_archive != NULL
&& !bfd_is_thin_archive (abfd->my_archive))
@@ -532,17 +533,17 @@ bfd_get_file_size (bfd *abfd)
if (adata != NULL)
{
archive_size = adata->parsed_size;
/* If the archive is compressed we can't compare against
file size. */
/* If the archive is compressed, assume an element won't
expand more than eight times file size. */
if (adata->arch_header != NULL
&& memcmp (((struct ar_hdr *) adata->arch_header)->ar_fmag,
"Z\012", 2) == 0)
return archive_size;
compression_p2 = 3;
abfd = abfd->my_archive;
}
}
file_size = bfd_get_size (abfd);
file_size = bfd_get_size (abfd) << compression_p2;
if (archive_size < file_size)
return archive_size;
return file_size;
+10
View File
@@ -1551,6 +1551,7 @@ _bfd_coff_get_external_symbols (bfd *abfd)
size_t symesz;
size_t size;
void * syms;
ufile_ptr filesize;
if (obj_coff_external_syms (abfd) != NULL)
return true;
@@ -1565,6 +1566,15 @@ _bfd_coff_get_external_symbols (bfd *abfd)
if (size == 0)
return true;
filesize = bfd_get_file_size (abfd);
if (filesize != 0
&& ((ufile_ptr) obj_sym_filepos (abfd) > filesize
|| size > filesize - obj_sym_filepos (abfd)))
{
bfd_set_error (bfd_error_file_truncated);
return false;
}
if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0)
return false;
syms = _bfd_malloc_and_read (abfd, size, size);