From dbc88fc14992c556b94e77de563a8f7abcb0b653 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 19 Feb 2018 09:52:53 +1030 Subject: [PATCH] PT_LOAD and PT_GNU_RELRO segment overlap Commit 325ba6fb34 excluded degenerate zero length PT_LOAD segments, but that only fixed part of the problem, which was that the load segment limits were not calculated properly. PR 22845 * elf.c (IS_TBSS): Define. (_bfd_elf_map_sections_to_segments): Use IS_TBSS. (assign_file_positions_for_non_load_sections): Revert last change. Properly calculate load segment limits to compare against relro limits. --- bfd/ChangeLog | 8 ++++++++ bfd/elf.c | 23 ++++++++++------------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 946c6bcd7b6..9340d62c74d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2018-02-19 Alan Modra + + PR 22845 + * elf.c (IS_TBSS): Define. + (_bfd_elf_map_sections_to_segments): Use IS_TBSS. + (assign_file_positions_for_non_load_sections): Revert last change. + Properly calculate load segment limits to compare against relro limits. + 2018-02-17 Alan Modra PR 22845 diff --git a/bfd/elf.c b/bfd/elf.c index b069b592652..f3a70f11438 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -4542,6 +4542,9 @@ elf_modify_segment_map (bfd *abfd, return TRUE; } +#define IS_TBSS(s) \ + ((s->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) == SEC_THREAD_LOCAL) + /* Set up a mapping from BFD sections to program segments. */ bfd_boolean @@ -4801,11 +4804,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) executable = TRUE; last_hdr = hdr; /* .tbss sections effectively have zero size. */ - if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) - != SEC_THREAD_LOCAL) - last_size = hdr->size; - else - last_size = 0; + last_size = !IS_TBSS (hdr) ? hdr->size : 0; continue; } @@ -4831,10 +4830,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) last_hdr = hdr; /* .tbss sections effectively have zero size. */ - if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL) - last_size = hdr->size; - else - last_size = 0; + last_size = !IS_TBSS (hdr) ? hdr->size : 0; phdr_index = i; phdr_in_segment = FALSE; } @@ -4843,8 +4839,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) for .tbss. */ if (last_hdr != NULL && (i - phdr_index != 1 - || ((last_hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) - != SEC_THREAD_LOCAL))) + || !IS_TBSS (last_hdr))) { m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment); if (m == NULL) @@ -5897,9 +5892,11 @@ assign_file_positions_for_non_load_sections (bfd *abfd, lm = lm->next, lp++) { if (lp->p_type == PT_LOAD - && lp->p_memsz != 0 && lm->count != 0 - && lm->sections[lm->count - 1]->vma >= start + && (lm->sections[lm->count - 1]->vma + + (!IS_TBSS (lm->sections[lm->count - 1]) + ? lm->sections[lm->count - 1]->size + : 0)) > start && lm->sections[0]->vma < end) break; } -- 2.30.2