aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2023-04-19 22:32:15 +0930
committerAlan Modra <amodra@gmail.com>2023-04-20 09:03:53 +0930
commit3b37f0f1b86cc1fb3ba9cc6d89695109db7f829a (patch)
tree1104d218e517b7bd96be04d5f08e9bcec020ff5b /bfd
parent685b44ee816c6e508d282ae3766f2441b5ae9334 (diff)
downloadbinutils-3b37f0f1b86cc1fb3ba9cc6d89695109db7f829a.zip
binutils-3b37f0f1b86cc1fb3ba9cc6d89695109db7f829a.tar.gz
binutils-3b37f0f1b86cc1fb3ba9cc6d89695109db7f829a.tar.bz2
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.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/bfdio.c9
-rw-r--r--bfd/coffgen.c10
2 files changed, 15 insertions, 4 deletions
diff --git a/bfd/bfdio.c b/bfd/bfdio.c
index 337d4a1..990d349 100644
--- a/bfd/bfdio.c
+++ b/bfd/bfdio.c
@@ -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;
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
index 4725406..05f2640 100644
--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -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);