summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar valoq <valoq@mailbox.org>2016-11-06 20:44:32 +0100
committerLibravatar valoq <valoq@mailbox.org>2016-11-06 20:44:32 +0100
commitcf2c9e6436f16c727d09b433c1ac821849d3daa1 (patch)
tree8a57806636d3671eabfe2fd4a577c40691725c97
parentadopted wire profile to recent changes (diff)
parentseccomp rework (diff)
downloadfirejail-cf2c9e6436f16c727d09b433c1ac821849d3daa1.tar.gz
firejail-cf2c9e6436f16c727d09b433c1ac821849d3daa1.tar.zst
firejail-cf2c9e6436f16c727d09b433c1ac821849d3daa1.zip
Merge remote-tracking branch 'upstream/master'
-rw-r--r--README4
-rw-r--r--README.md2
-rw-r--r--etc/evince.profile2
-rw-r--r--etc/firefox.profile5
-rw-r--r--etc/mupdf.profile2
-rw-r--r--etc/zoom.profile23
-rw-r--r--platform/debian/conffiles1
-rw-r--r--src/firejail/bandwidth.c2
-rw-r--r--src/firejail/errno.c207
-rw-r--r--src/firejail/firejail.h3
-rw-r--r--src/firejail/fs_bin.c2
-rw-r--r--src/firejail/fs_etc.c2
-rw-r--r--src/firejail/main.c56
-rw-r--r--src/firejail/netfilter.c8
-rw-r--r--src/firejail/profile.c16
-rw-r--r--src/firejail/sandbox.c2
-rw-r--r--src/firejail/sbox.c17
-rw-r--r--src/firejail/seccomp.c72
-rw-r--r--src/firejail/usage.c441
-rw-r--r--src/firejail/x11.c48
-rw-r--r--src/fnet/Makefile.in4
-rw-r--r--src/fseccomp/Makefile.in4
-rw-r--r--src/fseccomp/main.c2
-rw-r--r--src/fseccomp/protocol.c2
-rw-r--r--src/fseccomp/syscall.c87
-rwxr-xr-xtest/filters/seccomp-errno.exp44
26 files changed, 327 insertions, 731 deletions
diff --git a/README b/README
index 50bc00099..7599f4cf1 100644
--- a/README
+++ b/README
@@ -80,6 +80,8 @@ Fred-Barclay (https://github.com/Fred-Barclay)
80 - evince profile enhancement 80 - evince profile enhancement
81 - tightened Spotify profile 81 - tightened Spotify profile
82 - added xiphos and Tor Browser Bundle profiles 82 - added xiphos and Tor Browser Bundle profiles
83BogDan Vatra (https://github.com/bog-dan-ro)
84 - zoom profile
83Impyy (https://github.com/Impyy) 85Impyy (https://github.com/Impyy)
84 - added mumble profile 86 - added mumble profile
85valoq (https://github.com/valoq) 87valoq (https://github.com/valoq)
@@ -88,6 +90,8 @@ valoq (https://github.com/valoq)
88 - added support for /srv in --whitelist feature 90 - added support for /srv in --whitelist feature
89 - Eye of GNOME, Evolution, display (imagemagik) and Wire profiles 91 - Eye of GNOME, Evolution, display (imagemagik) and Wire profiles
90 - blacklist suid binaries in disable-common.inc 92 - blacklist suid binaries in disable-common.inc
93 - fix man pages
94 - various profile improvements
91Vadim A. Misbakh-Soloviov (https://github.com/msva) 95Vadim A. Misbakh-Soloviov (https://github.com/msva)
92 - profile fixes 96 - profile fixes
93Rafael Cavalcanti (https://github.com/rccavalcanti) 97Rafael Cavalcanti (https://github.com/rccavalcanti)
diff --git a/README.md b/README.md
index c6484d3b7..931b27ef3 100644
--- a/README.md
+++ b/README.md
@@ -52,5 +52,5 @@ Use this issue to request new profiles: https://github.com/netblue30/firejail/is
52 52
53````` 53`````
54## New Profiles 54## New Profiles
55xiphos, Tor Browser Bundle, display (imagemagik), Wire, mumble 55xiphos, Tor Browser Bundle, display (imagemagik), Wire, mumble, zoom
56 56
diff --git a/etc/evince.profile b/etc/evince.profile
index 9a9113c70..cbb2083f4 100644
--- a/etc/evince.profile
+++ b/etc/evince.profile
@@ -6,7 +6,7 @@ include /etc/firejail/disable-passwdmgr.inc
6 6
7caps.drop all 7caps.drop all
8netfilter 8netfilter
9net none 9#net none - creates some problems on some distributions
10nogroups 10nogroups
11nonewprivs 11nonewprivs
12noroot 12noroot
diff --git a/etc/firefox.profile b/etc/firefox.profile
index 7875ca6b9..7862bd010 100644
--- a/etc/firefox.profile
+++ b/etc/firefox.profile
@@ -47,8 +47,7 @@ whitelist ~/.config/pipelight-silverlight5.1
47include /etc/firejail/whitelist-common.inc 47include /etc/firejail/whitelist-common.inc
48 48
49# experimental features 49# experimental features
50 50#private-bin firefox,which,sh,dbus-launch,dbus-send,env
51private-bin firefox,which,sh,dbus-launch,dbus-send,env 51#private-etc passwd,group,hostname,hosts,localtime,nsswitch.conf,resolv.conf,xdg,gtk-2.0,gtk-3.0,X11,pango,fonts,firefox,mime.types,mailcap,asound.conf,pulse
52private-etc passwd,group,hostname,hosts,localtime,nsswitch.conf,resolv.conf,xdg,gtk-2.0,gtk-3.0,X11,pango,fonts,firefox,mime.types,mailcap,asound.conf,pulse
53private-dev 52private-dev
54private-tmp 53private-tmp
diff --git a/etc/mupdf.profile b/etc/mupdf.profile
index 65e6a8978..e022866e8 100644
--- a/etc/mupdf.profile
+++ b/etc/mupdf.profile
@@ -16,7 +16,7 @@ net none
16shell none 16shell none
17tracelog 17tracelog
18 18
19seccomp.keep access,arch_prctl,brk,clone,close,connect,execve,exit_group,fchmod,fchown,fcntl,fstat,futex,getcwd,getpeername,getrlimit,getsockname,getsockopt,lseek,lstat,mlock,mmap,mprotect,munmap,nanosleep,open,poll,prctl,read,recvfrom,recvmsg,restart_syscall,rt_sigaction,rt_sigprocmask,select,sendmsg,set_robust_list,set_tid_address,setresgid,setresuid,shmat,shmctl,shmget,shutdown,socket,stat,sysinfo,uname,unshare,wait4,write,writev 19#seccomp.keep access,arch_prctl,brk,clone,close,connect,execve,exit_group,fchmod,fchown,fcntl,fstat,futex,getcwd,getpeername,getrlimit,getsockname,getsockopt,lseek,lstat,mlock,mmap,mprotect,munmap,nanosleep,open,poll,prctl,read,recvfrom,recvmsg,restart_syscall,rt_sigaction,rt_sigprocmask,select,sendmsg,set_robust_list,set_tid_address,setresgid,setresuid,shmat,shmctl,shmget,shutdown,socket,stat,sysinfo,uname,unshare,wait4,write,writev
20 20
21private-bin mupdf 21private-bin mupdf
22private-tmp 22private-tmp
diff --git a/etc/zoom.profile b/etc/zoom.profile
new file mode 100644
index 000000000..f5831dd88
--- /dev/null
+++ b/etc/zoom.profile
@@ -0,0 +1,23 @@
1# Firejail profile for zoom.us
2
3noblacklist ~/.config/zoomus.conf
4
5include /etc/firejail/disable-common.inc
6include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-devel.inc
8
9
10# Whitelists
11
12mkdir ~/.zoom
13whitelist ~/.zoom
14
15
16caps.drop all
17netfilter
18nonewprivs
19noroot
20protocol unix,inet,inet6
21seccomp
22
23private-tmp
diff --git a/platform/debian/conffiles b/platform/debian/conffiles
index df660ab4f..ae8db5a67 100644
--- a/platform/debian/conffiles
+++ b/platform/debian/conffiles
@@ -171,3 +171,4 @@
171/etc/firejail/display.profile 171/etc/firejail/display.profile
172/etc/firejail/Wire.profile 172/etc/firejail/Wire.profile
173/etc/firejail/mumble.profile 173/etc/firejail/mumble.profile
174/etc/firejail/zoom.profile
diff --git a/src/firejail/bandwidth.c b/src/firejail/bandwidth.c
index ab9714afe..512cc0b05 100644
--- a/src/firejail/bandwidth.c
+++ b/src/firejail/bandwidth.c
@@ -462,7 +462,7 @@ void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, in
462 arg[1] = "-c"; 462 arg[1] = "-c";
463 arg[2] = cmd; 463 arg[2] = cmd;
464 arg[3] = NULL; 464 arg[3] = NULL;
465 assert(getenv("LD_PRELOAD") == NULL); 465 clearenv();
466 execvp(arg[0], arg); 466 execvp(arg[0], arg);
467 467
468 // it will never get here 468 // it will never get here
diff --git a/src/firejail/errno.c b/src/firejail/errno.c
deleted file mode 100644
index 8215c99a1..000000000
--- a/src/firejail/errno.c
+++ /dev/null
@@ -1,207 +0,0 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#ifdef HAVE_SECCOMP
21#include "firejail.h"
22#include <errno.h>
23//#include <attr/xattr.h>
24
25typedef struct {
26 char *name;
27 int nr;
28} ErrnoEntry;
29
30static ErrnoEntry errnolist[] = {
31//
32// code generated using tools/extract-errnos
33//
34 {"EPERM", EPERM},
35 {"ENOENT", ENOENT},
36 {"ESRCH", ESRCH},
37 {"EINTR", EINTR},
38 {"EIO", EIO},
39 {"ENXIO", ENXIO},
40 {"E2BIG", E2BIG},
41 {"ENOEXEC", ENOEXEC},
42 {"EBADF", EBADF},
43 {"ECHILD", ECHILD},
44 {"EAGAIN", EAGAIN},
45 {"ENOMEM", ENOMEM},
46 {"EACCES", EACCES},
47 {"EFAULT", EFAULT},
48 {"ENOTBLK", ENOTBLK},
49 {"EBUSY", EBUSY},
50 {"EEXIST", EEXIST},
51 {"EXDEV", EXDEV},
52 {"ENODEV", ENODEV},
53 {"ENOTDIR", ENOTDIR},
54 {"EISDIR", EISDIR},
55 {"EINVAL", EINVAL},
56 {"ENFILE", ENFILE},
57 {"EMFILE", EMFILE},
58 {"ENOTTY", ENOTTY},
59 {"ETXTBSY", ETXTBSY},
60 {"EFBIG", EFBIG},
61 {"ENOSPC", ENOSPC},
62 {"ESPIPE", ESPIPE},
63 {"EROFS", EROFS},
64 {"EMLINK", EMLINK},
65 {"EPIPE", EPIPE},
66 {"EDOM", EDOM},
67 {"ERANGE", ERANGE},
68 {"EDEADLK", EDEADLK},
69 {"ENAMETOOLONG", ENAMETOOLONG},
70 {"ENOLCK", ENOLCK},
71 {"ENOSYS", ENOSYS},
72 {"ENOTEMPTY", ENOTEMPTY},
73 {"ELOOP", ELOOP},
74 {"EWOULDBLOCK", EWOULDBLOCK},
75 {"ENOMSG", ENOMSG},
76 {"EIDRM", EIDRM},
77 {"ECHRNG", ECHRNG},
78 {"EL2NSYNC", EL2NSYNC},
79 {"EL3HLT", EL3HLT},
80 {"EL3RST", EL3RST},
81 {"ELNRNG", ELNRNG},
82 {"EUNATCH", EUNATCH},
83 {"ENOCSI", ENOCSI},
84 {"EL2HLT", EL2HLT},
85 {"EBADE", EBADE},
86 {"EBADR", EBADR},
87 {"EXFULL", EXFULL},
88 {"ENOANO", ENOANO},
89 {"EBADRQC", EBADRQC},
90 {"EBADSLT", EBADSLT},
91 {"EDEADLOCK", EDEADLOCK},
92 {"EBFONT", EBFONT},
93 {"ENOSTR", ENOSTR},
94 {"ENODATA", ENODATA},
95 {"ETIME", ETIME},
96 {"ENOSR", ENOSR},
97 {"ENONET", ENONET},
98 {"ENOPKG", ENOPKG},
99 {"EREMOTE", EREMOTE},
100 {"ENOLINK", ENOLINK},
101 {"EADV", EADV},
102 {"ESRMNT", ESRMNT},
103 {"ECOMM", ECOMM},
104 {"EPROTO", EPROTO},
105 {"EMULTIHOP", EMULTIHOP},
106 {"EDOTDOT", EDOTDOT},
107 {"EBADMSG", EBADMSG},
108 {"EOVERFLOW", EOVERFLOW},
109 {"ENOTUNIQ", ENOTUNIQ},
110 {"EBADFD", EBADFD},
111 {"EREMCHG", EREMCHG},
112 {"ELIBACC", ELIBACC},
113 {"ELIBBAD", ELIBBAD},
114 {"ELIBSCN", ELIBSCN},
115 {"ELIBMAX", ELIBMAX},
116 {"ELIBEXEC", ELIBEXEC},
117 {"EILSEQ", EILSEQ},
118 {"ERESTART", ERESTART},
119 {"ESTRPIPE", ESTRPIPE},
120 {"EUSERS", EUSERS},
121 {"ENOTSOCK", ENOTSOCK},
122 {"EDESTADDRREQ", EDESTADDRREQ},
123 {"EMSGSIZE", EMSGSIZE},
124 {"EPROTOTYPE", EPROTOTYPE},
125 {"ENOPROTOOPT", ENOPROTOOPT},
126 {"EPROTONOSUPPORT", EPROTONOSUPPORT},
127 {"ESOCKTNOSUPPORT", ESOCKTNOSUPPORT},
128 {"EOPNOTSUPP", EOPNOTSUPP},
129 {"EPFNOSUPPORT", EPFNOSUPPORT},
130 {"EAFNOSUPPORT", EAFNOSUPPORT},
131 {"EADDRINUSE", EADDRINUSE},
132 {"EADDRNOTAVAIL", EADDRNOTAVAIL},
133 {"ENETDOWN", ENETDOWN},
134 {"ENETUNREACH", ENETUNREACH},
135 {"ENETRESET", ENETRESET},
136 {"ECONNABORTED", ECONNABORTED},
137 {"ECONNRESET", ECONNRESET},
138 {"ENOBUFS", ENOBUFS},
139 {"EISCONN", EISCONN},
140 {"ENOTCONN", ENOTCONN},
141 {"ESHUTDOWN", ESHUTDOWN},
142 {"ETOOMANYREFS", ETOOMANYREFS},
143 {"ETIMEDOUT", ETIMEDOUT},
144 {"ECONNREFUSED", ECONNREFUSED},
145 {"EHOSTDOWN", EHOSTDOWN},
146 {"EHOSTUNREACH", EHOSTUNREACH},
147 {"EALREADY", EALREADY},
148 {"EINPROGRESS", EINPROGRESS},
149 {"ESTALE", ESTALE},
150 {"EUCLEAN", EUCLEAN},
151 {"ENOTNAM", ENOTNAM},
152 {"ENAVAIL", ENAVAIL},
153 {"EISNAM", EISNAM},
154 {"EREMOTEIO", EREMOTEIO},
155 {"EDQUOT", EDQUOT},
156 {"ENOMEDIUM", ENOMEDIUM},
157 {"EMEDIUMTYPE", EMEDIUMTYPE},
158 {"ECANCELED", ECANCELED},
159 {"ENOKEY", ENOKEY},
160 {"EKEYEXPIRED", EKEYEXPIRED},
161 {"EKEYREVOKED", EKEYREVOKED},
162 {"EKEYREJECTED", EKEYREJECTED},
163 {"EOWNERDEAD", EOWNERDEAD},
164 {"ENOTRECOVERABLE", ENOTRECOVERABLE},
165 {"ERFKILL", ERFKILL},
166 {"EHWPOISON", EHWPOISON},
167 {"ENOTSUP", ENOTSUP},
168#ifdef ENOATTR
169 {"ENOATTR", ENOATTR},
170#endif
171};
172
173int errno_highest_nr(void) {
174 int i, max = 0;
175 int elems = sizeof(errnolist) / sizeof(errnolist[0]);
176 for (i = 0; i < elems; i++) {
177 if (errnolist[i].nr > max)
178 max = errnolist[i].nr;
179 }
180
181 return max;
182}
183
184int errno_find_name(const char *name) {
185 EUID_ASSERT();
186
187 int i;
188 int elems = sizeof(errnolist) / sizeof(errnolist[0]);
189 for (i = 0; i < elems; i++) {
190 if (strcasecmp(name, errnolist[i].name) == 0)
191 return errnolist[i].nr;
192 }
193
194 return -1;
195}
196
197char *errno_find_nr(int nr) {
198 int i;
199 int elems = sizeof(errnolist) / sizeof(errnolist[0]);
200 for (i = 0; i < elems; i++) {
201 if (nr == errnolist[i].nr)
202 return errnolist[i].name;
203 }
204
205 return "unknown";
206}
207#endif // HAVE_SECCOMP
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index cf540ff91..56dbd6868 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -222,7 +222,6 @@ typedef struct config_t {
222 char *seccomp_list;// optional seccomp list on top of default filter 222 char *seccomp_list;// optional seccomp list on top of default filter
223 char *seccomp_list_drop; // seccomp drop list 223 char *seccomp_list_drop; // seccomp drop list
224 char *seccomp_list_keep; // seccomp keep list 224 char *seccomp_list_keep; // seccomp keep list
225 char **seccomp_list_errno; // seccomp errno[nr] lists
226 char *protocol; // protocol list 225 char *protocol; // protocol list
227 226
228 // rlimits 227 // rlimits
@@ -496,12 +495,12 @@ void fs_private_home_list(void);
496 495
497 496
498// seccomp.c 497// seccomp.c
498char *seccomp_check_list(const char *str);
499int seccomp_load(const char *fname); 499int seccomp_load(const char *fname);
500void seccomp_filter_32(void); 500void seccomp_filter_32(void);
501void seccomp_filter_64(void); 501void seccomp_filter_64(void);
502int seccomp_filter_drop(int enforce_seccomp); 502int seccomp_filter_drop(int enforce_seccomp);
503int seccomp_filter_keep(void); 503int seccomp_filter_keep(void);
504int seccomp_filter_errno(void);
505void seccomp_print_filter_name(const char *name); 504void seccomp_print_filter_name(const char *name);
506void seccomp_print_filter(pid_t pid); 505void seccomp_print_filter(pid_t pid);
507 506
diff --git a/src/firejail/fs_bin.c b/src/firejail/fs_bin.c
index d6fee0608..a3576e7c4 100644
--- a/src/firejail/fs_bin.c
+++ b/src/firejail/fs_bin.c
@@ -191,7 +191,7 @@ static void duplicate(char *fname) {
191 char *f; 191 char *f;
192 if (asprintf(&f, "%s/%s", RUN_BIN_DIR, fname) == -1) 192 if (asprintf(&f, "%s/%s", RUN_BIN_DIR, fname) == -1)
193 errExit("asprintf"); 193 errExit("asprintf");
194 assert(getenv("LD_PRELOAD") == NULL); 194 clearenv();
195 execlp(RUN_CP_COMMAND, RUN_CP_COMMAND, "-a", actual_path, f, NULL); 195 execlp(RUN_CP_COMMAND, RUN_CP_COMMAND, "-a", actual_path, f, NULL);
196 perror("execlp"); 196 perror("execlp");
197 _exit(1); 197 _exit(1);
diff --git a/src/firejail/fs_etc.c b/src/firejail/fs_etc.c
index 4f3417236..830de7c9f 100644
--- a/src/firejail/fs_etc.c
+++ b/src/firejail/fs_etc.c
@@ -105,7 +105,7 @@ static void duplicate(char *fname) {
105 char *f; 105 char *f;
106 if (asprintf(&f, "/etc/%s", fname) == -1) 106 if (asprintf(&f, "/etc/%s", fname) == -1)
107 errExit("asprintf"); 107 errExit("asprintf");
108 assert(getenv("LD_PRELOAD") == NULL); 108 clearenv();
109 execlp(RUN_CP_COMMAND, RUN_CP_COMMAND, "-a", "--parents", f, RUN_MNT_DIR, NULL); 109 execlp(RUN_CP_COMMAND, RUN_CP_COMMAND, "-a", "--parents", f, RUN_MNT_DIR, NULL);
110 perror("execlp"); 110 perror("execlp");
111 _exit(1); 111 _exit(1);
diff --git a/src/firejail/main.c b/src/firejail/main.c
index fc86f9651..b6f3a7f59 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -851,9 +851,6 @@ int main(int argc, char **argv) {
851 int custom_profile = 0; // custom profile loaded 851 int custom_profile = 0; // custom profile loaded
852 char *custom_profile_dir = NULL; // custom profile directory 852 char *custom_profile_dir = NULL; // custom profile directory
853 int arg_noprofile = 0; // use default.profile if none other found/specified 853 int arg_noprofile = 0; // use default.profile if none other found/specified
854#ifdef HAVE_SECCOMP
855 int highest_errno = errno_highest_nr();
856#endif
857 854
858 // build /run/firejail directory structure 855 // build /run/firejail directory structure
859 preproc_build_firejail_dir(); 856 preproc_build_firejail_dir();
@@ -1155,9 +1152,7 @@ int main(int argc, char **argv) {
1155 exit(1); 1152 exit(1);
1156 } 1153 }
1157 arg_seccomp = 1; 1154 arg_seccomp = 1;
1158 cfg.seccomp_list = strdup(argv[i] + 10); 1155 cfg.seccomp_list = seccomp_check_list(argv[i] + 10);
1159 if (!cfg.seccomp_list)
1160 errExit("strdup");
1161 } 1156 }
1162 else { 1157 else {
1163 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); 1158 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
@@ -1171,9 +1166,7 @@ int main(int argc, char **argv) {
1171 exit(1); 1166 exit(1);
1172 } 1167 }
1173 arg_seccomp = 1; 1168 arg_seccomp = 1;
1174 cfg.seccomp_list_drop = strdup(argv[i] + 15); 1169 cfg.seccomp_list_drop = seccomp_check_list(argv[i] + 15);
1175 if (!cfg.seccomp_list_drop)
1176 errExit("strdup");
1177 } 1170 }
1178 else { 1171 else {
1179 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); 1172 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
@@ -1187,43 +1180,7 @@ int main(int argc, char **argv) {
1187 exit(1); 1180 exit(1);
1188 } 1181 }
1189 arg_seccomp = 1; 1182 arg_seccomp = 1;
1190 cfg.seccomp_list_keep = strdup(argv[i] + 15); 1183 cfg.seccomp_list_keep = seccomp_check_list(argv[i] + 15);
1191 if (!cfg.seccomp_list_keep)
1192 errExit("strdup");
1193 }
1194 else {
1195 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
1196 exit(1);
1197 }
1198 }
1199 else if (strncmp(argv[i], "--seccomp.e", 11) == 0 && strchr(argv[i], '=')) {
1200 if (checkcfg(CFG_SECCOMP)) {
1201 if (arg_seccomp && !cfg.seccomp_list_errno) {
1202 fprintf(stderr, "Error: seccomp already enabled\n");
1203 exit(1);
1204 }
1205 char *eq = strchr(argv[i], '=');
1206 char *errnoname = strndup(argv[i] + 10, eq - (argv[i] + 10));
1207 int nr = errno_find_name(errnoname);
1208 if (nr == -1) {
1209 fprintf(stderr, "Error: unknown errno %s\n", errnoname);
1210 free(errnoname);
1211 exit(1);
1212 }
1213
1214 if (!cfg.seccomp_list_errno)
1215 cfg.seccomp_list_errno = calloc(highest_errno+1, sizeof(cfg.seccomp_list_errno[0]));
1216
1217 if (cfg.seccomp_list_errno[nr]) {
1218 fprintf(stderr, "Error: errno %s already configured\n", errnoname);
1219 free(errnoname);
1220 exit(1);
1221 }
1222 arg_seccomp = 1;
1223 cfg.seccomp_list_errno[nr] = strdup(eq+1);
1224 if (!cfg.seccomp_list_errno[nr])
1225 errExit("strdup");
1226 free(errnoname);
1227 } 1184 }
1228 else { 1185 else {
1229 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); 1186 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
@@ -2606,13 +2563,6 @@ int main(int argc, char **argv) {
2606 waitpid(child, &status, 0); 2563 waitpid(child, &status, 0);
2607 2564
2608 // free globals 2565 // free globals
2609#ifdef HAVE_SECCOMP
2610 if (cfg.seccomp_list_errno) {
2611 for (i = 0; i < highest_errno; i++)
2612 free(cfg.seccomp_list_errno[i]);
2613 free(cfg.seccomp_list_errno);
2614 }
2615#endif
2616 if (cfg.profile) { 2566 if (cfg.profile) {
2617 ProfileEntry *prf = cfg.profile; 2567 ProfileEntry *prf = cfg.profile;
2618 while (prf != NULL) { 2568 while (prf != NULL) {
diff --git a/src/firejail/netfilter.c b/src/firejail/netfilter.c
index efef45d90..1df4b7a0f 100644
--- a/src/firejail/netfilter.c
+++ b/src/firejail/netfilter.c
@@ -143,8 +143,7 @@ void netfilter(const char *fname) {
143 dup2(fd,STDIN_FILENO); 143 dup2(fd,STDIN_FILENO);
144 144
145 // wipe out environment variables 145 // wipe out environment variables
146 environ = NULL; 146 clearenv();
147 assert(getenv("LD_PRELOAD") == NULL);
148 execl(iptables_restore, iptables_restore, NULL); 147 execl(iptables_restore, iptables_restore, NULL);
149 perror("execl"); 148 perror("execl");
150 _exit(1); 149 _exit(1);
@@ -258,8 +257,7 @@ void netfilter6(const char *fname) {
258 dup2(fd,STDIN_FILENO); 257 dup2(fd,STDIN_FILENO);
259 258
260 // wipe out environment variables 259 // wipe out environment variables
261 environ = NULL; 260 clearenv();
262 assert(getenv("LD_PRELOAD") == NULL);
263 execl(ip6tables_restore, ip6tables_restore, NULL); 261 execl(ip6tables_restore, ip6tables_restore, NULL);
264 perror("execl"); 262 perror("execl");
265 _exit(1); 263 _exit(1);
@@ -273,7 +271,7 @@ void netfilter6(const char *fname) {
273 if (child < 0) 271 if (child < 0)
274 errExit("fork"); 272 errExit("fork");
275 if (child == 0) { 273 if (child == 0) {
276 environ = NULL; 274 clearenv();
277 execl(ip6tables, ip6tables, "-vL", NULL); 275 execl(ip6tables, ip6tables, "-vL", NULL);
278 perror("execl"); 276 perror("execl");
279 _exit(1); 277 _exit(1);
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index f7d5e87e6..f3a7eb727 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -529,9 +529,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
529#ifdef HAVE_SECCOMP 529#ifdef HAVE_SECCOMP
530 if (checkcfg(CFG_SECCOMP)) { 530 if (checkcfg(CFG_SECCOMP)) {
531 arg_seccomp = 1; 531 arg_seccomp = 1;
532 cfg.seccomp_list = strdup(ptr + 8); 532 cfg.seccomp_list = seccomp_check_list(ptr + 8);
533 if (!cfg.seccomp_list)
534 errExit("strdup");
535 } 533 }
536 else 534 else
537 fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); 535 fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n");
@@ -545,9 +543,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
545#ifdef HAVE_SECCOMP 543#ifdef HAVE_SECCOMP
546 if (checkcfg(CFG_SECCOMP)) { 544 if (checkcfg(CFG_SECCOMP)) {
547 arg_seccomp = 1; 545 arg_seccomp = 1;
548 cfg.seccomp_list_drop = strdup(ptr + 13); 546 cfg.seccomp_list_drop = seccomp_check_list(ptr + 13);
549 if (!cfg.seccomp_list_drop)
550 errExit("strdup");
551 } 547 }
552 else 548 else
553 fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); 549 fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n");
@@ -560,9 +556,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
560#ifdef HAVE_SECCOMP 556#ifdef HAVE_SECCOMP
561 if (checkcfg(CFG_SECCOMP)) { 557 if (checkcfg(CFG_SECCOMP)) {
562 arg_seccomp = 1; 558 arg_seccomp = 1;
563 cfg.seccomp_list_keep= strdup(ptr + 13); 559 cfg.seccomp_list_keep= seccomp_check_list(ptr + 13);
564 if (!cfg.seccomp_list_keep)
565 errExit("strdup");
566 } 560 }
567 else 561 else
568 fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); 562 fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n");
@@ -576,7 +570,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
576 arg_caps_list = strdup(ptr + 10); 570 arg_caps_list = strdup(ptr + 10);
577 if (!arg_caps_list) 571 if (!arg_caps_list)
578 errExit("strdup"); 572 errExit("strdup");
579 // verify seccomp list and exit if problems 573 // verify caps list and exit if problems
580 if (caps_check_list(arg_caps_list, NULL)) 574 if (caps_check_list(arg_caps_list, NULL))
581 exit(1); 575 exit(1);
582 return 0; 576 return 0;
@@ -588,7 +582,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
588 arg_caps_list = strdup(ptr + 10); 582 arg_caps_list = strdup(ptr + 10);
589 if (!arg_caps_list) 583 if (!arg_caps_list)
590 errExit("strdup"); 584 errExit("strdup");
591 // verify seccomp list and exit if problems 585 // verify caps list and exit if problems
592 if (caps_check_list(arg_caps_list, NULL)) 586 if (caps_check_list(arg_caps_list, NULL))
593 exit(1); 587 exit(1);
594 return 0; 588 return 0;
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index e3c95283d..556cb1fca 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -847,8 +847,6 @@ assert(0);
847 if (arg_seccomp == 1) { 847 if (arg_seccomp == 1) {
848 if (cfg.seccomp_list_keep) 848 if (cfg.seccomp_list_keep)
849 seccomp_filter_keep(); 849 seccomp_filter_keep();
850 else if (cfg.seccomp_list_errno)
851 seccomp_filter_errno();
852 else 850 else
853 seccomp_filter_drop(enforce_seccomp); 851 seccomp_filter_drop(enforce_seccomp);
854 } 852 }
diff --git a/src/firejail/sbox.c b/src/firejail/sbox.c
index a5a067090..b16736dee 100644
--- a/src/firejail/sbox.c
+++ b/src/firejail/sbox.c
@@ -136,6 +136,21 @@ int sbox_run(unsigned filter, int num, ...) {
136 if (child < 0) 136 if (child < 0)
137 errExit("fork"); 137 errExit("fork");
138 if (child == 0) { 138 if (child == 0) {
139 // clean the new process
140 clearenv();
141 int max = 20; // getdtablesize() is overkill for a firejail process
142 for (i = 3; i < max; i++)
143 close(i); // close open files
144 int fd = open("/dev/null",O_RDWR, 0);
145 if (fd != -1) {
146 dup2 (fd, STDIN_FILENO);
147 if (fd > 2)
148 close (fd);
149 }
150 else // the user could run the sandbox without /dev/null
151 close(STDIN_FILENO);
152 umask(027);
153
139 // apply filters 154 // apply filters
140 if (filter & SBOX_CAPS_NONE) { 155 if (filter & SBOX_CAPS_NONE) {
141 caps_drop_all(); 156 caps_drop_all();
@@ -165,7 +180,7 @@ int sbox_run(unsigned filter, int num, ...) {
165 else if (filter & SBOX_USER) 180 else if (filter & SBOX_USER)
166 drop_privs(1); 181 drop_privs(1);
167 182
168 assert(getenv("LD_PRELOAD") == NULL); 183 clearenv();
169 if (arg[0]) // get rid of scan-build warning 184 if (arg[0]) // get rid of scan-build warning
170 execvp(arg[0], arg); 185 execvp(arg[0], arg);
171 else 186 else
diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c
index 74d29fc9d..20807f5b1 100644
--- a/src/firejail/seccomp.c
+++ b/src/firejail/seccomp.c
@@ -22,6 +22,34 @@
22#include "firejail.h" 22#include "firejail.h"
23#include "../include/seccomp.h" 23#include "../include/seccomp.h"
24 24
25char *seccomp_check_list(const char *str) {
26 assert(str);
27 if (strlen(str) == 0) {
28 fprintf(stderr, "Error: empty syscall lists are not allowed\n");
29 exit(1);
30 }
31
32 int len = strlen(str) + 1;
33 char *rv = malloc(len);
34 if (!rv)
35 errExit("malloc");
36 memset(rv, 0, len);
37
38 const char *ptr1 = str;
39 char *ptr2 = rv;
40 while (*ptr1 != '\0') {
41 if (isalnum(*ptr1) || *ptr1 == '_' || *ptr1 == ',' || *ptr1 == ':')
42 *ptr2++ = *ptr1++;
43 else {
44 fprintf(stderr, "Error: invalid syscall list\n");
45 exit(1);
46 }
47 }
48
49 return rv;
50}
51
52
25int seccomp_load(const char *fname) { 53int seccomp_load(const char *fname) {
26 assert(fname); 54 assert(fname);
27 55
@@ -136,10 +164,6 @@ int seccomp_filter_drop(int enforce_seccomp) {
136#endif 164#endif
137 if (arg_debug) 165 if (arg_debug)
138 printf("Build default+drop seccomp filter\n"); 166 printf("Build default+drop seccomp filter\n");
139 if (strlen(cfg.seccomp_list) == 0) {
140 fprintf(stderr, "Error: empty syscall lists are not allowed\n");
141 exit(1);
142 }
143 167
144 // build the seccomp filter as a regular user 168 // build the seccomp filter as a regular user
145 int rv; 169 int rv;
@@ -157,10 +181,6 @@ int seccomp_filter_drop(int enforce_seccomp) {
157 else if (cfg.seccomp_list == NULL && cfg.seccomp_list_drop) { 181 else if (cfg.seccomp_list == NULL && cfg.seccomp_list_drop) {
158 if (arg_debug) 182 if (arg_debug)
159 printf("Build drop seccomp filter\n"); 183 printf("Build drop seccomp filter\n");
160 if (strlen(cfg.seccomp_list_drop) == 0) {
161 fprintf(stderr, "Error: empty syscall lists are not allowed\n");
162 exit(1);
163 }
164 184
165 // build the seccomp filter as a regular user 185 // build the seccomp filter as a regular user
166 int rv; 186 int rv;
@@ -199,10 +219,6 @@ int seccomp_filter_drop(int enforce_seccomp) {
199int seccomp_filter_keep(void) { 219int seccomp_filter_keep(void) {
200 if (arg_debug) 220 if (arg_debug)
201 printf("Build drop seccomp filter\n"); 221 printf("Build drop seccomp filter\n");
202 if (strlen(cfg.seccomp_list_keep) == 0) {
203 fprintf(stderr, "Error: empty syscall lists are not allowed\n");
204 exit(1);
205 }
206 222
207 // build the seccomp filter as a regular user 223 // build the seccomp filter as a regular user
208 int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 4, 224 int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 4,
@@ -216,38 +232,6 @@ int seccomp_filter_keep(void) {
216 return seccomp_load(RUN_SECCOMP_CFG); 232 return seccomp_load(RUN_SECCOMP_CFG);
217} 233}
218 234
219// errno filter for seccomp option
220int seccomp_filter_errno(void) {
221#if 0 //todo: disabled temporarely, bring it back
222 int i;
223 int higest_errno = errno_highest_nr();
224 filter_init();
225
226 // apply errno list
227
228 for (i = 0; i < higest_errno; i++) {
229 if (cfg.seccomp_list_errno[i]) {
230 if (syscall_check_list(cfg.seccomp_list_errno[i], filter_add_errno, i)) {
231 fprintf(stderr, "Error: cannot load seccomp filter\n");
232 exit(1);
233 }
234 }
235 }
236
237 filter_end_blacklist();
238 if (arg_debug)
239 filter_debug();
240
241 // save seccomp filter in /run/firejail/mnt/seccomp
242 // in order to use it in --join operations
243 write_seccomp_file();
244 return seccomp_load(RUN_SECCOMP_CFG);
245#else
246printf("*** --seccomp.<errno> is temporarily disabled, it will be brought back soon ***\n");
247 return 0;
248#endif
249}
250
251void seccomp_print_filter_name(const char *name) { 235void seccomp_print_filter_name(const char *name) {
252 EUID_ASSERT(); 236 EUID_ASSERT();
253 if (!name || strlen(name) == 0) { 237 if (!name || strlen(name) == 0) {
diff --git a/src/firejail/usage.c b/src/firejail/usage.c
index 7db91b5a9..c8bed06e3 100644
--- a/src/firejail/usage.c
+++ b/src/firejail/usage.c
@@ -23,381 +23,190 @@ void usage(void) {
23 printf("firejail - version %s\n\n", VERSION); 23 printf("firejail - version %s\n\n", VERSION);
24 printf("Firejail is a SUID sandbox program that reduces the risk of security breaches by\n"); 24 printf("Firejail is a SUID sandbox program that reduces the risk of security breaches by\n");
25 printf("restricting the running environment of untrusted applications using Linux\n"); 25 printf("restricting the running environment of untrusted applications using Linux\n");
26 printf("namespaces. It includes a sandbox profile for Mozilla Firefox.\n\n"); 26 printf("namespaces.\n");
27 printf("\n"); 27 printf("\n");
28 printf("Usage: firejail [options] [program and arguments]\n\n"); 28 printf("Usage: firejail [options] [program and arguments]\n");
29 printf("\n"); 29 printf("\n");
30 printf("Without any options, the sandbox consists of a filesystem chroot build from the\n"); 30 printf("Options:\n");
31 printf("current system directories mounted read-only, and new PID and IPC\n"); 31 printf(" -- - signal the end of options and disables further option processing.\n");
32 printf("namespaces. If no program is specified as an argument, /bin/bash is started by\n"); 32 printf(" --allow-debuggers - allow tools such as strace and gdb inside the sandbox.\n");
33 printf("default in the sandbox.\n\n"); 33 printf(" --allusers - all user home directories are visible inside the sandbox.\n");
34 printf("\n"); 34 printf(" --apparmor - enable AppArmor confinement.\n");
35 printf("Options:\n\n"); 35 printf(" --appimage - sandbox an AppImage application.\n");
36 printf(" -- - signal the end of options and disables further option processing.\n\n"); 36 printf(" --audit[=test-program] - audit the sandbox.\n");
37 printf(" --allow-debuggers - allow tools such as strace and gdb inside the sandbox.\n\n");
38 printf(" --allusers - all user home directories are visible inside the sandbox.\n\n");
39 printf(" --apparmor - enable AppArmor confinement\n\n");
40 printf(" --appimage - sandbox an AppImage application\n\n");
41 printf(" --audit - audit the sandbox, see Audit section for more details\n\n");
42 printf(" --audit=test-program - audit the sandbox, see Audit section for more details\n\n");
43#ifdef HAVE_NETWORK 37#ifdef HAVE_NETWORK
44 printf(" --bandwidth=name|pid - set bandwidth limits for the sandbox identified\n"); 38 printf(" --bandwidth=name|pid - set bandwidth limits\n");
45 printf("\tby name or PID, see Traffic Shaping section fo more details.\n\n");
46#endif 39#endif
47#ifdef HAVE_BIND 40#ifdef HAVE_BIND
48 printf(" --bind=dirname1,dirname2 - mount-bind dirname1 on top of dirname2.\n\n"); 41 printf(" --bind=dirname1,dirname2 - mount-bind dirname1 on top of dirname2.\n");
49 printf(" --bind=filename1,filename2 - mount-bind filename1 on top of filename2.\n\n"); 42 printf(" --bind=filename1,filename2 - mount-bind filename1 on top of filename2.\n");
50#endif 43#endif
51 printf(" --blacklist=dirname_or_filename - blacklist directory or file.\n\n"); 44 printf(" --blacklist=filename - blacklist directory or file.\n");
52 printf(" -c - execute command and exit.\n\n"); 45 printf(" -c - execute command and exit.\n");
53 printf(" --caps - enable default Linux capabilities filter.\n\n"); 46 printf(" --caps - enable default Linux capabilities filter.\n");
54 printf(" --caps.drop=all - drop all capabilities.\n\n"); 47 printf(" --caps.drop=all - drop all capabilities.\n");
55 printf(" --caps.drop=capability,capability - blacklist capabilities filter.\n\n"); 48 printf(" --caps.drop=capability,capability - blacklist capabilities filter.\n");
56 printf(" --caps.keep=capability,capability - whitelist capabilities filter.\n\n"); 49 printf(" --caps.keep=capability,capability - whitelist capabilities filter.\n");
57 printf(" --caps.print=name|pid - print the caps filter for the sandbox identified\n"); 50 printf(" --caps.print=name|pid - print the caps filter.\n");
58 printf("\tby name or PID.\n\n");
59 printf(" --cgroup=tasks-file - place the sandbox in the specified control group.\n"); 51 printf(" --cgroup=tasks-file - place the sandbox in the specified control group.\n");
60 printf("\ttasks-file is the full path of cgroup tasks file.\n\n");
61#ifdef HAVE_CHROOT 52#ifdef HAVE_CHROOT
62 printf(" --chroot=dirname - chroot into directory.\n\n"); 53 printf(" --chroot=dirname - chroot into directory.\n");
63#endif 54#endif
64 printf(" --cpu=cpu-number,cpu-number - set cpu affinity.\n\n"); 55 printf(" --cpu=cpu-number,cpu-number - set cpu affinity.\n");
65 printf(" --cpu.print=name|pid - print the cup in use by the sandbox identified\n"); 56 printf(" --cpu.print=name|pid - print the cpus in use.\n");
66 printf("\tby name or PID.\n\n"); 57 printf(" --csh - use /bin/csh as default shell.\n");
67 printf(" --csh - use /bin/csh as default shell.\n\n"); 58 printf(" --debug - print sandbox debug messages.\n");
68 59 printf(" --debug-blacklists - debug blacklisting.\n");
69 printf(" --debug - print sandbox debug messages.\n\n"); 60 printf(" --debug-caps - print all recognized capabilities.\n");
70 printf(" --debug-blacklists - debug blacklisting.\n\n"); 61 printf(" --debug-check-filename - debug filename checking.\n");
71 printf(" --debug-caps - print all recognized capabilities in the current Firejail\n"); 62 printf(" --debug-errnos - print all recognized error numbers.\n");
72 printf("\tsoftware build.\n\n"); 63 printf(" --debug-protocols - print all recognized protocols.\n");
73 printf(" --debug-check-filename - debug filename checking.\n\n"); 64 printf(" --debug-syscalls - print all recognized system calls.\n");
74 printf(" --debug-errnos - print all recognized error numbers in the current Firejail\n");
75 printf("\tsoftware build.\n\n");
76 printf(" --debug-protocols - print all recognized protocols in the current Firejail\n");
77 printf("\tsoftware build.\n\n");
78 printf(" --debug-syscalls - print all recognized system calls in the current Firejail\n");
79 printf("\tsoftware build.\n\n");
80#ifdef HAVE_WHITELIST 65#ifdef HAVE_WHITELIST
81 printf(" --debug-whitelists - debug whitelisting.\n\n"); 66 printf(" --debug-whitelists - debug whitelisting.\n");
82#endif 67#endif
83
84
85#ifdef HAVE_NETWORK 68#ifdef HAVE_NETWORK
86 printf(" --defaultgw=address - use this address as default gateway in the new network\n"); 69 printf(" --defaultgw=address - configure default gateway.\n");
87 printf("\tnamespace.\n\n");
88#endif 70#endif
89 printf(" --dns=address - set a DNS server for the sandbox. Up to three DNS servers\n"); 71 printf(" --dns=address - set DNS server.\n");
90 printf("\tcan be defined.\n\n"); 72 printf(" --dns.print=name|pid - print DNS configuration.\n");
91 printf(" --dns.print=name|pid - print DNS configuration for the sandbox identified\n"); 73
92 printf("\tby name or PID.\n\n"); 74 printf(" --env=name=value - set environment variable.\n");
93 75 printf(" --fs.print=name|pid - print the filesystem log.\n");
94 printf(" --env=name=value - set environment variable in the new sandbox.\n\n"); 76 printf(" --get=name|pid filename - get a file from sandbox container.\n");
95 printf(" --fs.print=name|pid - print the filesystem log for the sandbox identified\n"); 77 printf(" --help, -? - this help screen.\n");
96 printf("\tby name or PID.\n\n"); 78 printf(" --hostname=name - set sandbox hostname.\n");
97 printf(" --get=name|pid filename - get a file from sandbox container.\n\n"); 79 printf(" --ignore=command - ignore command in profile files.\n");
98 printf(" --help, -? - this help screen.\n\n");
99 printf(" --hostname=name - set sandbox hostname.\n\n");
100 printf(" --ignore=command - ignore command in profile files.\n\n");
101#ifdef HAVE_NETWORK 80#ifdef HAVE_NETWORK
102 printf(" --interface=name - move interface in a new network namespace. Up to four\n"); 81 printf(" --interface=name - move interface in sandbox.\n");
103 printf("\t--interface options can be specified.\n\n"); 82 printf(" --ip=address - set interface IP address.\n");
104 printf(" --ip=address - set interface IP address.\n\n"); 83 printf(" --ip=none - no IP address and no default gateway are configured.\n");
105 printf(" --ip=none - no IP address and no default gateway address are configured\n"); 84 printf(" --ip6=address - set interface IPv6 address.\n");
106 printf("\tin the new network namespace. Use this option in case you intend to\n"); 85 printf(" --iprange=address,address - configure an IP address in this range.\n");
107 printf("\tstart an external DHCP client in the sandbox.\n\n");
108 printf(" --ip6=address - set interface IPv6 address.\n\n");
109 printf(" --iprange=address,address - configure an IP address in this range.\n\n");
110#endif 86#endif
111 printf(" --ipc-namespace - enable a new IPC namespace if the sandbox was started as\n"); 87 printf(" --ipc-namespace - enable a new IPC namespace.\n");
112 printf("\tregular user. IPC namespace is enabled by default only if the sandbox\n"); 88 printf(" --join=name|pid - join the sandbox.\n");
113 printf("\tis started as root.\n\n"); 89 printf(" --join-filesystem=name|pid - join the mount namespace.\n");
114 printf(" --join=name|pid - join the sandbox identified by name or PID.\n\n");
115 printf(" --join-filesystem=name|pid - join the mount namespace of the sandbox\n");
116 printf("\tidentified by name or PID.\n\n");
117#ifdef HAVE_NETWORK 90#ifdef HAVE_NETWORK
118 printf(" --join-network=name|pid - join the network namespace of the sandbox\n"); 91 printf(" --join-network=name|pid - join the network namespace.\n");
119 printf("\tidentified by name or PID.\n\n");
120#endif 92#endif
121 printf(" --list - list all sandboxes.\n\n"); 93 printf(" --list - list all sandboxes.\n");
122 printf(" --ls=name|pid dir_or_filename - list files in sandbox container.\n\n"); 94 printf(" --ls=name|pid dir_or_filename - list files in sandbox container.\n");
123#ifdef HAVE_NETWORK 95#ifdef HAVE_NETWORK
124 printf(" --mac=xx:xx:xx:xx:xx:xx - set interface MAC address.\n\n"); 96 printf(" --mac=xx:xx:xx:xx:xx:xx - set interface MAC address.\n");
125 printf(" --mtu=number - set interface MTU.\n\n"); 97 printf(" --mtu=number - set interface MTU.\n");
126#endif 98#endif
127 printf(" --name=name - set sandbox name.\n\n"); 99 printf(" --name=name - set sandbox name.\n");
128#ifdef HAVE_NETWORK 100#ifdef HAVE_NETWORK
129 printf(" --net=bridgename - enable network namespaces and connect to this bridge\n"); 101 printf(" --net=bridgename - enable network namespaces and connect to this bridge.\n");
130 printf("\tdevice. Up to four --net devices can be defined.\n\n");
131
132 printf(" --net=ethernet_interface - enable network namespaces and connect to this\n"); 102 printf(" --net=ethernet_interface - enable network namespaces and connect to this\n");
133 printf("\tEthernet interface using the standard Linux macvlan driver. Up to four\n"); 103 printf("\tEthernet interface.\n");
134 printf("\t--net devices can be defined.\n\n"); 104 printf(" --net=none - enable a new, unconnected network namespace.\n");
135 105 printf(" --netfilter[=filename] - enable the default client network filter.\n");
136 printf(" --net=none - enable a new, unconnected network namespace.\n\n"); 106 printf(" --netfilter6=filename - enable the IPv6 network filter.\n");
137 107 printf(" --netstats - monitor network statistics.\n");
138 printf(" --netfilter - enable the default client network filter in the new\n");
139 printf("\tnetwork namespace.\n\n");
140 printf(" --netfilter=filename - enable the network filter specified by\n");
141 printf("\tfilename in the new network namespace. The filter file format\n");
142 printf("\tis the format of iptables-save and iptable-restore commands.\n\n");
143 printf(" --netfilter6=filename - enable the IPv6 network filter specified by\n");
144 printf("\tfilename in the new network namespace. The filter file format\n");
145 printf("\tis the format of ip6tables-save and ip6table-restore commands.\n\n");
146
147 printf(" --netstats - monitor network statistics for sandboxes creating a new\n");
148 printf("\tnetwork namespace.\n\n");
149#endif 108#endif
150 printf(" --nice=value - set nice value.\n\n"); 109 printf(" --nice=value - set nice value.\n");
151 printf(" --no3d - disable 3D hardware acceleration.\n\n"); 110 printf(" --no3d - disable 3D hardware acceleration.\n");
152 printf(" --noblacklist=dirname_or_filename - disable blacklist for directory or\n"); 111 printf(" --noblacklist=filename - disable blacklist for file or directory .\n");
153 printf("\tfile.\n\n"); 112 printf(" --noexec=filename - remount the file or directory noexec nosuid and nodev.\n");
154 printf(" --noexec=dirname_of_filenam - remount the file or directory noexec\n"); 113 printf(" --nogroups - disable supplementary groups.\n");
155 printf("\tnosuid and nodev\n\n"); 114 printf(" --noprofile - do not use a security profile.\n");
156 printf(" --nogroups - disable supplementary groups. Without this option,\n");
157 printf("\tsupplementary groups are enabled for the user starting the sandbox.\n");
158 printf("\tFor root, groups are always disabled.\n\n");
159
160 printf(" --noprofile - do not use a profile. Profile priority is use the one\n");
161 printf("\tspecified on the command line, next try to find one that\n");
162 printf("\tmatches the command name, and lastly use %s.profile\n", DEFAULT_USER_PROFILE);
163 printf("\tif running as regular user or %s.profile if running as\n", DEFAULT_ROOT_PROFILE);
164 printf("\troot.\n\n");
165#ifdef HAVE_USERNS 115#ifdef HAVE_USERNS
166 printf(" --noroot - install a user namespace with a single user - the current\n"); 116 printf(" --noroot - install a user namespace with only the current user.\n");
167 printf("\tuser. root user does not exist in the new namespace. This option\n");
168 printf("\tis not supported for --chroot and --overlay configurations.\n\n");
169#endif 117#endif
170 printf(" --nonewprivs - sets the NO_NEW_PRIVS prctl - the child processes\n"); 118 printf(" --nonewprivs - sets the NO_NEW_PRIVS prctl.\n");
171 printf("\tcannot gain privileges using execve(2); in particular, this prevents\n"); 119 printf(" --output=logfile - stdout logging and log rotation.\n");
172 printf("\tgaining privileges by calling a suid binary\n\n");
173 printf(" --nosound - disable sound system.\n\n");
174
175 printf(" --output=logfile - stdout logging and log rotation. Copy stdout and stderr\n");
176 printf("\tto logfile, and keep the size of the file under 500KB using log\n");
177 printf("\trotation. Five files with prefixes .1 to .5 are used in\n");
178 printf("\trotation.\n\n");
179
180 printf(" --overlay - mount a filesystem overlay on top of the current filesystem.\n"); 120 printf(" --overlay - mount a filesystem overlay on top of the current filesystem.\n");
181 printf("\tThe upper filesystem layer is persistent, and stored in\n");
182 printf("\t$HOME/.firejail/<PID> directory. (OverlayFS support is required in\n");
183 printf("\tLinux kernel for this option to work). \n\n");
184
185 printf(" --overlay-named=name - mount a filesystem overlay on top of the current\n"); 121 printf(" --overlay-named=name - mount a filesystem overlay on top of the current\n");
186 printf("\tfilesystem. The upper filesystem layer is persistent, and stored in\n"); 122 printf("\tfilesystem, and store it in name directory.\n");
187 printf("\t$HOME/.firejail/<NAME> directory. (OverlayFS support is required in\n"); 123 printf(" --overlay-tmpfs - mount a temporary filesystem overlay on top of the current\n");
188 printf("\tLinux kernel for this option to work). \n\n"); 124 printf("\tfilesystem.\n");
189 125 printf(" --overlay-clean - clean all overlays stored in $HOME/.firejail directory.\n");
190 printf(" --overlay-tmpfs - mount a filesystem overlay on top of the current\n"); 126 printf(" --private - temporary home directory.\n");
191 printf("\tfilesystem. The upper layer is stored in a tmpfs filesystem,\n"); 127 printf(" --private=directory - use directory as user home.\n");
192 printf("\tand it is discarded when the sandbox is closed. (OverlayFS\n");
193 printf("\tsupport is required in Linux kernel for this option to work).\n\n");
194
195 printf(" --overlay-clean - clean all overlays stored in $HOME/.firejail directory.\n\n");
196
197 printf(" --private - mount new /root and /home/user directories in temporary\n");
198 printf("\tfilesystems. All modifications are discarded when the sandbox is\n");
199 printf("\tclosed.\n\n");
200 printf(" --private=directory - use directory as user home.\n\n");
201 printf(" --private-home=file,directory - build a new user home in a temporary\n"); 128 printf(" --private-home=file,directory - build a new user home in a temporary\n");
202 printf("\t\tfilesystem, and copy the files and directories in the list in\n"); 129 printf("\tfilesystem, and copy the files and directories in the list in\n");
203 printf("\t\tthe new home. All modifications are discarded when the sandbox\n"); 130 printf("\tthe new home.\n");
204 printf("\t\tis closed.\n\n");
205
206 printf(" --private-bin=file,file - build a new /bin in a temporary filesystem,\n"); 131 printf(" --private-bin=file,file - build a new /bin in a temporary filesystem,\n");
207 printf("\tand copy the programs in the list.\n\n"); 132 printf("\tand copy the programs in the list.\n");
208
209 printf(" --private-dev - create a new /dev directory. Only dri, null, full, zero,\n"); 133 printf(" --private-dev - create a new /dev directory. Only dri, null, full, zero,\n");
210 printf("\ttty, pst, ptms, random, snd, urandom, log and shm devices are available.\n\n"); 134 printf("\ttty, pst, ptms, random, snd, urandom, log and shm devices are available.\n");
211
212 printf(" --private-etc=file,directory - build a new /etc in a temporary\n"); 135 printf(" --private-etc=file,directory - build a new /etc in a temporary\n");
213 printf("\tfilesystem, and copy the files and directories in the list.\n"); 136 printf("\tfilesystem, and copy the files and directories in the list.\n");
214 printf("\tAll modifications are discarded when the sandbox is closed.\n\n"); 137 printf(" --private-tmp - mount a tmpfs on top of /tmp directory.\n");
215 138 printf(" --profile=filename - use a custom profile.\n");
216 printf(" --private-tmp - mount a tmpfs on top of /tmp directory\n\n"); 139 printf(" --profile-path=directory - use this directory to look for profile files.\n");
217
218 printf(" --profile=filename - use a custom profile.\n\n");
219 printf(" --profile-path=directory - use this directory to look for profile files.\n\n");
220
221 printf(" --protocol=protocol,protocol,protocol - enable protocol filter.\n"); 140 printf(" --protocol=protocol,protocol,protocol - enable protocol filter.\n");
222 printf("\tProtocol values: unix, inet, inet6, netlink, packet.\n\n"); 141 printf(" --protocol.print=name|pid - print the protocol filter.\n");
223 printf(" --protocol.print=name|pid - print the protocol filter for the sandbox\n"); 142 printf(" --put=name|pid src-filename dest-filename - put a file in sandbox container.\n");
224 printf("\tidentified by name or PID.\n\n"); 143 printf(" --quiet - turn off Firejail's output.\n");
225 144 printf(" --read-only=filename - set directory or file read-only..\n");
226 printf(" --put=name|pid src-filename dest-filename - put a file in sandbox container.\n\n"); 145 printf(" --read-write=filename - set directory or file read-write..\n");
227
228 printf(" --quiet - turn off Firejail's output.\n\n");
229 printf(" --read-only=dirname_or_filename - set directory or file read-only..\n\n");
230 printf(" --read-write=dirname_or_filename - set directory or file read-write..\n\n");
231 printf(" --rlimit-fsize=number - set the maximum file size that can be created\n"); 146 printf(" --rlimit-fsize=number - set the maximum file size that can be created\n");
232 printf("\tby a process.\n\n"); 147 printf("\tby a process.\n");
233 printf(" --rlimit-nofile=number - set the maximum number of files that can be\n"); 148 printf(" --rlimit-nofile=number - set the maximum number of files that can be\n");
234 printf("\topened by a process.\n\n"); 149 printf("\topened by a process.\n");
235 printf(" --rlimit-nproc=number - set the maximum number of processes that can be\n"); 150 printf(" --rlimit-nproc=number - set the maximum number of processes that can be\n");
236 printf("\tcreated for the real user ID of the calling process.\n\n"); 151 printf("\tcreated for the real user ID of the calling process.\n");
237 printf(" --rlimit-sigpending=number - set the maximum number of pending signals\n"); 152 printf(" --rlimit-sigpending=number - set the maximum number of pending signals\n");
238 printf("\tfor a process.\n\n"); 153 printf("\tfor a process.\n");
239 printf(" --rmenv=name - remove environment variable in the new sandbox.\n\n"); 154 printf(" --rmenv=name - remove environment variable in the new sandbox.\n");
240#ifdef HAVE_NETWORK 155#ifdef HAVE_NETWORK
241 printf(" --scan - ARP-scan all the networks from inside a network namespace.\n"); 156 printf(" --scan - ARP-scan all the networks from inside a network namespace.\n");
242 printf("\tThis makes it possible to detect macvlan kernel device drivers\n");
243 printf("\trunning on the current host.\n\n");
244#endif 157#endif
245#ifdef HAVE_SECCOMP 158#ifdef HAVE_SECCOMP
246 printf(" --seccomp - enable seccomp filter and apply the default blacklist.\n\n"); 159 printf(" --seccomp - enable seccomp filter and apply the default blacklist.\n");
247
248 printf(" --seccomp=syscall,syscall,syscall - enable seccomp filter, blacklist the\n"); 160 printf(" --seccomp=syscall,syscall,syscall - enable seccomp filter, blacklist the\n");
249 printf("\tdefault syscall list and the syscalls specified by the command.\n\n"); 161 printf("\tdefault syscall list and the syscalls specified by the command.\n");
250
251 printf(" --seccomp.drop=syscall,syscall,syscall - enable seccomp filter, and\n"); 162 printf(" --seccomp.drop=syscall,syscall,syscall - enable seccomp filter, and\n");
252 printf("\tblacklist the syscalls specified by the command.\n\n"); 163 printf("\tblacklist the syscalls specified by the command.\n");
253
254 printf(" --seccomp.keep=syscall,syscall,syscall - enable seccomp filter, and\n"); 164 printf(" --seccomp.keep=syscall,syscall,syscall - enable seccomp filter, and\n");
255 printf("\twhitelist the syscalls specified by the command.\n\n"); 165 printf("\twhitelist the syscalls specified by the command.\n");
256
257 printf(" --seccomp.<errno>=syscall,syscall,syscall - enable seccomp filter, and\n"); 166 printf(" --seccomp.<errno>=syscall,syscall,syscall - enable seccomp filter, and\n");
258 printf("\treturn errno for the syscalls specified by the command.\n\n"); 167 printf("\treturn errno for the syscalls specified by the command.\n");
259
260 printf(" --seccomp.print=name|pid - print the seccomp filter for the sandbox\n"); 168 printf(" --seccomp.print=name|pid - print the seccomp filter for the sandbox\n");
261 printf("\tidentified by name or PID.\n\n"); 169 printf("\tidentified by name or PID.\n");
262#endif 170#endif
263 171 printf(" --shell=none - run the program directly without a user shell.\n");
264 printf(" --shell=none - run the program directly without a user shell.\n\n"); 172 printf(" --shell=program - set default user shell.\n");
265 printf(" --shell=program - set default user shell.\n\n"); 173 printf(" --shutdown=name|pid - shutdown the sandbox identified by name or PID.\n");
266 printf(" --shutdown=name|pid - shutdown the sandbox identified by name or PID.\n\n");
267 printf(" --tmpfs=dirname - mount a tmpfs filesystem on directory dirname.\n"); 174 printf(" --tmpfs=dirname - mount a tmpfs filesystem on directory dirname.\n");
268 printf("\tThis option is available only when running the sandbox as root.\n\n"); 175 printf(" --top - monitor the most CPU-intensive sandboxes.\n");
269 printf(" --top - monitor the most CPU-intensive sandboxes.\n\n"); 176 printf(" --trace - trace open, access and connect system calls.\n");
270 printf(" --trace - trace open, access and connect system calls.\n\n");
271 printf(" --tracelog - add a syslog message for every access to files or\n"); 177 printf(" --tracelog - add a syslog message for every access to files or\n");
272 printf("\tdirectoires blacklisted by the security profile.\n\n"); 178 printf("\tdirectoires blacklisted by the security profile.\n");
273 printf(" --tree - print a tree of all sandboxed processes.\n\n"); 179 printf(" --tree - print a tree of all sandboxed processes.\n");
274 printf(" --version - print program version and exit.\n\n"); 180 printf(" --version - print program version and exit.\n");
275#ifdef HAVE_NETWORK 181#ifdef HAVE_NETWORK
276 printf(" --veth-name=name - use this name for the interface connected to the bridge\n"); 182 printf(" --veth-name=name - use this name for the interface connected to the bridge.\n");
277 printf("\tfor --net=bridgename commands, instead of the default one.\n\n");
278#endif 183#endif
279#ifdef HAVE_WHITELIST 184#ifdef HAVE_WHITELIST
280 printf(" --whitelist=dirname_or_filename - whitelist directory or file.\n\n"); 185 printf(" --whitelist=filename - whitelist directory or file.\n");
281#endif 186#endif
282 printf(" --writable-etc - /etc directory is mounted read-write.\n\n"); 187 printf(" --writable-etc - /etc directory is mounted read-write.\n");
283 printf(" --writable-var - /var directory is mounted read-write.\n\n"); 188 printf(" --writable-var - /var directory is mounted read-write.\n");
284
285 printf(" --x11 - enable X11 sandboxing. The software checks first if Xpra is\n"); 189 printf(" --x11 - enable X11 sandboxing. The software checks first if Xpra is\n");
286 printf("\tinstalled, then it checks if Xephyr is installed. If all fails, it will\n"); 190 printf("\tinstalled, then it checks if Xephyr is installed. If all fails, it will\n");
287 printf("\tattempt to use X11 security extension.\n\n"); 191 printf("\tattempt to use X11 security extension.\n");
288 printf(" --x11=none - disable access to X11 sockets.\n\n"); 192 printf(" --x11=none - disable access to X11 sockets.\n");
289 printf(" --x11=xephyr - enable Xephyr X11 server. The window size is 800x600.\n\n"); 193 printf(" --x11=xephyr - enable Xephyr X11 server. The window size is 800x600.\n");
290 printf(" --x11=xorg - enable X11 security extension.\n\n"); 194 printf(" --x11=xorg - enable X11 security extension.\n");
291 printf(" --x11=xpra - enable Xpra X11 server.\n\n"); 195 printf(" --x11=xpra - enable Xpra X11 server.\n");
292 printf(" --zsh - use /usr/bin/zsh as default shell.\n\n"); 196 printf(" --zsh - use /usr/bin/zsh as default shell.\n");
293 printf("\n");
294 printf("\n");
295
296
297#ifdef HAVE_NETWORK
298 printf("Traffic Shaping\n\n");
299
300 printf("Network bandwidth is an expensive resource shared among all sandboxes\n");
301 printf("running on a system. Traffic shaping allows the user to increase network\n");
302 printf("performance by controlling the amount of data that flows into and out of the\n");
303 printf("sandboxes. Firejail implements a simple rate-limiting shaper based on Linux\n");
304 printf("command tc. The shaper works at sandbox level, and can be used only for\n");
305 printf("sandboxes configured with new network namespaces.\n\n");
306
307 printf("Set rate-limits:\n");
308 printf(" firejail --bandwidth={name|pid} set network-name down-speed up-speed\n\n");
309 printf("Clear rate-limits:\n");
310 printf(" firejail --bandwidth={name|pid} clear network-name\n\n");
311 printf("Status:\n");
312 printf(" firejail --bandwidth={name|pid} status\n\n");
313 printf("where:\n");
314 printf(" name - sandbox name\n");
315 printf(" pid - sandbox pid\n");
316 printf(" network-name - network name as used by --net option\n");
317 printf(" down-speed - download speed in KB/s (decimal kilobyte per second)\n");
318 printf(" up-speed - upload speed in KB/s (decimal kilobyte per second)\n");
319 printf("\n");
320 printf("Example:\n");
321 printf(" $ firejail --name=mybrowser --net=eth0 firefox &\n");
322 printf(" $ firejail --bandwidth=mybrowser set eth0 80 20\n");
323 printf(" $ firejail --bandwidth=mybrowser status\n");
324 printf(" $ firejail --bandwidth=mybrowser clear eth0\n");
325 printf("\n");
326 printf("\n");
327#endif
328
329 printf("Audit\n\n");
330 printf("Audit feature allows the user to point out gaps in security profiles. The\n");
331 printf("implementation replaces the program to be sandboxed with a test program. By\n");
332 printf("default, we use faudit program distributed with Firejail. A custom test program\n");
333 printf("can also be supplied by the user. Examples:\n\n");
334 printf("Running the default audit program:\n");
335 printf(" $ firejail --audit transmission-gtk\n\n");
336 printf("Running a custom audit program:\n");
337 printf(" $ firejail --audit=~/sandbox-test transmission-gtk\n\n");
338 printf("In the examples above, the sandbox configures transmission-gtk profile and\n");
339 printf("starts the test program. The real program, transmission-gtk, will not be\n");
340 printf("started.\n\n\n");
341
342 printf("Monitoring\n\n");
343
344 printf("Option --list prints a list of all sandboxes. The format for each entry is as\n");
345 printf("follows:\n\n");
346 printf(" PID:USER:Command\n\n");
347
348 printf("Option --tree prints the tree of processes running in the sandbox. The format\n");
349 printf("for each process entry is as follows:\n\n");
350 printf(" PID:USER:Command\n\n");
351
352 printf("Option --top is similar to the UNIX top command, however it applies only to\n");
353 printf("sandboxes. Listed below are the available fields (columns) in alphabetical\n");
354 printf("order:\n\n");
355 printf(" Command - command used to start the sandbox.\n");
356 printf(" CPU%% - CPU usage, the sandbox share of the elapsed CPU time since the\n");
357 printf("\tlast screen update\n");
358 printf(" PID - Unique process ID for the task controlling the sandbox.\n");
359 printf(" Prcs - number of processes running in sandbox, including the controlling\n");
360 printf("\tprocess.\n");
361 printf(" RES - Resident Memory Size (KiB), sandbox non-swapped physical memory.\n");
362 printf("\tIt is a sum of the RES values for all processes running in the\n");
363 printf("\tsandbox.\n");
364 printf(" SHR - Shared Memory Size (KiB), it reflects memory shared with other\n");
365 printf("\tprocesses. It is a sum of the SHR values for all processes running\n");
366 printf("\tin the sandbox, including the controlling process.\n");
367 printf(" Uptime - sandbox running time in hours:minutes:seconds format.\n");
368 printf(" User - The owner of the sandbox.\n");
369 printf("\n");
370 printf("\n");
371 printf("Profile files\n\n");
372 printf("Several command line configuration options can be passed to the program using\n");
373 printf("profile files. Default Firejail profile files are stored in /etc/firejail\n");
374 printf("directory, user profile files are stored in ~/.config/firejail directory. See\n");
375 printf("man 5 firejail-profile for more information.\n\n");
376 printf("\n");
377 printf("Restricted shell\n\n");
378 printf("To configure a restricted shell, replace /bin/bash with /usr/bin/firejail in\n");
379 printf("/etc/passwd file for each user that needs to be restricted.\n");
380 printf("Alternatively, you can specify /usr/bin/firejail in adduser command:\n\n");
381 printf(" adduser --shell /usr/bin/firejail username\n\n");
382 printf("Arguments to be passed to firejail executable upon login are declared in\n");
383 printf("/etc/firejail/login.users file.\n\n");
384 printf("\n"); 197 printf("\n");
385 printf("Examples:\n\n"); 198 printf("Examples:\n");
386 printf(" $ firejail\n");
387 printf("\tstart a regular /bin/bash session in sandbox\n");
388 printf(" $ firejail firefox\n"); 199 printf(" $ firejail firefox\n");
389 printf("\tstart Mozilla Firefox\n"); 200 printf("\tstart Mozilla Firefox\n");
390 printf(" $ firejail --debug firefox\n"); 201 printf(" $ firejail --debug firefox\n");
391 printf("\tdebug Firefox sandbox\n"); 202 printf("\tdebug Firefox sandbox\n");
392 printf(" $ firejail --private firefox\n"); 203 printf(" $ firejail --private --sna=8.8.8.8 firefox\n");
393 printf("\tstart Firefox with a new, empty home directory\n"); 204 printf("\tstart Firefox with a new, empty home directory, and a well-known DNS\n");
394 printf(" $ firejail --net=br0 ip=10.10.20.10\n"); 205 printf("\tserver setting.\n");
395 printf("\tstart a /bin/bash session in a new network namespace; the session is\n"); 206 printf(" $ firejail --net=eth0 firefox\n");
396 printf("\tconnected to the main network using br0 bridge device, an IP address\n"); 207 printf("\tstart Firefox in a new network namespace\n");
397 printf("\tof 10.10.20.10 is assigned to the sandbox\n"); 208 printf(" $ firejail --x11=xorg firefox\n");
398 printf(" $ firejail --net=br0 --net=br1 --net=br2\n"); 209 printf("\tstart Firefox and sandbox X11\n");
399 printf("\tstart a /bin/bash session in a new network namespace and connect it\n");
400 printf("\tto br0, br1, and br2 host bridge devices\n");
401 printf(" $ firejail --list\n"); 210 printf(" $ firejail --list\n");
402 printf("\tlist all running sandboxes\n"); 211 printf("\tlist all running sandboxes\n");
403 printf("\n"); 212 printf("\n");
diff --git a/src/firejail/x11.c b/src/firejail/x11.c
index 6cba95501..ecab8880a 100644
--- a/src/firejail/x11.c
+++ b/src/firejail/x11.c
@@ -312,6 +312,7 @@ void x11_start_xephyr(int argc, char **argv) {
312 if (arg_debug) 312 if (arg_debug)
313 printf("Starting xephyr...\n"); 313 printf("Starting xephyr...\n");
314 314
315 // running without privileges - see drop_privs call above
315 assert(getenv("LD_PRELOAD") == NULL); 316 assert(getenv("LD_PRELOAD") == NULL);
316 execvp(server_argv[0], server_argv); 317 execvp(server_argv[0], server_argv);
317 perror("execvp"); 318 perror("execvp");
@@ -354,6 +355,7 @@ void x11_start_xephyr(int argc, char **argv) {
354 if (!arg_quiet) 355 if (!arg_quiet)
355 printf("\n*** Attaching to Xephyr display %d ***\n\n", display); 356 printf("\n*** Attaching to Xephyr display %d ***\n\n", display);
356 357
358 // running without privileges - see drop_privs call above
357 assert(getenv("LD_PRELOAD") == NULL); 359 assert(getenv("LD_PRELOAD") == NULL);
358 execvp(jail_argv[0], jail_argv); 360 execvp(jail_argv[0], jail_argv);
359 perror("execvp"); 361 perror("execvp");
@@ -434,6 +436,7 @@ void x11_start_xpra(int argc, char **argv) {
434 dup2(fd_null,2); 436 dup2(fd_null,2);
435 } 437 }
436 438
439 // running without privileges - see drop_privs call above
437 assert(getenv("LD_PRELOAD") == NULL); 440 assert(getenv("LD_PRELOAD") == NULL);
438 execvp(server_argv[0], server_argv); 441 execvp(server_argv[0], server_argv);
439 perror("execvp"); 442 perror("execvp");
@@ -481,6 +484,7 @@ void x11_start_xpra(int argc, char **argv) {
481 if (!arg_quiet) 484 if (!arg_quiet)
482 printf("\n*** Attaching to xpra display %d ***\n\n", display); 485 printf("\n*** Attaching to xpra display %d ***\n\n", display);
483 486
487 // running without privileges - see drop_privs call above
484 assert(getenv("LD_PRELOAD") == NULL); 488 assert(getenv("LD_PRELOAD") == NULL);
485 execvp(attach_argv[0], attach_argv); 489 execvp(attach_argv[0], attach_argv);
486 perror("execvp"); 490 perror("execvp");
@@ -512,6 +516,7 @@ void x11_start_xpra(int argc, char **argv) {
512 if (jail < 0) 516 if (jail < 0)
513 errExit("fork"); 517 errExit("fork");
514 if (jail == 0) { 518 if (jail == 0) {
519 // running without privileges - see drop_privs call above
515 assert(getenv("LD_PRELOAD") == NULL); 520 assert(getenv("LD_PRELOAD") == NULL);
516 if (firejail_argv[0]) // shut up llvm scan-build 521 if (firejail_argv[0]) // shut up llvm scan-build
517 execvp(firejail_argv[0], firejail_argv); 522 execvp(firejail_argv[0], firejail_argv);
@@ -539,6 +544,7 @@ void x11_start_xpra(int argc, char **argv) {
539 dup2(fd_null,1); 544 dup2(fd_null,1);
540 dup2(fd_null,2); 545 dup2(fd_null,2);
541 } 546 }
547 // running without privileges - see drop_privs call above
542 assert(getenv("LD_PRELOAD") == NULL); 548 assert(getenv("LD_PRELOAD") == NULL);
543 execvp(stop_argv[0], stop_argv); 549 execvp(stop_argv[0], stop_argv);
544 perror("execvp"); 550 perror("execvp");
@@ -638,7 +644,7 @@ void x11_block(void) {
638 644
639void x11_xorg(void) { 645void x11_xorg(void) {
640#ifdef HAVE_X11 646#ifdef HAVE_X11
641 // destination 647 // destination - create an empty ~/.Xauthotrity file if it doesn't exist already, and use it as a mount point
642 char *dest; 648 char *dest;
643 if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1) 649 if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1)
644 errExit("asprintf"); 650 errExit("asprintf");
@@ -652,47 +658,67 @@ void x11_xorg(void) {
652 fclose(fp); 658 fclose(fp);
653 } 659 }
654 660
661 // check xauth utility is present in the system
655 if (stat("/usr/bin/xauth", &s) == -1) { 662 if (stat("/usr/bin/xauth", &s) == -1) {
656 fprintf(stderr, "Error: cannot find /usr/bin/xauth executable\n"); 663 fprintf(stderr, "Error: cannot find /usr/bin/xauth executable\n");
657 exit(1); 664 exit(1);
658 } 665 }
659 666
667 // create a temporary .Xauthority file
668 char tmpfname[] = "/tmp/.tmpXauth-XXXXXX";
669 int fd = mkstemp(tmpfname);
670 if (fd == -1) {
671 fprintf(stderr, "Error: cannot create .Xauthority file\n");
672 exit(1);
673 }
674 close(fd);
675 if (chown(tmpfname, getuid(), getgid()) == -1)
676 errExit("chown");
677
660 pid_t child = fork(); 678 pid_t child = fork();
661 if (child < 0) 679 if (child < 0)
662 errExit("fork"); 680 errExit("fork");
663 if (child == 0) { 681 if (child == 0) {
664 // generate a new .Xauthority file 682 // generate the new .Xauthority file using xauth utility
665 if (arg_debug) 683 if (arg_debug)
666 printf("Generating a new .Xauthority file\n"); 684 printf("Generating a new .Xauthority file\n");
667 685 drop_privs(1);
668 // elevate privileges - files in /run/firejail/mnt directory belong to root
669 if (setreuid(0, 0) < 0)
670 errExit("setreuid");
671 if (setregid(0, 0) < 0)
672 errExit("setregid");
673 686
674 char *display = getenv("DISPLAY"); 687 char *display = getenv("DISPLAY");
675 if (!display) 688 if (!display)
676 display = ":0.0"; 689 display = ":0.0";
677 690
678 assert(getenv("LD_PRELOAD") == NULL); 691 clearenv();
679 execlp("/usr/bin/xauth", "/usr/bin/xauth", "-f", RUN_XAUTHORITY_SEC_FILE, 692 execlp("/usr/bin/xauth", "/usr/bin/xauth", "-f", tmpfname,
680 "generate", display, "MIT-MAGIC-COOKIE-1", "untrusted", NULL); 693 "generate", display, "MIT-MAGIC-COOKIE-1", "untrusted", NULL);
681 694
682 _exit(0); 695 _exit(0);
683 } 696 }
697
684 // wait for the child to finish 698 // wait for the child to finish
685 waitpid(child, NULL, 0); 699 waitpid(child, NULL, 0);
686 700
687 // check the file was created and set mode and ownership 701 // check the file was created and set mode and ownership
688 if (stat(RUN_XAUTHORITY_SEC_FILE, &s) == -1) { 702 if (stat(tmpfname, &s) == -1) {
689 fprintf(stderr, "Error: cannot create the new .Xauthority file\n"); 703 fprintf(stderr, "Error: cannot create the new .Xauthority file\n");
690 exit(1); 704 exit(1);
691 } 705 }
706 if (chown(tmpfname, getuid(), getgid()) == -1)
707 errExit("chown");
708 if (chmod(tmpfname, 0600) == -1)
709 errExit("chmod");
710
711 // move the temporary file in RUN_XAUTHORITY_SEC_FILE in order to have it deleted
712 // automatically when the sandbox is closed
713 if (copy_file(tmpfname, RUN_XAUTHORITY_SEC_FILE, getuid(), getgid(), 0600)) {
714 fprintf(stderr, "asdfdsfError: cannot create the new .Xauthority file\n");
715 exit(1);
716 }
692 if (chown(RUN_XAUTHORITY_SEC_FILE, getuid(), getgid()) == -1) 717 if (chown(RUN_XAUTHORITY_SEC_FILE, getuid(), getgid()) == -1)
693 errExit("chown"); 718 errExit("chown");
694 if (chmod(RUN_XAUTHORITY_SEC_FILE, 0600) == -1) 719 if (chmod(RUN_XAUTHORITY_SEC_FILE, 0600) == -1)
695 errExit("chmod"); 720 errExit("chmod");
721 unlink(tmpfname);
696 722
697 // mount 723 // mount
698 if (mount(RUN_XAUTHORITY_SEC_FILE, dest, "none", MS_BIND, "mode=0600") == -1) { 724 if (mount(RUN_XAUTHORITY_SEC_FILE, dest, "none", MS_BIND, "mode=0600") == -1) {
diff --git a/src/fnet/Makefile.in b/src/fnet/Makefile.in
index b515d2333..bba4406d4 100644
--- a/src/fnet/Makefile.in
+++ b/src/fnet/Makefile.in
@@ -33,8 +33,8 @@ LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread
33%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/libnetlink.h 33%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/libnetlink.h
34 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ 34 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
35 35
36fnet: $(OBJS) ../lib/libnetlink.o ../lib/common.o 36fnet: $(OBJS) ../lib/libnetlink.o
37 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/libnetlink.o $(LIBS) $(EXTRA_LDFLAGS) 37 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/libnetlink.o $(LIBS)
38 38
39clean:; rm -f *.o fnet 39clean:; rm -f *.o fnet
40 40
diff --git a/src/fseccomp/Makefile.in b/src/fseccomp/Makefile.in
index 110d2c95f..1878ad2f3 100644
--- a/src/fseccomp/Makefile.in
+++ b/src/fseccomp/Makefile.in
@@ -33,8 +33,8 @@ LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread
33%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/syscall.h 33%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/syscall.h
34 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ 34 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
35 35
36fseccomp: $(OBJS) ../lib/libnetlink.o ../lib/common.o 36fseccomp: $(OBJS)
37 $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTRA_LDFLAGS) 37 $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
38 38
39clean:; rm -f *.o fseccomp 39clean:; rm -f *.o fseccomp
40 40
diff --git a/src/fseccomp/main.c b/src/fseccomp/main.c
index 22b13bcd9..39e72fdf9 100644
--- a/src/fseccomp/main.c
+++ b/src/fseccomp/main.c
@@ -40,7 +40,7 @@ static void usage(void) {
40int main(int argc, char **argv) { 40int main(int argc, char **argv) {
41#if 0 41#if 0
42{ 42{
43system("cat /proc/self/status"); 43//system("cat /proc/self/status");
44int i; 44int i;
45for (i = 0; i < argc; i++) 45for (i = 0; i < argc; i++)
46 printf("*%s* ", argv[i]); 46 printf("*%s* ", argv[i]);
diff --git a/src/fseccomp/protocol.c b/src/fseccomp/protocol.c
index 38c5f9d88..7bf560fe1 100644
--- a/src/fseccomp/protocol.c
+++ b/src/fseccomp/protocol.c
@@ -107,7 +107,7 @@ void protocol_build_filter(const char *prlist, const char *fname) {
107 assert(fname); 107 assert(fname);
108 108
109#ifndef SYS_socket 109#ifndef SYS_socket
110 fprintf(stderr, "Warning: --protocol not supported on this platform\n"); 110 fprintf(stderr, "Warning fseccomp: --protocol not supported on this platform\n");
111 return; 111 return;
112#else 112#else
113 // build the filter 113 // build the filter
diff --git a/src/fseccomp/syscall.c b/src/fseccomp/syscall.c
index e2052efde..6696f2b11 100644
--- a/src/fseccomp/syscall.c
+++ b/src/fseccomp/syscall.c
@@ -67,12 +67,52 @@ void syscall_print(void) {
67 printf("\n"); 67 printf("\n");
68} 68}
69 69
70// allowed input:
71// - syscall
72// - syscall(error)
73static void syscall_process_name(const char *name, int *syscall_nr, int *error_nr) {
74 assert(name);
75 if (strlen(name) == 0)
76 goto error;
77 *error_nr = -1;
78
79 // syntax check
80 char *str = strdup(name);
81 if (!str)
82 errExit("strdup");
83
84 char *syscall_name = str;
85 char *error_name = strchr(str, ':');
86 if (error_name) {
87 *error_name = '\0';
88 error_name++;
89 }
90 if (strlen(syscall_name) == 0) {
91 free(str);
92 goto error;
93 }
94
95 *syscall_nr = syscall_find_name(syscall_name);
96 if (error_name) {
97 *error_nr = errno_find_name(error_name);
98 if (*error_nr == -1)
99 *syscall_nr = -1;
100 }
101
102 free(str);
103 return;
104
105error:
106 fprintf(stderr, "Error fseccomp: invalid syscall list entry %s\n", name);
107 exit(1);
108}
109
70// return 1 if error, 0 if OK 110// return 1 if error, 0 if OK
71int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall, int arg), int fd, int arg) { 111int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall, int arg), int fd, int arg) {
72 // don't allow empty lists 112 // don't allow empty lists
73 if (slist == NULL || *slist == '\0') { 113 if (slist == NULL || *slist == '\0') {
74 fprintf(stderr, "Error: empty syscall lists are not allowed\n"); 114 fprintf(stderr, "Error fseccomp: empty syscall lists are not allowed\n");
75 return -1; 115 exit(1);
76 } 116 }
77 117
78 // work on a copy of the string 118 // work on a copy of the string
@@ -80,29 +120,28 @@ int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall,
80 if (!str) 120 if (!str)
81 errExit("strdup"); 121 errExit("strdup");
82 122
83 char *ptr = str; 123 char *ptr =strtok(str, ",");
84 char *start = str; 124 if (ptr == NULL) {
85 while (*ptr != '\0') { 125 fprintf(stderr, "Error fseccomp: empty syscall lists are not allowed\n");
86 if (islower(*ptr) || isdigit(*ptr) || *ptr == '_') 126 exit(1);
87 ;
88 else if (*ptr == ',') {
89 *ptr = '\0';
90 int nr = syscall_find_name(start);
91 if (nr == -1)
92 fprintf(stderr, "Warning: syscall %s not found\n", start);
93 else if (callback != NULL)
94 callback(fd, nr, arg);
95
96 start = ptr + 1;
97 }
98 ptr++;
99 } 127 }
100 if (*start != '\0') { 128
101 int nr = syscall_find_name(start); 129 while (ptr) {
102 if (nr == -1) 130printf("ptr %s\n", ptr);
103 fprintf(stderr, "Warning: syscall %s not found\n", start); 131
104 else if (callback != NULL) 132 int syscall_nr;
105 callback(fd, nr, arg); 133 int error_nr;
134 syscall_process_name(ptr, &syscall_nr, &error_nr);
135printf("%d, %d\n", syscall_nr, error_nr);
136 if (syscall_nr == -1)
137 fprintf(stderr, "Warning fseccomp: syscall %s not found\n", ptr);
138 else if (callback != NULL) {
139 if (error_nr != -1)
140 filter_add_errno(fd, syscall_nr, error_nr);
141 else
142 callback(fd, syscall_nr, arg);
143 }
144 ptr = strtok(NULL, ",");
106 } 145 }
107 146
108 free(str); 147 free(str);
diff --git a/test/filters/seccomp-errno.exp b/test/filters/seccomp-errno.exp
index 4df1948be..c3af2fbe9 100755
--- a/test/filters/seccomp-errno.exp
+++ b/test/filters/seccomp-errno.exp
@@ -8,23 +8,23 @@ spawn $env(SHELL)
8match_max 100000 8match_max 100000
9 9
10send -- "touch seccomp-test-file\r" 10send -- "touch seccomp-test-file\r"
11sleep 1 11after 100
12 12
13send -- "firejail --seccomp.enoent=unlinkat rm seccomp-test-file\r" 13send -- "firejail --seccomp=unlinkat:ENOENT rm seccomp-test-file\r"
14expect { 14expect {
15 timeout {puts "TESTING ERROR 0\n";exit} 15 timeout {puts "TESTING ERROR 0\n";exit}
16 "No such file or directory" 16 "No such file or directory"
17} 17}
18sleep 1 18sleep 1
19 19
20send -- "firejail --seccomp.enoent=unlinkat --debug rm seccomp-test-file\r" 20send -- "firejail --seccomp=unlinkat:ENOENT --debug rm seccomp-test-file\r"
21expect { 21expect {
22 timeout {puts "TESTING ERROR 1\n";exit} 22 timeout {puts "TESTING ERROR 1\n";exit}
23 "unlinkat 2 ENOENT" 23 "unlinkat 2 ENOENT"
24} 24}
25sleep 1 25sleep 1
26 26
27send -- "firejail --seccomp.enoent=unlinkat,mkdir\r" 27send -- "firejail --seccomp=unlinkat:ENOENT,mkdir:ENOENT\r"
28expect { 28expect {
29 timeout {puts "TESTING ERROR 2\n";exit} 29 timeout {puts "TESTING ERROR 2\n";exit}
30 "Child process initialized" 30 "Child process initialized"
@@ -49,42 +49,6 @@ puts "\n"
49send -- "exit\r" 49send -- "exit\r"
50sleep 1 50sleep 1
51 51
52
53send -- "firejail --seccomp.enoent=unlinkat --seccomp.enoent=mkdir\r"
54expect {
55 timeout {puts "TESTING ERROR 5\n";exit}
56 "errno enoent already configured"
57}
58sleep 1
59
60send -- "firejail --seccomp.enoent=unlinkat --seccomp.eperm=mkdir\r"
61expect {
62 timeout {puts "TESTING ERROR 6\n";exit}
63 "Child process initialized"
64}
65sleep 1
66send -- "rm seccomp-test-file\r"
67expect {
68 timeout {puts "TESTING ERROR 7\n";exit}
69 "No such file or directory"
70}
71after 100
72puts "\n"
73
74send -- "mkdir seccomp-test-dir\r"
75expect {
76 timeout {puts "TESTING ERROR 8\n";exit}
77 "Operation not permitted"
78}
79after 100
80puts "\n"
81
82send -- "exit\r"
83sleep 1
84
85
86
87
88send -- "rm seccomp-test-file\r" 52send -- "rm seccomp-test-file\r"
89after 100 53after 100
90puts "all done\n" 54puts "all done\n"