diff options
author | Mark Wielaard <mark@klomp.org> | 2019-10-20 17:26:29 +0200 |
---|---|---|
committer | Mark Wielaard <mark@klomp.org> | 2019-10-26 02:13:47 +0200 |
commit | 9d3003f6b0baa94a53013fbefb4f6542bc532a6c (patch) | |
tree | 6ce2fb5eb71504096f6dbee106fc3241ae781029 /src | |
parent | 90f4bb30381b0354b8b40cd09e68005713bfd69a (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/ChangeLog | 4 | ||||
-rw-r--r-- | src/unstrip.c | 15 |
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; |