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.c81
1 files changed, 66 insertions, 15 deletions
diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c
index 686812957..a564b1316 100644
--- a/sandbox-seccomp-filter.c
+++ b/sandbox-seccomp-filter.c
@@ -35,11 +35,15 @@
35 35
36#include "includes.h" 36#include "includes.h"
37 37
38#include <sys/types.h>
39
40#include "ssh-sandbox.h"
41
38#ifdef SANDBOX_SECCOMP_FILTER 42#ifdef SANDBOX_SECCOMP_FILTER
39 43
40#include <sys/types.h>
41#include <sys/resource.h> 44#include <sys/resource.h>
42#include <sys/prctl.h> 45#include <sys/prctl.h>
46#include <sys/wait.h>
43 47
44#include <linux/audit.h> 48#include <linux/audit.h>
45#include <linux/filter.h> 49#include <linux/filter.h>
@@ -57,7 +61,6 @@
57#include <unistd.h> 61#include <unistd.h>
58 62
59#include "log.h" 63#include "log.h"
60#include "ssh-sandbox.h"
61#include "xmalloc.h" 64#include "xmalloc.h"
62 65
63/* Linux seccomp_filter sandbox */ 66/* Linux seccomp_filter sandbox */
@@ -122,8 +125,33 @@ struct ssh_sandbox {
122 pid_t child_pid; 125 pid_t child_pid;
123}; 126};
124 127
125struct ssh_sandbox * 128static int
126ssh_sandbox_init(void) 129sandbox_seccomp_filter_probe(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)
127{ 155{
128 struct ssh_sandbox *box; 156 struct ssh_sandbox *box;
129 157
@@ -143,7 +171,8 @@ extern struct monitor *pmonitor;
143void mm_log_handler(LogLevel level, const char *msg, void *ctx); 171void mm_log_handler(LogLevel level, const char *msg, void *ctx);
144 172
145static void 173static void
146ssh_sandbox_violation(int signum, siginfo_t *info, void *void_context) 174sandbox_seccomp_filter_violation(int signum, siginfo_t *info,
175 void *void_context)
147{ 176{
148 char msg[256]; 177 char msg[256];
149 178
@@ -155,7 +184,7 @@ ssh_sandbox_violation(int signum, siginfo_t *info, void *void_context)
155} 184}
156 185
157static void 186static void
158ssh_sandbox_child_debugging(void) 187sandbox_seccomp_filter_child_debugging(void)
159{ 188{
160 struct sigaction act; 189 struct sigaction act;
161 sigset_t mask; 190 sigset_t mask;
@@ -165,7 +194,7 @@ ssh_sandbox_child_debugging(void)
165 sigemptyset(&mask); 194 sigemptyset(&mask);
166 sigaddset(&mask, SIGSYS); 195 sigaddset(&mask, SIGSYS);
167 196
168 act.sa_sigaction = &ssh_sandbox_violation; 197 act.sa_sigaction = &sandbox_seccomp_filter_violation;
169 act.sa_flags = SA_SIGINFO; 198 act.sa_flags = SA_SIGINFO;
170 if (sigaction(SIGSYS, &act, NULL) == -1) 199 if (sigaction(SIGSYS, &act, NULL) == -1)
171 fatal("%s: sigaction(SIGSYS): %s", __func__, strerror(errno)); 200 fatal("%s: sigaction(SIGSYS): %s", __func__, strerror(errno));
@@ -175,8 +204,8 @@ ssh_sandbox_child_debugging(void)
175} 204}
176#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ 205#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */
177 206
178void 207static void
179ssh_sandbox_child(struct ssh_sandbox *box) 208sandbox_seccomp_filter_child(void *vbox)
180{ 209{
181 struct rlimit rl_zero; 210 struct rlimit rl_zero;
182 211
@@ -193,7 +222,7 @@ ssh_sandbox_child(struct ssh_sandbox *box)
193 __func__, strerror(errno)); 222 __func__, strerror(errno));
194 223
195#ifdef SANDBOX_SECCOMP_FILTER_DEBUG 224#ifdef SANDBOX_SECCOMP_FILTER_DEBUG
196 ssh_sandbox_child_debugging(); 225 sandbox_seccomp_filter_child_debugging();
197#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ 226#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */
198 227
199 debug3("%s: setting PR_SET_NO_NEW_PRIVS", __func__); 228 debug3("%s: setting PR_SET_NO_NEW_PRIVS", __func__);
@@ -206,17 +235,39 @@ ssh_sandbox_child(struct ssh_sandbox *box)
206 __func__, strerror(errno)); 235 __func__, strerror(errno));
207} 236}
208 237
209void 238static void
210ssh_sandbox_parent_finish(struct ssh_sandbox *box) 239sandbox_seccomp_filter_parent_finish(void *vbox)
211{ 240{
212 free(box); 241 free(vbox);
213 debug3("%s: finished", __func__); 242 debug3("%s: finished", __func__);
214} 243}
215 244
216void 245static void
217ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) 246sandbox_seccomp_filter_parent_preauth(void *vbox, pid_t child_pid)
218{ 247{
248 struct ssh_sandbox *box = vbox;
249
219 box->child_pid = child_pid; 250 box->child_pid = child_pid;
220} 251}
221 252
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
222#endif /* SANDBOX_SECCOMP_FILTER */ 273#endif /* SANDBOX_SECCOMP_FILTER */