Blame SOURCES/binutils-CVE-2018-7570.patch

381f6c
--- binutils.orig/bfd/elf.c	2018-05-01 11:42:03.151425659 +0100
381f6c
+++ binutils-2.30/bfd/elf.c	2018-05-01 12:30:42.129206856 +0100
381f6c
@@ -5713,6 +5713,9 @@ assign_file_positions_for_load_sections
381f6c
   return TRUE;
381f6c
 }
381f6c
 
381f6c
+#define IS_TBSS(s) \
381f6c
+  ((s->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) == SEC_THREAD_LOCAL)
381f6c
+
381f6c
 /* Assign file positions for the other sections.  */
381f6c
 
381f6c
 static bfd_boolean
381f6c
@@ -5862,65 +5865,100 @@ assign_file_positions_for_non_load_secti
381f6c
     {
381f6c
       if (p->p_type == PT_GNU_RELRO)
381f6c
 	{
381f6c
-	  const Elf_Internal_Phdr *lp;
381f6c
-	  struct elf_segment_map *lm;
381f6c
+	  bfd_vma start, end;
381f6c
+	  bfd_boolean ok;
381f6c
 
381f6c
 	  if (link_info != NULL)
381f6c
 	    {
381f6c
 	      /* During linking the range of the RELRO segment is passed
381f6c
-		 in link_info.  */
381f6c
+		 in link_info.  Note that there may be padding between
381f6c
+		 relro_start and the first RELRO section.  */
381f6c
+	      start = link_info->relro_start;
381f6c
+	      end = link_info->relro_end;
381f6c
+	    }
381f6c
+	  else if (m->count != 0)
381f6c
+	    {
381f6c
+	      if (!m->p_size_valid)
381f6c
+		abort ();
381f6c
+	      start = m->sections[0]->vma;
381f6c
+	      end = start + m->p_size;
381f6c
+	    }
381f6c
+	  else
381f6c
+	    {
381f6c
+	      start = 0;
381f6c
+	      end = 0;
381f6c
+	    }
381f6c
+
381f6c
+	  ok = FALSE;
381f6c
+	  if (start < end)
381f6c
+	    {
381f6c
+	      struct elf_segment_map *lm;
381f6c
+	      const Elf_Internal_Phdr *lp;
381f6c
+	      unsigned int i;
381f6c
+
381f6c
+	      /* Find a LOAD segment containing a section in the RELRO
381f6c
+		 segment.  */
381f6c
 	      for (lm = elf_seg_map (abfd), lp = phdrs;
381f6c
 		   lm != NULL;
381f6c
 		   lm = lm->next, lp++)
381f6c
 		{
381f6c
 		  if (lp->p_type == PT_LOAD
381f6c
-		      && lp->p_vaddr < link_info->relro_end
381f6c
 		      && lm->count != 0
381f6c
-		      && lm->sections[0]->vma >= link_info->relro_start)
381f6c
+		      && (lm->sections[lm->count - 1]->vma
381f6c
+			  + (!IS_TBSS (lm->sections[lm->count - 1])
381f6c
+			     ? lm->sections[lm->count - 1]->size
381f6c
+			     : 0)) > start
381f6c
+		      && lm->sections[0]->vma < end)
381f6c
 		    break;
381f6c
 		}
381f6c
 
381f6c
-	      BFD_ASSERT (lm != NULL);
381f6c
-	    }
381f6c
-	  else
381f6c
-	    {
381f6c
-	      /* Otherwise we are copying an executable or shared
381f6c
-		 library, but we need to use the same linker logic.  */
381f6c
-	      for (lp = phdrs; lp < phdrs + count; ++lp)
381f6c
+	      if (lm != NULL)
381f6c
 		{
381f6c
-		  if (lp->p_type == PT_LOAD
381f6c
-		      && lp->p_paddr == p->p_paddr)
381f6c
-		    break;
381f6c
+		  /* Find the section starting the RELRO segment.  */
381f6c
+		  for (i = 0; i < lm->count; i++)
381f6c
+		    {
381f6c
+		      asection *s = lm->sections[i];
381f6c
+		      if (s->vma >= start
381f6c
+			  && s->vma < end
381f6c
+			  && s->size != 0)
381f6c
+			break;
381f6c
+		    }
381f6c
+
381f6c
+		  if (i < lm->count)
381f6c
+		    {
381f6c
+		      p->p_vaddr = lm->sections[i]->vma;
381f6c
+		      p->p_paddr = lm->sections[i]->lma;
381f6c
+		      p->p_offset = lm->sections[i]->filepos;
381f6c
+		      p->p_memsz = end - p->p_vaddr;
381f6c
+		      p->p_filesz = p->p_memsz;
381f6c
+
381f6c
+		      /* The RELRO segment typically ends a few bytes
381f6c
+			 into .got.plt but other layouts are possible.
381f6c
+			 In cases where the end does not match any
381f6c
+			 loaded section (for instance is in file
381f6c
+			 padding), trim p_filesz back to correspond to
381f6c
+			 the end of loaded section contents.  */
381f6c
+		      if (p->p_filesz > lp->p_vaddr + lp->p_filesz - p->p_vaddr)
381f6c
+			p->p_filesz = lp->p_vaddr + lp->p_filesz - p->p_vaddr;
381f6c
+
381f6c
+		      /* Preserve the alignment and flags if they are
381f6c
+			 valid.  The gold linker generates RW/4 for
381f6c
+			 the PT_GNU_RELRO section.  It is better for
381f6c
+			 objcopy/strip to honor these attributes
381f6c
+			 otherwise gdb will choke when using separate
381f6c
+			 debug files.  */
381f6c
+		      if (!m->p_align_valid)
381f6c
+			p->p_align = 1;
381f6c
+		      if (!m->p_flags_valid)
381f6c
+			p->p_flags = PF_R;
381f6c
+		      ok = TRUE;
381f6c
+		    }
381f6c
 		}
381f6c
 	    }
381f6c
-
381f6c
-	  if (lp < phdrs + count)
381f6c
-	    {
381f6c
-	      p->p_vaddr = lp->p_vaddr;
381f6c
-	      p->p_paddr = lp->p_paddr;
381f6c
-	      p->p_offset = lp->p_offset;
381f6c
-	      if (link_info != NULL)
381f6c
-		p->p_filesz = link_info->relro_end - lp->p_vaddr;
381f6c
-	      else if (m->p_size_valid)
381f6c
-		p->p_filesz = m->p_size;
381f6c
-	      else
381f6c
-		abort ();
381f6c
-	      p->p_memsz = p->p_filesz;
381f6c
-	      /* Preserve the alignment and flags if they are valid. The
381f6c
-		 gold linker generates RW/4 for the PT_GNU_RELRO section.
381f6c
-		 It is better for objcopy/strip to honor these attributes
381f6c
-		 otherwise gdb will choke when using separate debug files.
381f6c
-	       */
381f6c
-	      if (!m->p_align_valid)
381f6c
-		p->p_align = 1;
381f6c
-	      if (!m->p_flags_valid)
381f6c
-		p->p_flags = PF_R;
381f6c
-	    }
381f6c
-	  else
381f6c
-	    {
381f6c
-	      memset (p, 0, sizeof *p);
381f6c
-	      p->p_type = PT_NULL;
381f6c
-	    }
381f6c
+	  if (link_info != NULL)
381f6c
+	    BFD_ASSERT (ok);
381f6c
+	  if (!ok)
381f6c
+	    memset (p, 0, sizeof *p);
381f6c
 	}
381f6c
       else if (p->p_type == PT_GNU_STACK)
381f6c
 	{