summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/firecfg/firecfg.config61
-rw-r--r--src/firejail/firejail.h2
-rw-r--r--src/firejail/fs_dev.c2
-rw-r--r--src/firejail/fs_home.c12
-rw-r--r--src/firejail/fs_var.c18
-rw-r--r--src/firejail/fs_whitelist.c118
-rw-r--r--src/firejail/preproc.c2
-rw-r--r--src/firejail/profile.c7
-rw-r--r--src/firejail/restrict_users.c10
-rw-r--r--src/firejail/util.c7
-rw-r--r--src/firejail/x11.c4
-rw-r--r--src/fseccomp/seccomp.c8
-rw-r--r--src/man/firejail.txt511
13 files changed, 427 insertions, 335 deletions
diff --git a/src/firecfg/firecfg.config b/src/firecfg/firecfg.config
index 3c42567d4..dd056553e 100644
--- a/src/firecfg/firecfg.config
+++ b/src/firecfg/firecfg.config
@@ -1,15 +1,16 @@
1# /usr/lib/firejail/firecfg.config - firecfg utility configuration file 1# /usr/lib/firejail/firecfg.config - firecfg utility configuration file
2# This is the list of programs in alphabetical order handled by firecfg utility 2# This is the list of programs in alphabetical order handled by firecfg utility
3# 3#
4# Cryptocat is added but commented since isn't installed to a */bin... keep an eye on this
5#qemu-system-x86_64 4#qemu-system-x86_64
60ad 50ad
72048-qt 62048-qt
7Cryptocat
8Cyberfox 8Cyberfox
9Discord 9Discord
10DiscordCanary 10DiscordCanary
11FossaMail 11FossaMail
12Fritzing 12Fritzing
13Gitter
13JDownloader 14JDownloader
14Mathematica 15Mathematica
15Natron 16Natron
@@ -33,13 +34,14 @@ archaudit-report
33ardour4 34ardour4
34ardour5 35ardour5
35arduino 36arduino
37aria2c
36ark 38ark
37arm 39arm
38artha 40artha
39# atom
40# atom-beta
41assogiate 41assogiate
42asunder 42asunder
43# atom
44# atom-beta
43atool 45atool
44atril 46atril
45atril-previewer 47atril-previewer
@@ -54,6 +56,7 @@ baobab
54basilisk 56basilisk
55beaker 57beaker
56bibletime 58bibletime
59bitcoin-qt
57bitlbee 60bitlbee
58bleachbit 61bleachbit
59blender 62blender
@@ -76,6 +79,8 @@ calligrasheets
76calligrastage 79calligrastage
77calligrawords 80calligrawords
78catfish 81catfish
82celluloid
83checkbashisms
79cherrytree 84cherrytree
80chromium 85chromium
81chromium-browser 86chromium-browser
@@ -88,20 +93,24 @@ clamtk
88claws-mail 93claws-mail
89clawsker 94clawsker
90clementine 95clementine
96clion
91clipit 97clipit
92cliqz 98cliqz
93cmus 99cmus
94code 100code
101code-oss
95conkeror 102conkeror
96conky 103conky
97corebird 104corebird
98crow 105crow
106cryptocat
99cvlc 107cvlc
100cyberfox 108cyberfox
101darktable 109darktable
102dconf-editor 110dconf-editor
103deadbeef 111deadbeef
104deluge 112deluge
113devhelp
105dex2jar 114dex2jar
106dia 115dia
107dig 116dig
@@ -120,6 +129,7 @@ dooble-qt4
120dosbox 129dosbox
121dragon 130dragon
122dropbox 131dropbox
132d-feet
123easystroke 133easystroke
124ebook-viewer 134ebook-viewer
125electrum 135electrum
@@ -147,9 +157,13 @@ fbreader
147feedreader 157feedreader
148feh 158feh
149ffmpeg 159ffmpeg
160ffmpegthumbnailer
161ffplay
162ffprobe
150file-roller 163file-roller
151filezilla 164filezilla
152firefox 165firefox
166firefox-beta
153firefox-developer-edition 167firefox-developer-edition
154firefox-esr 168firefox-esr
155firefox-nightly 169firefox-nightly
@@ -159,18 +173,22 @@ flashpeak-slimjet
159flowblade 173flowblade
160font-manager 174font-manager
161fontforge 175fontforge
176fossamail
162franz 177franz
163freecad 178freecad
164freecadcmd 179freecadcmd
165freshclam 180freshclam
166frozen-bubble 181frozen-bubble
167gajim 182gajim
183gajim-history-manager
168galculator 184galculator
185gcalccmd
169gcloud 186gcloud
170gconf-editor 187gconf-editor
171geany 188geany
172geary 189geary
173gedit 190gedit
191geekbench
174geeqie 192geeqie
175ghb 193ghb
176ghostwriter 194ghostwriter
@@ -183,8 +201,8 @@ gitter
183gjs 201gjs
184globaltime 202globaltime
185gnome-2048 203gnome-2048
186gnome-builder
187gnome-books 204gnome-books
205gnome-builder
188gnome-calculator 206gnome-calculator
189gnome-chess 207gnome-chess
190gnome-clocks 208gnome-clocks
@@ -196,8 +214,11 @@ gnome-maps
196gnome-mplayer 214gnome-mplayer
197gnome-mpv 215gnome-mpv
198gnome-music 216gnome-music
217gnome-nettool
199gnome-photos 218gnome-photos
200gnome-recipes 219gnome-recipes
220gnome-schedule
221gnome-system-log
201gnome-twitch 222gnome-twitch
202gnome-weather 223gnome-weather
203goobox 224goobox
@@ -284,6 +305,7 @@ lximage-qt
284lxmusic 305lxmusic
285lynx 306lynx
286macrofusion 307macrofusion
308masterpdfeditor
287masterpdfeditor4 309masterpdfeditor4
288masterpdfeditor5 310masterpdfeditor5
289mate-calc 311mate-calc
@@ -295,6 +317,7 @@ mcabber
295mediainfo 317mediainfo
296mediathekview 318mediathekview
297meld 319meld
320mencoder
298mendeleydesktop 321mendeleydesktop
299midori 322midori
300min 323min
@@ -321,12 +344,17 @@ mutt
321mypaint 344mypaint
322mypaint-ora-thumbnailer 345mypaint-ora-thumbnailer
323natron 346natron
324#nautilus - removed in order to let the application start in a new sandbox when clicking on icons in the file manager
325ncdu 347ncdu
348netactview
349nethack
326netsurf 350netsurf
327neverball 351neverball
328nheko 352nheko
329nitroshare 353nitroshare
354nitroshare-cli
355nitroshare-nmh
356nitroshare-send
357nitroshare-ui
330nylas 358nylas
331nyx 359nyx
332obs 360obs
@@ -343,6 +371,7 @@ orage
343palemoon 371palemoon
344parole 372parole
345patch 373patch
374pavucontrol
346pdfchain 375pdfchain
347pdfmod 376pdfmod
348pdfsam 377pdfsam
@@ -360,6 +389,7 @@ playonlinux
360pluma 389pluma
361polari 390polari
362ppsspp 391ppsspp
392pragha
363psi-plus 393psi-plus
364pybitmessage 394pybitmessage
365# pycharm-community - FB note: may enable later 395# pycharm-community - FB note: may enable later
@@ -369,6 +399,7 @@ qemu-launcher
369qlipper 399qlipper
370qmmp 400qmmp
371qpdfview 401qpdfview
402qt-faststart
372qtox 403qtox
373quassel 404quassel
374quiterss 405quiterss
@@ -376,6 +407,8 @@ qupzilla
376qutebrowser 407qutebrowser
377rambox 408rambox
378redeclipse 409redeclipse
410redshift
411regextester
379remmina 412remmina
380rhythmbox 413rhythmbox
381ricochet 414ricochet
@@ -389,13 +422,17 @@ sayonara
389scallion 422scallion
390scribus 423scribus
391sdat2img 424sdat2img
425seahorse
426seahorse-tool
392seamonkey 427seamonkey
393seamonkey-bin 428seamonkey-bin
429secret-tool
394shellcheck 430shellcheck
395shotcut 431shotcut
396signal-desktop 432signal-desktop
397silentarmy 433silentarmy
398simple-scan 434simple-scan
435simplescreenrecorder
399simutrans 436simutrans
400skanlite 437skanlite
401skype 438skype
@@ -403,8 +440,9 @@ skypeforlinux
403slack 440slack
404smplayer 441smplayer
405smtube 442smtube
406sol 443snox
407soffice 444soffice
445sol
408soundconverter 446soundconverter
409spotify 447spotify
410sqlitebrowser 448sqlitebrowser
@@ -416,12 +454,15 @@ steam
416steam-native 454steam-native
417stellarium 455stellarium
418strings 456strings
457studio.sh
419subdownloader 458subdownloader
420supertux2 459supertux2
421supertuxkart 460supertuxkart
422surf 461surf
423sylpheed 462sylpheed
424synfigstudio 463synfigstudio
464sysprof
465sysprof-cli
425teamspeak3 466teamspeak3
426telegram 467telegram
427telegram-desktop 468telegram-desktop
@@ -464,9 +505,16 @@ tor-browser-zh-tw
464torbrowser-launcher 505torbrowser-launcher
465totem 506totem
466tracker 507tracker
508transgui
467transmission-cli 509transmission-cli
510transmission-create
511transmission-daemon
512transmission-edit
468transmission-gtk 513transmission-gtk
469transmission-qt 514transmission-qt
515transmission-remote
516transmission-remote-cli
517transmission-remote-gtk
470transmission-show 518transmission-show
471truecraft 519truecraft
472tuxguitar 520tuxguitar
@@ -505,6 +553,7 @@ xchat
505xed 553xed
506xfburn 554xfburn
507xfce4-dict 555xfce4-dict
556xfce4-mixer
508xfce4-notes 557xfce4-notes
509xiphos 558xiphos
510xmms 559xmms
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 1372c3ca3..01ddf2a14 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -78,6 +78,7 @@
78#define RUN_WHITELIST_HOME_DIR "/run/firejail/mnt/orig-home" // default home directory masking 78#define RUN_WHITELIST_HOME_DIR "/run/firejail/mnt/orig-home" // default home directory masking
79#define RUN_WHITELIST_RUN_DIR "/run/firejail/mnt/orig-run" // default run directory masking 79#define RUN_WHITELIST_RUN_DIR "/run/firejail/mnt/orig-run" // default run directory masking
80#define RUN_WHITELIST_HOME_USER_DIR "/run/firejail/mnt/orig-home-user" // home directory whitelisting 80#define RUN_WHITELIST_HOME_USER_DIR "/run/firejail/mnt/orig-home-user" // home directory whitelisting
81#define RUN_WHITELIST_RUN_USER_DIR "/run/firejail/mnt/orig-run-user" // run directory whitelisting
81#define RUN_WHITELIST_TMP_DIR "/run/firejail/mnt/orig-tmp" 82#define RUN_WHITELIST_TMP_DIR "/run/firejail/mnt/orig-tmp"
82#define RUN_WHITELIST_MEDIA_DIR "/run/firejail/mnt/orig-media" 83#define RUN_WHITELIST_MEDIA_DIR "/run/firejail/mnt/orig-media"
83#define RUN_WHITELIST_MNT_DIR "/run/firejail/mnt/orig-mnt" 84#define RUN_WHITELIST_MNT_DIR "/run/firejail/mnt/orig-mnt"
@@ -211,6 +212,7 @@ typedef struct profile_entry_t {
211 unsigned etc_dir:1; // whitelist in /etc directory 212 unsigned etc_dir:1; // whitelist in /etc directory
212 unsigned share_dir:1; // whitelist in /usr/share directory 213 unsigned share_dir:1; // whitelist in /usr/share directory
213 unsigned module_dir:1; // whitelist in /sys/module directory 214 unsigned module_dir:1; // whitelist in /sys/module directory
215 unsigned run_dir:1; // whitelist in /run/user/$uid directory
214}ProfileEntry; 216}ProfileEntry;
215 217
216typedef struct config_t { 218typedef struct config_t {
diff --git a/src/firejail/fs_dev.c b/src/firejail/fs_dev.c
index 4872d6cd9..bd036908a 100644
--- a/src/firejail/fs_dev.c
+++ b/src/firejail/fs_dev.c
@@ -228,7 +228,7 @@ void fs_private_dev(void){
228 } 228 }
229 229
230 // mount tmpfs on top of /dev 230 // mount tmpfs on top of /dev
231 if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 231 if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
232 errExit("mounting /dev"); 232 errExit("mounting /dev");
233 fs_logger("tmpfs /dev"); 233 fs_logger("tmpfs /dev");
234 234
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c
index 7746aa44b..e35bf073d 100644
--- a/src/firejail/fs_home.c
+++ b/src/firejail/fs_home.c
@@ -270,7 +270,7 @@ void fs_private_homedir(void) {
270 // mask /root 270 // mask /root
271 if (arg_debug) 271 if (arg_debug)
272 printf("Mounting a new /root directory\n"); 272 printf("Mounting a new /root directory\n");
273 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME | MS_REC, "mode=700,gid=0") < 0) 273 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME, "mode=700,gid=0") < 0)
274 errExit("mounting home directory"); 274 errExit("mounting home directory");
275 fs_logger("tmpfs /root"); 275 fs_logger("tmpfs /root");
276 } 276 }
@@ -278,7 +278,7 @@ void fs_private_homedir(void) {
278 // mask /home 278 // mask /home
279 if (arg_debug) 279 if (arg_debug)
280 printf("Mounting a new /home directory\n"); 280 printf("Mounting a new /home directory\n");
281 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 281 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME, "mode=755,gid=0") < 0)
282 errExit("mounting home directory"); 282 errExit("mounting home directory");
283 fs_logger("tmpfs /home"); 283 fs_logger("tmpfs /home");
284 } 284 }
@@ -313,7 +313,7 @@ void fs_private(void) {
313 else { 313 else {
314 if (arg_allusers) 314 if (arg_allusers)
315 fwarning("--allusers disabled by --private or --whitelist\n"); 315 fwarning("--allusers disabled by --private or --whitelist\n");
316 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 316 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME, "mode=755,gid=0") < 0)
317 errExit("mounting home directory"); 317 errExit("mounting home directory");
318 fs_logger("tmpfs /home"); 318 fs_logger("tmpfs /home");
319 } 319 }
@@ -321,7 +321,7 @@ void fs_private(void) {
321 // mask /root 321 // mask /root
322 if (arg_debug) 322 if (arg_debug)
323 printf("Mounting a new /root directory\n"); 323 printf("Mounting a new /root directory\n");
324 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME | MS_REC, "mode=700,gid=0") < 0) 324 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME, "mode=700,gid=0") < 0)
325 errExit("mounting root directory"); 325 errExit("mounting root directory");
326 fs_logger("tmpfs /root"); 326 fs_logger("tmpfs /root");
327 327
@@ -517,14 +517,14 @@ void fs_private_home_list(void) {
517 // mask /root 517 // mask /root
518 if (arg_debug) 518 if (arg_debug)
519 printf("Mounting a new /root directory\n"); 519 printf("Mounting a new /root directory\n");
520 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=700,gid=0") < 0) 520 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=700,gid=0") < 0)
521 errExit("mounting home directory"); 521 errExit("mounting home directory");
522 } 522 }
523 else { 523 else {
524 // mask /home 524 // mask /home
525 if (arg_debug) 525 if (arg_debug)
526 printf("Mounting a new /home directory\n"); 526 printf("Mounting a new /home directory\n");
527 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 527 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
528 errExit("mounting home directory"); 528 errExit("mounting home directory");
529 } 529 }
530 530
diff --git a/src/firejail/fs_var.c b/src/firejail/fs_var.c
index 5b872ad75..75369b47c 100644
--- a/src/firejail/fs_var.c
+++ b/src/firejail/fs_var.c
@@ -118,7 +118,7 @@ void fs_var_log(void) {
118 // mount a tmpfs on top of /var/log 118 // mount a tmpfs on top of /var/log
119 if (arg_debug) 119 if (arg_debug)
120 printf("Mounting tmpfs on /var/log\n"); 120 printf("Mounting tmpfs on /var/log\n");
121 if (mount("tmpfs", "/var/log", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 121 if (mount("tmpfs", "/var/log", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
122 errExit("mounting /var/log"); 122 errExit("mounting /var/log");
123 fs_logger("tmpfs /var/log"); 123 fs_logger("tmpfs /var/log");
124 124
@@ -153,7 +153,7 @@ void fs_var_lib(void) {
153 if (stat("/var/lib/dhcp", &s) == 0) { 153 if (stat("/var/lib/dhcp", &s) == 0) {
154 if (arg_debug) 154 if (arg_debug)
155 printf("Mounting tmpfs on /var/lib/dhcp\n"); 155 printf("Mounting tmpfs on /var/lib/dhcp\n");
156 if (mount("tmpfs", "/var/lib/dhcp", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 156 if (mount("tmpfs", "/var/lib/dhcp", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
157 errExit("mounting /var/lib/dhcp"); 157 errExit("mounting /var/lib/dhcp");
158 fs_logger("tmpfs /var/lib/dhcp"); 158 fs_logger("tmpfs /var/lib/dhcp");
159 159
@@ -172,7 +172,7 @@ void fs_var_lib(void) {
172 if (stat("/var/lib/nginx", &s) == 0) { 172 if (stat("/var/lib/nginx", &s) == 0) {
173 if (arg_debug) 173 if (arg_debug)
174 printf("Mounting tmpfs on /var/lib/nginx\n"); 174 printf("Mounting tmpfs on /var/lib/nginx\n");
175 if (mount("tmpfs", "/var/lib/nginx", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 175 if (mount("tmpfs", "/var/lib/nginx", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
176 errExit("mounting /var/lib/nginx"); 176 errExit("mounting /var/lib/nginx");
177 fs_logger("tmpfs /var/lib/nginx"); 177 fs_logger("tmpfs /var/lib/nginx");
178 } 178 }
@@ -181,7 +181,7 @@ void fs_var_lib(void) {
181 if (stat("/var/lib/snmp", &s) == 0) { 181 if (stat("/var/lib/snmp", &s) == 0) {
182 if (arg_debug) 182 if (arg_debug)
183 printf("Mounting tmpfs on /var/lib/snmp\n"); 183 printf("Mounting tmpfs on /var/lib/snmp\n");
184 if (mount("tmpfs", "/var/lib/snmp", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 184 if (mount("tmpfs", "/var/lib/snmp", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
185 errExit("mounting /var/lib/snmp"); 185 errExit("mounting /var/lib/snmp");
186 fs_logger("tmpfs /var/lib/snmp"); 186 fs_logger("tmpfs /var/lib/snmp");
187 } 187 }
@@ -190,7 +190,7 @@ void fs_var_lib(void) {
190 if (stat("/var/lib/sudo", &s) == 0) { 190 if (stat("/var/lib/sudo", &s) == 0) {
191 if (arg_debug) 191 if (arg_debug)
192 printf("Mounting tmpfs on /var/lib/sudo\n"); 192 printf("Mounting tmpfs on /var/lib/sudo\n");
193 if (mount("tmpfs", "/var/lib/sudo", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 193 if (mount("tmpfs", "/var/lib/sudo", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
194 errExit("mounting /var/lib/sudo"); 194 errExit("mounting /var/lib/sudo");
195 fs_logger("tmpfs /var/lib/sudo"); 195 fs_logger("tmpfs /var/lib/sudo");
196 } 196 }
@@ -202,7 +202,7 @@ void fs_var_cache(void) {
202 if (stat("/var/cache/apache2", &s) == 0) { 202 if (stat("/var/cache/apache2", &s) == 0) {
203 if (arg_debug) 203 if (arg_debug)
204 printf("Mounting tmpfs on /var/cache/apache2\n"); 204 printf("Mounting tmpfs on /var/cache/apache2\n");
205 if (mount("tmpfs", "/var/cache/apache2", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 205 if (mount("tmpfs", "/var/cache/apache2", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
206 errExit("mounting /var/cache/apache2"); 206 errExit("mounting /var/cache/apache2");
207 fs_logger("tmpfs /var/cache/apache2"); 207 fs_logger("tmpfs /var/cache/apache2");
208 } 208 }
@@ -210,7 +210,7 @@ void fs_var_cache(void) {
210 if (stat("/var/cache/lighttpd", &s) == 0) { 210 if (stat("/var/cache/lighttpd", &s) == 0) {
211 if (arg_debug) 211 if (arg_debug)
212 printf("Mounting tmpfs on /var/cache/lighttpd\n"); 212 printf("Mounting tmpfs on /var/cache/lighttpd\n");
213 if (mount("tmpfs", "/var/cache/lighttpd", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 213 if (mount("tmpfs", "/var/cache/lighttpd", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
214 errExit("mounting /var/cache/lighttpd"); 214 errExit("mounting /var/cache/lighttpd");
215 fs_logger("tmpfs /var/cache/lighttpd"); 215 fs_logger("tmpfs /var/cache/lighttpd");
216 216
@@ -250,7 +250,7 @@ void fs_var_lock(void) {
250 if (is_dir("/var/lock")) { 250 if (is_dir("/var/lock")) {
251 if (arg_debug) 251 if (arg_debug)
252 printf("Mounting tmpfs on /var/lock\n"); 252 printf("Mounting tmpfs on /var/lock\n");
253 if (mount("tmpfs", "/var/lock", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=1777,gid=0") < 0) 253 if (mount("tmpfs", "/var/lock", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME, "mode=1777,gid=0") < 0)
254 errExit("mounting /lock"); 254 errExit("mounting /lock");
255 fs_logger("tmpfs /var/lock"); 255 fs_logger("tmpfs /var/lock");
256 } 256 }
@@ -266,7 +266,7 @@ void fs_var_tmp(void) {
266 if (!is_link("/var/tmp")) { 266 if (!is_link("/var/tmp")) {
267 if (arg_debug) 267 if (arg_debug)
268 printf("Mounting tmpfs on /var/tmp\n"); 268 printf("Mounting tmpfs on /var/tmp\n");
269 if (mount("tmpfs", "/var/tmp", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=1777,gid=0") < 0) 269 if (mount("tmpfs", "/var/tmp", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME, "mode=1777,gid=0") < 0)
270 errExit("mounting /var/tmp"); 270 errExit("mounting /var/tmp");
271 fs_logger("tmpfs /var/tmp"); 271 fs_logger("tmpfs /var/tmp");
272 } 272 }
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c
index 6cd445433..d128065d3 100644
--- a/src/firejail/fs_whitelist.c
+++ b/src/firejail/fs_whitelist.c
@@ -33,19 +33,20 @@
33//#define TEST_MOUNTINFO 33//#define TEST_MOUNTINFO
34 34
35#define EMPTY_STRING ("") 35#define EMPTY_STRING ("")
36#define MAXBUF 4098
37static size_t homedir_len; // cache length of homedir string 36static size_t homedir_len; // cache length of homedir string
37static size_t runuser_len; // cache length of runuser string
38static char *runuser;
38 39
39 40
40static int mkpath(const char* path, mode_t mode) { 41static int mkpath(const char* path, mode_t mode) {
41 assert(path && *path); 42 assert(path && *path);
42 mode |= 0111; 43 mode |= 0111;
43 44
44 // create directories with uid/gid as root or as current user if inside home directory 45 // create directories with uid/gid as root or as current user if inside home or run directory
45 int userhome = 0; 46 int userprivs = 0;
46 if (strncmp(path, cfg.homedir, homedir_len) == 0) { 47 if (strncmp(path, cfg.homedir, homedir_len) == 0 || strncmp(path, runuser, runuser_len) == 0) {
47 EUID_USER(); 48 EUID_USER();
48 userhome = 1; 49 userprivs = 1;
49 } 50 }
50 51
51 // work on a copy of the path 52 // work on a copy of the path
@@ -68,11 +69,6 @@ static int mkpath(const char* path, mode_t mode) {
68 char *tok = strtok(dup, "/"); 69 char *tok = strtok(dup, "/");
69 assert(tok); // path is no top level directory 70 assert(tok); // path is no top level directory
70 while (tok) { 71 while (tok) {
71 // skip all instances of "/./"
72 if (strcmp(tok, ".") == 0) {
73 tok = strtok(NULL, "/");
74 continue;
75 }
76 // create the directory if necessary 72 // create the directory if necessary
77 if (mkdirat(parentfd, tok, mode) == -1) { 73 if (mkdirat(parentfd, tok, mode) == -1) {
78 if (errno != EEXIST) { 74 if (errno != EEXIST) {
@@ -80,7 +76,7 @@ static int mkpath(const char* path, mode_t mode) {
80 perror("mkdir"); 76 perror("mkdir");
81 close(parentfd); 77 close(parentfd);
82 free(dup); 78 free(dup);
83 if (userhome) { 79 if (userprivs) {
84 EUID_ROOT(); 80 EUID_ROOT();
85 } 81 }
86 return -1; 82 return -1;
@@ -95,7 +91,7 @@ static int mkpath(const char* path, mode_t mode) {
95 perror("open"); 91 perror("open");
96 close(parentfd); 92 close(parentfd);
97 free(dup); 93 free(dup);
98 if (userhome) { 94 if (userprivs) {
99 EUID_ROOT(); 95 EUID_ROOT();
100 } 96 }
101 return -1; 97 return -1;
@@ -110,7 +106,7 @@ static int mkpath(const char* path, mode_t mode) {
110 fs_logger2("mkpath", path); 106 fs_logger2("mkpath", path);
111 107
112 free(dup); 108 free(dup);
113 if (userhome) { 109 if (userprivs) {
114 EUID_ROOT(); 110 EUID_ROOT();
115 } 111 }
116 return fd; 112 return fd;
@@ -205,6 +201,12 @@ static void whitelist_path(ProfileEntry *entry) {
205 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_MODULE_DIR, fname) == -1) 201 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_MODULE_DIR, fname) == -1)
206 errExit("asprintf"); 202 errExit("asprintf");
207 } 203 }
204 else if (entry->run_dir) {
205 fname = path + runuser_len + 1; // strlen("/run/user/$uid/")
206
207 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_RUN_USER_DIR, fname) == -1)
208 errExit("asprintf");
209 }
208 assert(wfile); 210 assert(wfile);
209 211
210 if (arg_debug || arg_debug_whitelists) 212 if (arg_debug || arg_debug_whitelists)
@@ -331,7 +333,11 @@ void fs_whitelist(void) {
331 if (!entry) 333 if (!entry)
332 return; 334 return;
333 335
336 if (asprintf(&runuser, "/run/user/%u", getuid()) == -1)
337 errExit("asprintf");
338 runuser_len = strlen(runuser);
334 homedir_len = strlen(cfg.homedir); 339 homedir_len = strlen(cfg.homedir);
340
335 char *new_name = NULL; 341 char *new_name = NULL;
336 int home_dir = 0; // /home/user directory flag 342 int home_dir = 0; // /home/user directory flag
337 int tmp_dir = 0; // /tmp directory flag 343 int tmp_dir = 0; // /tmp directory flag
@@ -344,6 +350,7 @@ void fs_whitelist(void) {
344 int etc_dir = 0; // /etc directory flag 350 int etc_dir = 0; // /etc directory flag
345 int share_dir = 0; // /usr/share directory flag 351 int share_dir = 0; // /usr/share directory flag
346 int module_dir = 0; // /sys/module directory flag 352 int module_dir = 0; // /sys/module directory flag
353 int run_dir = 0; // /run/user/$uid directory flag
347 354
348 size_t nowhitelist_c = 0; 355 size_t nowhitelist_c = 0;
349 size_t nowhitelist_m = 32; 356 size_t nowhitelist_m = 32;
@@ -455,6 +462,8 @@ void fs_whitelist(void) {
455 share_dir = 1; 462 share_dir = 1;
456 else if (strncmp(new_name, "/sys/module/", 12) == 0) 463 else if (strncmp(new_name, "/sys/module/", 12) == 0)
457 module_dir = 1; 464 module_dir = 1;
465 else if (strncmp(new_name, runuser, runuser_len) == 0 && new_name[runuser_len] == '/')
466 run_dir = 1;
458 } 467 }
459 468
460 entry->data = EMPTY_STRING; 469 entry->data = EMPTY_STRING;
@@ -630,6 +639,15 @@ void fs_whitelist(void) {
630 goto errexit; 639 goto errexit;
631 } 640 }
632 } 641 }
642 else if (strncmp(new_name, runuser, runuser_len) == 0 && new_name[runuser_len] == '/') {
643 entry->run_dir = 1;
644 run_dir = 1;
645 // both path and absolute path are under /run/user/$uid
646 if (strncmp(fname, runuser, runuser_len) != 0 || fname[runuser_len] != '/') {
647 free(fname);
648 goto errexit;
649 }
650 }
633 else { 651 else {
634 free(fname); 652 free(fname);
635 goto errexit; 653 goto errexit;
@@ -710,7 +728,7 @@ void fs_whitelist(void) {
710 // mount tmpfs on /tmp 728 // mount tmpfs on /tmp
711 if (arg_debug || arg_debug_whitelists) 729 if (arg_debug || arg_debug_whitelists)
712 printf("Mounting tmpfs on /tmp directory\n"); 730 printf("Mounting tmpfs on /tmp directory\n");
713 if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=1777,gid=0") < 0) 731 if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=1777,gid=0") < 0)
714 errExit("mounting tmpfs on /tmp"); 732 errExit("mounting tmpfs on /tmp");
715 fs_logger("tmpfs /tmp"); 733 fs_logger("tmpfs /tmp");
716 } 734 }
@@ -727,7 +745,7 @@ void fs_whitelist(void) {
727 // mount tmpfs on /media 745 // mount tmpfs on /media
728 if (arg_debug || arg_debug_whitelists) 746 if (arg_debug || arg_debug_whitelists)
729 printf("Mounting tmpfs on /media directory\n"); 747 printf("Mounting tmpfs on /media directory\n");
730 if (mount("tmpfs", "/media", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 748 if (mount("tmpfs", "/media", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
731 errExit("mounting tmpfs on /media"); 749 errExit("mounting tmpfs on /media");
732 fs_logger("tmpfs /media"); 750 fs_logger("tmpfs /media");
733 } 751 }
@@ -747,7 +765,7 @@ void fs_whitelist(void) {
747 // mount tmpfs on /mnt 765 // mount tmpfs on /mnt
748 if (arg_debug || arg_debug_whitelists) 766 if (arg_debug || arg_debug_whitelists)
749 printf("Mounting tmpfs on /mnt directory\n"); 767 printf("Mounting tmpfs on /mnt directory\n");
750 if (mount("tmpfs", "/mnt", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 768 if (mount("tmpfs", "/mnt", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
751 errExit("mounting tmpfs on /mnt"); 769 errExit("mounting tmpfs on /mnt");
752 fs_logger("tmpfs /mnt"); 770 fs_logger("tmpfs /mnt");
753 } 771 }
@@ -766,7 +784,7 @@ void fs_whitelist(void) {
766 // mount tmpfs on /var 784 // mount tmpfs on /var
767 if (arg_debug || arg_debug_whitelists) 785 if (arg_debug || arg_debug_whitelists)
768 printf("Mounting tmpfs on /var directory\n"); 786 printf("Mounting tmpfs on /var directory\n");
769 if (mount("tmpfs", "/var", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 787 if (mount("tmpfs", "/var", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
770 errExit("mounting tmpfs on /var"); 788 errExit("mounting tmpfs on /var");
771 fs_logger("tmpfs /var"); 789 fs_logger("tmpfs /var");
772 } 790 }
@@ -781,7 +799,7 @@ void fs_whitelist(void) {
781 // mount tmpfs on /dev 799 // mount tmpfs on /dev
782 if (arg_debug || arg_debug_whitelists) 800 if (arg_debug || arg_debug_whitelists)
783 printf("Mounting tmpfs on /dev directory\n"); 801 printf("Mounting tmpfs on /dev directory\n");
784 if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 802 if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
785 errExit("mounting tmpfs on /dev"); 803 errExit("mounting tmpfs on /dev");
786 fs_logger("tmpfs /dev"); 804 fs_logger("tmpfs /dev");
787 } 805 }
@@ -798,7 +816,7 @@ void fs_whitelist(void) {
798 // mount tmpfs on /opt 816 // mount tmpfs on /opt
799 if (arg_debug || arg_debug_whitelists) 817 if (arg_debug || arg_debug_whitelists)
800 printf("Mounting tmpfs on /opt directory\n"); 818 printf("Mounting tmpfs on /opt directory\n");
801 if (mount("tmpfs", "/opt", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 819 if (mount("tmpfs", "/opt", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
802 errExit("mounting tmpfs on /opt"); 820 errExit("mounting tmpfs on /opt");
803 fs_logger("tmpfs /opt"); 821 fs_logger("tmpfs /opt");
804 } 822 }
@@ -818,7 +836,7 @@ void fs_whitelist(void) {
818 // mount tmpfs on /srv 836 // mount tmpfs on /srv
819 if (arg_debug || arg_debug_whitelists) 837 if (arg_debug || arg_debug_whitelists)
820 printf("Mounting tmpfs on /srv directory\n"); 838 printf("Mounting tmpfs on /srv directory\n");
821 if (mount("tmpfs", "/srv", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 839 if (mount("tmpfs", "/srv", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
822 errExit("mounting tmpfs on /srv"); 840 errExit("mounting tmpfs on /srv");
823 fs_logger("tmpfs /srv"); 841 fs_logger("tmpfs /srv");
824 } 842 }
@@ -838,7 +856,7 @@ void fs_whitelist(void) {
838 // mount tmpfs on /srv 856 // mount tmpfs on /srv
839 if (arg_debug || arg_debug_whitelists) 857 if (arg_debug || arg_debug_whitelists)
840 printf("Mounting tmpfs on /etc directory\n"); 858 printf("Mounting tmpfs on /etc directory\n");
841 if (mount("tmpfs", "/etc", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 859 if (mount("tmpfs", "/etc", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
842 errExit("mounting tmpfs on /etc"); 860 errExit("mounting tmpfs on /etc");
843 fs_logger("tmpfs /etc"); 861 fs_logger("tmpfs /etc");
844 } 862 }
@@ -858,7 +876,7 @@ void fs_whitelist(void) {
858 // mount tmpfs on /srv 876 // mount tmpfs on /srv
859 if (arg_debug || arg_debug_whitelists) 877 if (arg_debug || arg_debug_whitelists)
860 printf("Mounting tmpfs on /usr/share directory\n"); 878 printf("Mounting tmpfs on /usr/share directory\n");
861 if (mount("tmpfs", "/usr/share", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 879 if (mount("tmpfs", "/usr/share", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
862 errExit("mounting tmpfs on /usr/share"); 880 errExit("mounting tmpfs on /usr/share");
863 fs_logger("tmpfs /usr/share"); 881 fs_logger("tmpfs /usr/share");
864 } 882 }
@@ -878,7 +896,7 @@ void fs_whitelist(void) {
878 // mount tmpfs on /sys/module 896 // mount tmpfs on /sys/module
879 if (arg_debug || arg_debug_whitelists) 897 if (arg_debug || arg_debug_whitelists)
880 printf("Mounting tmpfs on /sys/module directory\n"); 898 printf("Mounting tmpfs on /sys/module directory\n");
881 if (mount("tmpfs", "/sys/module", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 899 if (mount("tmpfs", "/sys/module", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
882 errExit("mounting tmpfs on /sys/module"); 900 errExit("mounting tmpfs on /sys/module");
883 fs_logger("tmpfs /sys/module"); 901 fs_logger("tmpfs /sys/module");
884 } 902 }
@@ -886,6 +904,30 @@ void fs_whitelist(void) {
886 module_dir = 0; 904 module_dir = 0;
887 } 905 }
888 906
907 // /run/user mountpoint
908 if (run_dir) {
909 // check if /run/user/$uid directory exists
910 if (stat(runuser, &s) == 0) {
911 // keep a copy of real /run/user/$uid directory in RUN_WHITELIST_RUN_USER_DIR
912 mkdir_attr(RUN_WHITELIST_RUN_USER_DIR, 0700, getuid(), getgid());
913 if (mount(runuser, RUN_WHITELIST_RUN_USER_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
914 errExit("mount bind");
915
916 // mount tmpfs on /run/user/$uid
917 if (arg_debug || arg_debug_whitelists)
918 printf("Mounting tmpfs on %s directory\n", runuser);
919 char *options;
920 if (asprintf(&options, "mode=700,uid=%u,gid=%u", getuid(), getgid()) == -1)
921 errExit("asprintf");
922 if (mount("tmpfs", runuser, "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, options) < 0)
923 errExit("mounting tmpfs on /run/user/<uid>");
924 free(options);
925 fs_logger2("tmpfs", runuser);
926 }
927 else
928 run_dir = 0;
929 }
930
889 931
890 // go through profile rules again, and interpret whitelist commands 932 // go through profile rules again, and interpret whitelist commands
891 entry = cfg.profile; 933 entry = cfg.profile;
@@ -937,81 +979,89 @@ void fs_whitelist(void) {
937 979
938 // mask the real home directory, currently mounted on RUN_WHITELIST_HOME_DIR 980 // mask the real home directory, currently mounted on RUN_WHITELIST_HOME_DIR
939 if (home_dir) { 981 if (home_dir) {
940 if (mount("tmpfs", RUN_WHITELIST_HOME_USER_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 982 if (mount("tmpfs", RUN_WHITELIST_HOME_USER_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
941 errExit("mount tmpfs"); 983 errExit("mount tmpfs");
942 fs_logger2("tmpfs", RUN_WHITELIST_HOME_USER_DIR); 984 fs_logger2("tmpfs", RUN_WHITELIST_HOME_USER_DIR);
943 } 985 }
944 986
945 // mask the real /tmp directory, currently mounted on RUN_WHITELIST_TMP_DIR 987 // mask the real /tmp directory, currently mounted on RUN_WHITELIST_TMP_DIR
946 if (tmp_dir) { 988 if (tmp_dir) {
947 if (mount("tmpfs", RUN_WHITELIST_TMP_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 989 if (mount("tmpfs", RUN_WHITELIST_TMP_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
948 errExit("mount tmpfs"); 990 errExit("mount tmpfs");
949 fs_logger2("tmpfs", RUN_WHITELIST_TMP_DIR); 991 fs_logger2("tmpfs", RUN_WHITELIST_TMP_DIR);
950 } 992 }
951 993
952 // mask the real /var directory, currently mounted on RUN_WHITELIST_VAR_DIR 994 // mask the real /var directory, currently mounted on RUN_WHITELIST_VAR_DIR
953 if (var_dir) { 995 if (var_dir) {
954 if (mount("tmpfs", RUN_WHITELIST_VAR_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 996 if (mount("tmpfs", RUN_WHITELIST_VAR_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
955 errExit("mount tmpfs"); 997 errExit("mount tmpfs");
956 fs_logger2("tmpfs", RUN_WHITELIST_VAR_DIR); 998 fs_logger2("tmpfs", RUN_WHITELIST_VAR_DIR);
957 } 999 }
958 1000
959 // mask the real /opt directory, currently mounted on RUN_WHITELIST_OPT_DIR 1001 // mask the real /opt directory, currently mounted on RUN_WHITELIST_OPT_DIR
960 if (opt_dir) { 1002 if (opt_dir) {
961 if (mount("tmpfs", RUN_WHITELIST_OPT_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 1003 if (mount("tmpfs", RUN_WHITELIST_OPT_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
962 errExit("mount tmpfs"); 1004 errExit("mount tmpfs");
963 fs_logger2("tmpfs", RUN_WHITELIST_OPT_DIR); 1005 fs_logger2("tmpfs", RUN_WHITELIST_OPT_DIR);
964 } 1006 }
965 1007
966 // mask the real /dev directory, currently mounted on RUN_WHITELIST_DEV_DIR 1008 // mask the real /dev directory, currently mounted on RUN_WHITELIST_DEV_DIR
967 if (dev_dir) { 1009 if (dev_dir) {
968 if (mount("tmpfs", RUN_WHITELIST_DEV_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 1010 if (mount("tmpfs", RUN_WHITELIST_DEV_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
969 errExit("mount tmpfs"); 1011 errExit("mount tmpfs");
970 fs_logger2("tmpfs", RUN_WHITELIST_DEV_DIR); 1012 fs_logger2("tmpfs", RUN_WHITELIST_DEV_DIR);
971 } 1013 }
972 1014
973 // mask the real /media directory, currently mounted on RUN_WHITELIST_MEDIA_DIR 1015 // mask the real /media directory, currently mounted on RUN_WHITELIST_MEDIA_DIR
974 if (media_dir) { 1016 if (media_dir) {
975 if (mount("tmpfs", RUN_WHITELIST_MEDIA_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 1017 if (mount("tmpfs", RUN_WHITELIST_MEDIA_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
976 errExit("mount tmpfs"); 1018 errExit("mount tmpfs");
977 fs_logger2("tmpfs", RUN_WHITELIST_MEDIA_DIR); 1019 fs_logger2("tmpfs", RUN_WHITELIST_MEDIA_DIR);
978 } 1020 }
979 1021
980 // mask the real /mnt directory, currently mounted on RUN_WHITELIST_MNT_DIR 1022 // mask the real /mnt directory, currently mounted on RUN_WHITELIST_MNT_DIR
981 if (mnt_dir) { 1023 if (mnt_dir) {
982 if (mount("tmpfs", RUN_WHITELIST_MNT_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 1024 if (mount("tmpfs", RUN_WHITELIST_MNT_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
983 errExit("mount tmpfs"); 1025 errExit("mount tmpfs");
984 fs_logger2("tmpfs", RUN_WHITELIST_MNT_DIR); 1026 fs_logger2("tmpfs", RUN_WHITELIST_MNT_DIR);
985 } 1027 }
986 1028
987 // mask the real /srv directory, currently mounted on RUN_WHITELIST_SRV_DIR 1029 // mask the real /srv directory, currently mounted on RUN_WHITELIST_SRV_DIR
988 if (srv_dir) { 1030 if (srv_dir) {
989 if (mount("tmpfs", RUN_WHITELIST_SRV_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 1031 if (mount("tmpfs", RUN_WHITELIST_SRV_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
990 errExit("mount tmpfs"); 1032 errExit("mount tmpfs");
991 fs_logger2("tmpfs", RUN_WHITELIST_SRV_DIR); 1033 fs_logger2("tmpfs", RUN_WHITELIST_SRV_DIR);
992 } 1034 }
993 1035
994 // mask the real /etc directory, currently mounted on RUN_WHITELIST_ETC_DIR 1036 // mask the real /etc directory, currently mounted on RUN_WHITELIST_ETC_DIR
995 if (etc_dir) { 1037 if (etc_dir) {
996 if (mount("tmpfs", RUN_WHITELIST_ETC_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 1038 if (mount("tmpfs", RUN_WHITELIST_ETC_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
997 errExit("mount tmpfs"); 1039 errExit("mount tmpfs");
998 fs_logger2("tmpfs", RUN_WHITELIST_ETC_DIR); 1040 fs_logger2("tmpfs", RUN_WHITELIST_ETC_DIR);
999 } 1041 }
1000 1042
1001 // mask the real /usr/share directory, currently mounted on RUN_WHITELIST_SHARE_DIR 1043 // mask the real /usr/share directory, currently mounted on RUN_WHITELIST_SHARE_DIR
1002 if (share_dir) { 1044 if (share_dir) {
1003 if (mount("tmpfs", RUN_WHITELIST_SHARE_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 1045 if (mount("tmpfs", RUN_WHITELIST_SHARE_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
1004 errExit("mount tmpfs"); 1046 errExit("mount tmpfs");
1005 fs_logger2("tmpfs", RUN_WHITELIST_SHARE_DIR); 1047 fs_logger2("tmpfs", RUN_WHITELIST_SHARE_DIR);
1006 } 1048 }
1007 1049
1008 // mask the real /sys/module directory, currently mounted on RUN_WHITELIST_MODULE_DIR 1050 // mask the real /sys/module directory, currently mounted on RUN_WHITELIST_MODULE_DIR
1009 if (module_dir) { 1051 if (module_dir) {
1010 if (mount("tmpfs", RUN_WHITELIST_MODULE_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 1052 if (mount("tmpfs", RUN_WHITELIST_MODULE_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
1011 errExit("mount tmpfs"); 1053 errExit("mount tmpfs");
1012 fs_logger2("tmpfs", RUN_WHITELIST_MODULE_DIR); 1054 fs_logger2("tmpfs", RUN_WHITELIST_MODULE_DIR);
1013 } 1055 }
1014 1056
1057 // mask the real /run/user/$uid directory, currently mounted on RUN_WHITELIST_MODULE_DIR
1058 if (run_dir) {
1059 if (mount("tmpfs", RUN_WHITELIST_RUN_USER_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
1060 errExit("mount tmpfs");
1061 fs_logger2("tmpfs", RUN_WHITELIST_RUN_USER_DIR);
1062 }
1063
1064 free(runuser);
1015 return; 1065 return;
1016 1066
1017errexit: 1067errexit:
diff --git a/src/firejail/preproc.c b/src/firejail/preproc.c
index 905cc0f15..2effebbaa 100644
--- a/src/firejail/preproc.c
+++ b/src/firejail/preproc.c
@@ -80,7 +80,7 @@ void preproc_mount_mnt_dir(void) {
80 if (!tmpfs_mounted) { 80 if (!tmpfs_mounted) {
81 if (arg_debug) 81 if (arg_debug)
82 printf("Mounting tmpfs on %s directory\n", RUN_MNT_DIR); 82 printf("Mounting tmpfs on %s directory\n", RUN_MNT_DIR);
83 if (mount("tmpfs", RUN_MNT_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 83 if (mount("tmpfs", RUN_MNT_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=755,gid=0") < 0)
84 errExit("mounting /run/firejail/mnt"); 84 errExit("mounting /run/firejail/mnt");
85 tmpfs_mounted = 1; 85 tmpfs_mounted = 1;
86 fs_logger2("tmpfs", RUN_MNT_DIR); 86 fs_logger2("tmpfs", RUN_MNT_DIR);
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index c163133c3..667b03652 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -241,9 +241,6 @@ error:
241// return 1 if the command is to be added to the linked list of profile commands 241// return 1 if the command is to be added to the linked list of profile commands
242// return 0 if the command was already executed inside the function 242// return 0 if the command was already executed inside the function
243int profile_check_line(char *ptr, int lineno, const char *fname) { 243int profile_check_line(char *ptr, int lineno, const char *fname) {
244#ifdef HAVE_WHITELIST
245 static int whitelist_warning_printed = 0;
246#endif
247 EUID_ASSERT(); 244 EUID_ASSERT();
248 245
249 // check and process conditional profile lines 246 // check and process conditional profile lines
@@ -858,8 +855,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
858 cfg.dns4 = dns; 855 cfg.dns4 = dns;
859 else { 856 else {
860 fprintf(stderr, "Error: up to 4 DNS servers can be specified\n"); 857 fprintf(stderr, "Error: up to 4 DNS servers can be specified\n");
861 free(dns); 858 exit(1);
862 return 1;
863 } 859 }
864 return 0; 860 return 0;
865 } 861 }
@@ -1314,6 +1310,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
1314 ptr += 10; 1310 ptr += 10;
1315 } 1311 }
1316 else { 1312 else {
1313 static int whitelist_warning_printed = 0;
1317 if (!whitelist_warning_printed) { 1314 if (!whitelist_warning_printed) {
1318 warning_feature_disabled("whitelist"); 1315 warning_feature_disabled("whitelist");
1319 whitelist_warning_printed = 1; 1316 whitelist_warning_printed = 1;
diff --git a/src/firejail/restrict_users.c b/src/firejail/restrict_users.c
index 7778d7ed8..5c5ace90b 100644
--- a/src/firejail/restrict_users.c
+++ b/src/firejail/restrict_users.c
@@ -83,7 +83,7 @@ static void sanitize_home(void) {
83 errExit("mount bind"); 83 errExit("mount bind");
84 84
85 // mount tmpfs in the new home 85 // mount tmpfs in the new home
86 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 86 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
87 errExit("mount tmpfs"); 87 errExit("mount tmpfs");
88 fs_logger("tmpfs /home"); 88 fs_logger("tmpfs /home");
89 89
@@ -105,7 +105,7 @@ static void sanitize_home(void) {
105 errExit("mount bind"); 105 errExit("mount bind");
106 106
107 // mask home dir under /run 107 // mask home dir under /run
108 if (mount("tmpfs", RUN_WHITELIST_HOME_DIR, "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 108 if (mount("tmpfs", RUN_WHITELIST_HOME_DIR, "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
109 errExit("mount tmpfs"); 109 errExit("mount tmpfs");
110 fs_logger2("tmpfs", RUN_WHITELIST_HOME_DIR); 110 fs_logger2("tmpfs", RUN_WHITELIST_HOME_DIR);
111 if (!arg_private) 111 if (!arg_private)
@@ -138,7 +138,7 @@ static void sanitize_run(void) {
138 errExit("mount bind"); 138 errExit("mount bind");
139 139
140 // mount tmpfs on /run/user 140 // mount tmpfs on /run/user
141 if (mount("tmpfs", "/run/user", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 141 if (mount("tmpfs", "/run/user", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
142 errExit("mount tmpfs"); 142 errExit("mount tmpfs");
143 fs_logger("tmpfs /run/user"); 143 fs_logger("tmpfs /run/user");
144 144
@@ -156,7 +156,7 @@ static void sanitize_run(void) {
156 errExit("mount bind"); 156 errExit("mount bind");
157 157
158 // mask mirrored /run/user/$UID directory 158 // mask mirrored /run/user/$UID directory
159 if (mount("tmpfs", RUN_WHITELIST_RUN_DIR, "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 159 if (mount("tmpfs", RUN_WHITELIST_RUN_DIR, "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
160 errExit("mount tmpfs"); 160 errExit("mount tmpfs");
161 fs_logger2("tmpfs", RUN_WHITELIST_RUN_DIR); 161 fs_logger2("tmpfs", RUN_WHITELIST_RUN_DIR);
162 162
@@ -398,7 +398,7 @@ void restrict_users(void) {
398 else { 398 else {
399 // user has the home directory outside /home 399 // user has the home directory outside /home
400 // mount tmpfs on top of /home in order to hide it 400 // mount tmpfs on top of /home in order to hide it
401 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 401 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
402 errExit("mount tmpfs"); 402 errExit("mount tmpfs");
403 fs_logger("tmpfs /home"); 403 fs_logger("tmpfs /home");
404 } 404 }
diff --git a/src/firejail/util.c b/src/firejail/util.c
index 0e869ef7a..dd298a31a 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -1163,11 +1163,6 @@ int safe_fd(const char *path, int flags) {
1163 char *tok = strtok(dup, "/"); 1163 char *tok = strtok(dup, "/");
1164 assert(tok); 1164 assert(tok);
1165 while (tok) { 1165 while (tok) {
1166 // skip all "/./"
1167 if (strcmp(tok, ".") == 0) {
1168 tok = strtok(NULL, "/");
1169 continue;
1170 }
1171 // open the element, assuming it is a directory; this fails with ENOTDIR if it is a symbolic link 1166 // open the element, assuming it is a directory; this fails with ENOTDIR if it is a symbolic link
1172 fd = openat(parentfd, tok, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); 1167 fd = openat(parentfd, tok, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
1173 if (fd == -1) { 1168 if (fd == -1) {
@@ -1267,7 +1262,7 @@ int invalid_sandbox(const pid_t pid) {
1267} 1262}
1268 1263
1269int has_handler(pid_t pid, int signal) { 1264int has_handler(pid_t pid, int signal) {
1270 if (signal > 0) { 1265 if (signal > 0 && signal <= SIGRTMAX) {
1271 char *fname; 1266 char *fname;
1272 if (asprintf(&fname, "/proc/%d/status", pid) == -1) 1267 if (asprintf(&fname, "/proc/%d/status", pid) == -1)
1273 errExit("asprintf"); 1268 errExit("asprintf");
diff --git a/src/firejail/x11.c b/src/firejail/x11.c
index 63b36053b..b0ed10b30 100644
--- a/src/firejail/x11.c
+++ b/src/firejail/x11.c
@@ -1099,7 +1099,7 @@ void x11_xorg(void) {
1099 } 1099 }
1100 1100
1101 // temporarily mount a tempfs on top of /tmp directory 1101 // temporarily mount a tempfs on top of /tmp directory
1102 if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=1777,gid=0") < 0) 1102 if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME, "mode=1777,gid=0") < 0)
1103 errExit("mounting /tmp"); 1103 errExit("mounting /tmp");
1104 1104
1105 // create the temporary .Xauthority file 1105 // create the temporary .Xauthority file
@@ -1253,7 +1253,7 @@ void fs_x11(void) {
1253 1253
1254 // This directory must be mode 1777, or Xlib will barf. 1254 // This directory must be mode 1777, or Xlib will barf.
1255 if (mount("tmpfs", "/tmp/.X11-unix", "tmpfs", 1255 if (mount("tmpfs", "/tmp/.X11-unix", "tmpfs",
1256 MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, 1256 MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME,
1257 "mode=1777,uid=0,gid=0") < 0) 1257 "mode=1777,uid=0,gid=0") < 0)
1258 errExit("mounting tmpfs on /tmp/.X11-unix"); 1258 errExit("mounting tmpfs on /tmp/.X11-unix");
1259 fs_logger("tmpfs /tmp/.X11-unix"); 1259 fs_logger("tmpfs /tmp/.X11-unix");
diff --git a/src/fseccomp/seccomp.c b/src/fseccomp/seccomp.c
index fc0299a34..2a719725e 100644
--- a/src/fseccomp/seccomp.c
+++ b/src/fseccomp/seccomp.c
@@ -258,6 +258,14 @@ void memory_deny_write_execute(const char *fname) {
258 BPF_STMT(BPF_ALU+BPF_AND+BPF_K, SHM_EXEC), 258 BPF_STMT(BPF_ALU+BPF_AND+BPF_K, SHM_EXEC),
259 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SHM_EXEC, 0, 1), 259 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SHM_EXEC, 0, 1),
260 KILL_PROCESS, 260 KILL_PROCESS,
261 RETURN_ALLOW,
262#endif
263#ifdef SYS_memfd_create
264 // block memfd_create as it can be used to create
265 // arbitrary memory contents which can be later mapped
266 // as executable
267 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, SYS_memfd_create, 0, 1),
268 KILL_PROCESS,
261 RETURN_ALLOW 269 RETURN_ALLOW
262#endif 270#endif
263 }; 271 };
diff --git a/src/man/firejail.txt b/src/man/firejail.txt
index 052aeb56b..8f5aa777f 100644
--- a/src/man/firejail.txt
+++ b/src/man/firejail.txt
@@ -99,33 +99,33 @@ $ firejail --allusers
99\fB\-\-apparmor 99\fB\-\-apparmor
100Enable AppArmor confinement. For more information, please see \fBAPPARMOR\fR section below. 100Enable AppArmor confinement. For more information, please see \fBAPPARMOR\fR section below.
101.TP 101.TP
102\fB\-\-appimage 102\fB\-\-apparmor.print=name|pid
103Sandbox an AppImage (https://appimage.org/) application. If the sandbox is started 103Print the AppArmor confinement status for the sandbox identified by name or by PID.
104as a regular user, nonewprivs and a default capabilities filter are enabled.
105.br 104.br
106 105
107.br 106.br
108Example: 107Example:
109.br 108.br
110$ firejail --appimage krita-3.0-x86_64.appimage 109$ firejail \-\-apparmor.print=browser
111.br 110.br
112$ firejail --appimage --private krita-3.0-x86_64.appimage 1115074:netblue:/usr/bin/firejail /usr/bin/firefox-esr
113.br 112.br
114$ firejail --appimage --net=none --x11 krita-3.0-x86_64.appimage 113 AppArmor: firejail-default enforce
115 114
116.TP 115.TP
117\fB\-\-apparmor.print=name|pid 116\fB\-\-appimage
118Print the AppArmor confinement status for the sandbox identified by name or by PID. 117Sandbox an AppImage (https://appimage.org/) application. If the sandbox is started
118as a regular user, nonewprivs and a default capabilities filter are enabled.
119.br 119.br
120 120
121.br 121.br
122Example: 122Example:
123.br 123.br
124$ firejail \-\-apparmor.print=browser 124$ firejail --appimage krita-3.0-x86_64.appimage
125.br 125.br
1265074:netblue:/usr/bin/firejail /usr/bin/firefox-esr 126$ firejail --appimage --private krita-3.0-x86_64.appimage
127.br 127.br
128 AppArmor: firejail-default enforce 128$ firejail --appimage --net=none --x11 krita-3.0-x86_64.appimage
129 129
130.TP 130.TP
131\fB\-\-audit 131\fB\-\-audit
@@ -701,10 +701,6 @@ Example:
701$ firejail --keep-var-tmp 701$ firejail --keep-var-tmp
702 702
703.TP 703.TP
704\fB\-\-ls=name|pid dir_or_filename
705List files in sandbox container, see \fBFILE TRANSFER\fR section for more details.
706
707.TP
708\fB\-\-list 704\fB\-\-list
709List all sandboxes, see \fBMONITORING\fR section for more details. 705List all sandboxes, see \fBMONITORING\fR section for more details.
710.br 706.br
@@ -720,7 +716,10 @@ $ firejail \-\-list
720.br 716.br
7217064:netblue::firejail \-\-noroot xterm 7177064:netblue::firejail \-\-noroot xterm
722.br 718.br
723$ 719.TP
720\fB\-\-ls=name|pid dir_or_filename
721List files in sandbox container, see \fBFILE TRANSFER\fR section for more details.
722
724.TP 723.TP
725\fB\-\-mac=address 724\fB\-\-mac=address
726Assign MAC addresses to the last network interface defined by a \-\-net option. This option 725Assign MAC addresses to the last network interface defined by a \-\-net option. This option
@@ -735,6 +734,7 @@ $ firejail \-\-net=eth0 \-\-mac=00:11:22:33:44:55 firefox
735.TP 734.TP
736\fB\-\-machine-id 735\fB\-\-machine-id
737Spoof id number in /etc/machine-id file - a new random id is generated inside the sandbox. 736Spoof id number in /etc/machine-id file - a new random id is generated inside the sandbox.
737Note that this breaks audio support. Enable it when sound is not required.
738.br 738.br
739 739
740.br 740.br
@@ -747,8 +747,8 @@ $ firejail \-\-machine-id
747Install a seccomp filter to block attempts to create memory mappings 747Install a seccomp filter to block attempts to create memory mappings
748that are both writable and executable, to change mappings to be 748that are both writable and executable, to change mappings to be
749executable, or to create executable shared memory. The filter examines 749executable, or to create executable shared memory. The filter examines
750the arguments of mmap, mmap2, mprotect, pkey_mprotect and shmat system 750the arguments of mmap, mmap2, mprotect, pkey_mprotect, memfd_create and
751calls and kills the process if necessary. 751shmat system calls and kills the process if necessary.
752.br 752.br
753 753
754.br 754.br
@@ -814,6 +814,24 @@ $ sudo ifconfig br1 10.10.30.1/24
814$ firejail \-\-net=br0 \-\-net=br1 814$ firejail \-\-net=br0 \-\-net=br1
815 815
816.TP 816.TP
817\fB\-\-net=none
818Enable a new, unconnected network namespace. The only interface
819available in the new namespace is a new loopback interface (lo).
820Use this option to deny
821network access to programs that don't really need network access.
822.br
823
824.br
825Example:
826.br
827$ firejail \-\-net=none vlc
828.br
829
830.br
831Note: \-\-net=none can crash the application on some platforms.
832In these cases, it can be replaced with \-\-protocol=unix.
833
834.TP
817\fB\-\-net=ethernet_interface|wireless_interface 835\fB\-\-net=ethernet_interface|wireless_interface
818Enable a new network namespace and connect it 836Enable a new network namespace and connect it
819to this ethernet interface using the standard Linux macvlan|ipvaln 837to this ethernet interface using the standard Linux macvlan|ipvaln
@@ -847,24 +865,6 @@ Example:
847$ firejail \-\-net=tap0 \-\-ip=10.10.20.80 \-\-netmask=255.255.255.0 \-\-defaultgw=10.10.20.1 firefox 865$ firejail \-\-net=tap0 \-\-ip=10.10.20.80 \-\-netmask=255.255.255.0 \-\-defaultgw=10.10.20.1 firefox
848 866
849.TP 867.TP
850\fB\-\-net=none
851Enable a new, unconnected network namespace. The only interface
852available in the new namespace is a new loopback interface (lo).
853Use this option to deny
854network access to programs that don't really need network access.
855.br
856
857.br
858Example:
859.br
860$ firejail \-\-net=none vlc
861.br
862
863.br
864Note: \-\-net=none can crash the application on some platforms.
865In these cases, it can be replaced with \-\-protocol=unix.
866
867.TP
868\fB\-\-net.print=name|pid 868\fB\-\-net.print=name|pid
869If a new network namespace is enabled, print network interface configuration for the sandbox specified by name or PID. Example: 869If a new network namespace is enabled, print network interface configuration for the sandbox specified by name or PID. Example:
870.br 870.br
@@ -1067,6 +1067,17 @@ Example:
1067$ firejail --no3d firefox 1067$ firejail --no3d firefox
1068 1068
1069.TP 1069.TP
1070\fB\-\-noautopulse
1071Disable automatic ~/.config/pulse init, for complex setups such as remote
1072pulse servers or non-standard socket paths.
1073.br
1074
1075.br
1076Example:
1077.br
1078$ firejail \-\-noautopulse firefox
1079
1080.TP
1070\fB\-\-noblacklist=dirname_or_filename 1081\fB\-\-noblacklist=dirname_or_filename
1071Disable blacklist for this directory or file. 1082Disable blacklist for this directory or file.
1072.br 1083.br
@@ -1156,6 +1167,14 @@ uid=1000(netblue) gid=1000(netblue) groups=1000(netblue)
1156$ 1167$
1157 1168
1158.TP 1169.TP
1170\fB\-\-nonewprivs
1171Sets the NO_NEW_PRIVS prctl. This ensures that child processes
1172cannot acquire new privileges using execve(2); in particular,
1173this means that calling a suid binary (or one with file capabilities)
1174does not result in an increase of privilege. This option
1175is enabled by default if seccomp filter is activated.
1176
1177.TP
1159\fB\-\-noprofile 1178\fB\-\-noprofile
1160Do not use a security profile. 1179Do not use a security profile.
1161.br 1180.br
@@ -1208,14 +1227,6 @@ ping: icmp open socket: Operation not permitted
1208$ 1227$
1209 1228
1210.TP 1229.TP
1211\fB\-\-nonewprivs
1212Sets the NO_NEW_PRIVS prctl. This ensures that child processes
1213cannot acquire new privileges using execve(2); in particular,
1214this means that calling a suid binary (or one with file capabilities)
1215does not result in an increase of privilege. This option
1216is enabled by default if seccomp filter is activated.
1217
1218.TP
1219\fB\-\-nosound 1230\fB\-\-nosound
1220Disable sound system. 1231Disable sound system.
1221.br 1232.br
@@ -1226,17 +1237,6 @@ Example:
1226$ firejail \-\-nosound firefox 1237$ firejail \-\-nosound firefox
1227 1238
1228.TP 1239.TP
1229\fB\-\-noautopulse
1230Disable automatic ~/.config/pulse init, for complex setups such as remote
1231pulse servers or non-standard socket paths.
1232.br
1233
1234.br
1235Example:
1236.br
1237$ firejail \-\-noautopulse firefox
1238
1239.TP
1240\fB\-\-notv 1240\fB\-\-notv
1241Disable DVB (Digital Video Broadcasting) TV devices. 1241Disable DVB (Digital Video Broadcasting) TV devices.
1242.br 1242.br
@@ -1316,6 +1316,16 @@ Example:
1316$ firejail \-\-overlay firefox 1316$ firejail \-\-overlay firefox
1317 1317
1318.TP 1318.TP
1319\fB\-\-overlay-clean
1320Clean all overlays stored in $HOME/.firejail directory.
1321.br
1322
1323.br
1324Example:
1325.br
1326$ firejail \-\-overlay-clean
1327
1328.TP
1319\fB\-\-overlay-named=name 1329\fB\-\-overlay-named=name
1320Mount a filesystem overlay on top of the current filesystem. Unlike the regular filesystem container, 1330Mount a filesystem overlay on top of the current filesystem. Unlike the regular filesystem container,
1321the system directories are mounted read-write. All filesystem modifications go into the overlay. 1331the system directories are mounted read-write. All filesystem modifications go into the overlay.
@@ -1354,16 +1364,6 @@ Example:
1354$ firejail \-\-overlay-tmpfs firefox 1364$ firejail \-\-overlay-tmpfs firefox
1355 1365
1356.TP 1366.TP
1357\fB\-\-overlay-clean
1358Clean all overlays stored in $HOME/.firejail directory.
1359.br
1360
1361.br
1362Example:
1363.br
1364$ firejail \-\-overlay-clean
1365
1366.TP
1367\fB\-\-private 1367\fB\-\-private
1368Mount new /root and /home/user directories in temporary 1368Mount new /root and /home/user directories in temporary
1369filesystems. All modifications are discarded when the sandbox is 1369filesystems. All modifications are discarded when the sandbox is
@@ -1374,6 +1374,7 @@ closed.
1374Example: 1374Example:
1375.br 1375.br
1376$ firejail \-\-private firefox 1376$ firejail \-\-private firefox
1377
1377.TP 1378.TP
1378\fB\-\-private=directory 1379\fB\-\-private=directory
1379Use directory as user home. 1380Use directory as user home.
@@ -1385,17 +1386,26 @@ Example:
1385$ firejail \-\-private=/home/netblue/firefox-home firefox 1386$ firejail \-\-private=/home/netblue/firefox-home firefox
1386 1387
1387.TP 1388.TP
1388\fB\-\-private-home=file,directory 1389\fB\-\-private-bin=file,file
1389Build a new user home in a temporary 1390Build a new /bin in a temporary filesystem, and copy the programs in the list.
1390filesystem, and copy the files and directories in the list in the 1391If no listed file is found, /bin directory will be empty.
1391new home. All modifications are discarded when the sandbox is 1392The same directory is also bind-mounted over /sbin, /usr/bin, /usr/sbin and /usr/local/bin.
1392closed. 1393All modifications are discarded when the sandbox is closed. File globbing is supported,
1394see \fBFILE GLOBBING\fR section for more details.
1393.br 1395.br
1394 1396
1395.br 1397.br
1396Example: 1398Example:
1397.br 1399.br
1398$ firejail \-\-private-home=.mozilla firefox 1400$ firejail \-\-private-bin=bash,sed,ls,cat
1401.br
1402Parent pid 20841, child pid 20842
1403.br
1404Child process initialized
1405.br
1406$ ls /bin
1407.br
1408bash cat ls sed
1399 1409
1400.TP 1410.TP
1401\fB\-\-private-cache 1411\fB\-\-private-cache
@@ -1409,26 +1419,51 @@ Example:
1409$ firejail \-\-private-cache openbox 1419$ firejail \-\-private-cache openbox
1410 1420
1411.TP 1421.TP
1412\fB\-\-private-bin=file,file 1422\fB\-\-private-dev
1413Build a new /bin in a temporary filesystem, and copy the programs in the list. 1423Create a new /dev directory. Only disc, dri, null, full, zero, tty, pts, ptmx, random, snd, urandom, video, log and shm devices are available.
1414If no listed file is found, /bin directory will be empty.
1415The same directory is also bind-mounted over /sbin, /usr/bin, /usr/sbin and /usr/local/bin.
1416All modifications are discarded when the sandbox is closed. File globbing is supported,
1417see \fBFILE GLOBBING\fR section for more details.
1418.br 1424.br
1419 1425
1420.br 1426.br
1421Example: 1427Example:
1422.br 1428.br
1423$ firejail \-\-private-bin=bash,sed,ls,cat 1429$ firejail \-\-private-dev
1424.br 1430.br
1425Parent pid 20841, child pid 20842 1431Parent pid 9887, child pid 9888
1426.br 1432.br
1427Child process initialized 1433Child process initialized
1428.br 1434.br
1429$ ls /bin 1435$ ls /dev
1436.br
1437cdrom cdrw dri dvd dvdrw full log null ptmx pts random shm snd sr0 tty urandom zero
1438.br
1439$
1440.TP
1441\fB\-\-private-etc=file,directory
1442Build a new /etc in a temporary
1443filesystem, and copy the files and directories in the list.
1444If no listed file is found, /etc directory will be empty.
1445All modifications are discarded when the sandbox is closed.
1430.br 1446.br
1431bash cat ls sed 1447
1448.br
1449Example:
1450.br
1451$ firejail --private-etc=group,hostname,localtime, \\
1452.br
1453nsswitch.conf,passwd,resolv.conf
1454
1455.TP
1456\fB\-\-private-home=file,directory
1457Build a new user home in a temporary
1458filesystem, and copy the files and directories in the list in the
1459new home. All modifications are discarded when the sandbox is
1460closed.
1461.br
1462
1463.br
1464Example:
1465.br
1466$ firejail \-\-private-home=.mozilla firefox
1432 1467
1433.TP 1468.TP
1434\fB\-\-private-lib=file,directory 1469\fB\-\-private-lib=file,directory
@@ -1480,41 +1515,6 @@ $ ps
1480$ 1515$
1481.br 1516.br
1482 1517
1483
1484.TP
1485\fB\-\-private-dev
1486Create a new /dev directory. Only disc, dri, null, full, zero, tty, pts, ptmx, random, snd, urandom, video, log and shm devices are available.
1487.br
1488
1489.br
1490Example:
1491.br
1492$ firejail \-\-private-dev
1493.br
1494Parent pid 9887, child pid 9888
1495.br
1496Child process initialized
1497.br
1498$ ls /dev
1499.br
1500cdrom cdrw dri dvd dvdrw full log null ptmx pts random shm snd sr0 tty urandom zero
1501.br
1502$
1503.TP
1504\fB\-\-private-etc=file,directory
1505Build a new /etc in a temporary
1506filesystem, and copy the files and directories in the list.
1507If no listed file is found, /etc directory will be empty.
1508All modifications are discarded when the sandbox is closed.
1509.br
1510
1511.br
1512Example:
1513.br
1514$ firejail --private-etc=group,hostname,localtime, \\
1515.br
1516nsswitch.conf,passwd,resolv.conf
1517
1518.TP 1518.TP
1519\fB\-\-private-opt=file,directory 1519\fB\-\-private-opt=file,directory
1520Build a new /opt in a temporary 1520Build a new /opt in a temporary
@@ -1637,16 +1637,6 @@ Example:
1637.br 1637.br
1638$ firejail \-\-read-only=~/.mozilla firefox 1638$ firejail \-\-read-only=~/.mozilla firefox
1639.br 1639.br
1640
1641.br
1642A short note about mixing \-\-whitelist and \-\-read-only options. Whitelisted directories
1643should be made read-only independently. Making a parent directory read-only, will not
1644make the whitelist read-only. Example:
1645.br
1646
1647.br
1648$ firejail --whitelist=~/work --read-only=~ --read-only=~/work
1649
1650.TP 1640.TP
1651\fB\-\-read-write=dirname_or_filename 1641\fB\-\-read-write=dirname_or_filename
1652Set directory or file read-write. Only files or directories belonging to the current user are allowed for 1642Set directory or file read-write. Only files or directories belonging to the current user are allowed for
@@ -2210,7 +2200,7 @@ $ firejail \-\-net=br0 --veth-name=if0
2210Whitelist directory or file. A temporary file system is mounted on the top directory, and the 2200Whitelist directory or file. A temporary file system is mounted on the top directory, and the
2211whitelisted files are mount-binded inside. Modifications to whitelisted files are persistent, 2201whitelisted files are mount-binded inside. Modifications to whitelisted files are persistent,
2212everything else is discarded when the sandbox is closed. The top directory could be 2202everything else is discarded when the sandbox is closed. The top directory could be
2213user home, /dev, /etc, /media, /mnt, /opt, /srv, /sys/module, /usr/share, /var, and /tmp. 2203user home, /dev, /etc, /media, /mnt, /opt, /run/user/$UID, /srv, /sys/module, /tmp, /usr/share and /var.
2214.br 2204.br
2215 2205
2216.br 2206.br
@@ -2430,6 +2420,69 @@ Example:
2430$ firejail --net=eth0 --x11=xephyr --xephyr-screen=640x480 firefox 2420$ firejail --net=eth0 --x11=xephyr --xephyr-screen=640x480 firefox
2431.br 2421.br
2432 2422
2423.SH APPARMOR
2424.TP
2425AppArmor support is disabled by default at compile time. Use --enable-apparmor configuration option to enable it:
2426.br
2427
2428.br
2429$ ./configure --prefix=/usr --enable-apparmor
2430.TP
2431During software install, a generic AppArmor profile file, firejail-default, is placed in /etc/apparmor.d directory. The local customizations must be placed in /etc/apparmor.d/local/firejail-local. The profile needs to be loaded into the kernel by reloading apparmor.service, rebooting the system or running the following command as root:
2432.br
2433
2434.br
2435# apparmor_parser -r /etc/apparmor.d/firejail-default
2436.TP
2437The installed profile is supplemental for main firejail functions and among other things does the following:
2438.br
2439
2440.br
2441- Disable ptrace. With ptrace it is possible to inspect and hijack running programs. Usually this is needed only for debugging. You should have no problems running Chromium or Firefox. This feature is available only on Ubuntu kernels.
2442.br
2443
2444.br
2445- Whitelist write access to several files under /run, /proc and /sys.
2446.br
2447
2448.br
2449- Allow running programs only from well-known system paths, such as /bin, /sbin, /usr/bin etc. Those paths are available as read-only. Running programs and scripts from user home or other directories writable by the user is not allowed.
2450.br
2451
2452.br
2453- Prevent using non-standard network sockets. Only unix, inet, inet6, netlink, raw and packet are allowed.
2454.br
2455
2456.br
2457- Deny access to known sensitive paths like .snapshots.
2458
2459.TP
2460To enable AppArmor confinement on top of your current Firejail security features, pass \fB\-\-apparmor\fR flag to Firejail command line. You can also include \fBapparmor\fR command in a Firejail profile file. Example:
2461.br
2462
2463.br
2464$ firejail --apparmor firefox
2465
2466.SH AUDIT
2467Audit feature allows the user to point out gaps in security profiles. The
2468implementation replaces the program to be sandboxed with a test program. By
2469default, we use faudit program distributed with Firejail. A custom test program
2470can also be supplied by the user. Examples:
2471
2472Running the default audit program:
2473.br
2474 $ firejail --audit transmission-gtk
2475
2476Running a custom audit program:
2477.br
2478 $ firejail --audit=~/sandbox-test transmission-gtk
2479
2480In the examples above, the sandbox configures transmission-gtk profile and
2481starts the test program. The real program, transmission-gtk, will not be
2482started.
2483
2484Limitations: audit feature is not implemented for --x11 commands.
2485
2433.SH DESKTOP INTEGRATION 2486.SH DESKTOP INTEGRATION
2434A symbolic link to /usr/bin/firejail under the name of a program, will start the program in Firejail sandbox. 2487A symbolic link to /usr/bin/firejail under the name of a program, will start the program in Firejail sandbox.
2435The symbolic link should be placed in the first $PATH position. On most systems, a good place 2488The symbolic link should be placed in the first $PATH position. On most systems, a good place
@@ -2485,6 +2538,35 @@ $ firejail --tree
2485 2538
2486We provide a tool that automates all this integration, please see \fBman 1 firecfg\fR for more details. 2539We provide a tool that automates all this integration, please see \fBman 1 firecfg\fR for more details.
2487 2540
2541.SH EXAMPLES
2542.TP
2543\f\firejail
2544Sandbox a regular /bin/bash session.
2545.TP
2546\f\firejail firefox
2547Start Mozilla Firefox.
2548.TP
2549\f\firejail \-\-debug firefox
2550Debug Firefox sandbox.
2551.TP
2552\f\firejail \-\-private firefox
2553Start Firefox with a new, empty home directory.
2554.TP
2555\f\firejail --net=none vlc
2556Start VLC in an unconnected network namespace.
2557.TP
2558\f\firejail \-\-net=eth0 firefox
2559Start Firefox in a new network namespace. An IP address is
2560assigned automatically.
2561.TP
2562\f\firejail \-\-net=br0 \-\-ip=10.10.20.5 \-\-net=br1 \-\-net=br2
2563Start a /bin/bash session in a new network namespace and connect it
2564to br0, br1, and br2 host bridge devices. IP addresses are assigned
2565automatically for the interfaces connected to br1 and b2
2566.TP
2567\f\firejail \-\-list
2568List all sandboxed processes.
2569
2488.SH FILE GLOBBING 2570.SH FILE GLOBBING
2489.TP 2571.TP
2490Globbing is the operation that expands a wildcard pattern into the list of pathnames matching the pattern. Matching is defined by: 2572Globbing is the operation that expands a wildcard pattern into the list of pathnames matching the pattern. Matching is defined by:
@@ -2519,49 +2601,6 @@ $ firejail --blacklist=~/dir[1234]
2519$ firejail --read-only=~/dir[1-4] 2601$ firejail --read-only=~/dir[1-4]
2520.br 2602.br
2521 2603
2522.SH APPARMOR
2523.TP
2524AppArmor support is disabled by default at compile time. Use --enable-apparmor configuration option to enable it:
2525.br
2526
2527.br
2528$ ./configure --prefix=/usr --enable-apparmor
2529.TP
2530During software install, a generic AppArmor profile file, firejail-default, is placed in /etc/apparmor.d directory. The local customizations must be placed in /etc/apparmor.d/local/firejail-local. The profile needs to be loaded into the kernel by reloading apparmor.service, rebooting the system or running the following command as root:
2531.br
2532
2533.br
2534# apparmor_parser -r /etc/apparmor.d/firejail-default
2535.TP
2536The installed profile is supplemental for main firejail functions and among other things does the following:
2537.br
2538
2539.br
2540- Disable ptrace. With ptrace it is possible to inspect and hijack running programs. Usually this is needed only for debugging. You should have no problems running Chromium or Firefox. This feature is available only on Ubuntu kernels.
2541.br
2542
2543.br
2544- Whitelist write access to several files under /run, /proc and /sys.
2545.br
2546
2547.br
2548- Allow running programs only from well-known system paths, such as /bin, /sbin, /usr/bin etc. Those paths are available as read-only. Running programs and scripts from user home or other directories writable by the user is not allowed.
2549.br
2550
2551.br
2552- Prevent using non-standard network sockets. Only unix, inet, inet6, netlink, raw and packet are allowed.
2553.br
2554
2555.br
2556- Deny access to known sensitive paths like .snapshots.
2557
2558.TP
2559To enable AppArmor confinement on top of your current Firejail security features, pass \fB\-\-apparmor\fR flag to Firejail command line. You can also include \fBapparmor\fR command in a Firejail profile file. Example:
2560.br
2561
2562.br
2563$ firejail --apparmor firefox
2564
2565.SH FILE TRANSFER 2604.SH FILE TRANSFER
2566These features allow the user to inspect the filesystem container of an existing sandbox 2605These features allow the user to inspect the filesystem container of an existing sandbox
2567and transfer files from the container to the host filesystem. 2606and transfer files from the container to the host filesystem.
@@ -2610,68 +2649,6 @@ $ firejail \-\-get=mybrowser ~/Downloads/xpra-clipboard.png
2610$ firejail \-\-put=mybrowser xpra-clipboard.png ~/Downloads/xpra-clipboard.png 2649$ firejail \-\-put=mybrowser xpra-clipboard.png ~/Downloads/xpra-clipboard.png
2611.br 2650.br
2612 2651
2613.SH TRAFFIC SHAPING
2614Network bandwidth is an expensive resource shared among all sandboxes running on a system.
2615Traffic shaping allows the user to increase network performance by controlling
2616the amount of data that flows into and out of the sandboxes.
2617
2618Firejail implements a simple rate-limiting shaper based on Linux command tc.
2619The shaper works at sandbox level, and can be used only for sandboxes configured with new network namespaces.
2620
2621Set rate-limits:
2622
2623 $ firejail --bandwidth=name|pid set network download upload
2624
2625Clear rate-limits:
2626
2627 $ firejail --bandwidth=name|pid clear network
2628
2629Status:
2630
2631 $ firejail --bandwidth=name|pid status
2632
2633where:
2634.br
2635 name - sandbox name
2636.br
2637 pid - sandbox pid
2638.br
2639 network - network interface as used by \-\-net option
2640.br
2641 download - download speed in KB/s (kilobyte per second)
2642.br
2643 upload - upload speed in KB/s (kilobyte per second)
2644
2645Example:
2646.br
2647 $ firejail \-\-name=mybrowser \-\-net=eth0 firefox &
2648.br
2649 $ firejail \-\-bandwidth=mybrowser set eth0 80 20
2650.br
2651 $ firejail \-\-bandwidth=mybrowser status
2652.br
2653 $ firejail \-\-bandwidth=mybrowser clear eth0
2654
2655.SH AUDIT
2656Audit feature allows the user to point out gaps in security profiles. The
2657implementation replaces the program to be sandboxed with a test program. By
2658default, we use faudit program distributed with Firejail. A custom test program
2659can also be supplied by the user. Examples:
2660
2661Running the default audit program:
2662.br
2663 $ firejail --audit transmission-gtk
2664
2665Running a custom audit program:
2666.br
2667 $ firejail --audit=~/sandbox-test transmission-gtk
2668
2669In the examples above, the sandbox configures transmission-gtk profile and
2670starts the test program. The real program, transmission-gtk, will not be
2671started.
2672
2673Limitations: audit feature is not implemented for --x11 commands.
2674
2675.SH MONITORING 2652.SH MONITORING
2676Option \-\-list prints a list of all sandboxes. The format 2653Option \-\-list prints a list of all sandboxes. The format
2677for each process entry is as follows: 2654for each process entry is as follows:
@@ -2807,34 +2784,48 @@ adduser \-\-shell /usr/bin/firejail username
2807 2784
2808Additional arguments passed to firejail executable upon login are declared in /etc/firejail/login.users file. 2785Additional arguments passed to firejail executable upon login are declared in /etc/firejail/login.users file.
2809 2786
2810.SH EXAMPLES 2787.SH TRAFFIC SHAPING
2811.TP 2788Network bandwidth is an expensive resource shared among all sandboxes running on a system.
2812\f\firejail 2789Traffic shaping allows the user to increase network performance by controlling
2813Sandbox a regular /bin/bash session. 2790the amount of data that flows into and out of the sandboxes.
2814.TP 2791
2815\f\firejail firefox 2792Firejail implements a simple rate-limiting shaper based on Linux command tc.
2816Start Mozilla Firefox. 2793The shaper works at sandbox level, and can be used only for sandboxes configured with new network namespaces.
2817.TP 2794
2818\f\firejail \-\-debug firefox 2795Set rate-limits:
2819Debug Firefox sandbox. 2796
2820.TP 2797 $ firejail --bandwidth=name|pid set network download upload
2821\f\firejail \-\-private firefox 2798
2822Start Firefox with a new, empty home directory. 2799Clear rate-limits:
2823.TP 2800
2824\f\firejail --net=none vlc 2801 $ firejail --bandwidth=name|pid clear network
2825Start VLC in an unconnected network namespace. 2802
2826.TP 2803Status:
2827\f\firejail \-\-net=eth0 firefox 2804
2828Start Firefox in a new network namespace. An IP address is 2805 $ firejail --bandwidth=name|pid status
2829assigned automatically. 2806
2830.TP 2807where:
2831\f\firejail \-\-net=br0 \-\-ip=10.10.20.5 \-\-net=br1 \-\-net=br2 2808.br
2832Start a /bin/bash session in a new network namespace and connect it 2809 name - sandbox name
2833to br0, br1, and br2 host bridge devices. IP addresses are assigned 2810.br
2834automatically for the interfaces connected to br1 and b2 2811 pid - sandbox pid
2835.TP 2812.br
2836\f\firejail \-\-list 2813 network - network interface as used by \-\-net option
2837List all sandboxed processes. 2814.br
2815 download - download speed in KB/s (kilobyte per second)
2816.br
2817 upload - upload speed in KB/s (kilobyte per second)
2818
2819Example:
2820.br
2821 $ firejail \-\-name=mybrowser \-\-net=eth0 firefox &
2822.br
2823 $ firejail \-\-bandwidth=mybrowser set eth0 80 20
2824.br
2825 $ firejail \-\-bandwidth=mybrowser status
2826.br
2827 $ firejail \-\-bandwidth=mybrowser clear eth0
2828
2838.SH LICENSE 2829.SH LICENSE
2839This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 2830This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
2840.PP 2831.PP