aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Hatle <mark.hatle@windriver.com>2018-10-12 16:20:48 -0400
committerMark Hatle <mark.hatle@windriver.com>2019-06-24 11:17:47 -0400
commitf9975537dbfd9ade0fc813bd5cf5fcbe41753a37 (patch)
tree02e864a22518d4aec62360e4d707de3c8d68476c
parentbef24e6cee1e55b3bdbdb2defa625062cbb751a8 (diff)
downloadprelink-cross-cross_prelink.tar.gz
prelink-cross-cross_prelink.tar.bz2
prelink-cross-cross_prelink.zip
Detect PIE executables w/ COPY relocs, and prevent running over the sectionscross_prelink_stagingcross_prelink
before the commit (a89297f08cda5ca48d21088891150e7ccc9ddac3) the system would report: COPY relocations don't point into .bss or .sbss section Now, it often reports: file offsets not monotonically increasing This was tracked down (using this debug code) to the .gnu.conflict section being added. In one example the offset ranges ended up being: ../src/prelink: section 15 .fini file offset range 000012f4 and 000012fd ../src/prelink: section 16 .gnu.conflict file offset range 00001300 and 00002080 ../src/prelink: section 17 .rodata file offset range 00002000 and 000020a3 ../src/prelink: section 18 .eh_frame_hdr file offset range 000020a4 and 00002118 This indicates that the new .gnu.conflict section overwrites .rodata by 0x80 bytes. This commit includes a check and error return for this condition. Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
-rw-r--r--src/dso.c18
-rw-r--r--src/exec.c9
2 files changed, 25 insertions, 2 deletions
diff --git a/src/dso.c b/src/dso.c
index 1025c77..3c028ea 100644
--- a/src/dso.c
+++ b/src/dso.c
@@ -221,8 +221,22 @@ check_dso (DSO *dso)
|| RELOCATE_SCN (dso->shdr[last].sh_flags)
|| RELOCATE_SCN (dso->shdr[i].sh_flags))
{
- error (0, 0, "%s: section file offsets not monotonically increasing",
- dso->filename);
+ int j = 0;
+ for (j = 1; j < dso->ehdr.e_shnum; ++j) {
+ const char *name
+ = strptr (dso, dso->ehdr.e_shstrndx, dso->shdr[j].sh_name);
+
+ error(0, 0, "section %d %s file offset range %08lx and %08lx",
+ j, name,
+ dso->shdr[j].sh_offset,
+ dso->shdr[j].sh_offset + (dso->shdr[j].sh_type == SHT_NOBITS ? 0 : dso->shdr[j].sh_size));
+ }
+
+ error (0, 0, "%s: section [%d and %d] file offsets [%08lx and %08lx] not monotonically increasing",
+ dso->filename, last, i,
+ dso->shdr[last].sh_offset + (dso->shdr[last].sh_type == SHT_NOBITS ? 0 : dso->shdr[last].sh_size),
+ dso->shdr[i].sh_offset
+ );
return 1;
}
}
diff --git a/src/exec.c b/src/exec.c
index 4f56629..ca7fd14 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -1122,6 +1122,15 @@ error_out:
goto error_out;
if (set_dynamic (dso, DT_GNU_CONFLICTSZ, dso->shdr[i].sh_size, 1))
goto error_out;
+ /* Check if we're going to run over the next section */
+ if (dso->shdr[i].sh_offset
+ + (dso->shdr[i].sh_type == SHT_NOBITS
+ ? 0 : dso->shdr[i].sh_size) > dso->shdr[i+1].sh_offset)
+ {
+ error (0, ENOMEM, "%s: Could not create .gnu.conflict section [overwrites next section]",
+ dso->filename);
+ goto error_out;
+ }
}
if (undo != -1)