diff options
author | Alan Modra <amodra@gmail.com> | 2018-12-31 17:06:25 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2018-12-31 17:56:32 +1030 |
commit | 8fd04a4255376036e85c4e80d430b44ec4b06c64 (patch) | |
tree | 103df2c3136c544b5c65f742573aecab0124c6b2 | |
parent | 54025d5812ff100f5f0654eb7e1ffd50f2e37f5f (diff) | |
download | binutils-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/ChangeLog | 8 | ||||
-rw-r--r-- | ld/emultempl/elf32.em | 20 |
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) |