aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2018-02-23 21:22:43 +1030
committerAlan Modra <amodra@gmail.com>2018-02-23 21:40:48 +1030
commit01f7e10cf2dcf403462b2feed06c43135651556d (patch)
tree7bb79a8a98e79c0a34a9e45982362d60f1c485ec /bfd
parent340d33e565ee9749b06d31e55cb0222fa98bd546 (diff)
downloadfsf-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/ChangeLog6
-rw-r--r--bfd/elf.c84
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.
diff --git a/bfd/elf.c b/bfd/elf.c
index 2fb8377..cf03814 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -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)
{