This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Prevent a possible seg-fault in the section merging code, by always creating a padding buffer.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=38b28f7088057d70497de7312cd983ec8e408a76

commit 38b28f7088057d70497de7312cd983ec8e408a76
Author: Nick Clifton <nickc@redhat.com>
Date:   Thu Nov 16 13:06:22 2017 +0000

    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.

Diff:
---
 bfd/ChangeLog |  5 +++++
 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;
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]