From f95e171e11af975a042d468637cfdea96aaefdd0 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Wed, 22 Mar 2006 20:02:50 +0000 Subject: [PATCH] Workaround linux-2.6.14 binfmt_elf.c: SIGKILL if (0==.p_memsz) on a page boundary. p_lx_elf.cpp p_lx_exc.cpp committer: jreiser 1143057770 +0000 --- src/p_lx_elf.cpp | 20 ++++++++++++++------ src/p_lx_exc.cpp | 18 ++++++++++++++---- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index a7015625..8b09929f 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -587,12 +587,16 @@ PackLinuxElf32::generateElfHdr( // Info for OS kernel to set the brk() if (brka) { +#define PAGE_MASK (~0u<<12) + // linux-2.6.14 binfmt_elf.c: SIGKILL if (0==.p_memsz) on a page boundary + unsigned const brkb = brka | ((0==(~PAGE_MASK & brka)) ? 0x20 : 0); set_native32(&h2->phdr[1].p_type, PT_LOAD32); // be sure - set_native32(&h2->phdr[1].p_offset, 0xfff&brka); - set_native32(&h2->phdr[1].p_vaddr, brka); - set_native32(&h2->phdr[1].p_paddr, brka); + set_native32(&h2->phdr[1].p_offset, ~PAGE_MASK & brkb); + set_native32(&h2->phdr[1].p_vaddr, brkb); + set_native32(&h2->phdr[1].p_paddr, brkb); h2->phdr[1].p_filesz = 0; h2->phdr[1].p_memsz = 0; +#undef PAGE_MASK } } @@ -625,12 +629,16 @@ PackLinuxElf64::generateElfHdr( // Info for OS kernel to set the brk() if (brka) { +#define PAGE_MASK (~0ul<<12) + // linux-2.6.14 binfmt_elf.c: SIGKILL if (0==.p_memsz) on a page boundary + unsigned const brkb = brka | ((0==(~PAGE_MASK & brka)) ? 0x20 : 0); set_native32(&h2->phdr[1].p_type, PT_LOAD32); // be sure - set_native64(&h2->phdr[1].p_offset, 0xfff&brka); - set_native64(&h2->phdr[1].p_vaddr, brka); - set_native64(&h2->phdr[1].p_paddr, brka); + set_native64(&h2->phdr[1].p_offset, ~PAGE_MASK & brkb); + set_native64(&h2->phdr[1].p_vaddr, brkb); + set_native64(&h2->phdr[1].p_paddr, brkb); h2->phdr[1].p_filesz = 0; h2->phdr[1].p_memsz = 0; +#undef PAGE_MASK } } diff --git a/src/p_lx_exc.cpp b/src/p_lx_exc.cpp index 647af6b1..a85e2028 100644 --- a/src/p_lx_exc.cpp +++ b/src/p_lx_exc.cpp @@ -108,12 +108,22 @@ PackLinuxI386::generateElfHdr( // Info for OS kernel to set the brk() if (brka) { +#define PAGE_MASK (~0ul<<12) + // linux-2.6.14 binfmt_elf.c: SIGKILL if (0==.p_memsz) on a page boundary + unsigned const brkb = brka | ((0==(~PAGE_MASK & brka)) ? 0x20 : 0); h2->phdr[1].p_type = PT_LOAD; // be sure - h2->phdr[1].p_offset = 0xfff&brka; - h2->phdr[1].p_vaddr = brka; - h2->phdr[1].p_paddr = brka; + h2->phdr[1].p_offset = ~PAGE_MASK & brkb; + h2->phdr[1].p_vaddr = brkb; + h2->phdr[1].p_paddr = brkb; h2->phdr[1].p_filesz = 0; h2->phdr[1].p_memsz = 0; + if (0==h2->phdr[1].p_flags) { + h2->phdr[1].p_flags = Elf32_Phdr::PF_R|Elf32_Phdr::PF_W; + } + if (0==h2->phdr[1].p_align) { + h2->phdr[1].p_align = 0x1000; + } +#undef PAGE_MASK } if (ph.format==UPX_F_LINUX_i386 ) { @@ -128,7 +138,7 @@ PackLinuxI386::generateElfHdr( } else if (ph.format==UPX_F_LINUX_SH_i386) { assert(h2->ehdr.e_phnum==1); - h2->ehdr.e_phnum = 2; + h2->ehdr.e_phnum = 1; memset(&h2->linfo, 0, sizeof(h2->linfo)); fo->write(h2, sizeof(*h2)); }