diff options
-rw-r--r-- | src/firejail/bandwidth.c | 3 | ||||
-rw-r--r-- | src/firejail/firejail.h | 1 | ||||
-rw-r--r-- | src/firejail/output.c | 3 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 20 | ||||
-rw-r--r-- | src/firejail/sbox.c | 5 | ||||
-rw-r--r-- | src/firejail/seccomp.c | 49 | ||||
-rw-r--r-- | src/firejail/x11.c | 30 | ||||
-rw-r--r-- | src/fseccomp/syscall.c | 6 | ||||
-rw-r--r-- | src/man/firejail.txt | 2 |
9 files changed, 93 insertions, 26 deletions
diff --git a/src/firejail/bandwidth.c b/src/firejail/bandwidth.c index 24d027d54..831b76e79 100644 --- a/src/firejail/bandwidth.c +++ b/src/firejail/bandwidth.c | |||
@@ -441,6 +441,9 @@ void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, in | |||
441 | arg[2] = cmd; | 441 | arg[2] = cmd; |
442 | arg[3] = NULL; | 442 | arg[3] = NULL; |
443 | clearenv(); | 443 | clearenv(); |
444 | #ifdef HAVE_SECCOMP | ||
445 | seccomp_install_filters(); | ||
446 | #endif | ||
444 | execvp(arg[0], arg); | 447 | execvp(arg[0], arg); |
445 | 448 | ||
446 | // it will never get here | 449 | // it will never get here |
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 690f76e05..90f88ef37 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -536,6 +536,7 @@ void fs_private_home_list(void); | |||
536 | 536 | ||
537 | // seccomp.c | 537 | // seccomp.c |
538 | char *seccomp_check_list(const char *str); | 538 | char *seccomp_check_list(const char *str); |
539 | int seccomp_install_filters(void); | ||
539 | int seccomp_load(const char *fname); | 540 | int seccomp_load(const char *fname); |
540 | void seccomp_filter_32(void); | 541 | void seccomp_filter_32(void); |
541 | void seccomp_filter_64(void); | 542 | void seccomp_filter_64(void); |
diff --git a/src/firejail/output.c b/src/firejail/output.c index abdfa4d3b..d69f5f051 100644 --- a/src/firejail/output.c +++ b/src/firejail/output.c | |||
@@ -103,6 +103,9 @@ void check_output(int argc, char **argv) { | |||
103 | a[2] = cmd; | 103 | a[2] = cmd; |
104 | a[3] = NULL; | 104 | a[3] = NULL; |
105 | 105 | ||
106 | #ifdef HAVE_SECCOMP | ||
107 | seccomp_install_filters(); | ||
108 | #endif | ||
106 | execvp(a[0], a); | 109 | execvp(a[0], a); |
107 | 110 | ||
108 | perror("execvp"); | 111 | perror("execvp"); |
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 568549cbf..30b55d7d0 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -274,6 +274,9 @@ void start_audit(void) { | |||
274 | if (asprintf(&audit_prog, "%s/firejail/faudit", LIBDIR) == -1) | 274 | if (asprintf(&audit_prog, "%s/firejail/faudit", LIBDIR) == -1) |
275 | errExit("asprintf"); | 275 | errExit("asprintf"); |
276 | assert(getenv("LD_PRELOAD") == NULL); | 276 | assert(getenv("LD_PRELOAD") == NULL); |
277 | #ifdef HAVE_SECCOMP | ||
278 | seccomp_install_filters(); | ||
279 | #endif | ||
277 | execl(audit_prog, audit_prog, NULL); | 280 | execl(audit_prog, audit_prog, NULL); |
278 | perror("execl"); | 281 | perror("execl"); |
279 | exit(1); | 282 | exit(1); |
@@ -367,7 +370,10 @@ void start_application(void) { | |||
367 | if (arg_audit) { | 370 | if (arg_audit) { |
368 | assert(arg_audit_prog); | 371 | assert(arg_audit_prog); |
369 | #ifdef HAVE_GCOV | 372 | #ifdef HAVE_GCOV |
370 | __gcov_dump(); | 373 | __gcov_dump(); |
374 | #endif | ||
375 | #ifdef HAVE_SECCOMP | ||
376 | seccomp_install_filters(); | ||
371 | #endif | 377 | #endif |
372 | execl(arg_audit_prog, arg_audit_prog, NULL); | 378 | execl(arg_audit_prog, arg_audit_prog, NULL); |
373 | } | 379 | } |
@@ -394,7 +400,10 @@ void start_application(void) { | |||
394 | 400 | ||
395 | int rv = ok_to_run(cfg.original_argv[cfg.original_program_index]); | 401 | int rv = ok_to_run(cfg.original_argv[cfg.original_program_index]); |
396 | #ifdef HAVE_GCOV | 402 | #ifdef HAVE_GCOV |
397 | __gcov_dump(); | 403 | __gcov_dump(); |
404 | #endif | ||
405 | #ifdef HAVE_SECCOMP | ||
406 | seccomp_install_filters(); | ||
398 | #endif | 407 | #endif |
399 | if (rv) | 408 | if (rv) |
400 | execvp(cfg.original_argv[cfg.original_program_index], &cfg.original_argv[cfg.original_program_index]); | 409 | execvp(cfg.original_argv[cfg.original_program_index], &cfg.original_argv[cfg.original_program_index]); |
@@ -447,7 +456,10 @@ void start_application(void) { | |||
447 | if (!arg_command && !arg_quiet) | 456 | if (!arg_command && !arg_quiet) |
448 | print_time(); | 457 | print_time(); |
449 | #ifdef HAVE_GCOV | 458 | #ifdef HAVE_GCOV |
450 | __gcov_dump(); | 459 | __gcov_dump(); |
460 | #endif | ||
461 | #ifdef HAVE_SECCOMP | ||
462 | seccomp_install_filters(); | ||
451 | #endif | 463 | #endif |
452 | execvp(arg[0], arg); | 464 | execvp(arg[0], arg); |
453 | } | 465 | } |
@@ -988,7 +1000,7 @@ int sandbox(void* sandbox_arg) { | |||
988 | if (cfg.cgroup) | 1000 | if (cfg.cgroup) |
989 | save_cgroup(); | 1001 | save_cgroup(); |
990 | 1002 | ||
991 | // set seccomp //todo: push it down after drop_privs and/or configuring noroot | 1003 | // set seccomp |
992 | #ifdef HAVE_SECCOMP | 1004 | #ifdef HAVE_SECCOMP |
993 | // install protocol filter | 1005 | // install protocol filter |
994 | #ifdef SYS_socket | 1006 | #ifdef SYS_socket |
diff --git a/src/firejail/sbox.c b/src/firejail/sbox.c index 6cd58d78e..9b6d64646 100644 --- a/src/firejail/sbox.c +++ b/src/firejail/sbox.c | |||
@@ -205,11 +205,14 @@ int sbox_run(unsigned filter, int num, ...) { | |||
205 | if (arg_quiet) | 205 | if (arg_quiet) |
206 | setenv("FIREJAIL_QUIET", "yes", 1); | 206 | setenv("FIREJAIL_QUIET", "yes", 1); |
207 | 207 | ||
208 | #ifdef HAVE_SECCOMP | ||
209 | seccomp_install_filters(); | ||
210 | #endif | ||
208 | if (arg[0]) // get rid of scan-build warning | 211 | if (arg[0]) // get rid of scan-build warning |
209 | execvp(arg[0], arg); | 212 | execvp(arg[0], arg); |
210 | else | 213 | else |
211 | assert(0); | 214 | assert(0); |
212 | perror("execl"); | 215 | perror("execvp"); |
213 | _exit(1); | 216 | _exit(1); |
214 | } | 217 | } |
215 | 218 | ||
diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c index 516c97fa0..e855ce7ed 100644 --- a/src/firejail/seccomp.c +++ b/src/firejail/seccomp.c | |||
@@ -23,6 +23,13 @@ | |||
23 | #include "../include/seccomp.h" | 23 | #include "../include/seccomp.h" |
24 | #include <sys/mman.h> | 24 | #include <sys/mman.h> |
25 | 25 | ||
26 | typedef struct filter_list { | ||
27 | struct filter_list *next; | ||
28 | struct sock_fprog prog; | ||
29 | } FilterList; | ||
30 | |||
31 | static FilterList *filter_list_head = NULL; | ||
32 | |||
26 | static int err_printed = 0; | 33 | static int err_printed = 0; |
27 | 34 | ||
28 | char *seccomp_check_list(const char *str) { | 35 | char *seccomp_check_list(const char *str) { |
@@ -52,6 +59,24 @@ char *seccomp_check_list(const char *str) { | |||
52 | return rv; | 59 | return rv; |
53 | } | 60 | } |
54 | 61 | ||
62 | // install seccomp filters | ||
63 | int seccomp_install_filters(void) { | ||
64 | int r = 0; | ||
65 | FilterList *fl = filter_list_head; | ||
66 | if (fl) { | ||
67 | prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); | ||
68 | |||
69 | for (; fl; fl = fl->next) { | ||
70 | if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &fl->prog)) { | ||
71 | if (!err_printed) | ||
72 | fwarning("seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); | ||
73 | err_printed = 1; | ||
74 | r = 1; | ||
75 | } | ||
76 | } | ||
77 | } | ||
78 | return r; | ||
79 | } | ||
55 | 80 | ||
56 | int seccomp_load(const char *fname) { | 81 | int seccomp_load(const char *fname) { |
57 | assert(fname); | 82 | assert(fname); |
@@ -77,22 +102,16 @@ int seccomp_load(const char *fname) { | |||
77 | // close file | 102 | // close file |
78 | close(fd); | 103 | close(fd); |
79 | 104 | ||
80 | // install filter | 105 | FilterList *fl = malloc(sizeof(FilterList)); |
81 | struct sock_fprog prog = { | 106 | if (!fl) { |
82 | .len = entries, | 107 | fprintf(stderr, "Error: cannot allocate memory\n"); |
83 | .filter = filter, | 108 | exit(1); |
84 | }; | ||
85 | int r = 0; | ||
86 | if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { | ||
87 | if (!err_printed) | ||
88 | fwarning("seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); | ||
89 | err_printed = 1; | ||
90 | r = 1; | ||
91 | } | 109 | } |
92 | 110 | fl->next = filter_list_head; | |
93 | munmap(filter, size); | 111 | fl->prog.len = entries; |
94 | return r; | 112 | fl->prog.filter = filter; |
95 | 113 | filter_list_head = fl; | |
114 | return 0; | ||
96 | errexit: | 115 | errexit: |
97 | fprintf(stderr, "Error: cannot read %s\n", fname); | 116 | fprintf(stderr, "Error: cannot read %s\n", fname); |
98 | exit(1); | 117 | exit(1); |
diff --git a/src/firejail/x11.c b/src/firejail/x11.c index d41f46d93..26af8ad35 100644 --- a/src/firejail/x11.c +++ b/src/firejail/x11.c | |||
@@ -321,6 +321,9 @@ void x11_start_xvfb(int argc, char **argv) { | |||
321 | 321 | ||
322 | // running without privileges - see drop_privs call above | 322 | // running without privileges - see drop_privs call above |
323 | assert(getenv("LD_PRELOAD") == NULL); | 323 | assert(getenv("LD_PRELOAD") == NULL); |
324 | #ifdef HAVE_SECCOMP | ||
325 | seccomp_install_filters(); | ||
326 | #endif | ||
324 | execvp(server_argv[0], server_argv); | 327 | execvp(server_argv[0], server_argv); |
325 | perror("execvp"); | 328 | perror("execvp"); |
326 | _exit(1); | 329 | _exit(1); |
@@ -365,6 +368,9 @@ void x11_start_xvfb(int argc, char **argv) { | |||
365 | 368 | ||
366 | // running without privileges - see drop_privs call above | 369 | // running without privileges - see drop_privs call above |
367 | assert(getenv("LD_PRELOAD") == NULL); | 370 | assert(getenv("LD_PRELOAD") == NULL); |
371 | #ifdef HAVE_SECCOMP | ||
372 | seccomp_install_filters(); | ||
373 | #endif | ||
368 | execvp(jail_argv[0], jail_argv); | 374 | execvp(jail_argv[0], jail_argv); |
369 | perror("execvp"); | 375 | perror("execvp"); |
370 | _exit(1); | 376 | _exit(1); |
@@ -557,6 +563,9 @@ void x11_start_xephyr(int argc, char **argv) { | |||
557 | 563 | ||
558 | // running without privileges - see drop_privs call above | 564 | // running without privileges - see drop_privs call above |
559 | assert(getenv("LD_PRELOAD") == NULL); | 565 | assert(getenv("LD_PRELOAD") == NULL); |
566 | #ifdef HAVE_SECCOMP | ||
567 | seccomp_install_filters(); | ||
568 | #endif | ||
560 | execvp(server_argv[0], server_argv); | 569 | execvp(server_argv[0], server_argv); |
561 | perror("execvp"); | 570 | perror("execvp"); |
562 | _exit(1); | 571 | _exit(1); |
@@ -601,6 +610,9 @@ void x11_start_xephyr(int argc, char **argv) { | |||
601 | 610 | ||
602 | // running without privileges - see drop_privs call above | 611 | // running without privileges - see drop_privs call above |
603 | assert(getenv("LD_PRELOAD") == NULL); | 612 | assert(getenv("LD_PRELOAD") == NULL); |
613 | #ifdef HAVE_SECCOMP | ||
614 | seccomp_install_filters(); | ||
615 | #endif | ||
604 | execvp(jail_argv[0], jail_argv); | 616 | execvp(jail_argv[0], jail_argv); |
605 | perror("execvp"); | 617 | perror("execvp"); |
606 | _exit(1); | 618 | _exit(1); |
@@ -730,6 +742,9 @@ void x11_start_xpra_old(int argc, char **argv, int display, char *display_str) { | |||
730 | 742 | ||
731 | // running without privileges - see drop_privs call above | 743 | // running without privileges - see drop_privs call above |
732 | assert(getenv("LD_PRELOAD") == NULL); | 744 | assert(getenv("LD_PRELOAD") == NULL); |
745 | #ifdef HAVE_SECCOMP | ||
746 | seccomp_install_filters(); | ||
747 | #endif | ||
733 | execvp(server_argv[0], server_argv); | 748 | execvp(server_argv[0], server_argv); |
734 | perror("execvp"); | 749 | perror("execvp"); |
735 | _exit(1); | 750 | _exit(1); |
@@ -781,6 +796,9 @@ void x11_start_xpra_old(int argc, char **argv, int display, char *display_str) { | |||
781 | 796 | ||
782 | // running without privileges - see drop_privs call above | 797 | // running without privileges - see drop_privs call above |
783 | assert(getenv("LD_PRELOAD") == NULL); | 798 | assert(getenv("LD_PRELOAD") == NULL); |
799 | #ifdef HAVE_SECCOMP | ||
800 | seccomp_install_filters(); | ||
801 | #endif | ||
784 | execvp(attach_argv[0], attach_argv); | 802 | execvp(attach_argv[0], attach_argv); |
785 | perror("execvp"); | 803 | perror("execvp"); |
786 | _exit(1); | 804 | _exit(1); |
@@ -810,6 +828,9 @@ void x11_start_xpra_old(int argc, char **argv, int display, char *display_str) { | |||
810 | if (jail == 0) { | 828 | if (jail == 0) { |
811 | // running without privileges - see drop_privs call above | 829 | // running without privileges - see drop_privs call above |
812 | assert(getenv("LD_PRELOAD") == NULL); | 830 | assert(getenv("LD_PRELOAD") == NULL); |
831 | #ifdef HAVE_SECCOMP | ||
832 | seccomp_install_filters(); | ||
833 | #endif | ||
813 | if (firejail_argv[0]) // shut up llvm scan-build | 834 | if (firejail_argv[0]) // shut up llvm scan-build |
814 | execvp(firejail_argv[0], firejail_argv); | 835 | execvp(firejail_argv[0], firejail_argv); |
815 | perror("execvp"); | 836 | perror("execvp"); |
@@ -838,6 +859,9 @@ void x11_start_xpra_old(int argc, char **argv, int display, char *display_str) { | |||
838 | } | 859 | } |
839 | // running without privileges - see drop_privs call above | 860 | // running without privileges - see drop_privs call above |
840 | assert(getenv("LD_PRELOAD") == NULL); | 861 | assert(getenv("LD_PRELOAD") == NULL); |
862 | #ifdef HAVE_SECCOMP | ||
863 | seccomp_install_filters(); | ||
864 | #endif | ||
841 | execvp(stop_argv[0], stop_argv); | 865 | execvp(stop_argv[0], stop_argv); |
842 | perror("execvp"); | 866 | perror("execvp"); |
843 | _exit(1); | 867 | _exit(1); |
@@ -1004,6 +1028,9 @@ void x11_start_xpra_new(int argc, char **argv, char *display_str) { | |||
1004 | 1028 | ||
1005 | // running without privileges - see drop_privs call above | 1029 | // running without privileges - see drop_privs call above |
1006 | assert(getenv("LD_PRELOAD") == NULL); | 1030 | assert(getenv("LD_PRELOAD") == NULL); |
1031 | #ifdef HAVE_SECCOMP | ||
1032 | seccomp_install_filters(); | ||
1033 | #endif | ||
1007 | execvp(server_argv[0], server_argv); | 1034 | execvp(server_argv[0], server_argv); |
1008 | perror("execvp"); | 1035 | perror("execvp"); |
1009 | _exit(1); | 1036 | _exit(1); |
@@ -1141,6 +1168,9 @@ void x11_xorg(void) { | |||
1141 | #ifdef HAVE_GCOV | 1168 | #ifdef HAVE_GCOV |
1142 | __gcov_flush(); | 1169 | __gcov_flush(); |
1143 | #endif | 1170 | #endif |
1171 | #ifdef HAVE_SECCOMP | ||
1172 | seccomp_install_filters(); | ||
1173 | #endif | ||
1144 | execlp("/usr/bin/xauth", "/usr/bin/xauth", "-v", "-f", tmpfname, | 1174 | execlp("/usr/bin/xauth", "/usr/bin/xauth", "-v", "-f", tmpfname, |
1145 | "generate", display, "MIT-MAGIC-COOKIE-1", "untrusted", NULL); | 1175 | "generate", display, "MIT-MAGIC-COOKIE-1", "untrusted", NULL); |
1146 | 1176 | ||
diff --git a/src/fseccomp/syscall.c b/src/fseccomp/syscall.c index 3a9be51a7..08ae5953d 100644 --- a/src/fseccomp/syscall.c +++ b/src/fseccomp/syscall.c | |||
@@ -182,12 +182,8 @@ static const SyscallGroupList sysgroups[] = { | |||
182 | #endif | 182 | #endif |
183 | }, | 183 | }, |
184 | { .name = "@default-keep", .list = | 184 | { .name = "@default-keep", .list = |
185 | "dup," | ||
186 | "execve," | 185 | "execve," |
187 | "prctl," | 186 | "prctl" |
188 | "setgid," | ||
189 | "setgroups," | ||
190 | "setuid" | ||
191 | }, | 187 | }, |
192 | { .name = "@module", .list = | 188 | { .name = "@module", .list = |
193 | #ifdef SYS_delete_module | 189 | #ifdef SYS_delete_module |
diff --git a/src/man/firejail.txt b/src/man/firejail.txt index e9b27f9e4..89b815e02 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt | |||
@@ -1687,7 +1687,7 @@ rm: cannot remove `testfile': Operation not permitted | |||
1687 | \fB\-\-seccomp.keep=syscall,syscall,syscall | 1687 | \fB\-\-seccomp.keep=syscall,syscall,syscall |
1688 | Enable seccomp filter, and whitelist the syscalls specified by the | 1688 | Enable seccomp filter, and whitelist the syscalls specified by the |
1689 | command. The system calls needed by Firejail (group @default-keep: | 1689 | command. The system calls needed by Firejail (group @default-keep: |
1690 | dup, prctl, setgid, setgroups, setuid) are always whitelisted. | 1690 | prctl, execve) are handled with the preload library. |
1691 | .br | 1691 | .br |
1692 | 1692 | ||
1693 | .br | 1693 | .br |