aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2018-12-31 17:06:25 +1030
committerAlan Modra <amodra@gmail.com>2018-12-31 17:56:32 +1030
commit8fd04a4255376036e85c4e80d430b44ec4b06c64 (patch)
tree103df2c3136c544b5c65f742573aecab0124c6b2
parent54025d5812ff100f5f0654eb7e1ffd50f2e37f5f (diff)
downloadbinutils-8fd04a4255376036e85c4e80d430b44ec4b06c64.zip
binutils-8fd04a4255376036e85c4e80d430b44ec4b06c64.tar.gz
binutils-8fd04a4255376036e85c4e80d430b44ec4b06c64.tar.bz2
PR24042, Global-buffer-overflow problem in output_rel_find
place_orphan handled ELF SHT_REL/SHT_RELA specially, output_rel_find didn't. This mismatch was a bug and also meant it was possible to craft an object where ld accessed section->name out of bounds. PR 24042 * emultempl/elf32.em (output_rel_find): Drop "sec" param. Add "rela". (gld${EMULATION_NAME}_place_orphan): Use sh_type to calculate "rela" param of output_rel_find when ELF. Tidy uses of elfinput.
-rw-r--r--ld/ChangeLog8
-rw-r--r--ld/emultempl/elf32.em20
2 files changed, 20 insertions, 8 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index c7d4a0c..d7d9188 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,11 @@
+2018-12-31 Alan Modra <amodra@gmail.com>
+
+ PR 24042
+ * emultempl/elf32.em (output_rel_find): Drop "sec" param. Add
+ "rela".
+ (gld${EMULATION_NAME}_place_orphan): Use sh_type to calculate
+ "rela" param of output_rel_find when ELF. Tidy uses of elfinput.
+
2018-12-19 H.J. Lu <hongjiu.lu@intel.com>
PR gas/23997
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index ad31a62..b6faa39 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -1954,7 +1954,7 @@ fragment <<EOF
/* A variant of lang_output_section_find used by place_orphan. */
static lang_output_section_statement_type *
-output_rel_find (asection *sec, int isdyn)
+output_rel_find (int isdyn, int rela)
{
lang_output_section_statement_type *lookup;
lang_output_section_statement_type *last = NULL;
@@ -1962,7 +1962,6 @@ output_rel_find (asection *sec, int isdyn)
lang_output_section_statement_type *last_ro_alloc = NULL;
lang_output_section_statement_type *last_rel = NULL;
lang_output_section_statement_type *last_rel_alloc = NULL;
- int rela = sec->name[4] == 'a';
for (lookup = &lang_output_section_statement.head->output_section_statement;
lookup != NULL;
@@ -2270,8 +2269,9 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
else if ((flags & SEC_ALLOC) == 0)
;
else if ((flags & SEC_LOAD) != 0
- && ((elfinput && sh_type == SHT_NOTE)
- || (!elfinput && CONST_STRNEQ (secname, ".note"))))
+ && (elfinput
+ ? sh_type == SHT_NOTE
+ : CONST_STRNEQ (secname, ".note")))
place = &hold[orphan_interp];
else if ((flags & (SEC_LOAD | SEC_HAS_CONTENTS | SEC_THREAD_LOCAL)) == 0)
place = &hold[orphan_bss];
@@ -2281,9 +2281,10 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
place = &hold[orphan_tdata];
else if ((flags & SEC_READONLY) == 0)
place = &hold[orphan_data];
- else if (((elfinput && (sh_type == SHT_RELA || sh_type == SHT_REL))
- || (!elfinput && CONST_STRNEQ (secname, ".rel")))
- && (flags & SEC_LOAD) != 0)
+ else if ((flags & SEC_LOAD) != 0
+ && (elfinput
+ ? sh_type == SHT_RELA || sh_type == SHT_REL
+ : CONST_STRNEQ (secname, ".rel")))
place = &hold[orphan_rel];
else if ((flags & SEC_CODE) == 0)
place = &hold[orphan_rodata];
@@ -2298,7 +2299,10 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
if (place->name != NULL)
place->os = lang_output_section_find (place->name);
else
- place->os = output_rel_find (s, isdyn);
+ {
+ int rela = elfinput ? sh_type == SHT_RELA : secname[4] == 'a';
+ place->os = output_rel_find (isdyn, rela);
+ }
}
after = place->os;
if (after == NULL)