summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/pseudo/files/seccomp.patch
blob: be42eaf35336100095c80e229f7c0bcf9cdb4408 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
Pseudo changes the syscall access patterns which makes it incompatible with
seccomp. Therefore intercept the seccomp syscall and alter it, pretending that
seccomp was setup when in fact we do nothing. If we error as unsupported, 
utilities like file will exit with errors so we can't just disable it.

Upstream-Status: Pending
RP 2020/4/3
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>

Index: git/ports/linux/pseudo_wrappers.c
===================================================================
--- git.orig/ports/linux/pseudo_wrappers.c
+++ git/ports/linux/pseudo_wrappers.c
@@ -57,6 +57,7 @@ int pseudo_capset(cap_user_header_t hdrp
 long
 syscall(long number, ...) {
 	long rc = -1;
+	va_list ap;
 
 	if (!pseudo_check_wrappers() || !real_syscall) {
 		/* rc was initialized to the "failure" value */
@@ -77,6 +78,20 @@ syscall(long number, ...) {
 	(void) number;
 #endif
 
+#ifdef SYS_seccomp
+	/* pseudo and seccomp are incompatible as pseudo uses different syscalls
+	 * so pretend to enable seccomp but really do nothing */
+	if (number == SYS_seccomp) {
+		unsigned long cmd;
+		va_start(ap, number);
+		cmd = va_arg(ap, unsigned long);
+		va_end(ap);
+		if (cmd == SECCOMP_SET_MODE_FILTER) {
+		    return 0;
+		}
+	}
+#endif
+
 	/* gcc magic to attempt to just pass these args to syscall. we have to
 	 * guess about the number of args; the docs discuss calling conventions
 	 * up to 7, so let's try that?
@@ -92,3 +108,42 @@ static long wrap_syscall(long nr, va_lis
 	(void) ap;
 	return -1;
 }
+
+int
+prctl(int option, ...) {
+	int rc = -1;
+	va_list ap;
+
+	if (!pseudo_check_wrappers() || !real_prctl) {
+		/* rc was initialized to the "failure" value */
+		pseudo_enosys("prctl");
+		return rc;
+	}
+
+	/* pseudo and seccomp are incompatible as pseudo uses different syscalls
+	 * so pretend to enable seccomp but really do nothing */
+	if (option == PR_SET_SECCOMP) {
+		unsigned long cmd;
+		va_start(ap, option);
+		cmd = va_arg(ap, unsigned long);
+		va_end(ap);
+		if (cmd == SECCOMP_SET_MODE_FILTER) {
+		    return 0;
+		}
+	}
+
+	/* gcc magic to attempt to just pass these args to prctl. we have to
+	 * guess about the number of args; the docs discuss calling conventions
+	 * up to 5, so let's try that?
+	 */
+	void *res = __builtin_apply((void (*)()) real_prctl, __builtin_apply_args(), sizeof(long) * 5);
+	__builtin_return(res);
+}
+
+/* unused.
+ */
+static int wrap_prctl(int option, va_list ap) {
+	(void) option;
+	(void) ap;
+	return -1;
+}
Index: git/ports/linux/guts/prctl.c
===================================================================
--- /dev/null
+++ git/ports/linux/guts/prctl.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2020 Richard Purdie
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ * int prctl(int option, ...)
+ *	int rc = -1;
+ */
+
+	/* we should never get here, prctl is hand-wrapped */
+	rc = -1;
+
+/*	return rc;
+ * }
+ */
Index: git/ports/linux/portdefs.h
===================================================================
--- git.orig/ports/linux/portdefs.h
+++ git/ports/linux/portdefs.h
@@ -32,3 +32,5 @@ GLIBC_COMPAT_SYMBOL(memcpy,2.0);
 
 #include <linux/capability.h>
 #include <sys/syscall.h>
+#include <sys/prctl.h>
+#include <linux/seccomp.h>
Index: git/ports/linux/wrapfuncs.in
===================================================================
--- git.orig/ports/linux/wrapfuncs.in
+++ git/ports/linux/wrapfuncs.in
@@ -56,3 +56,4 @@ int getgrent_r(struct group *gbuf, char
 int capset(cap_user_header_t hdrp, const cap_user_data_t datap); /* real_func=pseudo_capset */
 long syscall(long nr, ...); /* hand_wrapped=1 */
 int renameat2(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, unsigned int flags); /* flags=AT_SYMLINK_NOFOLLOW */
+int prctl(int option, ...); /* hand_wrapped=1 */