Blame


1 e29dbd72 2021-01-23 op /*
2 1a49166d 2021-01-23 op * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
3 e29dbd72 2021-01-23 op *
4 e29dbd72 2021-01-23 op * Permission to use, copy, modify, and distribute this software for any
5 e29dbd72 2021-01-23 op * purpose with or without fee is hereby granted, provided that the above
6 e29dbd72 2021-01-23 op * copyright notice and this permission notice appear in all copies.
7 e29dbd72 2021-01-23 op *
8 e29dbd72 2021-01-23 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 e29dbd72 2021-01-23 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 e29dbd72 2021-01-23 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 e29dbd72 2021-01-23 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 e29dbd72 2021-01-23 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 e29dbd72 2021-01-23 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 e29dbd72 2021-01-23 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 e29dbd72 2021-01-23 op */
16 e29dbd72 2021-01-23 op
17 dafb57b8 2021-01-15 op #include "gmid.h"
18 dafb57b8 2021-01-15 op
19 dafb57b8 2021-01-15 op #if defined(__FreeBSD__)
20 dafb57b8 2021-01-15 op
21 dafb57b8 2021-01-15 op #include <sys/capsicum.h>
22 dafb57b8 2021-01-15 op
23 dafb57b8 2021-01-15 op void
24 dafb57b8 2021-01-15 op sandbox()
25 dafb57b8 2021-01-15 op {
26 dafb57b8 2021-01-15 op if (cap_enter() == -1)
27 dafb57b8 2021-01-15 op err(1, "cap_enter");
28 dafb57b8 2021-01-15 op }
29 dafb57b8 2021-01-15 op
30 dafb57b8 2021-01-15 op #elif defined(__linux__)
31 dafb57b8 2021-01-15 op
32 71b7eb2f 2021-01-17 op #include <sys/prctl.h>
33 71b7eb2f 2021-01-17 op #include <sys/syscall.h>
34 71b7eb2f 2021-01-17 op #include <sys/syscall.h>
35 71b7eb2f 2021-01-17 op #include <sys/types.h>
36 71b7eb2f 2021-01-17 op
37 71b7eb2f 2021-01-17 op #include <linux/audit.h>
38 71b7eb2f 2021-01-17 op #include <linux/filter.h>
39 71b7eb2f 2021-01-17 op #include <linux/seccomp.h>
40 71b7eb2f 2021-01-17 op
41 71b7eb2f 2021-01-17 op #include <errno.h>
42 3c0375e4 2021-01-20 op #include <fcntl.h>
43 71b7eb2f 2021-01-17 op #include <stddef.h>
44 71b7eb2f 2021-01-17 op #include <stdio.h>
45 71b7eb2f 2021-01-17 op #include <string.h>
46 71b7eb2f 2021-01-17 op
47 71b7eb2f 2021-01-17 op /* thanks chromium' src/seccomp.c */
48 71b7eb2f 2021-01-17 op #if defined(__i386__)
49 71b7eb2f 2021-01-17 op # define SECCOMP_AUDIT_ARCH AUDIT_ARCH_I386
50 71b7eb2f 2021-01-17 op #elif defined(__x86_64__)
51 71b7eb2f 2021-01-17 op # define SECCOMP_AUDIT_ARCH AUDIT_ARCH_X86_64
52 71b7eb2f 2021-01-17 op #elif defined(__arm__)
53 71b7eb2f 2021-01-17 op # define SECCOMP_AUDIT_ARCH AUDIT_ARCH_ARM
54 71b7eb2f 2021-01-17 op #elif defined(__aarch64__)
55 71b7eb2f 2021-01-17 op # define SECCOMP_AUDIT_ARCH AUDIT_ARCH_AARCH64
56 71b7eb2f 2021-01-17 op #elif defined(__mips__)
57 71b7eb2f 2021-01-17 op # if defined(__mips64)
58 71b7eb2f 2021-01-17 op # if defined(__MIPSEB__)
59 71b7eb2f 2021-01-17 op # define SECCOMP_AUDIT_ARCH AUDIT_ARCH_MIPS64
60 71b7eb2f 2021-01-17 op # else
61 71b7eb2f 2021-01-17 op # define SECCOMP_AUDIT_ARCH AUDIT_ARCH_MIPSEL64
62 71b7eb2f 2021-01-17 op # endif
63 71b7eb2f 2021-01-17 op # else
64 71b7eb2f 2021-01-17 op # if defined(__MIPSEB__)
65 71b7eb2f 2021-01-17 op # define SECCOMP_AUDIT_ARCH AUDIT_ARCH_MIPS
66 71b7eb2f 2021-01-17 op # else
67 71b7eb2f 2021-01-17 op # define SECCOMP_AUDIT_ARCH AUDIT_ARCH_MIPSEL
68 71b7eb2f 2021-01-17 op # endif
69 71b7eb2f 2021-01-17 op # endif
70 71b7eb2f 2021-01-17 op #else
71 71b7eb2f 2021-01-17 op # error "Platform does not support seccomp filter yet"
72 71b7eb2f 2021-01-17 op #endif
73 71b7eb2f 2021-01-17 op
74 71b7eb2f 2021-01-17 op /* uncomment to enable debugging. ONLY FOR DEVELOPMENT */
75 71b7eb2f 2021-01-17 op /* #define SC_DEBUG */
76 71b7eb2f 2021-01-17 op
77 71b7eb2f 2021-01-17 op #ifdef SC_DEBUG
78 71b7eb2f 2021-01-17 op # define SC_FAIL SECCOMP_RET_TRAP
79 71b7eb2f 2021-01-17 op #else
80 71b7eb2f 2021-01-17 op # define SC_FAIL SECCOMP_RET_KILL
81 71b7eb2f 2021-01-17 op #endif
82 71b7eb2f 2021-01-17 op
83 71b7eb2f 2021-01-17 op /* make the filter more readable */
84 71b7eb2f 2021-01-17 op #define SC_ALLOW(nr) \
85 71b7eb2f 2021-01-17 op BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_##nr, 0, 1), \
86 71b7eb2f 2021-01-17 op BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW)
87 71b7eb2f 2021-01-17 op
88 71b7eb2f 2021-01-17 op #ifdef SC_DEBUG
89 71b7eb2f 2021-01-17 op
90 71b7eb2f 2021-01-17 op #include <signal.h>
91 71b7eb2f 2021-01-17 op #include <unistd.h>
92 71b7eb2f 2021-01-17 op
93 71b7eb2f 2021-01-17 op static void
94 71b7eb2f 2021-01-17 op sandbox_seccomp_violation(int signum, siginfo_t *info, void *ctx)
95 71b7eb2f 2021-01-17 op {
96 71b7eb2f 2021-01-17 op (void)signum;
97 71b7eb2f 2021-01-17 op (void)ctx;
98 71b7eb2f 2021-01-17 op
99 71b7eb2f 2021-01-17 op fprintf(stderr, "%s: unexpected system call (arch:0x%x,syscall:%d @ %p)\n",
100 71b7eb2f 2021-01-17 op __func__, info->si_arch, info->si_syscall, info->si_call_addr);
101 71b7eb2f 2021-01-17 op _exit(1);
102 71b7eb2f 2021-01-17 op }
103 71b7eb2f 2021-01-17 op
104 71b7eb2f 2021-01-17 op static void
105 71b7eb2f 2021-01-17 op sandbox_seccomp_catch_sigsys(void)
106 71b7eb2f 2021-01-17 op {
107 71b7eb2f 2021-01-17 op struct sigaction act;
108 71b7eb2f 2021-01-17 op sigset_t mask;
109 71b7eb2f 2021-01-17 op
110 71b7eb2f 2021-01-17 op memset(&act, 0, sizeof(act));
111 71b7eb2f 2021-01-17 op sigemptyset(&mask);
112 71b7eb2f 2021-01-17 op sigaddset(&mask, SIGSYS);
113 71b7eb2f 2021-01-17 op
114 71b7eb2f 2021-01-17 op act.sa_sigaction = &sandbox_seccomp_violation;
115 71b7eb2f 2021-01-17 op act.sa_flags = SA_SIGINFO;
116 71b7eb2f 2021-01-17 op if (sigaction(SIGSYS, &act, NULL) == -1) {
117 71b7eb2f 2021-01-17 op fprintf(stderr, "%s: sigaction(SIGSYS): %s\n",
118 71b7eb2f 2021-01-17 op __func__, strerror(errno));
119 71b7eb2f 2021-01-17 op exit(1);
120 71b7eb2f 2021-01-17 op }
121 71b7eb2f 2021-01-17 op if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1) {
122 71b7eb2f 2021-01-17 op fprintf(stderr, "%s: sigprocmask(SIGSYS): %s\n",
123 71b7eb2f 2021-01-17 op __func__, strerror(errno));
124 71b7eb2f 2021-01-17 op exit(1);
125 71b7eb2f 2021-01-17 op }
126 71b7eb2f 2021-01-17 op }
127 71b7eb2f 2021-01-17 op #endif /* SC_DEBUG */
128 71b7eb2f 2021-01-17 op
129 dafb57b8 2021-01-15 op void
130 dafb57b8 2021-01-15 op sandbox()
131 dafb57b8 2021-01-15 op {
132 71b7eb2f 2021-01-17 op struct sock_filter filter[] = {
133 71b7eb2f 2021-01-17 op /* load the *current* architecture */
134 71b7eb2f 2021-01-17 op BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
135 71b7eb2f 2021-01-17 op (offsetof(struct seccomp_data, arch))),
136 71b7eb2f 2021-01-17 op /* ensure it's the same that we've been compiled on */
137 71b7eb2f 2021-01-17 op BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,
138 71b7eb2f 2021-01-17 op SECCOMP_AUDIT_ARCH, 1, 0),
139 71b7eb2f 2021-01-17 op /* if not, kill the program */
140 71b7eb2f 2021-01-17 op BPF_STMT(BPF_RET | BPF_K, SC_FAIL),
141 71b7eb2f 2021-01-17 op
142 71b7eb2f 2021-01-17 op /* load the syscall number */
143 71b7eb2f 2021-01-17 op BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
144 71b7eb2f 2021-01-17 op (offsetof(struct seccomp_data, nr))),
145 71b7eb2f 2021-01-17 op
146 71b7eb2f 2021-01-17 op /* allow logging on stdout */
147 71b7eb2f 2021-01-17 op SC_ALLOW(write),
148 71b7eb2f 2021-01-17 op SC_ALLOW(writev),
149 71b7eb2f 2021-01-17 op SC_ALLOW(readv),
150 71b7eb2f 2021-01-17 op
151 71b7eb2f 2021-01-17 op /* these are used to serve the files. note how we
152 71b7eb2f 2021-01-17 op * allow openat but not open. */
153 f6b9a079 2021-02-10 op SC_ALLOW(epoll_wait),
154 df58efff 2021-02-08 op SC_ALLOW(epoll_pwait),
155 df58efff 2021-02-08 op SC_ALLOW(epoll_ctl),
156 df58efff 2021-02-08 op SC_ALLOW(accept4),
157 71b7eb2f 2021-01-17 op SC_ALLOW(read),
158 71b7eb2f 2021-01-17 op SC_ALLOW(openat),
159 71b7eb2f 2021-01-17 op SC_ALLOW(fstat),
160 71b7eb2f 2021-01-17 op SC_ALLOW(close),
161 71b7eb2f 2021-01-17 op SC_ALLOW(lseek),
162 71b7eb2f 2021-01-17 op SC_ALLOW(brk),
163 71b7eb2f 2021-01-17 op SC_ALLOW(mmap),
164 71b7eb2f 2021-01-17 op SC_ALLOW(munmap),
165 c214d1ab 2021-02-08 op
166 c214d1ab 2021-02-08 op /* needed for signal handling */
167 c214d1ab 2021-02-08 op SC_ALLOW(rt_sigreturn),
168 c214d1ab 2021-02-08 op SC_ALLOW(rt_sigaction),
169 71b7eb2f 2021-01-17 op
170 71b7eb2f 2021-01-17 op /* we need recvmsg to receive fd */
171 71b7eb2f 2021-01-17 op SC_ALLOW(recvmsg),
172 71b7eb2f 2021-01-17 op
173 71b7eb2f 2021-01-17 op /* XXX: ??? */
174 71b7eb2f 2021-01-17 op SC_ALLOW(getpid),
175 71b7eb2f 2021-01-17 op
176 df58efff 2021-02-08 op /* alpine on amd64 */
177 f2b3a519 2021-01-20 op SC_ALLOW(clock_gettime),
178 df58efff 2021-02-08 op SC_ALLOW(madvise),
179 f2b3a519 2021-01-20 op
180 2d3f837a 2021-01-25 op /* void on aarch64 does a gettrandom */
181 2d3f837a 2021-01-25 op SC_ALLOW(getrandom),
182 2d3f837a 2021-01-25 op
183 f88311e5 2021-01-24 op /* for directory listing */
184 f88311e5 2021-01-24 op SC_ALLOW(getdents64),
185 f88311e5 2021-01-24 op
186 71b7eb2f 2021-01-17 op SC_ALLOW(exit),
187 71b7eb2f 2021-01-17 op SC_ALLOW(exit_group),
188 f2b3a519 2021-01-20 op
189 df58efff 2021-02-08 op /* stuff used by syslog. revisit once we move
190 df58efff 2021-02-08 op * logging in its own process */
191 df58efff 2021-02-08 op SC_ALLOW(socket),
192 df58efff 2021-02-08 op SC_ALLOW(sendto),
193 df58efff 2021-02-08 op SC_ALLOW(connect),
194 df58efff 2021-02-08 op
195 c214d1ab 2021-02-08 op /* allow only F_GETFL, F_SETFL & F_SETFD fcntl */
196 f88311e5 2021-01-24 op BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_fcntl, 0, 8),
197 de4f7131 2021-01-20 op BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
198 3c0375e4 2021-01-20 op (offsetof(struct seccomp_data, args[1]))),
199 3c0375e4 2021-01-20 op BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, F_GETFL, 0, 1),
200 3c0375e4 2021-01-20 op BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
201 3c0375e4 2021-01-20 op BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, F_SETFL, 0, 1),
202 3c0375e4 2021-01-20 op BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
203 f88311e5 2021-01-24 op BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, F_SETFD, 0, 1),
204 f88311e5 2021-01-24 op BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
205 3c0375e4 2021-01-20 op BPF_STMT(BPF_RET | BPF_K, SC_FAIL),
206 61f8d630 2021-01-20 op
207 f2b3a519 2021-01-20 op /* re-load the syscall number */
208 de4f7131 2021-01-20 op BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
209 de4f7131 2021-01-20 op (offsetof(struct seccomp_data, nr))),
210 de4f7131 2021-01-20 op
211 71b7eb2f 2021-01-17 op /* allow ioctl but only on fd 1, glibc doing stuff? */
212 71b7eb2f 2021-01-17 op BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_ioctl, 0, 3),
213 71b7eb2f 2021-01-17 op BPF_STMT(BPF_LD | BPF_W | BPF_ABS,
214 71b7eb2f 2021-01-17 op (offsetof(struct seccomp_data, args[0]))),
215 71b7eb2f 2021-01-17 op BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1, 0, 1),
216 71b7eb2f 2021-01-17 op BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
217 71b7eb2f 2021-01-17 op
218 71b7eb2f 2021-01-17 op /* disallow enything else */
219 71b7eb2f 2021-01-17 op BPF_STMT(BPF_RET | BPF_K, SC_FAIL),
220 71b7eb2f 2021-01-17 op };
221 71b7eb2f 2021-01-17 op
222 71b7eb2f 2021-01-17 op struct sock_fprog prog = {
223 71b7eb2f 2021-01-17 op .len = (unsigned short) (sizeof(filter) / sizeof(filter[0])),
224 71b7eb2f 2021-01-17 op .filter = filter,
225 71b7eb2f 2021-01-17 op };
226 71b7eb2f 2021-01-17 op
227 71b7eb2f 2021-01-17 op #ifdef SC_DEBUG
228 71b7eb2f 2021-01-17 op sandbox_seccomp_catch_sigsys();
229 71b7eb2f 2021-01-17 op #endif
230 71b7eb2f 2021-01-17 op
231 71b7eb2f 2021-01-17 op if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) {
232 71b7eb2f 2021-01-17 op fprintf(stderr, "%s: prctl(PR_SET_NO_NEW_PRIVS): %s\n",
233 71b7eb2f 2021-01-17 op __func__, strerror(errno));
234 71b7eb2f 2021-01-17 op exit(1);
235 71b7eb2f 2021-01-17 op }
236 71b7eb2f 2021-01-17 op
237 71b7eb2f 2021-01-17 op if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) == -1) {
238 71b7eb2f 2021-01-17 op fprintf(stderr, "%s: prctl(PR_SET_SECCOMP): %s\n",
239 71b7eb2f 2021-01-17 op __func__, strerror(errno));
240 71b7eb2f 2021-01-17 op exit(1);
241 71b7eb2f 2021-01-17 op }
242 dafb57b8 2021-01-15 op }
243 dafb57b8 2021-01-15 op
244 dafb57b8 2021-01-15 op #elif defined(__OpenBSD__)
245 dafb57b8 2021-01-15 op
246 dafb57b8 2021-01-15 op #include <unistd.h>
247 dafb57b8 2021-01-15 op
248 dafb57b8 2021-01-15 op void
249 dafb57b8 2021-01-15 op sandbox()
250 dafb57b8 2021-01-15 op {
251 dafb57b8 2021-01-15 op struct vhost *h;
252 dafb57b8 2021-01-15 op
253 dafb57b8 2021-01-15 op for (h = hosts; h->domain != NULL; ++h) {
254 2d3cc76f 2021-01-25 op if (unveil(h->dir, "r") == -1)
255 dafb57b8 2021-01-15 op err(1, "unveil %s for domain %s", h->dir, h->domain);
256 dafb57b8 2021-01-15 op }
257 dafb57b8 2021-01-15 op
258 881a9dd9 2021-01-16 op if (pledge("stdio recvfd rpath inet", NULL) == -1)
259 dafb57b8 2021-01-15 op err(1, "pledge");
260 dafb57b8 2021-01-15 op }
261 dafb57b8 2021-01-15 op
262 dafb57b8 2021-01-15 op #else
263 dafb57b8 2021-01-15 op
264 dafb57b8 2021-01-15 op void
265 dafb57b8 2021-01-15 op sandbox()
266 dafb57b8 2021-01-15 op {
267 dafb57b8 2021-01-15 op LOGN(NULL, "%s", "no sandbox method known for this OS");
268 dafb57b8 2021-01-15 op }
269 dafb57b8 2021-01-15 op
270 dafb57b8 2021-01-15 op #endif