From 58061cd121013425030b12adaa415f817a4764b8 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Sat, 15 Dec 2018 20:59:45 -0800 Subject: [PATCH] Check .p_offset https://github.com/upx/upx/issues/235 POC13 modified: p_lx_elf.cpp --- src/p_lx_elf.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index f49bf871..d61449b8 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -2128,7 +2128,7 @@ bool PackLinuxElf32::canPack() } xct_off = elf_get_offset_from_address(xct_va); if (opt->debug.debug_level) { - fprintf(stderr, "shlib canPack: xct_va=%#lx xct_off=%lx\n", + fprintf(stderr, "shlib canPack: xct_va=%#lx xct_off=%#lx\n", (long)xct_va, (long)xct_off); } goto proceed; // But proper packing depends on checking xct_va. @@ -2390,7 +2390,7 @@ PackLinuxElf64::canPack() } xct_off = elf_get_offset_from_address(xct_va); if (opt->debug.debug_level) { - fprintf(stderr, "shlib canPack: xct_va=%#lx xct_off=%lx\n", + fprintf(stderr, "shlib canPack: xct_va=%#lx xct_off=%#lx\n", (long)xct_va, (long)xct_off); } goto proceed; // But proper packing depends on checking xct_va. @@ -4614,7 +4614,14 @@ PackLinuxElf32::elf_get_offset_from_address(unsigned addr) const for (; --j>=0; ++phdr) if (PT_LOAD32 == get_te32(&phdr->p_type)) { unsigned const t = addr - get_te32(&phdr->p_vaddr); if (t < get_te32(&phdr->p_filesz)) { - return t + get_te32(&phdr->p_offset); + unsigned const p_offset = get_te32(&phdr->p_offset); + if (file_size <= (off_t)p_offset) { // FIXME: weak + char msg[40]; snprintf(msg, sizeof(msg), + "bad Elf32_Phdr[%d].p_offset %x", + -1+ e_phnum - j, p_offset); + throwCantPack(msg); + } + return t + p_offset; } } return 0; @@ -4687,7 +4694,14 @@ PackLinuxElf64::elf_get_offset_from_address(upx_uint64_t addr) const for (; --j>=0; ++phdr) if (PT_LOAD64 == get_te32(&phdr->p_type)) { upx_uint64_t const t = addr - get_te64(&phdr->p_vaddr); if (t < get_te64(&phdr->p_filesz)) { - return t + get_te64(&phdr->p_offset); + upx_uint64_t const p_offset = get_te64(&phdr->p_offset); + if (file_size <= (off_t)p_offset) { // FIXME: weak + char msg[40]; snprintf(msg, sizeof(msg), + "bad Elf64_Phdr[%d].p_offset %#lx", + -1+ e_phnum - j, (long unsigned)p_offset); + throwCantPack(msg); + } + return t + p_offset; } } return 0;