aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2021-10-06 13:38:42 +1030
committerAlan Modra <amodra@gmail.com>2021-10-06 15:30:23 +1030
commit1808483c2f3f323d8e0398282251a85cd956321b (patch)
tree8bcb354ac28060267ad47a80ff98606ed9c65181 /bfd
parent0a6041ce9383338fa62acb207683780faaa8b42c (diff)
downloadgdb-1808483c2f3f323d8e0398282251a85cd956321b.zip
gdb-1808483c2f3f323d8e0398282251a85cd956321b.tar.gz
gdb-1808483c2f3f323d8e0398282251a85cd956321b.tar.bz2
PR28402, fail to allocate line number array
This fixes a situation where the COFF code allocated memory for internal representaion arrays before reading the external file data. That meant the allocation didn't have any sanity check against file size. PR 28402 * coffcode.h (buy_and_read): Malloc rather than alloc memory. (coff_slurp_line_table): Read native line number info before allocating memory for internal line number array. Adjust error paths to suit. Remove now unnecessary line number count check. (coff_slurp_reloc_table): Adjust to suit buy_and_read change.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/coffcode.h35
1 files changed, 19 insertions, 16 deletions
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index d5d9153..c28d753 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -4294,7 +4294,7 @@ buy_and_read (bfd *abfd, file_ptr where,
}
if (bfd_seek (abfd, where, SEEK_SET) != 0)
return NULL;
- return _bfd_alloc_and_read (abfd, amt, amt);
+ return _bfd_malloc_and_read (abfd, amt, amt);
}
/*
@@ -4358,31 +4358,26 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
BFD_ASSERT (asect->lineno == NULL);
- if (asect->lineno_count > asect->size)
+ native_lineno = (LINENO *) buy_and_read (abfd, asect->line_filepos,
+ asect->lineno_count,
+ bfd_coff_linesz (abfd));
+ if (native_lineno == NULL)
{
_bfd_error_handler
- (_("%pB: warning: line number count (%#lx) exceeds section size (%#lx)"),
- abfd, (unsigned long) asect->lineno_count, (unsigned long) asect->size);
+ (_("%pB: warning: line number table read failed"), abfd);
return false;
}
if (_bfd_mul_overflow (asect->lineno_count + 1, sizeof (alent), &amt))
{
bfd_set_error (bfd_error_file_too_big);
+ free (native_lineno);
return false;
}
lineno_cache = (alent *) bfd_alloc (abfd, amt);
if (lineno_cache == NULL)
- return false;
-
- native_lineno = (LINENO *) buy_and_read (abfd, asect->line_filepos,
- asect->lineno_count,
- bfd_coff_linesz (abfd));
- if (native_lineno == NULL)
{
- _bfd_error_handler
- (_("%pB: warning: line number table read failed"), abfd);
- bfd_release (abfd, lineno_cache);
+ free (native_lineno);
return false;
}
@@ -4475,7 +4470,7 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
asect->lineno_count = cache_ptr - lineno_cache;
memset (cache_ptr, 0, sizeof (*cache_ptr));
- bfd_release (abfd, native_lineno);
+ free (native_lineno);
/* On some systems (eg AIX5.3) the lineno table may not be sorted. */
if (!ordered)
@@ -5093,14 +5088,20 @@ coff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols)
native_relocs = (RELOC *) buy_and_read (abfd, asect->rel_filepos,
asect->reloc_count,
bfd_coff_relsz (abfd));
+ if (native_relocs == NULL)
+ return false;
+
if (_bfd_mul_overflow (asect->reloc_count, sizeof (arelent), &amt))
{
bfd_set_error (bfd_error_file_too_big);
return false;
}
reloc_cache = (arelent *) bfd_alloc (abfd, amt);
- if (reloc_cache == NULL || native_relocs == NULL)
- return false;
+ if (reloc_cache == NULL)
+ {
+ free (native_relocs);
+ return false;
+ }
for (idx = 0; idx < asect->reloc_count; idx++)
{
@@ -5170,10 +5171,12 @@ coff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols)
(_("%pB: illegal relocation type %d at address %#" PRIx64),
abfd, dst.r_type, (uint64_t) dst.r_vaddr);
bfd_set_error (bfd_error_bad_value);
+ free (native_relocs);
return false;
}
}
+ free (native_relocs);
asect->relocation = reloc_cache;
return true;
}