This is the mail archive of the 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] MIPS/BFD: Fix a .pdr section linker buffer overrun


 This fixes an issue with MIPS ELF targets and the special .pdr (Procedure 
Descriptor Record) section overrunning the buffer allocated for section 
contents, affecting the linker.

 The reason for the overrun is the output section size is often shrunk in 
_bfd_mips_elf_discard_info, however the original input section retains its 
contents and size until _bfd_elf32_mips_write_section late in processing. 
The original size is not recorded anywhere.  Meanwhile the new size is 
used to calculate the amount of space required to hold any section's 
contents (max_contents_size in bfd_elf_final_link, used to allocate 
flinfo.contents) and if no other section happens to be large enough to 
cover the original span of .pdr, then the buffer allocated is too small 
and relocation processing in mips_elf_perform_relocation can poke randomly 
at space beyond the end of the buffer.

 Tom was (un)lucky enough to track down a case where this poking corrupted 
malloc's heap internal structures such as to cause a call to free 
flinfo->contents in elf_final_link_free to crash the linker.  This 
happened under specific circumstances only, with one of the cases in the 
GCC test suite built with GCC 4.9 (but not 4.8) for MIPS16 and the Linux 
target, with a specific version of host system libc only and binutils 
built at -O0.  He then prepared a self-contained sand box I could 
successfully use to debug and eventually track the issue down -- thanks, 

 The fix does what code elsewhere does for similar cases, such as stabs or 
mergeable sections, complementing:

commit eea6121ac0cb22524c627017191ca09825e3d702
Author: Alan Modra <>
Date:   Thu Jun 24 04:46:28 2004 +0000

    	* section.c (struct sec): Rename "_cooked_size" to "size".
    	Rename "_raw_size" to "rawsize".

that regressed original .pdr support code.  No regressions in mips-sde-elf 
or mips-linux-gnu testing.  OK to apply?

2014-07-31  Maciej W. Rozycki  <>

	* elfxx-mips.c (_bfd_mips_elf_discard_info): Set section's
	rawsize if changing size.


Index: binutils-fsf-trunk-quilt/bfd/elfxx-mips.c
--- binutils-fsf-trunk-quilt.orig/bfd/elfxx-mips.c	2014-07-31 02:41:01.537727067 +0100
+++ binutils-fsf-trunk-quilt/bfd/elfxx-mips.c	2014-07-31 02:43:47.558937585 +0100
@@ -12380,6 +12380,8 @@ _bfd_mips_elf_discard_info (bfd *abfd, s
   if (skip != 0)
       mips_elf_section_data (o)->u.tdata = tdata;
+      if (o->rawsize == 0)
+	o->rawsize = o->size;
       o->size -= skip * PDR_SIZE;
       ret = TRUE;

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