summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.in4
-rwxr-xr-xconfigure3
-rw-r--r--configure.ac3
-rw-r--r--src/firejail/Makefile.in2
-rw-r--r--src/firejail/errno.c11
-rw-r--r--src/firejail/firejail.h7
-rw-r--r--src/firejail/join.c2
-rw-r--r--src/firejail/main.c22
-rw-r--r--src/firejail/profile.c14
-rw-r--r--src/firejail/protocol.c247
-rw-r--r--src/firejail/sandbox.c20
-rw-r--r--src/firejail/sbox.c6
-rw-r--r--src/firejail/syscall.c13
-rw-r--r--src/include/syscall.h (renamed from src/firejail/syscall.h)1
14 files changed, 88 insertions, 267 deletions
diff --git a/Makefile.in b/Makefile.in
index 0ae8fc903..86acc206c 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,6 +1,6 @@
1all: apps man 1all: apps man
2MYLIBS = src/lib 2MYLIBS = src/lib
3APPS = src/firejail src/firemon src/firecfg src/libtrace src/libtracelog src/ftee src/faudit src/libconnect src/fnet 3APPS = src/firejail src/firemon src/firecfg src/libtrace src/libtracelog src/ftee src/faudit src/libconnect src/fnet src/fseccomp
4MANPAGES = firejail.1 firemon.1 firecfg.1 firejail-profile.5 firejail-login.5 4MANPAGES = firejail.1 firemon.1 firecfg.1 firejail-profile.5 firejail-login.5
5 5
6prefix=@prefix@ 6prefix=@prefix@
@@ -77,6 +77,7 @@ realinstall:
77 install -c -m 0644 src/firecfg/firecfg.config $(DESTDIR)/$(libdir)/firejail/. 77 install -c -m 0644 src/firecfg/firecfg.config $(DESTDIR)/$(libdir)/firejail/.
78 install -c -m 0755 src/faudit/faudit $(DESTDIR)/$(libdir)/firejail/. 78 install -c -m 0755 src/faudit/faudit $(DESTDIR)/$(libdir)/firejail/.
79 install -c -m 0755 src/fnet/fnet $(DESTDIR)/$(libdir)/firejail/. 79 install -c -m 0755 src/fnet/fnet $(DESTDIR)/$(libdir)/firejail/.
80 install -c -m 0755 src/fseccomp/fseccomp $(DESTDIR)/$(libdir)/firejail/.
80 # documents 81 # documents
81 install -m 0755 -d $(DESTDIR)/$(DOCDIR) 82 install -m 0755 -d $(DESTDIR)/$(DOCDIR)
82 install -c -m 0644 COPYING $(DESTDIR)/$(DOCDIR)/. 83 install -c -m 0644 COPYING $(DESTDIR)/$(DOCDIR)/.
@@ -126,6 +127,7 @@ install-strip: all
126 strip src/ftee/ftee 127 strip src/ftee/ftee
127 strip src/faudit/faudit 128 strip src/faudit/faudit
128 strip src/fnet/fnet 129 strip src/fnet/fnet
130 strip src/fseccomp/fseccomp
129 $(MAKE) realinstall 131 $(MAKE) realinstall
130 132
131uninstall: 133uninstall:
diff --git a/configure b/configure
index 58d236815..a89fddbef 100755
--- a/configure
+++ b/configure
@@ -3759,7 +3759,7 @@ if test "$prefix" = /usr; then
3759 sysconfdir="/etc" 3759 sysconfdir="/etc"
3760fi 3760fi
3761 3761
3762ac_config_files="$ac_config_files Makefile src/lib/Makefile src/fnet/Makefile src/firejail/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/ftee/Makefile src/faudit/Makefile src/libconnect/Makefile" 3762ac_config_files="$ac_config_files Makefile src/lib/Makefile src/fnet/Makefile src/firejail/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/ftee/Makefile src/faudit/Makefile src/libconnect/Makefile src/fseccomp/Makefile"
3763 3763
3764cat >confcache <<\_ACEOF 3764cat >confcache <<\_ACEOF
3765# This file is a shell script that caches the results of configure 3765# This file is a shell script that caches the results of configure
@@ -4479,6 +4479,7 @@ do
4479 "src/ftee/Makefile") CONFIG_FILES="$CONFIG_FILES src/ftee/Makefile" ;; 4479 "src/ftee/Makefile") CONFIG_FILES="$CONFIG_FILES src/ftee/Makefile" ;;
4480 "src/faudit/Makefile") CONFIG_FILES="$CONFIG_FILES src/faudit/Makefile" ;; 4480 "src/faudit/Makefile") CONFIG_FILES="$CONFIG_FILES src/faudit/Makefile" ;;
4481 "src/libconnect/Makefile") CONFIG_FILES="$CONFIG_FILES src/libconnect/Makefile" ;; 4481 "src/libconnect/Makefile") CONFIG_FILES="$CONFIG_FILES src/libconnect/Makefile" ;;
4482 "src/fseccomp/Makefile") CONFIG_FILES="$CONFIG_FILES src/fseccomp/Makefile" ;;
4482 4483
4483 *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; 4484 *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
4484 esac 4485 esac
diff --git a/configure.ac b/configure.ac
index c7125e9c5..9e7680d7d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -148,7 +148,8 @@ if test "$prefix" = /usr; then
148 sysconfdir="/etc" 148 sysconfdir="/etc"
149fi 149fi
150 150
151AC_OUTPUT(Makefile src/lib/Makefile src/fnet/Makefile src/firejail/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/ftee/Makefile src/faudit/Makefile src/libconnect/Makefile) 151AC_OUTPUT(Makefile src/lib/Makefile src/fnet/Makefile src/firejail/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile \
152src/firecfg/Makefile src/ftee/Makefile src/faudit/Makefile src/libconnect/Makefile src/fseccomp/Makefile)
152 153
153echo 154echo
154echo "Configuration options:" 155echo "Configuration options:"
diff --git a/src/firejail/Makefile.in b/src/firejail/Makefile.in
index c4c168236..c99b6c30c 100644
--- a/src/firejail/Makefile.in
+++ b/src/firejail/Makefile.in
@@ -30,7 +30,7 @@ BINOBJS = $(foreach file, $(OBJS), $file)
30CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' $(HAVE_X11) $(HAVE_PRIVATE_HOME) $(HAVE_APPARMOR) $(HAVE_OVERLAYFS) $(HAVE_SECCOMP) $(HAVE_GLOBALCFG) $(HAVE_SECCOMP_H) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_BIND) $(HAVE_FILE_TRANSFER) $(HAVE_WHITELIST) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security 30CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' $(HAVE_X11) $(HAVE_PRIVATE_HOME) $(HAVE_APPARMOR) $(HAVE_OVERLAYFS) $(HAVE_SECCOMP) $(HAVE_GLOBALCFG) $(HAVE_SECCOMP_H) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_BIND) $(HAVE_FILE_TRANSFER) $(HAVE_WHITELIST) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security
31LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread 31LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread
32 32
33%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/euid_common.h ../include/pid.h ../include/seccomp.h 33%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/euid_common.h ../include/pid.h ../include/seccomp.h ../include/syscall.h
34 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ 34 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
35 35
36firejail: $(OBJS) ../lib/libnetlink.o ../lib/common.o 36firejail: $(OBJS) ../lib/libnetlink.o ../lib/common.o
diff --git a/src/firejail/errno.c b/src/firejail/errno.c
index c493dfa09..03f10bb14 100644
--- a/src/firejail/errno.c
+++ b/src/firejail/errno.c
@@ -206,15 +206,4 @@ char *errno_find_nr(int nr) {
206 return "unknown"; 206 return "unknown";
207} 207}
208 208
209void errno_print(void) {
210 EUID_ASSERT();
211
212 int i;
213 int elems = sizeof(errnolist) / sizeof(errnolist[0]);
214 for (i = 0; i < elems; i++) {
215 printf("%d\t- %s\n", errnolist[i].nr, errnolist[i].name);
216 }
217 printf("\n");
218}
219
220#endif // HAVE_SECCOMP 209#endif // HAVE_SECCOMP
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 367f599ec..749656f8b 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -39,6 +39,7 @@
39#define RUN_RO_FILE "/run/firejail/firejail.ro.file" 39#define RUN_RO_FILE "/run/firejail/firejail.ro.file"
40#define RUN_MNT_DIR "/run/firejail/mnt" // a tmpfs is mounted on this directory before any of the files below are created 40#define RUN_MNT_DIR "/run/firejail/mnt" // a tmpfs is mounted on this directory before any of the files below are created
41#define RUN_SECCOMP_CFG "/run/firejail/mnt/seccomp" 41#define RUN_SECCOMP_CFG "/run/firejail/mnt/seccomp"
42#define RUN_SECCOMP_PROTOCOL "/run/firejail/mnt/seccomp.protocol"
42#define RUN_CGROUP_CFG "/run/firejail/mnt/cgroup" 43#define RUN_CGROUP_CFG "/run/firejail/mnt/cgroup"
43#define RUN_CPU_CFG "/run/firejail/mnt/cpu" 44#define RUN_CPU_CFG "/run/firejail/mnt/cpu"
44#define RUN_GROUPS_CFG "/run/firejail/mnt/groups" 45#define RUN_GROUPS_CFG "/run/firejail/mnt/groups"
@@ -514,8 +515,6 @@ void caps_print_filter_name(const char *name);
514const char *syscall_find_nr(int nr); 515const char *syscall_find_nr(int nr);
515// return -1 if error, 0 if no error 516// return -1 if error, 0 if no error
516int syscall_check_list(const char *slist, void (*callback)(int syscall, int arg), int arg); 517int syscall_check_list(const char *slist, void (*callback)(int syscall, int arg), int arg);
517// print all available syscallsseccomp
518void syscall_print(void);
519 518
520// fs_trace.c 519// fs_trace.c
521void fs_trace_preload(void); 520void fs_trace_preload(void);
@@ -598,7 +597,7 @@ void protocol_list();
598void protocol_print_filter_name(const char *name); 597void protocol_print_filter_name(const char *name);
599void protocol_print_filter(pid_t pid); 598void protocol_print_filter(pid_t pid);
600void protocol_store(const char *prlist); 599void protocol_store(const char *prlist);
601void protocol_filter(void); 600void protocol_filter(const char *fname);
602void protocol_filter_save(void); 601void protocol_filter_save(void);
603void protocol_filter_load(const char *fname); 602void protocol_filter_load(const char *fname);
604 603
@@ -686,11 +685,13 @@ void build_cmdline(char **command_line, char **window_title, int argc, char **ar
686// programs 685// programs
687#define PATH_FNET (LIBDIR "/firejail/fnet") 686#define PATH_FNET (LIBDIR "/firejail/fnet")
688#define PATH_FIREMON (PREFIX "/bin/firemon") 687#define PATH_FIREMON (PREFIX "/bin/firemon")
688#define PATH_FSECCOMP (LIBDIR "/firejail/fseccomp")
689// bitmapped filters for sbox_run 689// bitmapped filters for sbox_run
690#define SBOX_ROOT 1 690#define SBOX_ROOT 1
691#define SBOX_USER 2 691#define SBOX_USER 2
692#define SBOX_CAPS 4 692#define SBOX_CAPS 4
693#define SBOX_SECCOMP 8 693#define SBOX_SECCOMP 8
694// run sbox
694int sbox_run(unsigned filter, int num, ...); 695int sbox_run(unsigned filter, int num, ...);
695 696
696 697
diff --git a/src/firejail/join.c b/src/firejail/join.c
index ea44019ca..9b5fba24d 100644
--- a/src/firejail/join.c
+++ b/src/firejail/join.c
@@ -296,7 +296,7 @@ void join(pid_t pid, int argc, char **argv, int index) {
296 if (getuid() != 0) 296 if (getuid() != 0)
297 protocol_filter_load(RUN_PROTOCOL_CFG); 297 protocol_filter_load(RUN_PROTOCOL_CFG);
298 if (cfg.protocol) { // not available for uid 0 298 if (cfg.protocol) { // not available for uid 0
299 protocol_filter(); 299 protocol_filter(RUN_SECCOMP_PROTOCOL);
300 } 300 }
301 301
302 // set seccomp filter 302 // set seccomp filter
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 15d42a4e0..e210ceb31 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -404,8 +404,8 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
404#ifdef HAVE_SECCOMP 404#ifdef HAVE_SECCOMP
405 else if (strcmp(argv[i], "--debug-syscalls") == 0) { 405 else if (strcmp(argv[i], "--debug-syscalls") == 0) {
406 if (checkcfg(CFG_SECCOMP)) { 406 if (checkcfg(CFG_SECCOMP)) {
407 syscall_print(); 407 int rv = sbox_run(SBOX_USER | SBOX_CAPS | SBOX_SECCOMP, 2, PATH_FSECCOMP, "debug-syscalls");
408 exit(0); 408 exit(rv);
409 } 409 }
410 else { 410 else {
411 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); 411 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
@@ -414,7 +414,8 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
414 } 414 }
415 else if (strcmp(argv[i], "--debug-errnos") == 0) { 415 else if (strcmp(argv[i], "--debug-errnos") == 0) {
416 if (checkcfg(CFG_SECCOMP)) { 416 if (checkcfg(CFG_SECCOMP)) {
417 errno_print(); 417 int rv = sbox_run(SBOX_USER | SBOX_CAPS | SBOX_SECCOMP, 2, PATH_FSECCOMP, "debug-errnos");
418 exit(rv);
418 } 419 }
419 else { 420 else {
420 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); 421 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
@@ -438,8 +439,8 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
438 exit(0); 439 exit(0);
439 } 440 }
440 else if (strcmp(argv[i], "--debug-protocols") == 0) { 441 else if (strcmp(argv[i], "--debug-protocols") == 0) {
441 protocol_list(); 442 int rv = sbox_run(SBOX_USER | SBOX_CAPS | SBOX_SECCOMP, 2, PATH_FSECCOMP, "debug-protocols");
442 exit(0); 443 exit(rv);
443 } 444 }
444 else if (strncmp(argv[i], "--protocol.print=", 17) == 0) { 445 else if (strncmp(argv[i], "--protocol.print=", 17) == 0) {
445 if (checkcfg(CFG_SECCOMP)) { 446 if (checkcfg(CFG_SECCOMP)) {
@@ -1117,7 +1118,16 @@ int main(int argc, char **argv) {
1117#ifdef HAVE_SECCOMP 1118#ifdef HAVE_SECCOMP
1118 else if (strncmp(argv[i], "--protocol=", 11) == 0) { 1119 else if (strncmp(argv[i], "--protocol=", 11) == 0) {
1119 if (checkcfg(CFG_SECCOMP)) { 1120 if (checkcfg(CFG_SECCOMP)) {
1120 protocol_store(argv[i] + 11); 1121 if (cfg.protocol) {
1122 if (!arg_quiet)
1123 fprintf(stderr, "Warning: a protocol list is present, the new list \"%s\" will not be installed\n", argv[i] + 11);
1124 }
1125 else {
1126 // store list
1127 cfg.protocol = strdup(argv[i] + 11);
1128 if (!cfg.protocol)
1129 errExit("strdup");
1130 }
1121 } 1131 }
1122 else { 1132 else {
1123 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); 1133 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index e5c35a89d..f7d5e87e6 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -497,8 +497,18 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
497 497
498 if (strncmp(ptr, "protocol ", 9) == 0) { 498 if (strncmp(ptr, "protocol ", 9) == 0) {
499#ifdef HAVE_SECCOMP 499#ifdef HAVE_SECCOMP
500 if (checkcfg(CFG_SECCOMP)) 500 if (checkcfg(CFG_SECCOMP)) {
501 protocol_store(ptr + 9); 501 if (cfg.protocol) {
502 if (!arg_quiet)
503 fprintf(stderr, "Warning: a protocol list is present, the new list \"%s\" will not be installed\n", ptr + 9);
504 return 0;
505 }
506
507 // store list
508 cfg.protocol = strdup(ptr + 9);
509 if (!cfg.protocol)
510 errExit("strdup");
511 }
502 else 512 else
503 fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); 513 fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n");
504#endif 514#endif
diff --git a/src/firejail/protocol.c b/src/firejail/protocol.c
index 6321c703a..43f30e30a 100644
--- a/src/firejail/protocol.c
+++ b/src/firejail/protocol.c
@@ -18,241 +18,44 @@
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 20
21/*
22 struct sock_filter filter[] = {
23 VALIDATE_ARCHITECTURE,
24 EXAMINE_SYSCALL,
25 ONLY(SYS_socket),
26 EXAMINE_ARGUMENT(0), // allow only AF_INET and AF_INET6, drop everything else
27 WHITELIST(AF_INET),
28 WHITELIST(AF_INET6),
29 WHITELIST(AF_PACKET),
30 RETURN_ERRNO(ENOTSUP)
31 };
32 struct sock_fprog prog = {
33 .len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
34 .filter = filter,
35 };
36
37
38 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
39 perror("prctl(NO_NEW_PRIVS)");
40 return 1;
41 }
42 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
43 perror("prctl");
44 return 1;
45 }
46*/
47
48#ifdef HAVE_SECCOMP 21#ifdef HAVE_SECCOMP
49#include "firejail.h" 22#include "firejail.h"
50#include "../include/seccomp.h" 23#include "../include/seccomp.h"
51#include <sys/types.h>
52#include <sys/socket.h>
53
54static char *protocol[] = {
55 "unix",
56 "inet",
57 "inet6",
58 "netlink",
59 "packet",
60 NULL
61};
62
63static struct sock_filter protocol_filter_command[] = {
64 WHITELIST(AF_UNIX),
65 WHITELIST(AF_INET),
66 WHITELIST(AF_INET6),
67 WHITELIST(AF_NETLINK),
68 WHITELIST(AF_PACKET)
69};
70// Note: protocol[] and protocol_filter_command are synchronized
71
72// command length
73struct sock_filter whitelist[] = {
74 WHITELIST(AF_UNIX)
75};
76unsigned whitelist_len = sizeof(whitelist) / sizeof(struct sock_filter);
77
78 24
79 25// install protocol filter
80static int is_protocol(const char *p) { 26void protocol_filter(const char *fname) {
81 int i = 0;
82 while (protocol[i] != NULL) {
83 if (strcmp(protocol[i], p) == 0)
84 return 1;
85 i++;
86 }
87
88 return 0;
89}
90
91static struct sock_filter *find_protocol_domain(const char *p) {
92 int i = 0;
93 while (protocol[i] != NULL) {
94 if (strcmp(protocol[i], p) == 0)
95 return &protocol_filter_command[i * whitelist_len];
96 i++;
97 }
98
99 return NULL;
100}
101
102// --debug-protocols
103void protocol_list(void) {
104 EUID_ASSERT();
105
106#ifndef SYS_socket 27#ifndef SYS_socket
107 fprintf(stderr, "Warning: --protocol not supported on this platform\n"); 28 if (arg_debug)
29 printf("No support for --protocol on this platform\n");
108 return; 30 return;
109#endif 31#else
110 32 assert(fname);
111 int i = 0;
112 while (protocol[i] != NULL) {
113 printf("%s, ", protocol[i]);
114 i++;
115 }
116 printf("\n");
117}
118
119 33
120// check protocol list and store it in cfg structure 34 // check file
121void protocol_store(const char *prlist) { 35 struct stat s;
122 EUID_ASSERT(); 36 if (stat(fname, &s) == -1) {
123 assert(prlist); 37 fprintf(stderr, "Error: cannot read protocol filter file\n");
124 38 exit(1);
125 if (cfg.protocol && !arg_quiet) {
126 fprintf(stderr, "Warning: a protocol list is present, the new list \"%s\" will not be installed\n", prlist);
127 return;
128 } 39 }
129 40 int size = s.st_size;
130 // temporary list
131 char *tmplist = strdup(prlist);
132 if (!tmplist)
133 errExit("strdup");
134
135 // check list
136 char *token = strtok(tmplist, ",");
137 if (!token)
138 goto errout;
139
140 while (token) {
141 if (!is_protocol(token))
142 goto errout;
143 token = strtok(NULL, ",");
144 }
145 free(tmplist);
146
147 // store list
148 cfg.protocol = strdup(prlist);
149 if (!cfg.protocol)
150 errExit("strdup");
151 return;
152
153errout:
154 fprintf(stderr, "Error: invalid protocol list\n");
155 exit(1);
156}
157 41
158// install protocol filter 42 // read filter
159void protocol_filter(void) {
160 assert(cfg.protocol);
161 if (arg_debug)
162 printf("Set protocol filter: %s\n", cfg.protocol);
163
164#ifndef SYS_socket
165 (void) find_protocol_domain;
166 fprintf(stderr, "Warning: --protocol not supported on this platform\n");
167 return;
168#else
169 // build the filter
170 struct sock_filter filter[32]; // big enough 43 struct sock_filter filter[32]; // big enough
171 memset(&filter[0], 0, sizeof(filter)); 44 memset(&filter[0], 0, sizeof(filter));
172 uint8_t *ptr = (uint8_t *) &filter[0]; 45 int src = open(fname, O_RDONLY);
173 46 int rd = 0;
174 // header 47 while (rd < size) {
175 struct sock_filter filter_start[] = { 48 int rv = read(src, (unsigned char *) filter + rd, size - rd);
176 VALIDATE_ARCHITECTURE, 49 if (rv == -1) {
177 EXAMINE_SYSCALL, 50 fprintf(stderr, "Error: cannot read %s file\n", fname);
178 ONLY(SYS_socket), 51 exit(1);
179 EXAMINE_ARGUMENT(0) 52 }
180 }; 53 rd += rv;
181 memcpy(ptr, &filter_start[0], sizeof(filter_start));
182 ptr += sizeof(filter_start);
183
184#if 0
185printf("entries %u\n", (unsigned) (sizeof(filter_start) / sizeof(struct sock_filter)));
186{
187 unsigned j;
188 unsigned char *ptr2 = (unsigned char *) &filter[0];
189 for (j = 0; j < sizeof(filter); j++, ptr2++) {
190 if ((j % (sizeof(struct sock_filter))) == 0)
191 printf("\n%u: ", 1 + (unsigned) (j / (sizeof(struct sock_filter))));
192 printf("%02x, ", (*ptr2) & 0xff);
193 }
194 printf("\n");
195}
196printf("whitelist_len %u, struct sock_filter len %u\n", whitelist_len, (unsigned) sizeof(struct sock_filter));
197#endif
198
199
200 // parse list and add commands
201 char *tmplist = strdup(cfg.protocol);
202 if (!tmplist)
203 errExit("strdup");
204 char *token = strtok(tmplist, ",");
205 if (!token)
206 errExit("strtok");
207
208 while (token) {
209 struct sock_filter *domain = find_protocol_domain(token);
210 assert(domain);
211 memcpy(ptr, domain, whitelist_len * sizeof(struct sock_filter));
212 ptr += whitelist_len * sizeof(struct sock_filter);
213 token = strtok(NULL, ",");
214
215#if 0
216printf("entries %u\n", (unsigned) ((uint64_t) ptr - (uint64_t) (filter)) / (unsigned) sizeof(struct sock_filter));
217{
218 unsigned j;
219 unsigned char *ptr2 = (unsigned char *) &filter[0];
220 for (j = 0; j < sizeof(filter); j++, ptr2++) {
221 if ((j % (sizeof(struct sock_filter))) == 0)
222 printf("\n%u: ", 1 + (unsigned) (j / (sizeof(struct sock_filter))));
223 printf("%02x, ", (*ptr2) & 0xff);
224 }
225 printf("\n");
226}
227#endif
228
229
230 }
231 free(tmplist);
232
233 // add end of filter
234 struct sock_filter filter_end[] = {
235 RETURN_ERRNO(ENOTSUP)
236 };
237 memcpy(ptr, &filter_end[0], sizeof(filter_end));
238 ptr += sizeof(filter_end);
239
240#if 0
241printf("entries %u\n", (unsigned) ((uint64_t) ptr - (uint64_t) (filter)) / (unsigned) sizeof(struct sock_filter));
242{
243 unsigned j;
244 unsigned char *ptr2 = (unsigned char *) &filter[0];
245 for (j = 0; j < sizeof(filter); j++, ptr2++) {
246 if ((j % (sizeof(struct sock_filter))) == 0)
247 printf("\n%u: ", 1 + (unsigned) (j / (sizeof(struct sock_filter))));
248 printf("%02x, ", (*ptr2) & 0xff);
249 } 54 }
250 printf("\n"); 55 close(src);
251}
252#endif
253 56
254 // install filter 57 // install filter
255 unsigned short entries = (unsigned short) ((uintptr_t) ptr - (uintptr_t) (filter)) / (unsigned) sizeof(struct sock_filter); 58 unsigned short entries = (unsigned short) size / (unsigned short) sizeof(struct sock_filter);
256 struct sock_fprog prog = { 59 struct sock_fprog prog = {
257 .len = entries, 60 .len = entries,
258 .filter = filter, 61 .filter = filter,
@@ -262,7 +65,7 @@ printf("entries %u\n", (unsigned) ((uint64_t) ptr - (uint64_t) (filter)) / (uns
262 fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); 65 fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n");
263 return; 66 return;
264 } 67 }
265#endif // SYS_socket 68#endif
266} 69}
267 70
268void protocol_filter_save(void) { 71void protocol_filter_save(void) {
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index f5cca7494..7a63461ef 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -819,8 +819,24 @@ int sandbox(void* sandbox_arg) {
819#ifdef HAVE_SECCOMP 819#ifdef HAVE_SECCOMP
820 // install protocol filter 820 // install protocol filter
821 if (cfg.protocol) { 821 if (cfg.protocol) {
822 protocol_filter(); // install filter 822 if (arg_debug)
823 protocol_filter_save(); // save filter in PROTOCOL_CFG 823 printf("Set protocol filter: %s\n", cfg.protocol);
824 // as root, create RUN_SECCOMP_PROTOCOL file
825 // this is where fseccomp program will store the protocol filter
826 int dst = open(RUN_SECCOMP_PROTOCOL, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
827 if (dst == -1)
828 errExit("open");
829 close(dst);
830 if (chown(RUN_SECCOMP_PROTOCOL, getuid(), getgid()) == -1)
831 errExit("chown");
832
833 // build the seccomp filter as a regular user
834 int rv = sbox_run(SBOX_USER | SBOX_CAPS | SBOX_SECCOMP, 5,
835 PATH_FSECCOMP, "protocol", "build", cfg.protocol, RUN_SECCOMP_PROTOCOL);
836 if (rv)
837 exit(rv);
838 protocol_filter(RUN_SECCOMP_PROTOCOL); // install filter
839 protocol_filter_save(); // save filter in RUN_PROTOCOL_CFG
824 } 840 }
825 841
826 // if a keep list is available, disregard the drop list 842 // if a keep list is available, disregard the drop list
diff --git a/src/firejail/sbox.c b/src/firejail/sbox.c
index 8c6ace27e..d3ef2578c 100644
--- a/src/firejail/sbox.c
+++ b/src/firejail/sbox.c
@@ -124,14 +124,14 @@ int sbox_run(unsigned filter, int num, ...) {
124 arg[i] = NULL; 124 arg[i] = NULL;
125 va_end(valist); 125 va_end(valist);
126 126
127#if 0 127//#if 0
128{ 128{
129int i; 129int i;
130for (i = 0; i <= num; i++) 130for (i = 0; i <= num; i++)
131 printf("#%s# ", arg[i]); 131 printf("#%s# ", arg[i]);
132printf("\n"); 132printf("\n");
133} 133}
134#endif 134//#endif
135 pid_t child = fork(); 135 pid_t child = fork();
136 if (child < 0) 136 if (child < 0)
137 errExit("fork"); 137 errExit("fork");
@@ -169,7 +169,7 @@ printf("\n");
169 errExit("waitpid"); 169 errExit("waitpid");
170 } 170 }
171 if (WIFEXITED(status) && status != 0) { 171 if (WIFEXITED(status) && status != 0) {
172 fprintf(stderr, "Error: cannot run fnet\n"); 172 fprintf(stderr, "Error: failed to run %s\n", arg[0]);
173 exit(1); 173 exit(1);
174 } 174 }
175 175
diff --git a/src/firejail/syscall.c b/src/firejail/syscall.c
index 985cc8bb8..f405f23c8 100644
--- a/src/firejail/syscall.c
+++ b/src/firejail/syscall.c
@@ -31,7 +31,7 @@ static SyscallEntry syslist[] = {
31// 31//
32// code generated using tools/extract-syscall 32// code generated using tools/extract-syscall
33// 33//
34#include "syscall.h" 34#include "../include/syscall.h"
35// 35//
36// end of generated code 36// end of generated code
37// 37//
@@ -102,15 +102,4 @@ int syscall_check_list(const char *slist, void (*callback)(int syscall, int arg)
102 return 0; 102 return 0;
103} 103}
104 104
105void syscall_print(void) {
106 EUID_ASSERT();
107
108 int i;
109 int elems = sizeof(syslist) / sizeof(syslist[0]);
110 for (i = 0; i < elems; i++) {
111 printf("%d\t- %s\n", syslist[i].nr, syslist[i].name);
112 }
113 printf("\n");
114}
115
116#endif // HAVE_SECCOMP 105#endif // HAVE_SECCOMP
diff --git a/src/firejail/syscall.h b/src/include/syscall.h
index 68d4b5736..9a29779c9 100644
--- a/src/firejail/syscall.h
+++ b/src/include/syscall.h
@@ -20,7 +20,6 @@
20 20
21// content extracted from /bits/syscall.h file form glibc 2.22 21// content extracted from /bits/syscall.h file form glibc 2.22
22// using ../tools/extract_syscall tool 22// using ../tools/extract_syscall tool
23
24#if !defined __x86_64__ 23#if !defined __x86_64__
25#ifdef SYS__llseek 24#ifdef SYS__llseek
26#ifdef __NR__llseek 25#ifdef __NR__llseek