From a59005e836b84f070e1b2c541059317ed1936f4d Mon Sep 17 00:00:00 2001 From: John Reiser Date: Mon, 3 Apr 2017 20:11:08 -0700 Subject: [PATCH] Elf propagates NX via PT_GNU_STACK (except MIPS stub is too difficult for now) https://github.com/upx/upx/issues/81 modified: ../.github/travis_testsuite_1.sh modified: p_elf_enum.h modified: p_lx_elf.cpp modified: p_lx_elf.h modified: stub/amd64-linux.elf-entry.h modified: stub/i386-linux.elf-fold.h modified: stub/powerpc-linux.elf-fold.h modified: stub/powerpc64le-linux.elf-fold.h modified: stub/src/amd64-linux.elf-entry.S modified: stub/src/i386-linux.elf-fold.S modified: stub/src/powerpc-linux.elf-fold.S modified: stub/src/powerpc64le-linux.elf-fold.S modified: stub/tmp/amd64-linux.elf-entry.bin.dump modified: stub/tmp/i386-linux.elf-fold.map modified: stub/tmp/powerpc-linux.elf-fold.map modified: stub/tmp/powerpc64le-linux.elf-fold.map --- .github/travis_testsuite_1.sh | 42 +- src/p_elf_enum.h | 1 + src/p_lx_elf.cpp | 63 ++- src/p_lx_elf.h | 2 + src/stub/amd64-linux.elf-entry.h | 558 ++++++++++---------- src/stub/i386-linux.elf-fold.h | 206 ++++---- src/stub/powerpc-linux.elf-fold.h | 396 +++++++------- src/stub/powerpc64le-linux.elf-fold.h | 287 +++++----- src/stub/src/amd64-linux.elf-entry.S | 4 +- src/stub/src/i386-linux.elf-fold.S | 4 +- src/stub/src/powerpc-linux.elf-fold.S | 8 +- src/stub/src/powerpc64le-linux.elf-fold.S | 8 +- src/stub/tmp/amd64-linux.elf-entry.bin.dump | 4 +- src/stub/tmp/i386-linux.elf-fold.map | 24 +- src/stub/tmp/powerpc-linux.elf-fold.map | 36 +- src/stub/tmp/powerpc64le-linux.elf-fold.map | 78 +-- 16 files changed, 889 insertions(+), 832 deletions(-) diff --git a/.github/travis_testsuite_1.sh b/.github/travis_testsuite_1.sh index 57cec703..1aae69b6 100644 --- a/.github/travis_testsuite_1.sh +++ b/.github/travis_testsuite_1.sh @@ -150,81 +150,81 @@ c3f44b4d00a87384c03a6f9e7aec809c1addfe3e271244d38a474f296603088c *mipsel-linux.e b8c35fa2956da17ca505956e9f5017bb5f3a746322647e24ccb8ff28059cafa4 *powerpc-linux.elf/upx-3.91 " expected_sha256sums__t110_compress_ucl_nrv2b_3_no_filter="\ -d7c6e681951409257658c675f647969fe6f01207f779d0a7e3ab0a419f20ecf9 *amd64-linux.elf/upx-3.91 +c29d6412e2d3eaf027a59d13f475c4c1902bebefada05f54f369bde25255cf76 *amd64-linux.elf/upx-3.91 5b9ec916beae0eadc665235158a9ae5bce1309823a344503268a88e32e77824a *arm-wince.pe/upx-3.91.exe 18c154dd87227867cf6390038499393d454064af0668bf3451ef1e2e66290176 *armeb-linux.elf/upx-3.91 960dc15876221832510142816605b9ef568c0de3050ca0a79f3553643c5d5e0f *i386-dos32.djgpp2.coff/upx-3.91.exe -5d970493750d88ecd638998b83fa6107c5b4c290f2467894cdadfc359b9ecb9f *i386-linux.elf/upx-3.91 +96b8ca17587795451b1c164222468a4052443c2360f7fd812e7a6dbdf7ac92c3 *i386-linux.elf/upx-3.91 ca6925a15c1ab8931f0a8fe9ef87f5893403d6e46098f4cd1a5f6f6f0fbdeb44 *i386-win32.pe/upx-3.91.exe 14ff2a4e215a25ed7442b004bca3d82094f7c01784fc4876eb50d365441f35c3 *m68k-atari.tos/upx-3.91.ttp 4163afbb2475b669e131265c0f7ea179c35f19ccce66732feee08fe20c33775e *mipsel-linux.elf/upx-3.91 -2d96c1f769567a6c5b23a39fbc70d5303fe732dad4a6353fa06224ea1897d611 *powerpc-linux.elf/upx-3.91 +63a07691a10cf68cc46fc0da5f13c40e09e15f5caafd18cde70622d5c9e9473b *powerpc-linux.elf/upx-3.91 " expected_sha256sums__t120_compress_ucl_nrv2d_3_no_filter="\ -457988127f7c8d52b088971d88db74cb9e3197a23389f754bd3de16d03258898 *amd64-linux.elf/upx-3.91 +53ffed9b3a25e96075707105e30060b4f4ab7e2712356858cd7db56fcd6fcc9f *amd64-linux.elf/upx-3.91 22216286b1bf3066d9022b921f37beff6712b5f3fc8c092f2dc1477638d9f8cc *arm-wince.pe/upx-3.91.exe f7338f71b4e7ed729aecf6c6e7704c39f4d5b274685c28b877247686357c776e *armeb-linux.elf/upx-3.91 b6e98d36bd916fa63ec799e47dd7cac3674154370a9680492d84f1853bf14c3e *i386-dos32.djgpp2.coff/upx-3.91.exe -7f57e8993caa50eddd96b6f22be64b1ab619f35135c584e92d26b90bc9952a38 *i386-linux.elf/upx-3.91 +870a1875388417751360dab13e45486e1ecb33583833ba33920d9b1668d72b76 *i386-linux.elf/upx-3.91 d2692b3e4a278559456e299164714c4bb8ebbcf230ab12521619e2e94580597d *i386-win32.pe/upx-3.91.exe cd1ae0f2781787bf7c61f3600cc889313e6027615d78e562d624d717671e55c3 *m68k-atari.tos/upx-3.91.ttp 26b30c10ba8980fa6fc564b79eb2931e07bb7b2f89f07a0656c28be71185a3ea *mipsel-linux.elf/upx-3.91 -c4cf483a825385b51fba75852c42b0e08d73ea0b0236a548571f6bb24fa9ed0a *powerpc-linux.elf/upx-3.91 +8c2d16dfd9e87fd6925aa4b3465e6b35a16464cea2dc879aa7abb0bd0beba0c7 *powerpc-linux.elf/upx-3.91 " expected_sha256sums__t130_compress_ucl_nrv2e_3_no_filter="\ -b6d5be27ef60c487ad53ddd5efdbedaf39de40810a30accd99c7ab618cd5aab9 *amd64-linux.elf/upx-3.91 +3ab9a7cd2f2a6d7cd7e11a9911147f9d41a8708f48e2e06c19e9487d2472015f *amd64-linux.elf/upx-3.91 08c55815175ce0d34fca3b368336dd346a2354dbe4f046210c82f6961350a50f *arm-wince.pe/upx-3.91.exe b5f27af98d063473853ee28f6572c7438c167d80bcc2b89c30fb436cc5e79309 *armeb-linux.elf/upx-3.91 45f50d69e685f7ea752f76c05554d4c2ce023c0218465a4f8919138a76ae6c71 *i386-dos32.djgpp2.coff/upx-3.91.exe -3bbe4b9b439bc12dace58ea8524fccd5944dffcd83a2b49be18c6a06e3c30490 *i386-linux.elf/upx-3.91 +2cde86ee89c67e5162a6065f0a7d76c852a9c366dbf8b61add07e14936bd7cf9 *i386-linux.elf/upx-3.91 eb7c2f74979c11b35193a0a9d428596bda46420d9363666fe1b967f5cd1610c6 *i386-win32.pe/upx-3.91.exe cefb13395220fb2e931d0fb32e27663c4a27035f9e79131bbabc44fa54e6336e *m68k-atari.tos/upx-3.91.ttp 602be188fca1dd63593a2ace68ea221d720fd2ddf9df85c1ab019feda69f1cad *mipsel-linux.elf/upx-3.91 -32c7a6c79fa5249b87655b32742f91a90b931c61a2b24fa818df8648e40f9710 *powerpc-linux.elf/upx-3.91 +0811b87fa4856312d9c676656031b3d16a2fe506ce2aa7cb45f6f99c51620b0e *powerpc-linux.elf/upx-3.91 " expected_sha256sums__t140_compress_lzma_2_no_filter="\ -4a447b051e2d8c2ce7f10399f0e7bfeb6f4e5d5ab3fde22e448d15eeb08037ae *amd64-linux.elf/upx-3.91 +aef7536e23f95d8f1589f08af3c77c9210f0c475118b3f44297d7bf997c62239 *amd64-linux.elf/upx-3.91 9759deb5aa8fb004c4b23bbe174042e45869aedeea1a1dd1b729be0e736814da *arm-wince.pe/upx-3.91.exe c476387cb0f9a011f46e2c96bc0b481012cf6a3c6d4a4529c0630c1582cb4c4b *armeb-linux.elf/upx-3.91 a2a800d2ba5cfc1b6bb2b48c91adccb5d3c3b6c0b5c548affccac9244197a312 *i386-dos32.djgpp2.coff/upx-3.91.exe -3c37692bd418a90eb56f34179fa3f079f7e9d19542e1d86e4d58068e1aecf534 *i386-linux.elf/upx-3.91 +aca3e8fbb23609a6210a05c5d2d41e37e6aa2de6a1e4d2a1819f423bbe6090ad *i386-linux.elf/upx-3.91 80aba41aad8268085e853ec872f885981838a625c14095d21ba70cb7abe045a5 *i386-win32.pe/upx-3.91.exe bbed61e42fa7b330b5cde66e4614329f41e21facff1f3667edc03495219c29f9 *m68k-atari.tos/upx-3.91.ttp 57b47244a3a0d01725cbdc9af8572cbe20e2d173857015ad4d32245b52577dc2 *mipsel-linux.elf/upx-3.91 -c537b3986462459cfcd886e21f51d3d0c507e29f49926307f81d8fa79817a432 *powerpc-linux.elf/upx-3.91 +55f9336358ae7468a853cf5466c22acf52b162bf1a86fbbe372f811604933d2d *powerpc-linux.elf/upx-3.91 " expected_sha256sums__t150_compress_ucl_2_all_filters="\ -b700cb1e1a523b7f03a6a9476e94744dc1d0f7d1a4d23aa3fb6c3af5a7a259e2 *amd64-linux.elf/upx-3.91 +cc008e7206baeb849d65dc492d560cf846db0edcd968a76db84229d8c2109fba *amd64-linux.elf/upx-3.91 c7b0f611e9941be58b700219e7a5d34cdbdbf972b6184b13dec5e98fe84de808 *arm-wince.pe/upx-3.91.exe 4c6348cc3e99ba1f27dc8602b890ad7ff7e40351148470a7ed56dcbd112aad02 *armeb-linux.elf/upx-3.91 425c9128285f49b41f9b736f48794f5bebba6981250f669e5a342016b89f2170 *i386-dos32.djgpp2.coff/upx-3.91.exe -1e408f4b46a04a4497cb8506f441690bbb08501596d07da731be912dee87602f *i386-linux.elf/upx-3.91 +65fb2b8b9e7b9c4748f5e09276611b2e1e19a8cdca3a62289cad89b511418af1 *i386-linux.elf/upx-3.91 5565f8196d971feec261dc663ca7ec329fd82b1b18ad49593b865edbaa15765d *i386-win32.pe/upx-3.91.exe 78f24d77855034d467568f05c22cb5e3abd167c90a4d89f4e2059c3e6faa3e2b *m68k-atari.tos/upx-3.91.ttp 23d6856df8f31b9176e0f4709135ce81656ed94539bf909e873b787ce89821cd *mipsel-linux.elf/upx-3.91 -ae840ecf9b171a3e989b22bea5dcd04a5ec1998bb14aeb4836f66b4e03423f7e *powerpc-linux.elf/upx-3.91 +f8d4f47bcce13af4b957cca38539bfc8f7114cc61e693f673453ea44a7a9cabc *powerpc-linux.elf/upx-3.91 " expected_sha256sums__t160_compress_all_methods_1_no_filter="\ -79e014f4bf17239196b829068d17fbee3258e15438e61e6aebaf1aa3f50af68d *amd64-linux.elf/upx-3.91 +0121184400216f893ce55a35868ac8accf868a88ee6a028b92af1ab4694e8300 *amd64-linux.elf/upx-3.91 6b2333719a4fe6c8d2067f682d57cf6fc5fd928bffad4e61aaffcc31287772a7 *arm-wince.pe/upx-3.91.exe e6c5e7ed8935980983ccce9871414e39fe06dbd0f94660d67dde447a1cd51aea *armeb-linux.elf/upx-3.91 d09af3652aa601650f9cd0f125d54e50dfe57b45b9871567140e62a04d032407 *i386-dos32.djgpp2.coff/upx-3.91.exe -fe84e197d9d498138f9600a7c5e31f10804f6c25b28e617786dbbdc6e42919e8 *i386-linux.elf/upx-3.91 +30e86a1aefd2e63657cd77b9faab5cd32d24ac05b47d10da34cf2c95e60903cd *i386-linux.elf/upx-3.91 c3c8b428f7e57a528db89f1365b4f3fda60f0dc03eadb30775ecdbadaa19f0aa *i386-win32.pe/upx-3.91.exe 53c77efbccf41072c4c206343ba3c838be04c47eab415d18c08f086d481612db *m68k-atari.tos/upx-3.91.ttp 616cefa819c0e516c554faac20e6aaf9350a2aacf0041a2641d5809c0da220df *mipsel-linux.elf/upx-3.91 -deae210ec67691e12a530eac3620267bf832800b412fc272739e7346dc481e77 *powerpc-linux.elf/upx-3.91 +9f02f888a9b138d9dd591a43e9b92edaca338921f67e6d0cc8962f9dfb1cda73 *powerpc-linux.elf/upx-3.91 " expected_sha256sums__t170_compress_all_methods_no_lzma_5_no_filter="\ -a5af9273126baeb15dce877d76fc4d3e971d3f60796ee1b176ed01d9bd76bb8f *amd64-linux.elf/upx-3.91 +4293317d05256cc63bcd78b31832778f8274f46e0877a041762e3a20831e12a0 *amd64-linux.elf/upx-3.91 685b7e419b8b0fe3cabdf338a5cad17da55edc608c1bb91c13580b5988d38908 *arm-wince.pe/upx-3.91.exe 536b092822a86875b73ccc95f6685419c7903beb1e48a4afd872e243a7761830 *armeb-linux.elf/upx-3.91 fd0652470c19ebb4a2d1a49e02e71acf9fadab78e513bb4f75d1dc26a0caa7a3 *i386-dos32.djgpp2.coff/upx-3.91.exe -052357e8e078a444952727212f06efef7f389f77e4ec61568ad3959cdecafde9 *i386-linux.elf/upx-3.91 +3addcdad5fb7812e3ce6593136667b2c265ad0ac57672ea3df873daf356533f9 *i386-linux.elf/upx-3.91 5b334db8debd2d59470cad25c7b45e38f6195cdafe92dc8281e4edc9c51385ef *i386-win32.pe/upx-3.91.exe db1c6a70d990cb9a8e02db9b28054267658ce371b8a50e909efdd04cd3670279 *m68k-atari.tos/upx-3.91.ttp 19b801ace68ca0ff034dd557d3ef0a8340d8f17d7b97f120727f67ce098a7d7a *mipsel-linux.elf/upx-3.91 -9dee1dbc76410fbf1b43f1e03de2148bff3586ff5dc9777ec652724be772ded0 *powerpc-linux.elf/upx-3.91 +c0aba0d6137db996486bbb5d08b58187d1ada11cf9057214261bc30f7d2b593b *powerpc-linux.elf/upx-3.91 " ########## end .sha256sums.recreate diff --git a/src/p_elf_enum.h b/src/p_elf_enum.h index ffa31d0e..f86675ae 100644 --- a/src/p_elf_enum.h +++ b/src/p_elf_enum.h @@ -91,6 +91,7 @@ PT_INTERP = 3, /* Name of program interpreter */ PT_NOTE = 4, /* Auxiliary information (esp. OpenBSD) */ PT_PHDR = 6 /* Entry for header table itself */ + , PT_GNU_STACK = 0x6474e551 /* Indicates stack executability */ }; enum { // p_flags diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index 0622fef0..22037eab 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -46,6 +46,8 @@ #define PT_LOAD64 Elf64_Phdr::PT_LOAD #define PT_NOTE32 Elf32_Phdr::PT_NOTE #define PT_NOTE64 Elf64_Phdr::PT_NOTE +#define PT_GNU_STACK32 Elf32_Phdr::PT_GNU_STACK +#define PT_GNU_STACK64 Elf64_Phdr::PT_GNU_STACK //static unsigned const EF_ARM_HASENTRY = 0x02; static unsigned const EF_ARM_EABI_VER4 = 0x04000000; @@ -539,7 +541,7 @@ void PackLinuxElf::defineSymbols(Filter const *) } PackLinuxElf32::PackLinuxElf32(InputFile *f) - : super(f), phdri(NULL) , shdri(NULL), note_body(NULL), + : super(f), phdri(NULL) , shdri(NULL), gnu_stack(NULL), note_body(NULL), page_mask(~0u<ehdr.e_type = ehdri.e_type; // ET_EXEC vs ET_DYN (gcc -pie -fPIC) h3->ehdr.e_ident[Elf32_Ehdr::EI_OSABI] = ei_osabi; + unsigned phnum_o = get_te16(&h2->ehdr.e_phnum); if (Elf32_Ehdr::EM_MIPS==e_machine) { // MIPS R3000 FIXME h3->ehdr.e_ident[Elf32_Ehdr::EI_OSABI] = Elf32_Ehdr::ELFOSABI_NONE; h3->ehdr.e_flags = ehdri.e_flags; @@ -2342,11 +2345,18 @@ PackLinuxElf32::generateElfHdr( } sz_elf_hdrs = sizeof(*h2) - sizeof(linfo); // default + if (gnu_stack) { + sz_elf_hdrs += sizeof(Elf32_Phdr); + memcpy(&h2->phdr[phnum_o++], gnu_stack, sizeof(*gnu_stack)); + set_te16(&h2->ehdr.e_phnum, phnum_o); + } set_te32(&h2->phdr[0].p_filesz, sizeof(*h2)); // + identsize; h2->phdr[0].p_memsz = h2->phdr[0].p_filesz; for (unsigned j=0; j < 3; ++j) { - set_te32(&h3->phdr[j].p_align, page_size); + if (PT_LOAD32==get_te32(&h3->phdr[j].p_type)) { + set_te32(&h3->phdr[j].p_align, page_size); + } } // Info for OS kernel to set the brk() @@ -2364,10 +2374,16 @@ PackLinuxElf32::generateElfHdr( set_te32(&h2->phdr[1].p_flags, Elf32_Phdr::PF_R | Elf32_Phdr::PF_W); } if (ph.format==getFormat()) { - assert(2==get_te16(&h2->ehdr.e_phnum)); + assert((2+ !!gnu_stack) == get_te16(&h2->ehdr.e_phnum)); set_te32(&h2->phdr[0].p_flags, ~Elf32_Phdr::PF_W & get_te32(&h2->phdr[0].p_flags)); - memset(&h2->linfo, 0, sizeof(h2->linfo)); - fo->write(h2, sizeof(*h2)); + if (!gnu_stack) { + memset(&h2->linfo, 0, sizeof(h2->linfo)); + fo->write(h2, sizeof(*h2)); + } + else { + memset(&h3->linfo, 0, sizeof(h3->linfo)); + fo->write(h3, sizeof(*h3)); + } } else { assert(false); // unknown ph.format, PackLinuxElf32 @@ -2562,6 +2578,7 @@ PackLinuxElf64::generateElfHdr( memcpy(h3, proto, sizeof(*h3)); // reads beyond, but OK h3->ehdr.e_type = ehdri.e_type; // ET_EXEC vs ET_DYN (gcc -pie -fPIC) h3->ehdr.e_ident[Elf32_Ehdr::EI_OSABI] = ei_osabi; + unsigned phnum_o = get_te16(&h2->ehdr.e_phnum); assert(get_te32(&h2->ehdr.e_phoff) == sizeof(Elf64_Ehdr)); h2->ehdr.e_shoff = 0; @@ -2578,11 +2595,18 @@ PackLinuxElf64::generateElfHdr( } sz_elf_hdrs = sizeof(*h2) - sizeof(linfo); // default + if (gnu_stack) { + sz_elf_hdrs += sizeof(Elf64_Phdr); + memcpy(&h2->phdr[phnum_o++], gnu_stack, sizeof(*gnu_stack)); + set_te16(&h2->ehdr.e_phnum, phnum_o); + } set_te64(&h2->phdr[0].p_filesz, sizeof(*h2)); // + identsize; h2->phdr[0].p_memsz = h2->phdr[0].p_filesz; - for (unsigned j=0; j < 3; ++j) { - set_te64(&h3->phdr[j].p_align, page_size); + for (unsigned j=0; j < 4; ++j) { + if (PT_LOAD64==get_te32(&h3->phdr[j].p_type)) { + set_te64(&h3->phdr[j].p_align, page_size); + } } // Info for OS kernel to set the brk() @@ -2611,10 +2635,16 @@ PackLinuxElf64::generateElfHdr( set_te32(&h2->phdr[1].p_flags, Elf64_Phdr::PF_R | Elf64_Phdr::PF_W); } if (ph.format==getFormat()) { - assert(2==get_te16(&h2->ehdr.e_phnum)); + assert((2+ !!gnu_stack) == get_te16(&h2->ehdr.e_phnum)); set_te32(&h2->phdr[0].p_flags, ~Elf64_Phdr::PF_W & get_te32(&h2->phdr[0].p_flags)); - memset(&h2->linfo, 0, sizeof(h2->linfo)); - fo->write(h2, sizeof(*h2)); + if (!gnu_stack) { + memset(&h2->linfo, 0, sizeof(h2->linfo)); + fo->write(h2, sizeof(*h2)); + } + else { + memset(&h3->linfo, 0, sizeof(h3->linfo)); + fo->write(h3, sizeof(*h3)); + } } else { assert(false); // unknown ph.format, PackLinuxElf64 @@ -2655,6 +2685,12 @@ void PackLinuxElf32::pack1(OutputFile *fo, Filter & /*ft*/) ++lg2_page; } } + if (phdr->PT_GNU_STACK32 == type) { + // MIPS stub cannot handle GNU_STACK yet. + if (Elf32_Ehdr::EM_MIPS != this->e_machine) { + gnu_stack = phdr; + } + } } page_size = 1u<PT_GNU_STACK64 == type) { + gnu_stack = phdr; + } } page_size = 1u <