summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2019-10-20 17:26:29 +0200
committerMark Wielaard <mark@klomp.org>2019-10-26 02:13:47 +0200
commit9d3003f6b0baa94a53013fbefb4f6542bc532a6c (patch)
tree6ce2fb5eb71504096f6dbee106fc3241ae781029 /src
parent90f4bb30381b0354b8b40cd09e68005713bfd69a (diff)
unstrip: Add sanity check for bogus sh_offset of allocated sections.
unstrip tries to preserve any allocated section offset in an executable or shared library. If the offset is extremely large that would cause the disk to fill up because we will write out a file with lots of padding to put the section contents at that particular offset. Add a sanity check that makes sure we just error out if there is such a bogus offset by checking that no offset is larger than the original ELF file size. https://sourceware.org/bugzilla/show_bug.cgi?id=25083 Signed-off-by: Mark Wielaard <mark@klomp.org>
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog4
-rw-r--r--src/unstrip.c15
2 files changed, 19 insertions, 0 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 9a7d9558..a20faff7 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+2019-10-20 Mark Wielaard <mark@klomp.org>
+
+ * unstrip.c (copy_elided_sections): Set and check max_off.
+
2019-10-21 Mark Wielaard <mark@klomp.org>
* unstrip.c (adjust_relocs): Add map_size argument and check ndx
diff --git a/src/unstrip.c b/src/unstrip.c
index c097d460..4e4366e5 100644
--- a/src/unstrip.c
+++ b/src/unstrip.c
@@ -1397,6 +1397,16 @@ more sections in stripped file than debug file -- arguments reversed?"));
if (unlikely (stripped_shnum == 0))
error (EXIT_FAILURE, 0, _("no sections in stripped file"));
+ /* Used as sanity check for allocated section offset, if the section
+ offset needs to be preserved. We want to know the max size of the
+ ELF file, to check if any existing section offsets are OK. */
+ int64_t max_off = -1;
+ if (stripped_ehdr->e_type != ET_REL)
+ {
+ elf_flagelf (stripped, ELF_C_SET, ELF_F_LAYOUT);
+ max_off = elf_update (stripped, ELF_C_NULL);
+ }
+
/* Cache the stripped file's section details. */
struct section sections[stripped_shnum - 1];
Elf_Scn *scn = NULL;
@@ -1697,6 +1707,11 @@ more sections in stripped file than debug file -- arguments reversed?"));
/* Preserve the file layout of the allocated sections. */
if (stripped_ehdr->e_type != ET_REL && (shdr_mem.sh_flags & SHF_ALLOC))
{
+ if (max_off > 0 && sec->shdr.sh_offset > (Elf64_Off) max_off)
+ error (EXIT_FAILURE, 0,
+ "allocated section offset too large [%zd] %" PRIx64,
+ elf_ndxscn (sec->scn), sec->shdr.sh_offset);
+
shdr_mem.sh_offset = sec->shdr.sh_offset;
placed[elf_ndxscn (sec->outscn) - 1] = true;