diff options
author | Sergey Popov <pinkbyte@gentoo.org> | 2018-08-01 17:23:02 +0300 |
---|---|---|
committer | Sergey Popov <pinkbyte@gentoo.org> | 2018-08-01 17:26:59 +0300 |
commit | fe0b876d4e8abf8f9c28b365886fbbafdf9be14f (patch) | |
tree | 1022e23b2769d8d8e2ddd424b25e2e64b38bf566 /sys-apps/proot | |
parent | app-portage/portage-utils: version bump to v0.73 (diff) | |
download | gentoo-fe0b876d4e8abf8f9c28b365886fbbafdf9be14f.tar.gz gentoo-fe0b876d4e8abf8f9c28b365886fbbafdf9be14f.tar.bz2 gentoo-fe0b876d4e8abf8f9c28b365886fbbafdf9be14f.zip |
sys-apps/proot: revision bump
Backport patches to make PRoot work under newer kernels
and to remove RWX code sections
Closes: https://bugs.gentoo.org/536724
Package-Manager: Portage-2.3.40, Repoman-2.3.9
Diffstat (limited to 'sys-apps/proot')
-rw-r--r-- | sys-apps/proot/files/proot-2.3.1-lib-paths-fix.patch | 4 | ||||
-rw-r--r-- | sys-apps/proot/files/proot-5.1.0-loader.patch | 272 | ||||
-rw-r--r-- | sys-apps/proot/files/proot-5.1.0-makefile.patch | 22 | ||||
-rw-r--r-- | sys-apps/proot/proot-5.1.0-r1.ebuild | 73 |
4 files changed, 369 insertions, 2 deletions
diff --git a/sys-apps/proot/files/proot-2.3.1-lib-paths-fix.patch b/sys-apps/proot/files/proot-2.3.1-lib-paths-fix.patch index 43c0d03d978a..647f19183a9d 100644 --- a/sys-apps/proot/files/proot-2.3.1-lib-paths-fix.patch +++ b/sys-apps/proot/files/proot-2.3.1-lib-paths-fix.patch @@ -1,5 +1,5 @@ ---- src/execve/ldso.c 2013-01-23 16:22:37.870287856 +0400 -+++ src/execve/ldso.c 2013-01-23 16:31:40.219283675 +0400 +--- a/src/execve/ldso.c 2013-01-23 16:22:37.870287856 +0400 ++++ b/src/execve/ldso.c 2013-01-23 16:31:40.219283675 +0400 @@ -285,16 +285,10 @@ /* 6. /lib, /usr/lib + /usr/local/lib */ if (IS_CLASS32(elf_header)) diff --git a/sys-apps/proot/files/proot-5.1.0-loader.patch b/sys-apps/proot/files/proot-5.1.0-loader.patch new file mode 100644 index 000000000000..e74cfaa7807b --- /dev/null +++ b/sys-apps/proot/files/proot-5.1.0-loader.patch @@ -0,0 +1,272 @@ +commit 77d5ba4e5bb35f91d026a3240ad0a91a2d4b662a +Author: CĂ©dric VINCENT <cedric.vincent@st.com> +Date: Fri Feb 20 14:28:55 2015 +0100 + + Set tracee's stack executable when the loaded program requires this. + + This is required for UMEQ and for some older versions of PRoot. For + example: + + $ proot -q umeq-arm64-dce01957 -R ~/gentoo-arm64-20140718 + + Before: + + proot info: vpid 1 terminated with signal 11 + + Now, it is OK. + +diff --git a/src/compat.h b/src/compat.h +index 2b603f1..5009490 100644 +--- a/src/compat.h ++++ b/src/compat.h +@@ -243,5 +243,17 @@ + # ifndef MAP_ANONYMOUS + # define MAP_ANONYMOUS 0x20 + # endif ++# ifndef PROT_READ ++# define PROT_READ 0x1 ++# endif ++# ifndef PROT_WRITE ++# define PROT_WRITE 0x2 ++# endif ++# ifndef PROT_EXEC ++# define PROT_EXEC 0x4 ++# endif ++# ifndef PROT_GROWSDOWN ++# define PROT_GROWSDOWN 0x01000000 ++# endif + + #endif /* COMPAT_H */ +diff --git a/src/execve/elf.h b/src/execve/elf.h +index 3ced10c..a5b367b 100644 +--- a/src/execve/elf.h ++++ b/src/execve/elf.h +@@ -108,7 +108,8 @@ typedef union { + typedef enum { + PT_LOAD = 1, + PT_DYNAMIC = 2, +- PT_INTERP = 3 ++ PT_INTERP = 3, ++ PT_GNU_STACK = 0x6474e551, + } SegmentType; + + typedef struct { +diff --git a/src/execve/enter.c b/src/execve/enter.c +index cb84ec6..f0f3e7f 100644 +--- a/src/execve/enter.c ++++ b/src/execve/enter.c +@@ -252,6 +252,11 @@ static int add_load_info(const ElfHeader *elf_header, + return status; + break; + ++ case PT_GNU_STACK: ++ data->load_info->needs_executable_stack |= ++ ((PROGRAM_FIELD(*elf_header, *program_header, flags) & PF_X) != 0); ++ break; ++ + default: + break; + } +diff --git a/src/execve/execve.h b/src/execve/execve.h +index 11eca10..98b8d03 100644 +--- a/src/execve/execve.h ++++ b/src/execve/execve.h +@@ -49,6 +49,7 @@ typedef struct load_info { + char *raw_path; + Mapping *mappings; + ElfHeader elf_header; ++ bool needs_executable_stack; + + struct load_info *interp; + } LoadInfo; +diff --git a/src/execve/exit.c b/src/execve/exit.c +index e6eff44..36cc51f 100644 +--- a/src/execve/exit.c ++++ b/src/execve/exit.c +@@ -174,6 +174,9 @@ static void *transcript_mappings(void *cursor, const Mapping *mappings) + static int transfer_load_script(Tracee *tracee) + { + const word_t stack_pointer = peek_reg(tracee, CURRENT, STACK_POINTER); ++ static word_t page_size = 0; ++ static word_t page_mask = 0; ++ + word_t entry_point; + + size_t script_size; +@@ -190,10 +193,22 @@ static int transfer_load_script(Tracee *tracee) + void *buffer; + size_t buffer_size; + ++ bool needs_executable_stack; + LoadStatement *statement; + void *cursor; + int status; + ++ if (page_size == 0) { ++ page_size = sysconf(_SC_PAGE_SIZE); ++ if ((int) page_size <= 0) ++ page_size = 0x1000; ++ page_mask = ~(page_size - 1); ++ } ++ ++ needs_executable_stack = (tracee->load_info->needs_executable_stack ++ || ( tracee->load_info->interp != NULL ++ && tracee->load_info->interp->needs_executable_stack)); ++ + /* Strings addresses are required to generate the load script, + * for "open" actions. Since I want to generate it in one + * pass, these strings will be put right below the current +@@ -208,7 +223,7 @@ static int transfer_load_script(Tracee *tracee) + : strlen(tracee->load_info->raw_path) + 1); + + /* A padding will be appended at the end of the load script +- * (a.k.a "strings area") to ensure this latter is aligned on ++ * (a.k.a "strings area") to ensure this latter is aligned to + * a word boundary, for sake of performance. */ + padding_size = (stack_pointer - string1_size - string2_size - string3_size) + % sizeof_word(tracee); +@@ -229,6 +244,7 @@ static int transfer_load_script(Tracee *tracee) + : LOAD_STATEMENT_SIZE(*statement, open) + + (LOAD_STATEMENT_SIZE(*statement, mmap) + * talloc_array_length(tracee->load_info->interp->mappings))) ++ + (needs_executable_stack ? LOAD_STATEMENT_SIZE(*statement, make_stack_exec) : 0) + + LOAD_STATEMENT_SIZE(*statement, start); + + /* Allocate enough room for both the load script and the +@@ -266,6 +282,16 @@ static int transfer_load_script(Tracee *tracee) + else + entry_point = ELF_FIELD(tracee->load_info->elf_header, entry); + ++ if (needs_executable_stack) { ++ /* Load script statement: stack_exec. */ ++ statement = cursor; ++ ++ statement->action = LOAD_ACTION_MAKE_STACK_EXEC; ++ statement->make_stack_exec.start = stack_pointer & page_mask; ++ ++ cursor += LOAD_STATEMENT_SIZE(*statement, make_stack_exec); ++ } ++ + /* Load script statement: start. */ + statement = cursor; + +@@ -352,7 +378,7 @@ static int transfer_load_script(Tracee *tracee) + * | mmap file | + * +------------+ + * | open | +- * +------------+ <- stack pointer, sysarg1 (word aligned) ++ * +------------+ <- stack pointer, userarg1 (word aligned) + */ + + /* Remember we are in the sysexit stage, so be sure the +diff --git a/src/loader/assembly-arm.h b/src/loader/assembly-arm.h +index ee5bb85..59a7fe0 100644 +--- a/src/loader/assembly-arm.h ++++ b/src/loader/assembly-arm.h +@@ -89,4 +89,5 @@ + #define EXECVE 11 + #define EXIT 1 + #define PRCTL 172 ++#define MPROTECT 125 + +diff --git a/src/loader/assembly-x86.h b/src/loader/assembly-x86.h +index c83b3ef..4045144 100644 +--- a/src/loader/assembly-x86.h ++++ b/src/loader/assembly-x86.h +@@ -65,3 +65,4 @@ extern word_t syscall_1(word_t number, word_t arg1); + #define EXECVE 11 + #define EXIT 1 + #define PRCTL 172 ++#define MPROTECT 125 +diff --git a/src/loader/assembly-x86_64.h b/src/loader/assembly-x86_64.h +index c581208..6f431be 100644 +--- a/src/loader/assembly-x86_64.h ++++ b/src/loader/assembly-x86_64.h +@@ -93,3 +93,4 @@ + #define EXECVE 59 + #define EXIT 60 + #define PRCTL 157 ++#define MPROTECT 10 +diff --git a/src/loader/loader.c b/src/loader/loader.c +index 5b31b02..9c2037b 100644 +--- a/src/loader/loader.c ++++ b/src/loader/loader.c +@@ -171,6 +171,14 @@ void _start(void *cursor) + cursor += LOAD_STATEMENT_SIZE(*stmt, mmap); + break; + ++ case LOAD_ACTION_MAKE_STACK_EXEC: ++ SYSCALL(MPROTECT, 3, ++ stmt->make_stack_exec.start, 1, ++ PROT_READ | PROT_WRITE | PROT_EXEC | PROT_GROWSDOWN); ++ ++ cursor += LOAD_STATEMENT_SIZE(*stmt, make_stack_exec); ++ break; ++ + case LOAD_ACTION_START_TRACED: + traced = true; + /* Fall through. */ +diff --git a/src/loader/script.h b/src/loader/script.h +index bb48af5..6ae7621 100644 +--- a/src/loader/script.h ++++ b/src/loader/script.h +@@ -42,6 +42,10 @@ struct load_statement { + word_t clear_length; + } mmap; + ++ struct { ++ word_t start; ++ } make_stack_exec; ++ + struct { + word_t stack_pointer; + word_t entry_point; +@@ -67,7 +71,8 @@ typedef struct load_statement LoadStatement; + #define LOAD_ACTION_OPEN 1 + #define LOAD_ACTION_MMAP_FILE 2 + #define LOAD_ACTION_MMAP_ANON 3 +-#define LOAD_ACTION_START_TRACED 4 +-#define LOAD_ACTION_START 5 ++#define LOAD_ACTION_MAKE_STACK_EXEC 4 ++#define LOAD_ACTION_START_TRACED 5 ++#define LOAD_ACTION_START 6 + + #endif /* SCRIPT */ + +commit d649854ddb66779950954aac99d960379c631a71 +Author: Nicolas Cornu <ncornu@aldebaran.com> +Date: Wed Jul 29 14:52:57 2015 +0200 + + Fix use of size + +diff --git a/src/execve/enter.c b/src/execve/enter.c +index 8f22d9c..4c163a1 100644 +--- a/src/execve/enter.c ++++ b/src/execve/enter.c +@@ -454,10 +454,10 @@ static int expand_runner(Tracee* tracee, char host_path[PATH_MAX], char user_pat + } + + extern unsigned char _binary_loader_exe_start; +-extern unsigned char _binary_loader_exe_size; ++extern unsigned char _binary_loader_exe_end; + + extern unsigned char WEAK _binary_loader_m32_exe_start; +-extern unsigned char WEAK _binary_loader_m32_exe_size; ++extern unsigned char WEAK _binary_loader_m32_exe_end; + + /** + * Extract the built-in loader. This function returns NULL if an +@@ -483,11 +483,11 @@ static char *extract_loader(const Tracee *tracee, bool wants_32bit_version) + + if (wants_32bit_version) { + start = (void *) &_binary_loader_m32_exe_start; +- size = (size_t) &_binary_loader_m32_exe_size; ++ size = (size_t)(&_binary_loader_m32_exe_end-&_binary_loader_m32_exe_start); + } + else { + start = (void *) &_binary_loader_exe_start; +- size = (size_t) &_binary_loader_exe_size; ++ size = (size_t) (&_binary_loader_exe_end-&_binary_loader_exe_start); + } + + status2 = write(fd, start, size); diff --git a/sys-apps/proot/files/proot-5.1.0-makefile.patch b/sys-apps/proot/files/proot-5.1.0-makefile.patch new file mode 100644 index 000000000000..414cb29010cb --- /dev/null +++ b/sys-apps/proot/files/proot-5.1.0-makefile.patch @@ -0,0 +1,22 @@ +--- a/src/GNUmakefile 2018-08-01 16:30:00.957743804 +0300 ++++ b/src/GNUmakefile 2018-08-01 16:30:34.876741798 +0300 +@@ -15,8 +15,8 @@ + OBJDUMP = $(CROSS_COMPILE)objdump + + CPPFLAGS += -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -I. -I$(VPATH) +-CFLAGS += -Wall -Wextra -O2 +-LDFLAGS += -ltalloc ++CFLAGS += -Wall -Wextra ++LDFLAGS += -ltalloc -Wl,-z,noexecstack + + CARE_LDFLAGS = -larchive + +@@ -182,7 +182,7 @@ + $(eval $(call define_from_arch.h,$1,LOADER_ADDRESS)) + + LOADER_CFLAGS$1 += -fPIC -ffreestanding $(LOADER_ARCH_CFLAGS$1) +-LOADER_LDFLAGS$1 += -static -nostdlib -Wl$(BUILD_ID_NONE),-Ttext=$(LOADER_ADDRESS$1) ++LOADER_LDFLAGS$1 += -static -nostdlib -Wl$(BUILD_ID_NONE),-Ttext=$(LOADER_ADDRESS$1),-z,noexecstack + + loader/loader$1.o: loader/loader.c + @mkdir -p $$(dir $$@) diff --git a/sys-apps/proot/proot-5.1.0-r1.ebuild b/sys-apps/proot/proot-5.1.0-r1.ebuild new file mode 100644 index 000000000000..d8436f733386 --- /dev/null +++ b/sys-apps/proot/proot-5.1.0-r1.ebuild @@ -0,0 +1,73 @@ +# Copyright 1999-2018 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +EAPI=7 +MY_PN="PRoot" + +inherit eutils toolchain-funcs + +DESCRIPTION="User-space implementation of chroot, mount --bind, and binfmt_misc" +HOMEPAGE="https://proot-me.github.io/" +SRC_URI="https://github.com/proot-me/${MY_PN}/archive/v${PV}.tar.gz -> ${P}.tar.gz" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~amd64 ~x86" +IUSE="care test" + +RDEPEND="care? ( app-arch/libarchive:0= ) + sys-libs/talloc" +DEPEND="${RDEPEND} + care? ( dev-libs/uthash ) + test? ( dev-util/valgrind )" + +# Breaks sandbox +RESTRICT="test" + +S="${WORKDIR}/${MY_PN}-${PV}" + +PATCHES=( + "${FILESDIR}/${PN}-5.1.0-makefile.patch" + "${FILESDIR}/${PN}-2.3.1-lib-paths-fix.patch" + "${FILESDIR}/${PN}-5.1.0-loader.patch" +) + +src_compile() { + # build the proot and care targets + emake -C src V=1 \ + CC="$(tc-getCC)" \ + CHECK_VERSION="true" \ + CAREBUILDENV="ok" \ + proot $(use care && echo "care") +} + +src_install() { + if use care; then + dobin src/care + dodoc doc/care/*.txt + fi + dobin src/proot + newman doc/proot/man.1 proot.1 + dodoc doc/proot/*.txt + dodoc -r doc/articles +} + +src_test() { + emake -C tests -j1 CC="$(tc-getCC)" +} + +pkg_postinst() { + elog "If you have segfaults on recent (>4.8) kernels" + elog "try to disable seccomp support like so:" + elog "'export PROOT_NO_SECCOMP=1'" + elog "prior to running proot" + + if use care; then + elog "You have enabled 'care' USE flag, that builds and installs" + elog "dynamically linked care binary." + elog "Upstream does NOT support such way of building CARE," + elog "it provides only prebuilt binaries." + elog "CARE also has known problems on hardened systems" + elog "Please do NOT file bugs about them to https://bugs.gentoo.org" + fi +} |