This is the mail archive of the binutils@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]

[PATCH] PR binutils/19005: objcopy buffer-over-read


In objcopy, copy_object calls copy_section to copy contents of input
section to output section.  When --gap-fill= is used, objcopy extends
the size of output sectios to faill gaps between output sections with
gap fills.  In this case, we should set the output section size to the
input section size to avoid reading beypond the input section buffer
before calling copy_section and restores the output section size after
input sections have been copied.

OK for master?

H.J.
--
binutils/

	PR binutils/19005
	* objcopy.c (copy_object): Adjust the output section size to
	skip gap fills between sections when copying from input sections
	to output sections.

ld/testsuite/

	PR binutils/19005
	* ld-elf/pr19005.d: New file.
	* ld-elf/pr19005.s: Likewise.
	* ld-elf/pr19005.t: Likewise.
---
 binutils/objcopy.c            | 31 +++++++++++++++++++++++++++----
 ld/testsuite/ld-elf/pr19005.d | 10 ++++++++++
 ld/testsuite/ld-elf/pr19005.s | 11 +++++++++++
 ld/testsuite/ld-elf/pr19005.t |  6 ++++++
 4 files changed, 54 insertions(+), 4 deletions(-)
 create mode 100644 ld/testsuite/ld-elf/pr19005.d
 create mode 100644 ld/testsuite/ld-elf/pr19005.s
 create mode 100644 ld/testsuite/ld-elf/pr19005.t

diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index e4cb3e2..00368ff 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -1635,11 +1635,13 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
   asection **osections = NULL;
   asection *gnu_debuglink_section = NULL;
   bfd_size_type *gaps = NULL;
+  bfd_size_type *osizes = NULL;
   bfd_size_type max_gap = 0;
   long symsize;
   void *dhandle;
   enum bfd_architecture iarch;
   unsigned int imach;
+  unsigned int c, i;
 
   if (ibfd->xvec->byteorder != obfd->xvec->byteorder
       && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
@@ -2071,11 +2073,11 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
 	}
     }
 
-  if (bfd_count_sections (obfd) != 0
+  c = bfd_count_sections (obfd);
+  if (c != 0
       && (gap_fill_set || pad_to_set))
     {
       asection **set;
-      unsigned int c, i;
 
       /* We must fill in gaps between the sections and/or we must pad
 	 the last section to a specified address.  We do this by
@@ -2083,7 +2085,6 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
 	 increasing the section sizes as required to fill the gaps.
 	 We write out the gap contents below.  */
 
-      c = bfd_count_sections (obfd);
       osections = (asection **) xmalloc (c * sizeof (asection *));
       set = osections;
       bfd_map_over_sections (obfd, get_sections, &set);
@@ -2212,7 +2213,30 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
   bfd_map_over_sections (ibfd, copy_relocations_in_section, obfd);
 
   /* This has to happen after the symbol table has been set.  */
+  if (gap_fill_set)
+    {
+      /* Adjust the output section size to skip gap fills between
+	 sections.  */
+      c = bfd_count_sections (obfd);
+      osizes = (bfd_size_type *) xmalloc (c * sizeof (bfd_size_type));
+      memset (osizes, 0, c * sizeof (bfd_size_type));
+      for (i = 0; i < c; i++)
+	if (gaps[i] != 0)
+	  {
+	    osizes[i] = bfd_section_size (obfd, osections[i]);
+	    osections[i]->size = osizes[i] - gaps[i];
+	  }
+    }
   bfd_map_over_sections (ibfd, copy_section, obfd);
+  if (gap_fill_set)
+    {
+      /* Restore the output section size for gap fills between
+	 sections.  */
+      for (i = 0; i < c; i++)
+	if (osizes[i] != 0)
+	  osections[i]->size = osizes[i];
+      free (osizes);
+    }
 
   if (add_sections != NULL)
     {
@@ -2264,7 +2288,6 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
   if (gap_fill_set || pad_to_set)
     {
       bfd_byte *buf;
-      int c, i;
 
       /* Fill in the gaps.  */
       if (max_gap > 8192)
diff --git a/ld/testsuite/ld-elf/pr19005.d b/ld/testsuite/ld-elf/pr19005.d
new file mode 100644
index 0000000..a4df0d3
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr19005.d
@@ -0,0 +1,10 @@
+#ld: -Tpr19005.t
+#objcopy_linked_file: -O binary -j .foo -j .bar --gap-fill=0xff
+#objdump: -b binary -s
+
+#...
+Contents of section .data:
+ 0000 10ffffff ffffffff ffffffff ffffffff  ................
+ 0010 ffffffff ffffffff ffffffff ffffffff  ................
+ 0020 20.*
+#pass
diff --git a/ld/testsuite/ld-elf/pr19005.s b/ld/testsuite/ld-elf/pr19005.s
new file mode 100644
index 0000000..8bd860f
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr19005.s
@@ -0,0 +1,11 @@
+	.section .foo,"ax",%progbits
+	.globl	_start
+	.type	_start, %function
+_start:
+	.byte 0x10
+	.section .bar,"ax",%progbits
+	.globl	aligned
+	.type	aligned, %function
+	.p2align 5
+aligned:
+	.byte 0x20
diff --git a/ld/testsuite/ld-elf/pr19005.t b/ld/testsuite/ld-elf/pr19005.t
new file mode 100644
index 0000000..0e89e0b
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr19005.t
@@ -0,0 +1,6 @@
+SECTIONS
+{
+  .foo : { *(.foo) }
+  .bar : { *(.bar) }
+  /DISCARD/ : { *(.*) }
+}
-- 
2.4.3


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