diff options
Diffstat (limited to 'sandbox-seccomp-filter.c')
-rw-r--r-- | sandbox-seccomp-filter.c | 81 |
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 | ||
125 | struct ssh_sandbox * | 128 | static int |
126 | ssh_sandbox_init(void) | 129 | sandbox_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 | |||
153 | static void * | ||
154 | sandbox_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; | |||
143 | void mm_log_handler(LogLevel level, const char *msg, void *ctx); | 171 | void mm_log_handler(LogLevel level, const char *msg, void *ctx); |
144 | 172 | ||
145 | static void | 173 | static void |
146 | ssh_sandbox_violation(int signum, siginfo_t *info, void *void_context) | 174 | sandbox_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 | ||
157 | static void | 186 | static void |
158 | ssh_sandbox_child_debugging(void) | 187 | sandbox_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 | ||
178 | void | 207 | static void |
179 | ssh_sandbox_child(struct ssh_sandbox *box) | 208 | sandbox_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 | ||
209 | void | 238 | static void |
210 | ssh_sandbox_parent_finish(struct ssh_sandbox *box) | 239 | sandbox_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 | ||
216 | void | 245 | static void |
217 | ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) | 246 | sandbox_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 | ||
253 | Sandbox 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 | |||
264 | Sandbox 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 */ |