summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'sys-apps')
-rw-r--r--sys-apps/proot/files/proot-2.3.1-lib-paths-fix.patch4
-rw-r--r--sys-apps/proot/files/proot-5.1.0-loader.patch272
-rw-r--r--sys-apps/proot/files/proot-5.1.0-makefile.patch22
-rw-r--r--sys-apps/proot/proot-5.1.0-r1.ebuild73
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
+}