diff options
-rw-r--r-- | src/firejail/sbox.c | 2 | ||||
-rw-r--r-- | src/firejail/seccomp.c | 46 | ||||
-rw-r--r-- | src/fsec-optimize/Makefile.in | 2 | ||||
-rw-r--r-- | src/fsec-optimize/main.c | 17 | ||||
-rw-r--r-- | src/fsec-optimize/optimizer.c | 6 | ||||
-rw-r--r-- | src/fseccomp/main.c | 2 | ||||
-rw-r--r-- | src/fseccomp/seccomp_secondary.c | 2 | ||||
-rw-r--r-- | src/include/seccomp.h | 10 |
8 files changed, 63 insertions, 24 deletions
diff --git a/src/firejail/sbox.c b/src/firejail/sbox.c index a2aaa86eb..c3d3bd72c 100644 --- a/src/firejail/sbox.c +++ b/src/firejail/sbox.c | |||
@@ -120,7 +120,7 @@ static int __attribute__((noreturn)) sbox_do_exec_v(unsigned filtermask, char * | |||
120 | // handle X32 ABI | 120 | // handle X32 ABI |
121 | BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, X32_SYSCALL_BIT, 1, 0), | 121 | BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, X32_SYSCALL_BIT, 1, 0), |
122 | BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, 0, 1, 0), | 122 | BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, 0, 1, 0), |
123 | RETURN_ERRNO(EPERM), | 123 | KILL_OR_RETURN_ERRNO, |
124 | #endif | 124 | #endif |
125 | 125 | ||
126 | // syscall list | 126 | // syscall list |
diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c index e47e6c910..808dd4c37 100644 --- a/src/firejail/seccomp.c +++ b/src/firejail/seccomp.c | |||
@@ -208,7 +208,7 @@ int seccomp_filter_drop(bool native) { | |||
208 | // - seccomp | 208 | // - seccomp |
209 | if (cfg.seccomp_list_drop == NULL) { | 209 | if (cfg.seccomp_list_drop == NULL) { |
210 | // default seccomp if error action is not changed | 210 | // default seccomp if error action is not changed |
211 | if (cfg.seccomp_list == NULL && cfg.seccomp_error_action) { | 211 | if (cfg.seccomp_list == NULL && arg_seccomp_error_action == DEFAULT_SECCOMP_ERROR_ACTION) { |
212 | if (arg_seccomp_block_secondary) | 212 | if (arg_seccomp_block_secondary) |
213 | seccomp_filter_block_secondary(); | 213 | seccomp_filter_block_secondary(); |
214 | else { | 214 | else { |
@@ -221,11 +221,29 @@ int seccomp_filter_drop(bool native) { | |||
221 | } | 221 | } |
222 | // default seccomp filter with additional drop list | 222 | // default seccomp filter with additional drop list |
223 | else { // cfg.seccomp_list != NULL | 223 | else { // cfg.seccomp_list != NULL |
224 | if (arg_seccomp_block_secondary) | 224 | int rv; |
225 | |||
226 | if (arg_seccomp_block_secondary) { | ||
227 | if (arg_seccomp_error_action != DEFAULT_SECCOMP_ERROR_ACTION) { | ||
228 | if (arg_debug) | ||
229 | printf("Rebuild secondary block seccomp filter\n"); | ||
230 | rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 4, | ||
231 | PATH_FSECCOMP, "secondary", "block", RUN_SECCOMP_BLOCK_SECONDARY); | ||
232 | if (rv) | ||
233 | exit(rv); | ||
234 | } | ||
225 | seccomp_filter_block_secondary(); | 235 | seccomp_filter_block_secondary(); |
226 | else { | 236 | } else { |
227 | #if defined(__x86_64__) | 237 | #if defined(__x86_64__) |
228 | #if defined(__LP64__) | 238 | #if defined(__LP64__) |
239 | if (arg_seccomp_error_action != DEFAULT_SECCOMP_ERROR_ACTION) { | ||
240 | if (arg_debug) | ||
241 | printf("Rebuild 32 bit seccomp filter\n"); | ||
242 | rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 4, | ||
243 | PATH_FSECCOMP, "secondary", "32", RUN_SECCOMP_32); | ||
244 | if (rv) | ||
245 | exit(rv); | ||
246 | } | ||
229 | seccomp_filter_32(); | 247 | seccomp_filter_32(); |
230 | #endif | 248 | #endif |
231 | #endif | 249 | #endif |
@@ -242,16 +260,22 @@ int seccomp_filter_drop(bool native) { | |||
242 | list = cfg.seccomp_list32; | 260 | list = cfg.seccomp_list32; |
243 | } | 261 | } |
244 | 262 | ||
245 | if (list == NULL) | ||
246 | list = ""; | ||
247 | // build the seccomp filter as a regular user | 263 | // build the seccomp filter as a regular user |
248 | int rv; | 264 | if (list) |
249 | if (arg_allow_debuggers) | 265 | if (arg_allow_debuggers) |
250 | rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 7, | 266 | rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 7, |
251 | PATH_FSECCOMP, command, "drop", filter, postexec_filter, list, "allow-debuggers"); | 267 | PATH_FSECCOMP, command, "drop", filter, postexec_filter, list, "allow-debuggers"); |
268 | else | ||
269 | rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 6, | ||
270 | PATH_FSECCOMP, command, "drop", filter, postexec_filter, list); | ||
252 | else | 271 | else |
253 | rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 6, | 272 | if (arg_allow_debuggers) |
254 | PATH_FSECCOMP, command, "drop", filter, postexec_filter, list); | 273 | rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 4, |
274 | PATH_FSECCOMP, command, filter, "allow-debuggers"); | ||
275 | else | ||
276 | rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 3, | ||
277 | PATH_FSECCOMP, command, filter); | ||
278 | |||
255 | if (rv) | 279 | if (rv) |
256 | exit(rv); | 280 | exit(rv); |
257 | 281 | ||
diff --git a/src/fsec-optimize/Makefile.in b/src/fsec-optimize/Makefile.in index b6a28fdd8..cc5ac7e35 100644 --- a/src/fsec-optimize/Makefile.in +++ b/src/fsec-optimize/Makefile.in | |||
@@ -6,7 +6,7 @@ include ../common.mk | |||
6 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@ | 6 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@ |
7 | 7 | ||
8 | fsec-optimize: $(OBJS) ../lib/common.o ../lib/libnetlink.o | 8 | fsec-optimize: $(OBJS) ../lib/common.o ../lib/libnetlink.o |
9 | $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o $(LIBS) $(EXTRA_LDFLAGS) | 9 | $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o ../lib/errno.o $(LIBS) $(EXTRA_LDFLAGS) |
10 | 10 | ||
11 | clean:; rm -fr *.o fsec-optimize *.gcov *.gcda *.gcno *.plist | 11 | clean:; rm -fr *.o fsec-optimize *.gcov *.gcda *.gcno *.plist |
12 | 12 | ||
diff --git a/src/fsec-optimize/main.c b/src/fsec-optimize/main.c index 74aebc9e0..c64587068 100644 --- a/src/fsec-optimize/main.c +++ b/src/fsec-optimize/main.c | |||
@@ -18,6 +18,9 @@ | |||
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
19 | */ | 19 | */ |
20 | #include "fsec_optimize.h" | 20 | #include "fsec_optimize.h" |
21 | #include "../include/syscall.h" | ||
22 | |||
23 | int arg_seccomp_error_action = SECCOMP_RET_ERRNO | EPERM; // error action: errno, log or kill | ||
21 | 24 | ||
22 | static void usage(void) { | 25 | static void usage(void) { |
23 | printf("Usage:\n"); | 26 | printf("Usage:\n"); |
@@ -46,6 +49,20 @@ printf("\n"); | |||
46 | 49 | ||
47 | warn_dumpable(); | 50 | warn_dumpable(); |
48 | 51 | ||
52 | char *error_action = getenv("FIREJAIL_SECCOMP_ERROR_ACTION"); | ||
53 | if (error_action) { | ||
54 | if (strcmp(error_action, "kill") == 0) | ||
55 | arg_seccomp_error_action = SECCOMP_RET_KILL; | ||
56 | else if (strcmp(error_action, "log") == 0) | ||
57 | arg_seccomp_error_action = SECCOMP_RET_LOG; | ||
58 | else { | ||
59 | arg_seccomp_error_action = errno_find_name(error_action); | ||
60 | if (arg_seccomp_error_action == -1) | ||
61 | errExit("seccomp-error-action: unknown errno"); | ||
62 | arg_seccomp_error_action |= SECCOMP_RET_ERRNO; | ||
63 | } | ||
64 | } | ||
65 | |||
49 | char *fname = argv[1]; | 66 | char *fname = argv[1]; |
50 | 67 | ||
51 | // open input file | 68 | // open input file |
diff --git a/src/fsec-optimize/optimizer.c b/src/fsec-optimize/optimizer.c index 776beaa75..eb777f13b 100644 --- a/src/fsec-optimize/optimizer.c +++ b/src/fsec-optimize/optimizer.c | |||
@@ -33,7 +33,7 @@ | |||
33 | static inline int is_blacklist(struct sock_filter *bpf) { | 33 | static inline int is_blacklist(struct sock_filter *bpf) { |
34 | if (bpf->code == BPF_JMP + BPF_JEQ + BPF_K && | 34 | if (bpf->code == BPF_JMP + BPF_JEQ + BPF_K && |
35 | (bpf + 1)->code == BPF_RET + BPF_K && | 35 | (bpf + 1)->code == BPF_RET + BPF_K && |
36 | (bpf + 1)->k == SECCOMP_RET_KILL ) | 36 | (bpf + 1)->k == (__u32)arg_seccomp_error_action) |
37 | return 1; | 37 | return 1; |
38 | return 0; | 38 | return 0; |
39 | } | 39 | } |
@@ -89,9 +89,9 @@ static int optimize_blacklists(struct sock_filter *filter, int entries) { | |||
89 | } | 89 | } |
90 | } | 90 | } |
91 | 91 | ||
92 | // step 3: add the new ret KILL, and recalculate entries | 92 | // step 3: add the new ret KILL/LOG/ERRNO, and recalculate entries |
93 | filter_step2[j].code = BPF_RET + BPF_K; | 93 | filter_step2[j].code = BPF_RET + BPF_K; |
94 | filter_step2[j].k = SECCOMP_RET_KILL; | 94 | filter_step2[j].k = arg_seccomp_error_action; |
95 | entries = j + 1; | 95 | entries = j + 1; |
96 | 96 | ||
97 | // step 4: recalculate jumps | 97 | // step 4: recalculate jumps |
diff --git a/src/fseccomp/main.c b/src/fseccomp/main.c index c8259b079..f47efb5e8 100644 --- a/src/fseccomp/main.c +++ b/src/fseccomp/main.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include "fseccomp.h" | 20 | #include "fseccomp.h" |
21 | #include "../include/seccomp.h" | 21 | #include "../include/seccomp.h" |
22 | int arg_quiet = 0; | 22 | int arg_quiet = 0; |
23 | int arg_seccomp_error_action = EPERM; // error action: errno, log or kill | 23 | int arg_seccomp_error_action = SECCOMP_RET_ERRNO | EPERM; // error action: errno, log or kill |
24 | 24 | ||
25 | static void usage(void) { | 25 | static void usage(void) { |
26 | printf("Usage:\n"); | 26 | printf("Usage:\n"); |
diff --git a/src/fseccomp/seccomp_secondary.c b/src/fseccomp/seccomp_secondary.c index f024859d3..b8e8d0a89 100644 --- a/src/fseccomp/seccomp_secondary.c +++ b/src/fseccomp/seccomp_secondary.c | |||
@@ -126,7 +126,7 @@ void seccomp_secondary_block(const char *fname) { | |||
126 | EXAMINE_SYSCALL, | 126 | EXAMINE_SYSCALL, |
127 | #if defined(__x86_64__) | 127 | #if defined(__x86_64__) |
128 | // block x32 | 128 | // block x32 |
129 | HANDLE_X32_KILL, | 129 | HANDLE_X32, |
130 | #endif | 130 | #endif |
131 | // block personality(2) where domain != PER_LINUX or 0xffffffff (query current personality) | 131 | // block personality(2) where domain != PER_LINUX or 0xffffffff (query current personality) |
132 | // 0: if personality(2), continue to 1, else goto 7 (allow) | 132 | // 0: if personality(2), continue to 1, else goto 7 (allow) |
diff --git a/src/include/seccomp.h b/src/include/seccomp.h index 90db16d39..b3b75c2d1 100644 --- a/src/include/seccomp.h +++ b/src/include/seccomp.h | |||
@@ -201,7 +201,7 @@ | |||
201 | #define VALIDATE_ARCHITECTURE_KILL \ | 201 | #define VALIDATE_ARCHITECTURE_KILL \ |
202 | BPF_STMT(BPF_LD+BPF_W+BPF_ABS, (offsetof(struct seccomp_data, arch))), \ | 202 | BPF_STMT(BPF_LD+BPF_W+BPF_ABS, (offsetof(struct seccomp_data, arch))), \ |
203 | BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARCH_NR, 1, 0), \ | 203 | BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ARCH_NR, 1, 0), \ |
204 | BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL) | 204 | KILL_OR_RETURN_ERRNO |
205 | 205 | ||
206 | #define VALIDATE_ARCHITECTURE_64 \ | 206 | #define VALIDATE_ARCHITECTURE_64 \ |
207 | BPF_STMT(BPF_LD+BPF_W+BPF_ABS, (offsetof(struct seccomp_data, arch))), \ | 207 | BPF_STMT(BPF_LD+BPF_W+BPF_ABS, (offsetof(struct seccomp_data, arch))), \ |
@@ -222,11 +222,7 @@ | |||
222 | #define HANDLE_X32 \ | 222 | #define HANDLE_X32 \ |
223 | BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, X32_SYSCALL_BIT, 1, 0), \ | 223 | BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, X32_SYSCALL_BIT, 1, 0), \ |
224 | BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 0, 1, 0), \ | 224 | BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 0, 1, 0), \ |
225 | RETURN_ERRNO(EPERM) | 225 | KILL_OR_RETURN_ERRNO |
226 | #define HANDLE_X32_KILL \ | ||
227 | BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, X32_SYSCALL_BIT, 1, 0), \ | ||
228 | BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 0, 1, 0), \ | ||
229 | BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL) | ||
230 | #endif | 226 | #endif |
231 | 227 | ||
232 | #define EXAMINE_SYSCALL BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ | 228 | #define EXAMINE_SYSCALL BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ |
@@ -258,6 +254,8 @@ | |||
258 | BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO | nr) | 254 | BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO | nr) |
259 | 255 | ||
260 | extern int arg_seccomp_error_action; // error action: errno, log or kill | 256 | extern int arg_seccomp_error_action; // error action: errno, log or kill |
257 | #define DEFAULT_SECCOMP_ERROR_ACTION EPERM | ||
258 | |||
261 | #define KILL_OR_RETURN_ERRNO \ | 259 | #define KILL_OR_RETURN_ERRNO \ |
262 | BPF_STMT(BPF_RET+BPF_K, arg_seccomp_error_action) | 260 | BPF_STMT(BPF_RET+BPF_K, arg_seccomp_error_action) |
263 | 261 | ||