From 38b28f7088057d70497de7312cd983ec8e408a76 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 16 Nov 2017 13:06:22 +0000 Subject: [PATCH] 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. --- bfd/ChangeLog | 5 +++++ bfd/merge.c | 22 ++++++++++++---------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 648006e64f0..8e358dd575d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2017-11-16 Nick Clifton + + * merge.c (sec_merge_emit): Always create padding buffer. Add + asserts to make sure that the buffer is long enough. + 2017-11-15 Alan Modra * bfd.c (union _bfd_doprnt_args): Add "Bad". diff --git a/bfd/merge.c b/bfd/merge.c index ad8db83ef62..9775f727e36 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; } -- 2.30.2