summaryrefslogtreecommitdiff
path: root/sandbox-seccomp-filter.c
diff options
context:
space:
mode:
Diffstat (limited to 'sandbox-seccomp-filter.c')
-rw-r--r--sandbox-seccomp-filter.c93
1 files changed, 24 insertions, 69 deletions
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c
index a564b1316..ef2b13c4f 100644
--- a/sandbox-seccomp-filter.c
+++ b/sandbox-seccomp-filter.c
@@ -35,15 +35,11 @@
35 35
36#include "includes.h" 36#include "includes.h"
37 37
38#include <sys/types.h>
39
40#include "ssh-sandbox.h"
41
42#ifdef SANDBOX_SECCOMP_FILTER 38#ifdef SANDBOX_SECCOMP_FILTER
43 39
40#include <sys/types.h>
44#include <sys/resource.h> 41#include <sys/resource.h>
45#include <sys/prctl.h> 42#include <sys/prctl.h>
46#include <sys/wait.h>
47 43
48#include <linux/audit.h> 44#include <linux/audit.h>
49#include <linux/filter.h> 45#include <linux/filter.h>
@@ -61,6 +57,7 @@
61#include <unistd.h> 57#include <unistd.h>
62 58
63#include "log.h" 59#include "log.h"
60#include "ssh-sandbox.h"
64#include "xmalloc.h" 61#include "xmalloc.h"
65 62
66/* Linux seccomp_filter sandbox */ 63/* Linux seccomp_filter sandbox */
@@ -125,33 +122,8 @@ struct ssh_sandbox {
125 pid_t child_pid; 122 pid_t child_pid;
126}; 123};
127 124
128static int 125struct ssh_sandbox *
129sandbox_seccomp_filter_probe(void) 126ssh_sandbox_init(void)
130{
131 int status;
132 pid_t pid;
133
134 pid = fork();
135 if (pid == -1) {
136 fatal("fork of seccomp_filter probe child failed");
137 } else if (pid != 0) {
138 /* parent */
139 while (waitpid(pid, &status, 0) < 0) {
140 if (errno == EINTR)
141 continue;
142 fatal("%s: waitpid: %s", __func__, strerror(errno));
143 }
144 return (WIFEXITED(status) && WEXITSTATUS(status) == 0);
145 } else {
146 /* child */
147 errno = 0;
148 prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0);
149 _exit(errno == EFAULT ? 0 : 1);
150 }
151}
152
153static void *
154sandbox_seccomp_filter_init(void)
155{ 127{
156 struct ssh_sandbox *box; 128 struct ssh_sandbox *box;
157 129
@@ -171,8 +143,7 @@ extern struct monitor *pmonitor;
171void mm_log_handler(LogLevel level, const char *msg, void *ctx); 143void mm_log_handler(LogLevel level, const char *msg, void *ctx);
172 144
173static void 145static void
174sandbox_seccomp_filter_violation(int signum, siginfo_t *info, 146ssh_sandbox_violation(int signum, siginfo_t *info, void *void_context)
175 void *void_context)
176{ 147{
177 char msg[256]; 148 char msg[256];
178 149
@@ -184,7 +155,7 @@ sandbox_seccomp_filter_violation(int signum, siginfo_t *info,
184} 155}
185 156
186static void 157static void
187sandbox_seccomp_filter_child_debugging(void) 158ssh_sandbox_child_debugging(void)
188{ 159{
189 struct sigaction act; 160 struct sigaction act;
190 sigset_t mask; 161 sigset_t mask;
@@ -194,7 +165,7 @@ sandbox_seccomp_filter_child_debugging(void)
194 sigemptyset(&mask); 165 sigemptyset(&mask);
195 sigaddset(&mask, SIGSYS); 166 sigaddset(&mask, SIGSYS);
196 167
197 act.sa_sigaction = &sandbox_seccomp_filter_violation; 168 act.sa_sigaction = &ssh_sandbox_violation;
198 act.sa_flags = SA_SIGINFO; 169 act.sa_flags = SA_SIGINFO;
199 if (sigaction(SIGSYS, &act, NULL) == -1) 170 if (sigaction(SIGSYS, &act, NULL) == -1)
200 fatal("%s: sigaction(SIGSYS): %s", __func__, strerror(errno)); 171 fatal("%s: sigaction(SIGSYS): %s", __func__, strerror(errno));
@@ -204,10 +175,11 @@ sandbox_seccomp_filter_child_debugging(void)
204} 175}
205#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ 176#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */
206 177
207static void 178void
208sandbox_seccomp_filter_child(void *vbox) 179ssh_sandbox_child(struct ssh_sandbox *box)
209{ 180{
210 struct rlimit rl_zero; 181 struct rlimit rl_zero;
182 int nnp_failed = 0;
211 183
212 /* Set rlimits for completeness if possible. */ 184 /* Set rlimits for completeness if possible. */
213 rl_zero.rlim_cur = rl_zero.rlim_max = 0; 185 rl_zero.rlim_cur = rl_zero.rlim_max = 0;
@@ -222,52 +194,35 @@ sandbox_seccomp_filter_child(void *vbox)
222 __func__, strerror(errno)); 194 __func__, strerror(errno));
223 195
224#ifdef SANDBOX_SECCOMP_FILTER_DEBUG 196#ifdef SANDBOX_SECCOMP_FILTER_DEBUG
225 sandbox_seccomp_filter_child_debugging(); 197 ssh_sandbox_child_debugging();
226#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ 198#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */
227 199
228 debug3("%s: setting PR_SET_NO_NEW_PRIVS", __func__); 200 debug3("%s: setting PR_SET_NO_NEW_PRIVS", __func__);
229 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) 201 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) {
230 fatal("%s: prctl(PR_SET_NO_NEW_PRIVS): %s", 202 debug("%s: prctl(PR_SET_NO_NEW_PRIVS): %s",
231 __func__, strerror(errno)); 203 __func__, strerror(errno));
204 nnp_failed = 1;
205 }
232 debug3("%s: attaching seccomp filter program", __func__); 206 debug3("%s: attaching seccomp filter program", __func__);
233 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &preauth_program) == -1) 207 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &preauth_program) == -1)
234 fatal("%s: prctl(PR_SET_SECCOMP): %s", 208 debug("%s: prctl(PR_SET_SECCOMP): %s",
235 __func__, strerror(errno)); 209 __func__, strerror(errno));
210 else if (nnp_failed)
211 fatal("%s: SECCOMP_MODE_FILTER activated but "
212 "PR_SET_NO_NEW_PRIVS failed", __func__);
236} 213}
237 214
238static void 215void
239sandbox_seccomp_filter_parent_finish(void *vbox) 216ssh_sandbox_parent_finish(struct ssh_sandbox *box)
240{ 217{
241 free(vbox); 218 free(box);
242 debug3("%s: finished", __func__); 219 debug3("%s: finished", __func__);
243} 220}
244 221
245static void 222void
246sandbox_seccomp_filter_parent_preauth(void *vbox, pid_t child_pid) 223ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid)
247{ 224{
248 struct ssh_sandbox *box = vbox;
249
250 box->child_pid = child_pid; 225 box->child_pid = child_pid;
251} 226}
252 227
253Sandbox ssh_sandbox_seccomp_filter = {
254 "seccomp_filter",
255 sandbox_seccomp_filter_probe,
256 sandbox_seccomp_filter_init,
257 sandbox_seccomp_filter_child,
258 sandbox_seccomp_filter_parent_finish,
259 sandbox_seccomp_filter_parent_preauth
260};
261
262#else /* !SANDBOX_SECCOMP_FILTER */
263
264Sandbox ssh_sandbox_seccomp_filter = {
265 "seccomp_filter",
266 NULL,
267 NULL,
268 NULL,
269 NULL,
270 NULL
271};
272
273#endif /* SANDBOX_SECCOMP_FILTER */ 228#endif /* SANDBOX_SECCOMP_FILTER */