blob: 283f997941eac61b18401346d7cae995c9fdfc1c [file] [log] [blame]
Andrew Geissler82c905d2020-04-13 13:39:40 -05001Pseudo changes the syscall access patterns which makes it incompatible with
2seccomp. Therefore intercept the seccomp syscall and alter it, pretending that
3seccomp was setup when in fact we do nothing. If we error as unsupported,
4utilities like file will exit with errors so we can't just disable it.
5
6Upstream-Status: Pending
7RP 2020/4/3
8Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
9
10It fails to compile pseudo-native on centos 7:
11
12| ports/linux/pseudo_wrappers.c: In function ‘prctl’:
13| ports/linux/pseudo_wrappers.c:129:14: error: ‘SECCOMP_SET_MODE_FILTER’ undeclared (first use in this function)
14| if (cmd == SECCOMP_SET_MODE_FILTER) {
15| ^
16
17Add macro guard for seccomp to avoid the failure.
18
19Signed-off-by: Kai Kang <kai.kang@windriver.com>
20
21Index: git/ports/linux/pseudo_wrappers.c
22===================================================================
23--- git.orig/ports/linux/pseudo_wrappers.c
24+++ git/ports/linux/pseudo_wrappers.c
25@@ -57,6 +57,7 @@ int pseudo_capset(cap_user_header_t hdrp
26 long
27 syscall(long number, ...) {
28 long rc = -1;
29+ va_list ap;
30
31 if (!pseudo_check_wrappers() || !real_syscall) {
32 /* rc was initialized to the "failure" value */
33@@ -77,6 +78,20 @@ syscall(long number, ...) {
34 (void) number;
35 #endif
36
37+#ifdef SYS_seccomp
38+ /* pseudo and seccomp are incompatible as pseudo uses different syscalls
39+ * so pretend to enable seccomp but really do nothing */
40+ if (number == SYS_seccomp) {
41+ unsigned long cmd;
42+ va_start(ap, number);
43+ cmd = va_arg(ap, unsigned long);
44+ va_end(ap);
45+ if (cmd == SECCOMP_SET_MODE_FILTER) {
46+ return 0;
47+ }
48+ }
49+#endif
50+
51 /* gcc magic to attempt to just pass these args to syscall. we have to
52 * guess about the number of args; the docs discuss calling conventions
53 * up to 7, so let's try that?
54@@ -92,3 +108,44 @@ static long wrap_syscall(long nr, va_lis
55 (void) ap;
56 return -1;
57 }
58+
59+int
60+prctl(int option, ...) {
61+ int rc = -1;
62+ va_list ap;
63+
64+ if (!pseudo_check_wrappers() || !real_prctl) {
65+ /* rc was initialized to the "failure" value */
66+ pseudo_enosys("prctl");
67+ return rc;
68+ }
69+
70+#ifdef SECCOMP_SET_MODE_FILTER
71+ /* pseudo and seccomp are incompatible as pseudo uses different syscalls
72+ * so pretend to enable seccomp but really do nothing */
73+ if (option == PR_SET_SECCOMP) {
74+ unsigned long cmd;
75+ va_start(ap, option);
76+ cmd = va_arg(ap, unsigned long);
77+ va_end(ap);
78+ if (cmd == SECCOMP_SET_MODE_FILTER) {
79+ return 0;
80+ }
81+ }
82+#endif
83+
84+ /* gcc magic to attempt to just pass these args to prctl. we have to
85+ * guess about the number of args; the docs discuss calling conventions
86+ * up to 5, so let's try that?
87+ */
88+ void *res = __builtin_apply((void (*)()) real_prctl, __builtin_apply_args(), sizeof(long) * 5);
89+ __builtin_return(res);
90+}
91+
92+/* unused.
93+ */
94+static int wrap_prctl(int option, va_list ap) {
95+ (void) option;
96+ (void) ap;
97+ return -1;
98+}
99Index: git/ports/linux/guts/prctl.c
100===================================================================
101--- /dev/null
102+++ git/ports/linux/guts/prctl.c
103@@ -0,0 +1,15 @@
104+/*
105+ * Copyright (c) 2020 Richard Purdie
106+ *
107+ * SPDX-License-Identifier: LGPL-2.1-only
108+ *
109+ * int prctl(int option, ...)
110+ * int rc = -1;
111+ */
112+
113+ /* we should never get here, prctl is hand-wrapped */
114+ rc = -1;
115+
116+/* return rc;
117+ * }
118+ */
119Index: git/ports/linux/portdefs.h
120===================================================================
121--- git.orig/ports/linux/portdefs.h
122+++ git/ports/linux/portdefs.h
123@@ -32,3 +32,5 @@ GLIBC_COMPAT_SYMBOL(memcpy,2.0);
124
125 #include <linux/capability.h>
126 #include <sys/syscall.h>
127+#include <sys/prctl.h>
128+#include <linux/seccomp.h>
129Index: git/ports/linux/wrapfuncs.in
130===================================================================
131--- git.orig/ports/linux/wrapfuncs.in
132+++ git/ports/linux/wrapfuncs.in
133@@ -56,3 +56,4 @@ int getgrent_r(struct group *gbuf, char
134 int capset(cap_user_header_t hdrp, const cap_user_data_t datap); /* real_func=pseudo_capset */
135 long syscall(long nr, ...); /* hand_wrapped=1 */
136 int renameat2(int olddirfd, const char *oldpath, int newdirfd, const char *newpath, unsigned int flags); /* flags=AT_SYMLINK_NOFOLLOW */
137+int prctl(int option, ...); /* hand_wrapped=1 */