This is the mail archive of the
mailing list for the binutils project.
[PATCH] MIPS/BFD: Fix a .pdr section linker buffer overrun
- From: "Maciej W. Rozycki" <macro at codesourcery dot com>
- To: <binutils at sourceware dot org>
- Cc: Tom de Vries <tom at codesourcery dot com>
- Date: Thu, 31 Jul 2014 16:04:27 +0100
- Subject: [PATCH] MIPS/BFD: Fix a .pdr section linker buffer overrun
- Authentication-results: sourceware.org; auth=none
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:
Author: Alan Modra <firstname.lastname@example.org>
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 <email@example.com>
* elfxx-mips.c (_bfd_mips_elf_discard_info): Set section's
rawsize if changing size.
--- 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;