From 65109548f8fb13ac4a6c3311ea46a8b69c548576 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 24 Mar 2020 17:26:40 +1030 Subject: [PATCH] Overlarge allocation in _bfd_generic_read_ar_hdr_mag * archive.c (_bfd_generic_read_ar_hdr_mag): Sanity check extended name size. Use bfd_malloc rather than bfd_zmalloc, clearing just struct areltdata. --- bfd/ChangeLog | 6 ++++++ bfd/archive.c | 15 ++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index b5e0f2822e0..da8e05894f0 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2020-03-24 Alan Modra + + * archive.c (_bfd_generic_read_ar_hdr_mag): Sanity check extended + name size. Use bfd_malloc rather than bfd_zmalloc, clearing just + struct areltdata. + 2020-03-23 Sebastian Huber * elflink.c (_bfd_elf_tls_setup): Mention .tdata in comment. diff --git a/bfd/archive.c b/bfd/archive.c index 0c009f10de8..3423a336956 100644 --- a/bfd/archive.c +++ b/bfd/archive.c @@ -488,6 +488,7 @@ _bfd_generic_read_ar_hdr_mag (bfd *abfd, const char *mag) bfd_size_type parsed_size; struct areltdata *ared; char *filename = NULL; + ufile_ptr filesize; bfd_size_type namelen = 0; bfd_size_type allocsize = sizeof (struct areltdata) + sizeof (struct ar_hdr); char *allocptr = 0; @@ -538,11 +539,19 @@ _bfd_generic_read_ar_hdr_mag (bfd *abfd, const char *mag) { /* BSD-4.4 extended name */ namelen = atoi (&hdr.ar_name[3]); + filesize = bfd_get_file_size (abfd); + if (namelen > parsed_size + || namelen > -allocsize - 2 + || (filesize != 0 && namelen > filesize)) + { + bfd_set_error (bfd_error_malformed_archive); + return NULL; + } allocsize += namelen + 1; parsed_size -= namelen; extra_size = namelen; - allocptr = (char *) bfd_zmalloc (allocsize); + allocptr = (char *) bfd_malloc (allocsize); if (allocptr == NULL) return NULL; filename = (allocptr @@ -586,13 +595,13 @@ _bfd_generic_read_ar_hdr_mag (bfd *abfd, const char *mag) if (!allocptr) { - allocptr = (char *) bfd_zmalloc (allocsize); + allocptr = (char *) bfd_malloc (allocsize); if (allocptr == NULL) return NULL; } + memset (allocptr, 0, sizeof (struct areltdata)); ared = (struct areltdata *) allocptr; - ared->arch_header = allocptr + sizeof (struct areltdata); memcpy (ared->arch_header, &hdr, sizeof (struct ar_hdr)); ared->parsed_size = parsed_size; -- 2.30.2