From 9d3003f6b0baa94a53013fbefb4f6542bc532a6c Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sun, 20 Oct 2019 17:26:29 +0200 Subject: [PATCH] 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 --- src/ChangeLog | 4 ++++ src/unstrip.c | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/ChangeLog b/src/ChangeLog index 9a7d9558d..a20faff77 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2019-10-20 Mark Wielaard + + * unstrip.c (copy_elided_sections): Set and check max_off. + 2019-10-21 Mark Wielaard * unstrip.c (adjust_relocs): Add map_size argument and check ndx diff --git a/src/unstrip.c b/src/unstrip.c index c097d4602..4e4366e5e 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; -- 2.47.2