aboutsummaryrefslogtreecommitdiff
path: root/bfd/merge.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2017-11-16 13:06:22 +0000
committerNick Clifton <nickc@redhat.com>2017-11-16 13:06:22 +0000
commit38b28f7088057d70497de7312cd983ec8e408a76 (patch)
tree87ad221e6a2a9a6a3a619483aabe5489df6ac91e /bfd/merge.c
parent5f847646eeb0107cb8c5e44c8bca3a4c88c91673 (diff)
downloadbinutils-38b28f7088057d70497de7312cd983ec8e408a76.zip
binutils-38b28f7088057d70497de7312cd983ec8e408a76.tar.gz
binutils-38b28f7088057d70497de7312cd983ec8e408a76.tar.bz2
Prevent a possible seg-fault in the section merging code, by always creating a padding buffer.
* merge.c (sec_merge_emit): Always create padding buffer. Add asserts to make sure that the buffer is long enough.
Diffstat (limited to 'bfd/merge.c')
-rw-r--r--bfd/merge.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/bfd/merge.c b/bfd/merge.c
index ad8db83..9775f72 100644
--- a/bfd/merge.c
+++ b/bfd/merge.c
@@ -292,13 +292,15 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry,
char *pad = NULL;
bfd_size_type off = 0;
int alignment_power = sec->output_section->alignment_power;
+ bfd_size_type pad_len;
- if (alignment_power)
- {
- pad = (char *) bfd_zmalloc ((bfd_size_type) 1 << alignment_power);
- if (pad == NULL)
- return FALSE;
- }
+ /* FIXME: If alignment_power is 0 then really we should scan the
+ entry list for the largest required alignment and use that. */
+ pad_len = alignment_power ? ((bfd_size_type) 1 << alignment_power) : 16;
+
+ pad = (char *) bfd_zmalloc (pad_len);
+ if (pad == NULL)
+ return FALSE;
for (; entry != NULL && entry->secinfo == secinfo; entry = entry->next)
{
@@ -308,6 +310,7 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry,
len = -off & (entry->alignment - 1);
if (len != 0)
{
+ BFD_ASSERT (len <= pad_len);
if (contents)
{
memcpy (contents + offset, pad, len);
@@ -336,19 +339,18 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry,
off = sec->size - off;
if (off != 0)
{
+ BFD_ASSERT (off <= pad_len);
if (contents)
memcpy (contents + offset, pad, off);
else if (bfd_bwrite (pad, off, abfd) != off)
goto err;
}
- if (pad != NULL)
- free (pad);
+ free (pad);
return TRUE;
err:
- if (pad != NULL)
- free (pad);
+ free (pad);
return FALSE;
}