diff options
author | valoq <valoq@mailbox.org> | 2016-11-06 20:44:32 +0100 |
---|---|---|
committer | valoq <valoq@mailbox.org> | 2016-11-06 20:44:32 +0100 |
commit | cf2c9e6436f16c727d09b433c1ac821849d3daa1 (patch) | |
tree | 8a57806636d3671eabfe2fd4a577c40691725c97 | |
parent | adopted wire profile to recent changes (diff) | |
parent | seccomp rework (diff) | |
download | firejail-cf2c9e6436f16c727d09b433c1ac821849d3daa1.tar.gz firejail-cf2c9e6436f16c727d09b433c1ac821849d3daa1.tar.zst firejail-cf2c9e6436f16c727d09b433c1ac821849d3daa1.zip |
Merge remote-tracking branch 'upstream/master'
-rw-r--r-- | README | 4 | ||||
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | etc/evince.profile | 2 | ||||
-rw-r--r-- | etc/firefox.profile | 5 | ||||
-rw-r--r-- | etc/mupdf.profile | 2 | ||||
-rw-r--r-- | etc/zoom.profile | 23 | ||||
-rw-r--r-- | platform/debian/conffiles | 1 | ||||
-rw-r--r-- | src/firejail/bandwidth.c | 2 | ||||
-rw-r--r-- | src/firejail/errno.c | 207 | ||||
-rw-r--r-- | src/firejail/firejail.h | 3 | ||||
-rw-r--r-- | src/firejail/fs_bin.c | 2 | ||||
-rw-r--r-- | src/firejail/fs_etc.c | 2 | ||||
-rw-r--r-- | src/firejail/main.c | 56 | ||||
-rw-r--r-- | src/firejail/netfilter.c | 8 | ||||
-rw-r--r-- | src/firejail/profile.c | 16 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 2 | ||||
-rw-r--r-- | src/firejail/sbox.c | 17 | ||||
-rw-r--r-- | src/firejail/seccomp.c | 72 | ||||
-rw-r--r-- | src/firejail/usage.c | 441 | ||||
-rw-r--r-- | src/firejail/x11.c | 48 | ||||
-rw-r--r-- | src/fnet/Makefile.in | 4 | ||||
-rw-r--r-- | src/fseccomp/Makefile.in | 4 | ||||
-rw-r--r-- | src/fseccomp/main.c | 2 | ||||
-rw-r--r-- | src/fseccomp/protocol.c | 2 | ||||
-rw-r--r-- | src/fseccomp/syscall.c | 87 | ||||
-rwxr-xr-x | test/filters/seccomp-errno.exp | 44 |
26 files changed, 327 insertions, 731 deletions
@@ -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 |
83 | BogDan Vatra (https://github.com/bog-dan-ro) | ||
84 | - zoom profile | ||
83 | Impyy (https://github.com/Impyy) | 85 | Impyy (https://github.com/Impyy) |
84 | - added mumble profile | 86 | - added mumble profile |
85 | valoq (https://github.com/valoq) | 87 | valoq (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 | ||
91 | Vadim A. Misbakh-Soloviov (https://github.com/msva) | 95 | Vadim A. Misbakh-Soloviov (https://github.com/msva) |
92 | - profile fixes | 96 | - profile fixes |
93 | Rafael Cavalcanti (https://github.com/rccavalcanti) | 97 | Rafael Cavalcanti (https://github.com/rccavalcanti) |
@@ -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 |
55 | xiphos, Tor Browser Bundle, display (imagemagik), Wire, mumble | 55 | xiphos, 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 | ||
7 | caps.drop all | 7 | caps.drop all |
8 | netfilter | 8 | netfilter |
9 | net none | 9 | #net none - creates some problems on some distributions |
10 | nogroups | 10 | nogroups |
11 | nonewprivs | 11 | nonewprivs |
12 | noroot | 12 | noroot |
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 | |||
47 | include /etc/firejail/whitelist-common.inc | 47 | include /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 | |
51 | private-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 |
52 | 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 | ||
53 | private-dev | 52 | private-dev |
54 | private-tmp | 53 | private-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 | |||
16 | shell none | 16 | shell none |
17 | tracelog | 17 | tracelog |
18 | 18 | ||
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 | 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 | ||
21 | private-bin mupdf | 21 | private-bin mupdf |
22 | private-tmp | 22 | private-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 | |||
3 | noblacklist ~/.config/zoomus.conf | ||
4 | |||
5 | include /etc/firejail/disable-common.inc | ||
6 | include /etc/firejail/disable-programs.inc | ||
7 | include /etc/firejail/disable-devel.inc | ||
8 | |||
9 | |||
10 | # Whitelists | ||
11 | |||
12 | mkdir ~/.zoom | ||
13 | whitelist ~/.zoom | ||
14 | |||
15 | |||
16 | caps.drop all | ||
17 | netfilter | ||
18 | nonewprivs | ||
19 | noroot | ||
20 | protocol unix,inet,inet6 | ||
21 | seccomp | ||
22 | |||
23 | private-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 | |||
25 | typedef struct { | ||
26 | char *name; | ||
27 | int nr; | ||
28 | } ErrnoEntry; | ||
29 | |||
30 | static 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 | |||
173 | int 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 | |||
184 | int 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 | |||
197 | char *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 |
498 | char *seccomp_check_list(const char *str); | ||
499 | int seccomp_load(const char *fname); | 499 | int seccomp_load(const char *fname); |
500 | void seccomp_filter_32(void); | 500 | void seccomp_filter_32(void); |
501 | void seccomp_filter_64(void); | 501 | void seccomp_filter_64(void); |
502 | int seccomp_filter_drop(int enforce_seccomp); | 502 | int seccomp_filter_drop(int enforce_seccomp); |
503 | int seccomp_filter_keep(void); | 503 | int seccomp_filter_keep(void); |
504 | int seccomp_filter_errno(void); | ||
505 | void seccomp_print_filter_name(const char *name); | 504 | void seccomp_print_filter_name(const char *name); |
506 | void seccomp_print_filter(pid_t pid); | 505 | void 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 | ||
25 | char *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 | |||
25 | int seccomp_load(const char *fname) { | 53 | int 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) { | |||
199 | int seccomp_filter_keep(void) { | 219 | int 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 | ||
220 | int 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 | ||
246 | printf("*** --seccomp.<errno> is temporarily disabled, it will be brought back soon ***\n"); | ||
247 | return 0; | ||
248 | #endif | ||
249 | } | ||
250 | |||
251 | void seccomp_print_filter_name(const char *name) { | 235 | void 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 | ||
639 | void x11_xorg(void) { | 645 | void 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 | ||
36 | fnet: $(OBJS) ../lib/libnetlink.o ../lib/common.o | 36 | fnet: $(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 | ||
39 | clean:; rm -f *.o fnet | 39 | clean:; 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 | ||
36 | fseccomp: $(OBJS) ../lib/libnetlink.o ../lib/common.o | 36 | fseccomp: $(OBJS) |
37 | $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTRA_LDFLAGS) | 37 | $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) |
38 | 38 | ||
39 | clean:; rm -f *.o fseccomp | 39 | clean:; 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) { | |||
40 | int main(int argc, char **argv) { | 40 | int main(int argc, char **argv) { |
41 | #if 0 | 41 | #if 0 |
42 | { | 42 | { |
43 | system("cat /proc/self/status"); | 43 | //system("cat /proc/self/status"); |
44 | int i; | 44 | int i; |
45 | for (i = 0; i < argc; i++) | 45 | for (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) | ||
73 | static 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 | |||
105 | error: | ||
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 |
71 | int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall, int arg), int fd, int arg) { | 111 | int 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) | 130 | printf("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); | ||
135 | printf("%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) | |||
8 | match_max 100000 | 8 | match_max 100000 |
9 | 9 | ||
10 | send -- "touch seccomp-test-file\r" | 10 | send -- "touch seccomp-test-file\r" |
11 | sleep 1 | 11 | after 100 |
12 | 12 | ||
13 | send -- "firejail --seccomp.enoent=unlinkat rm seccomp-test-file\r" | 13 | send -- "firejail --seccomp=unlinkat:ENOENT rm seccomp-test-file\r" |
14 | expect { | 14 | expect { |
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 | } |
18 | sleep 1 | 18 | sleep 1 |
19 | 19 | ||
20 | send -- "firejail --seccomp.enoent=unlinkat --debug rm seccomp-test-file\r" | 20 | send -- "firejail --seccomp=unlinkat:ENOENT --debug rm seccomp-test-file\r" |
21 | expect { | 21 | expect { |
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 | } |
25 | sleep 1 | 25 | sleep 1 |
26 | 26 | ||
27 | send -- "firejail --seccomp.enoent=unlinkat,mkdir\r" | 27 | send -- "firejail --seccomp=unlinkat:ENOENT,mkdir:ENOENT\r" |
28 | expect { | 28 | expect { |
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" | |||
49 | send -- "exit\r" | 49 | send -- "exit\r" |
50 | sleep 1 | 50 | sleep 1 |
51 | 51 | ||
52 | |||
53 | send -- "firejail --seccomp.enoent=unlinkat --seccomp.enoent=mkdir\r" | ||
54 | expect { | ||
55 | timeout {puts "TESTING ERROR 5\n";exit} | ||
56 | "errno enoent already configured" | ||
57 | } | ||
58 | sleep 1 | ||
59 | |||
60 | send -- "firejail --seccomp.enoent=unlinkat --seccomp.eperm=mkdir\r" | ||
61 | expect { | ||
62 | timeout {puts "TESTING ERROR 6\n";exit} | ||
63 | "Child process initialized" | ||
64 | } | ||
65 | sleep 1 | ||
66 | send -- "rm seccomp-test-file\r" | ||
67 | expect { | ||
68 | timeout {puts "TESTING ERROR 7\n";exit} | ||
69 | "No such file or directory" | ||
70 | } | ||
71 | after 100 | ||
72 | puts "\n" | ||
73 | |||
74 | send -- "mkdir seccomp-test-dir\r" | ||
75 | expect { | ||
76 | timeout {puts "TESTING ERROR 8\n";exit} | ||
77 | "Operation not permitted" | ||
78 | } | ||
79 | after 100 | ||
80 | puts "\n" | ||
81 | |||
82 | send -- "exit\r" | ||
83 | sleep 1 | ||
84 | |||
85 | |||
86 | |||
87 | |||
88 | send -- "rm seccomp-test-file\r" | 52 | send -- "rm seccomp-test-file\r" |
89 | after 100 | 53 | after 100 |
90 | puts "all done\n" | 54 | puts "all done\n" |