aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar Topi Miettinen <toiwoton@gmail.com>2017-08-19 13:54:28 +0300
committerLibravatar Topi Miettinen <toiwoton@gmail.com>2017-08-19 14:01:37 +0300
commit85bb547e4054ab147d393bf437998ad76043783a (patch)
treef18a85f2767fedf3d9b5b1fa3b3996c8cc027a9c /src
parentMerge branch 'master' of https://github.com/netblue30/firejail (diff)
downloadfirejail-85bb547e4054ab147d393bf437998ad76043783a.tar.gz
firejail-85bb547e4054ab147d393bf437998ad76043783a.tar.zst
firejail-85bb547e4054ab147d393bf437998ad76043783a.zip
Postpone installation of seccomp filters just before execve
Diffstat (limited to 'src')
-rw-r--r--src/firejail/bandwidth.c3
-rw-r--r--src/firejail/firejail.h1
-rw-r--r--src/firejail/output.c3
-rw-r--r--src/firejail/sandbox.c20
-rw-r--r--src/firejail/sbox.c5
-rw-r--r--src/firejail/seccomp.c49
-rw-r--r--src/firejail/x11.c30
-rw-r--r--src/fseccomp/syscall.c6
-rw-r--r--src/man/firejail.txt2
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
538char *seccomp_check_list(const char *str); 538char *seccomp_check_list(const char *str);
539int seccomp_install_filters(void);
539int seccomp_load(const char *fname); 540int seccomp_load(const char *fname);
540void seccomp_filter_32(void); 541void seccomp_filter_32(void);
541void seccomp_filter_64(void); 542void 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
26typedef struct filter_list {
27 struct filter_list *next;
28 struct sock_fprog prog;
29} FilterList;
30
31static FilterList *filter_list_head = NULL;
32
26static int err_printed = 0; 33static int err_printed = 0;
27 34
28char *seccomp_check_list(const char *str) { 35char *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
63int 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
56int seccomp_load(const char *fname) { 81int 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;
96errexit: 115errexit:
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
1688Enable seccomp filter, and whitelist the syscalls specified by the 1688Enable seccomp filter, and whitelist the syscalls specified by the
1689command. The system calls needed by Firejail (group @default-keep: 1689command. The system calls needed by Firejail (group @default-keep:
1690dup, prctl, setgid, setgroups, setuid) are always whitelisted. 1690prctl, execve) are handled with the preload library.
1691.br 1691.br
1692 1692
1693.br 1693.br