/usr/src/binutils/patches/pr22881.diff is in binutils-source 2.30-15ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | # FIXME: Needs a proper backport
# DP: PR22881, null pointer dereference in assign_file_positions_for_non_load_sections
From 01f7e10cf2dcf403462b2feed06c43135651556d Mon Sep 17 00:00:00 2001
From: Alan Modra <amodra@gmail.com>
Date: Fri, 23 Feb 2018 21:22:43 +1030
Subject: [PATCH] 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.
---
bfd/ChangeLog | 6 +++++
bfd/elf.c | 84 ++++++++++++++++++++++++++++++++---------------------------
2 files changed, 52 insertions(+), 38 deletions(-)
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)
{
--
2.9.3
|