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 |
+} |