diff options
author | Nick Clifton <nickc@redhat.com> | 2017-11-16 13:06:22 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2017-11-16 13:06:22 +0000 |
commit | 38b28f7088057d70497de7312cd983ec8e408a76 (patch) | |
tree | 87ad221e6a2a9a6a3a619483aabe5489df6ac91e | |
parent | 5f847646eeb0107cb8c5e44c8bca3a4c88c91673 (diff) | |
download | gdb-38b28f7088057d70497de7312cd983ec8e408a76.zip gdb-38b28f7088057d70497de7312cd983ec8e408a76.tar.gz gdb-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.
-rw-r--r-- | bfd/ChangeLog | 5 | ||||
-rw-r--r-- | bfd/merge.c | 22 |
2 files changed, 17 insertions, 10 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 648006e..8e358dd 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2017-11-16 Nick Clifton <nickc@redhat.com> + + * 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 <amodra@gmail.com> * bfd.c (union _bfd_doprnt_args): Add "Bad". 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; } |