diff options
author | Alan Modra <amodra@gmail.com> | 2018-02-23 21:22:43 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2018-02-23 21:40:48 +1030 |
commit | 01f7e10cf2dcf403462b2feed06c43135651556d (patch) | |
tree | 7bb79a8a98e79c0a34a9e45982362d60f1c485ec /bfd | |
parent | 340d33e565ee9749b06d31e55cb0222fa98bd546 (diff) | |
download | fsf-binutils-gdb-01f7e10cf2dcf403462b2feed06c43135651556d.zip fsf-binutils-gdb-01f7e10cf2dcf403462b2feed06c43135651556d.tar.gz fsf-binutils-gdb-01f7e10cf2dcf403462b2feed06c43135651556d.tar.bz2 |
PR22881, null pointer dereference in assign_file_positions_for_non_load_sections
PR 22881
* elf.c (assign_file_positions_for_non_load_sections): Remove RELRO
segment if no matching LOAD segment.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 6 | ||||
-rw-r--r-- | bfd/elf.c | 84 |
2 files changed, 52 insertions, 38 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index b00836c..16186d8 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2018-02-23 Alan Modra <amodra@gmail.com> + + PR 22881 + * elf.c (assign_file_positions_for_non_load_sections): Remove RELRO + segment if no matching LOAD segment. + 2018-02-23 Kuan-Lin Chen <kuanlinchentw@gmail.com> * elf32-nds32.h: Define mask for ict_model. @@ -5859,6 +5859,7 @@ assign_file_positions_for_non_load_sections (bfd *abfd, if (p->p_type == PT_GNU_RELRO) { bfd_vma start, end; + bfd_boolean ok; if (link_info != NULL) { @@ -5881,6 +5882,7 @@ assign_file_positions_for_non_load_sections (bfd *abfd, end = 0; } + ok = FALSE; if (start < end) { struct elf_segment_map *lm; @@ -5902,48 +5904,54 @@ assign_file_positions_for_non_load_sections (bfd *abfd, && lm->sections[0]->vma < end) break; } - BFD_ASSERT (lm != NULL); - /* Find the section starting the RELRO segment. */ - for (i = 0; i < lm->count; i++) + if (lm != NULL) { - asection *s = lm->sections[i]; - if (s->vma >= start - && s->vma < end - && s->size != 0) - break; + /* Find the section starting the RELRO segment. */ + for (i = 0; i < lm->count; i++) + { + asection *s = lm->sections[i]; + if (s->vma >= start + && s->vma < end + && s->size != 0) + break; + } + + if (i < lm->count) + { + p->p_vaddr = lm->sections[i]->vma; + p->p_paddr = lm->sections[i]->lma; + p->p_offset = lm->sections[i]->filepos; + p->p_memsz = end - p->p_vaddr; + p->p_filesz = p->p_memsz; + + /* The RELRO segment typically ends a few bytes + into .got.plt but other layouts are possible. + In cases where the end does not match any + loaded section (for instance is in file + padding), trim p_filesz back to correspond to + the end of loaded section contents. */ + if (p->p_filesz > lp->p_vaddr + lp->p_filesz - p->p_vaddr) + p->p_filesz = lp->p_vaddr + lp->p_filesz - p->p_vaddr; + + /* Preserve the alignment and flags if they are + valid. The gold linker generates RW/4 for + the PT_GNU_RELRO section. It is better for + objcopy/strip to honor these attributes + otherwise gdb will choke when using separate + debug files. */ + if (!m->p_align_valid) + p->p_align = 1; + if (!m->p_flags_valid) + p->p_flags = PF_R; + ok = TRUE; + } } - BFD_ASSERT (i < lm->count); - - p->p_vaddr = lm->sections[i]->vma; - p->p_paddr = lm->sections[i]->lma; - p->p_offset = lm->sections[i]->filepos; - p->p_memsz = end - p->p_vaddr; - p->p_filesz = p->p_memsz; - - /* The RELRO segment typically ends a few bytes into - .got.plt but other layouts are possible. In cases - where the end does not match any loaded section (for - instance is in file padding), trim p_filesz back to - correspond to the end of loaded section contents. */ - if (p->p_filesz > lp->p_vaddr + lp->p_filesz - p->p_vaddr) - p->p_filesz = lp->p_vaddr + lp->p_filesz - p->p_vaddr; - - /* Preserve the alignment and flags if they are valid. The - gold linker generates RW/4 for the PT_GNU_RELRO section. - It is better for objcopy/strip to honor these attributes - otherwise gdb will choke when using separate debug files. - */ - if (!m->p_align_valid) - p->p_align = 1; - if (!m->p_flags_valid) - p->p_flags = PF_R; - } - else - { - memset (p, 0, sizeof *p); - p->p_type = PT_NULL; } + if (link_info != NULL) + BFD_ASSERT (ok); + if (!ok) + memset (p, 0, sizeof *p); } else if (p->p_type == PT_GNU_STACK) { |