Gentoo Archives: gentoo-commits

From: Sergey Popov <pinkbyte@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] repo/gentoo:master commit in: sys-apps/proot/files/, sys-apps/proot/
Date: Wed, 01 Aug 2018 14:27:17
Message-Id: 1533133619.fe0b876d4e8abf8f9c28b365886fbbafdf9be14f.pinkbyte@gentoo
1 commit: fe0b876d4e8abf8f9c28b365886fbbafdf9be14f
2 Author: Sergey Popov <pinkbyte <AT> gentoo <DOT> org>
3 AuthorDate: Wed Aug 1 14:23:02 2018 +0000
4 Commit: Sergey Popov <pinkbyte <AT> gentoo <DOT> org>
5 CommitDate: Wed Aug 1 14:26:59 2018 +0000
6 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=fe0b876d
7
8 sys-apps/proot: revision bump
9
10 Backport patches to make PRoot work under newer kernels
11 and to remove RWX code sections
12
13 Closes: https://bugs.gentoo.org/536724
14 Package-Manager: Portage-2.3.40, Repoman-2.3.9
15
16 .../proot/files/proot-2.3.1-lib-paths-fix.patch | 4 +-
17 sys-apps/proot/files/proot-5.1.0-loader.patch | 272 +++++++++++++++++++++
18 sys-apps/proot/files/proot-5.1.0-makefile.patch | 22 ++
19 sys-apps/proot/proot-5.1.0-r1.ebuild | 73 ++++++
20 4 files changed, 369 insertions(+), 2 deletions(-)
21
22 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
23 index 43c0d03d978..647f19183a9 100644
24 --- a/sys-apps/proot/files/proot-2.3.1-lib-paths-fix.patch
25 +++ b/sys-apps/proot/files/proot-2.3.1-lib-paths-fix.patch
26 @@ -1,5 +1,5 @@
27 ---- src/execve/ldso.c 2013-01-23 16:22:37.870287856 +0400
28 -+++ src/execve/ldso.c 2013-01-23 16:31:40.219283675 +0400
29 +--- a/src/execve/ldso.c 2013-01-23 16:22:37.870287856 +0400
30 ++++ b/src/execve/ldso.c 2013-01-23 16:31:40.219283675 +0400
31 @@ -285,16 +285,10 @@
32 /* 6. /lib, /usr/lib + /usr/local/lib */
33 if (IS_CLASS32(elf_header))
34
35 diff --git a/sys-apps/proot/files/proot-5.1.0-loader.patch b/sys-apps/proot/files/proot-5.1.0-loader.patch
36 new file mode 100644
37 index 00000000000..e74cfaa7807
38 --- /dev/null
39 +++ b/sys-apps/proot/files/proot-5.1.0-loader.patch
40 @@ -0,0 +1,272 @@
41 +commit 77d5ba4e5bb35f91d026a3240ad0a91a2d4b662a
42 +Author: Cédric VINCENT <cedric.vincent@××.com>
43 +Date: Fri Feb 20 14:28:55 2015 +0100
44 +
45 + Set tracee's stack executable when the loaded program requires this.
46 +
47 + This is required for UMEQ and for some older versions of PRoot. For
48 + example:
49 +
50 + $ proot -q umeq-arm64-dce01957 -R ~/gentoo-arm64-20140718
51 +
52 + Before:
53 +
54 + proot info: vpid 1 terminated with signal 11
55 +
56 + Now, it is OK.
57 +
58 +diff --git a/src/compat.h b/src/compat.h
59 +index 2b603f1..5009490 100644
60 +--- a/src/compat.h
61 ++++ b/src/compat.h
62 +@@ -243,5 +243,17 @@
63 + # ifndef MAP_ANONYMOUS
64 + # define MAP_ANONYMOUS 0x20
65 + # endif
66 ++# ifndef PROT_READ
67 ++# define PROT_READ 0x1
68 ++# endif
69 ++# ifndef PROT_WRITE
70 ++# define PROT_WRITE 0x2
71 ++# endif
72 ++# ifndef PROT_EXEC
73 ++# define PROT_EXEC 0x4
74 ++# endif
75 ++# ifndef PROT_GROWSDOWN
76 ++# define PROT_GROWSDOWN 0x01000000
77 ++# endif
78 +
79 + #endif /* COMPAT_H */
80 +diff --git a/src/execve/elf.h b/src/execve/elf.h
81 +index 3ced10c..a5b367b 100644
82 +--- a/src/execve/elf.h
83 ++++ b/src/execve/elf.h
84 +@@ -108,7 +108,8 @@ typedef union {
85 + typedef enum {
86 + PT_LOAD = 1,
87 + PT_DYNAMIC = 2,
88 +- PT_INTERP = 3
89 ++ PT_INTERP = 3,
90 ++ PT_GNU_STACK = 0x6474e551,
91 + } SegmentType;
92 +
93 + typedef struct {
94 +diff --git a/src/execve/enter.c b/src/execve/enter.c
95 +index cb84ec6..f0f3e7f 100644
96 +--- a/src/execve/enter.c
97 ++++ b/src/execve/enter.c
98 +@@ -252,6 +252,11 @@ static int add_load_info(const ElfHeader *elf_header,
99 + return status;
100 + break;
101 +
102 ++ case PT_GNU_STACK:
103 ++ data->load_info->needs_executable_stack |=
104 ++ ((PROGRAM_FIELD(*elf_header, *program_header, flags) & PF_X) != 0);
105 ++ break;
106 ++
107 + default:
108 + break;
109 + }
110 +diff --git a/src/execve/execve.h b/src/execve/execve.h
111 +index 11eca10..98b8d03 100644
112 +--- a/src/execve/execve.h
113 ++++ b/src/execve/execve.h
114 +@@ -49,6 +49,7 @@ typedef struct load_info {
115 + char *raw_path;
116 + Mapping *mappings;
117 + ElfHeader elf_header;
118 ++ bool needs_executable_stack;
119 +
120 + struct load_info *interp;
121 + } LoadInfo;
122 +diff --git a/src/execve/exit.c b/src/execve/exit.c
123 +index e6eff44..36cc51f 100644
124 +--- a/src/execve/exit.c
125 ++++ b/src/execve/exit.c
126 +@@ -174,6 +174,9 @@ static void *transcript_mappings(void *cursor, const Mapping *mappings)
127 + static int transfer_load_script(Tracee *tracee)
128 + {
129 + const word_t stack_pointer = peek_reg(tracee, CURRENT, STACK_POINTER);
130 ++ static word_t page_size = 0;
131 ++ static word_t page_mask = 0;
132 ++
133 + word_t entry_point;
134 +
135 + size_t script_size;
136 +@@ -190,10 +193,22 @@ static int transfer_load_script(Tracee *tracee)
137 + void *buffer;
138 + size_t buffer_size;
139 +
140 ++ bool needs_executable_stack;
141 + LoadStatement *statement;
142 + void *cursor;
143 + int status;
144 +
145 ++ if (page_size == 0) {
146 ++ page_size = sysconf(_SC_PAGE_SIZE);
147 ++ if ((int) page_size <= 0)
148 ++ page_size = 0x1000;
149 ++ page_mask = ~(page_size - 1);
150 ++ }
151 ++
152 ++ needs_executable_stack = (tracee->load_info->needs_executable_stack
153 ++ || ( tracee->load_info->interp != NULL
154 ++ && tracee->load_info->interp->needs_executable_stack));
155 ++
156 + /* Strings addresses are required to generate the load script,
157 + * for "open" actions. Since I want to generate it in one
158 + * pass, these strings will be put right below the current
159 +@@ -208,7 +223,7 @@ static int transfer_load_script(Tracee *tracee)
160 + : strlen(tracee->load_info->raw_path) + 1);
161 +
162 + /* A padding will be appended at the end of the load script
163 +- * (a.k.a "strings area") to ensure this latter is aligned on
164 ++ * (a.k.a "strings area") to ensure this latter is aligned to
165 + * a word boundary, for sake of performance. */
166 + padding_size = (stack_pointer - string1_size - string2_size - string3_size)
167 + % sizeof_word(tracee);
168 +@@ -229,6 +244,7 @@ static int transfer_load_script(Tracee *tracee)
169 + : LOAD_STATEMENT_SIZE(*statement, open)
170 + + (LOAD_STATEMENT_SIZE(*statement, mmap)
171 + * talloc_array_length(tracee->load_info->interp->mappings)))
172 ++ + (needs_executable_stack ? LOAD_STATEMENT_SIZE(*statement, make_stack_exec) : 0)
173 + + LOAD_STATEMENT_SIZE(*statement, start);
174 +
175 + /* Allocate enough room for both the load script and the
176 +@@ -266,6 +282,16 @@ static int transfer_load_script(Tracee *tracee)
177 + else
178 + entry_point = ELF_FIELD(tracee->load_info->elf_header, entry);
179 +
180 ++ if (needs_executable_stack) {
181 ++ /* Load script statement: stack_exec. */
182 ++ statement = cursor;
183 ++
184 ++ statement->action = LOAD_ACTION_MAKE_STACK_EXEC;
185 ++ statement->make_stack_exec.start = stack_pointer & page_mask;
186 ++
187 ++ cursor += LOAD_STATEMENT_SIZE(*statement, make_stack_exec);
188 ++ }
189 ++
190 + /* Load script statement: start. */
191 + statement = cursor;
192 +
193 +@@ -352,7 +378,7 @@ static int transfer_load_script(Tracee *tracee)
194 + * | mmap file |
195 + * +------------+
196 + * | open |
197 +- * +------------+ <- stack pointer, sysarg1 (word aligned)
198 ++ * +------------+ <- stack pointer, userarg1 (word aligned)
199 + */
200 +
201 + /* Remember we are in the sysexit stage, so be sure the
202 +diff --git a/src/loader/assembly-arm.h b/src/loader/assembly-arm.h
203 +index ee5bb85..59a7fe0 100644
204 +--- a/src/loader/assembly-arm.h
205 ++++ b/src/loader/assembly-arm.h
206 +@@ -89,4 +89,5 @@
207 + #define EXECVE 11
208 + #define EXIT 1
209 + #define PRCTL 172
210 ++#define MPROTECT 125
211 +
212 +diff --git a/src/loader/assembly-x86.h b/src/loader/assembly-x86.h
213 +index c83b3ef..4045144 100644
214 +--- a/src/loader/assembly-x86.h
215 ++++ b/src/loader/assembly-x86.h
216 +@@ -65,3 +65,4 @@ extern word_t syscall_1(word_t number, word_t arg1);
217 + #define EXECVE 11
218 + #define EXIT 1
219 + #define PRCTL 172
220 ++#define MPROTECT 125
221 +diff --git a/src/loader/assembly-x86_64.h b/src/loader/assembly-x86_64.h
222 +index c581208..6f431be 100644
223 +--- a/src/loader/assembly-x86_64.h
224 ++++ b/src/loader/assembly-x86_64.h
225 +@@ -93,3 +93,4 @@
226 + #define EXECVE 59
227 + #define EXIT 60
228 + #define PRCTL 157
229 ++#define MPROTECT 10
230 +diff --git a/src/loader/loader.c b/src/loader/loader.c
231 +index 5b31b02..9c2037b 100644
232 +--- a/src/loader/loader.c
233 ++++ b/src/loader/loader.c
234 +@@ -171,6 +171,14 @@ void _start(void *cursor)
235 + cursor += LOAD_STATEMENT_SIZE(*stmt, mmap);
236 + break;
237 +
238 ++ case LOAD_ACTION_MAKE_STACK_EXEC:
239 ++ SYSCALL(MPROTECT, 3,
240 ++ stmt->make_stack_exec.start, 1,
241 ++ PROT_READ | PROT_WRITE | PROT_EXEC | PROT_GROWSDOWN);
242 ++
243 ++ cursor += LOAD_STATEMENT_SIZE(*stmt, make_stack_exec);
244 ++ break;
245 ++
246 + case LOAD_ACTION_START_TRACED:
247 + traced = true;
248 + /* Fall through. */
249 +diff --git a/src/loader/script.h b/src/loader/script.h
250 +index bb48af5..6ae7621 100644
251 +--- a/src/loader/script.h
252 ++++ b/src/loader/script.h
253 +@@ -42,6 +42,10 @@ struct load_statement {
254 + word_t clear_length;
255 + } mmap;
256 +
257 ++ struct {
258 ++ word_t start;
259 ++ } make_stack_exec;
260 ++
261 + struct {
262 + word_t stack_pointer;
263 + word_t entry_point;
264 +@@ -67,7 +71,8 @@ typedef struct load_statement LoadStatement;
265 + #define LOAD_ACTION_OPEN 1
266 + #define LOAD_ACTION_MMAP_FILE 2
267 + #define LOAD_ACTION_MMAP_ANON 3
268 +-#define LOAD_ACTION_START_TRACED 4
269 +-#define LOAD_ACTION_START 5
270 ++#define LOAD_ACTION_MAKE_STACK_EXEC 4
271 ++#define LOAD_ACTION_START_TRACED 5
272 ++#define LOAD_ACTION_START 6
273 +
274 + #endif /* SCRIPT */
275 +
276 +commit d649854ddb66779950954aac99d960379c631a71
277 +Author: Nicolas Cornu <ncornu@×××××××××.com>
278 +Date: Wed Jul 29 14:52:57 2015 +0200
279 +
280 + Fix use of size
281 +
282 +diff --git a/src/execve/enter.c b/src/execve/enter.c
283 +index 8f22d9c..4c163a1 100644
284 +--- a/src/execve/enter.c
285 ++++ b/src/execve/enter.c
286 +@@ -454,10 +454,10 @@ static int expand_runner(Tracee* tracee, char host_path[PATH_MAX], char user_pat
287 + }
288 +
289 + extern unsigned char _binary_loader_exe_start;
290 +-extern unsigned char _binary_loader_exe_size;
291 ++extern unsigned char _binary_loader_exe_end;
292 +
293 + extern unsigned char WEAK _binary_loader_m32_exe_start;
294 +-extern unsigned char WEAK _binary_loader_m32_exe_size;
295 ++extern unsigned char WEAK _binary_loader_m32_exe_end;
296 +
297 + /**
298 + * Extract the built-in loader. This function returns NULL if an
299 +@@ -483,11 +483,11 @@ static char *extract_loader(const Tracee *tracee, bool wants_32bit_version)
300 +
301 + if (wants_32bit_version) {
302 + start = (void *) &_binary_loader_m32_exe_start;
303 +- size = (size_t) &_binary_loader_m32_exe_size;
304 ++ size = (size_t)(&_binary_loader_m32_exe_end-&_binary_loader_m32_exe_start);
305 + }
306 + else {
307 + start = (void *) &_binary_loader_exe_start;
308 +- size = (size_t) &_binary_loader_exe_size;
309 ++ size = (size_t) (&_binary_loader_exe_end-&_binary_loader_exe_start);
310 + }
311 +
312 + status2 = write(fd, start, size);
313
314 diff --git a/sys-apps/proot/files/proot-5.1.0-makefile.patch b/sys-apps/proot/files/proot-5.1.0-makefile.patch
315 new file mode 100644
316 index 00000000000..414cb29010c
317 --- /dev/null
318 +++ b/sys-apps/proot/files/proot-5.1.0-makefile.patch
319 @@ -0,0 +1,22 @@
320 +--- a/src/GNUmakefile 2018-08-01 16:30:00.957743804 +0300
321 ++++ b/src/GNUmakefile 2018-08-01 16:30:34.876741798 +0300
322 +@@ -15,8 +15,8 @@
323 + OBJDUMP = $(CROSS_COMPILE)objdump
324 +
325 + CPPFLAGS += -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -I. -I$(VPATH)
326 +-CFLAGS += -Wall -Wextra -O2
327 +-LDFLAGS += -ltalloc
328 ++CFLAGS += -Wall -Wextra
329 ++LDFLAGS += -ltalloc -Wl,-z,noexecstack
330 +
331 + CARE_LDFLAGS = -larchive
332 +
333 +@@ -182,7 +182,7 @@
334 + $(eval $(call define_from_arch.h,$1,LOADER_ADDRESS))
335 +
336 + LOADER_CFLAGS$1 += -fPIC -ffreestanding $(LOADER_ARCH_CFLAGS$1)
337 +-LOADER_LDFLAGS$1 += -static -nostdlib -Wl$(BUILD_ID_NONE),-Ttext=$(LOADER_ADDRESS$1)
338 ++LOADER_LDFLAGS$1 += -static -nostdlib -Wl$(BUILD_ID_NONE),-Ttext=$(LOADER_ADDRESS$1),-z,noexecstack
339 +
340 + loader/loader$1.o: loader/loader.c
341 + @mkdir -p $$(dir $$@)
342
343 diff --git a/sys-apps/proot/proot-5.1.0-r1.ebuild b/sys-apps/proot/proot-5.1.0-r1.ebuild
344 new file mode 100644
345 index 00000000000..d8436f73338
346 --- /dev/null
347 +++ b/sys-apps/proot/proot-5.1.0-r1.ebuild
348 @@ -0,0 +1,73 @@
349 +# Copyright 1999-2018 Gentoo Foundation
350 +# Distributed under the terms of the GNU General Public License v2
351 +
352 +EAPI=7
353 +MY_PN="PRoot"
354 +
355 +inherit eutils toolchain-funcs
356 +
357 +DESCRIPTION="User-space implementation of chroot, mount --bind, and binfmt_misc"
358 +HOMEPAGE="https://proot-me.github.io/"
359 +SRC_URI="https://github.com/proot-me/${MY_PN}/archive/v${PV}.tar.gz -> ${P}.tar.gz"
360 +
361 +LICENSE="GPL-2"
362 +SLOT="0"
363 +KEYWORDS="~amd64 ~x86"
364 +IUSE="care test"
365 +
366 +RDEPEND="care? ( app-arch/libarchive:0= )
367 + sys-libs/talloc"
368 +DEPEND="${RDEPEND}
369 + care? ( dev-libs/uthash )
370 + test? ( dev-util/valgrind )"
371 +
372 +# Breaks sandbox
373 +RESTRICT="test"
374 +
375 +S="${WORKDIR}/${MY_PN}-${PV}"
376 +
377 +PATCHES=(
378 + "${FILESDIR}/${PN}-5.1.0-makefile.patch"
379 + "${FILESDIR}/${PN}-2.3.1-lib-paths-fix.patch"
380 + "${FILESDIR}/${PN}-5.1.0-loader.patch"
381 +)
382 +
383 +src_compile() {
384 + # build the proot and care targets
385 + emake -C src V=1 \
386 + CC="$(tc-getCC)" \
387 + CHECK_VERSION="true" \
388 + CAREBUILDENV="ok" \
389 + proot $(use care && echo "care")
390 +}
391 +
392 +src_install() {
393 + if use care; then
394 + dobin src/care
395 + dodoc doc/care/*.txt
396 + fi
397 + dobin src/proot
398 + newman doc/proot/man.1 proot.1
399 + dodoc doc/proot/*.txt
400 + dodoc -r doc/articles
401 +}
402 +
403 +src_test() {
404 + emake -C tests -j1 CC="$(tc-getCC)"
405 +}
406 +
407 +pkg_postinst() {
408 + elog "If you have segfaults on recent (>4.8) kernels"
409 + elog "try to disable seccomp support like so:"
410 + elog "'export PROOT_NO_SECCOMP=1'"
411 + elog "prior to running proot"
412 +
413 + if use care; then
414 + elog "You have enabled 'care' USE flag, that builds and installs"
415 + elog "dynamically linked care binary."
416 + elog "Upstream does NOT support such way of building CARE,"
417 + elog "it provides only prebuilt binaries."
418 + elog "CARE also has known problems on hardened systems"
419 + elog "Please do NOT file bugs about them to https://bugs.gentoo.org"
420 + fi
421 +}