diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/firecfg/firecfg.config | 61 | ||||
-rw-r--r-- | src/firejail/firejail.h | 2 | ||||
-rw-r--r-- | src/firejail/fs_dev.c | 2 | ||||
-rw-r--r-- | src/firejail/fs_home.c | 12 | ||||
-rw-r--r-- | src/firejail/fs_var.c | 18 | ||||
-rw-r--r-- | src/firejail/fs_whitelist.c | 118 | ||||
-rw-r--r-- | src/firejail/preproc.c | 2 | ||||
-rw-r--r-- | src/firejail/profile.c | 7 | ||||
-rw-r--r-- | src/firejail/restrict_users.c | 10 | ||||
-rw-r--r-- | src/firejail/util.c | 7 | ||||
-rw-r--r-- | src/firejail/x11.c | 4 | ||||
-rw-r--r-- | src/fseccomp/seccomp.c | 8 | ||||
-rw-r--r-- | src/man/firejail.txt | 511 |
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 |
6 | 0ad | 5 | 0ad |
7 | 2048-qt | 6 | 2048-qt |
7 | Cryptocat | ||
8 | Cyberfox | 8 | Cyberfox |
9 | Discord | 9 | Discord |
10 | DiscordCanary | 10 | DiscordCanary |
11 | FossaMail | 11 | FossaMail |
12 | Fritzing | 12 | Fritzing |
13 | Gitter | ||
13 | JDownloader | 14 | JDownloader |
14 | Mathematica | 15 | Mathematica |
15 | Natron | 16 | Natron |
@@ -33,13 +34,14 @@ archaudit-report | |||
33 | ardour4 | 34 | ardour4 |
34 | ardour5 | 35 | ardour5 |
35 | arduino | 36 | arduino |
37 | aria2c | ||
36 | ark | 38 | ark |
37 | arm | 39 | arm |
38 | artha | 40 | artha |
39 | # atom | ||
40 | # atom-beta | ||
41 | assogiate | 41 | assogiate |
42 | asunder | 42 | asunder |
43 | # atom | ||
44 | # atom-beta | ||
43 | atool | 45 | atool |
44 | atril | 46 | atril |
45 | atril-previewer | 47 | atril-previewer |
@@ -54,6 +56,7 @@ baobab | |||
54 | basilisk | 56 | basilisk |
55 | beaker | 57 | beaker |
56 | bibletime | 58 | bibletime |
59 | bitcoin-qt | ||
57 | bitlbee | 60 | bitlbee |
58 | bleachbit | 61 | bleachbit |
59 | blender | 62 | blender |
@@ -76,6 +79,8 @@ calligrasheets | |||
76 | calligrastage | 79 | calligrastage |
77 | calligrawords | 80 | calligrawords |
78 | catfish | 81 | catfish |
82 | celluloid | ||
83 | checkbashisms | ||
79 | cherrytree | 84 | cherrytree |
80 | chromium | 85 | chromium |
81 | chromium-browser | 86 | chromium-browser |
@@ -88,20 +93,24 @@ clamtk | |||
88 | claws-mail | 93 | claws-mail |
89 | clawsker | 94 | clawsker |
90 | clementine | 95 | clementine |
96 | clion | ||
91 | clipit | 97 | clipit |
92 | cliqz | 98 | cliqz |
93 | cmus | 99 | cmus |
94 | code | 100 | code |
101 | code-oss | ||
95 | conkeror | 102 | conkeror |
96 | conky | 103 | conky |
97 | corebird | 104 | corebird |
98 | crow | 105 | crow |
106 | cryptocat | ||
99 | cvlc | 107 | cvlc |
100 | cyberfox | 108 | cyberfox |
101 | darktable | 109 | darktable |
102 | dconf-editor | 110 | dconf-editor |
103 | deadbeef | 111 | deadbeef |
104 | deluge | 112 | deluge |
113 | devhelp | ||
105 | dex2jar | 114 | dex2jar |
106 | dia | 115 | dia |
107 | dig | 116 | dig |
@@ -120,6 +129,7 @@ dooble-qt4 | |||
120 | dosbox | 129 | dosbox |
121 | dragon | 130 | dragon |
122 | dropbox | 131 | dropbox |
132 | d-feet | ||
123 | easystroke | 133 | easystroke |
124 | ebook-viewer | 134 | ebook-viewer |
125 | electrum | 135 | electrum |
@@ -147,9 +157,13 @@ fbreader | |||
147 | feedreader | 157 | feedreader |
148 | feh | 158 | feh |
149 | ffmpeg | 159 | ffmpeg |
160 | ffmpegthumbnailer | ||
161 | ffplay | ||
162 | ffprobe | ||
150 | file-roller | 163 | file-roller |
151 | filezilla | 164 | filezilla |
152 | firefox | 165 | firefox |
166 | firefox-beta | ||
153 | firefox-developer-edition | 167 | firefox-developer-edition |
154 | firefox-esr | 168 | firefox-esr |
155 | firefox-nightly | 169 | firefox-nightly |
@@ -159,18 +173,22 @@ flashpeak-slimjet | |||
159 | flowblade | 173 | flowblade |
160 | font-manager | 174 | font-manager |
161 | fontforge | 175 | fontforge |
176 | fossamail | ||
162 | franz | 177 | franz |
163 | freecad | 178 | freecad |
164 | freecadcmd | 179 | freecadcmd |
165 | freshclam | 180 | freshclam |
166 | frozen-bubble | 181 | frozen-bubble |
167 | gajim | 182 | gajim |
183 | gajim-history-manager | ||
168 | galculator | 184 | galculator |
185 | gcalccmd | ||
169 | gcloud | 186 | gcloud |
170 | gconf-editor | 187 | gconf-editor |
171 | geany | 188 | geany |
172 | geary | 189 | geary |
173 | gedit | 190 | gedit |
191 | geekbench | ||
174 | geeqie | 192 | geeqie |
175 | ghb | 193 | ghb |
176 | ghostwriter | 194 | ghostwriter |
@@ -183,8 +201,8 @@ gitter | |||
183 | gjs | 201 | gjs |
184 | globaltime | 202 | globaltime |
185 | gnome-2048 | 203 | gnome-2048 |
186 | gnome-builder | ||
187 | gnome-books | 204 | gnome-books |
205 | gnome-builder | ||
188 | gnome-calculator | 206 | gnome-calculator |
189 | gnome-chess | 207 | gnome-chess |
190 | gnome-clocks | 208 | gnome-clocks |
@@ -196,8 +214,11 @@ gnome-maps | |||
196 | gnome-mplayer | 214 | gnome-mplayer |
197 | gnome-mpv | 215 | gnome-mpv |
198 | gnome-music | 216 | gnome-music |
217 | gnome-nettool | ||
199 | gnome-photos | 218 | gnome-photos |
200 | gnome-recipes | 219 | gnome-recipes |
220 | gnome-schedule | ||
221 | gnome-system-log | ||
201 | gnome-twitch | 222 | gnome-twitch |
202 | gnome-weather | 223 | gnome-weather |
203 | goobox | 224 | goobox |
@@ -284,6 +305,7 @@ lximage-qt | |||
284 | lxmusic | 305 | lxmusic |
285 | lynx | 306 | lynx |
286 | macrofusion | 307 | macrofusion |
308 | masterpdfeditor | ||
287 | masterpdfeditor4 | 309 | masterpdfeditor4 |
288 | masterpdfeditor5 | 310 | masterpdfeditor5 |
289 | mate-calc | 311 | mate-calc |
@@ -295,6 +317,7 @@ mcabber | |||
295 | mediainfo | 317 | mediainfo |
296 | mediathekview | 318 | mediathekview |
297 | meld | 319 | meld |
320 | mencoder | ||
298 | mendeleydesktop | 321 | mendeleydesktop |
299 | midori | 322 | midori |
300 | min | 323 | min |
@@ -321,12 +344,17 @@ mutt | |||
321 | mypaint | 344 | mypaint |
322 | mypaint-ora-thumbnailer | 345 | mypaint-ora-thumbnailer |
323 | natron | 346 | natron |
324 | #nautilus - removed in order to let the application start in a new sandbox when clicking on icons in the file manager | ||
325 | ncdu | 347 | ncdu |
348 | netactview | ||
349 | nethack | ||
326 | netsurf | 350 | netsurf |
327 | neverball | 351 | neverball |
328 | nheko | 352 | nheko |
329 | nitroshare | 353 | nitroshare |
354 | nitroshare-cli | ||
355 | nitroshare-nmh | ||
356 | nitroshare-send | ||
357 | nitroshare-ui | ||
330 | nylas | 358 | nylas |
331 | nyx | 359 | nyx |
332 | obs | 360 | obs |
@@ -343,6 +371,7 @@ orage | |||
343 | palemoon | 371 | palemoon |
344 | parole | 372 | parole |
345 | patch | 373 | patch |
374 | pavucontrol | ||
346 | pdfchain | 375 | pdfchain |
347 | pdfmod | 376 | pdfmod |
348 | pdfsam | 377 | pdfsam |
@@ -360,6 +389,7 @@ playonlinux | |||
360 | pluma | 389 | pluma |
361 | polari | 390 | polari |
362 | ppsspp | 391 | ppsspp |
392 | pragha | ||
363 | psi-plus | 393 | psi-plus |
364 | pybitmessage | 394 | pybitmessage |
365 | # pycharm-community - FB note: may enable later | 395 | # pycharm-community - FB note: may enable later |
@@ -369,6 +399,7 @@ qemu-launcher | |||
369 | qlipper | 399 | qlipper |
370 | qmmp | 400 | qmmp |
371 | qpdfview | 401 | qpdfview |
402 | qt-faststart | ||
372 | qtox | 403 | qtox |
373 | quassel | 404 | quassel |
374 | quiterss | 405 | quiterss |
@@ -376,6 +407,8 @@ qupzilla | |||
376 | qutebrowser | 407 | qutebrowser |
377 | rambox | 408 | rambox |
378 | redeclipse | 409 | redeclipse |
410 | redshift | ||
411 | regextester | ||
379 | remmina | 412 | remmina |
380 | rhythmbox | 413 | rhythmbox |
381 | ricochet | 414 | ricochet |
@@ -389,13 +422,17 @@ sayonara | |||
389 | scallion | 422 | scallion |
390 | scribus | 423 | scribus |
391 | sdat2img | 424 | sdat2img |
425 | seahorse | ||
426 | seahorse-tool | ||
392 | seamonkey | 427 | seamonkey |
393 | seamonkey-bin | 428 | seamonkey-bin |
429 | secret-tool | ||
394 | shellcheck | 430 | shellcheck |
395 | shotcut | 431 | shotcut |
396 | signal-desktop | 432 | signal-desktop |
397 | silentarmy | 433 | silentarmy |
398 | simple-scan | 434 | simple-scan |
435 | simplescreenrecorder | ||
399 | simutrans | 436 | simutrans |
400 | skanlite | 437 | skanlite |
401 | skype | 438 | skype |
@@ -403,8 +440,9 @@ skypeforlinux | |||
403 | slack | 440 | slack |
404 | smplayer | 441 | smplayer |
405 | smtube | 442 | smtube |
406 | sol | 443 | snox |
407 | soffice | 444 | soffice |
445 | sol | ||
408 | soundconverter | 446 | soundconverter |
409 | spotify | 447 | spotify |
410 | sqlitebrowser | 448 | sqlitebrowser |
@@ -416,12 +454,15 @@ steam | |||
416 | steam-native | 454 | steam-native |
417 | stellarium | 455 | stellarium |
418 | strings | 456 | strings |
457 | studio.sh | ||
419 | subdownloader | 458 | subdownloader |
420 | supertux2 | 459 | supertux2 |
421 | supertuxkart | 460 | supertuxkart |
422 | surf | 461 | surf |
423 | sylpheed | 462 | sylpheed |
424 | synfigstudio | 463 | synfigstudio |
464 | sysprof | ||
465 | sysprof-cli | ||
425 | teamspeak3 | 466 | teamspeak3 |
426 | telegram | 467 | telegram |
427 | telegram-desktop | 468 | telegram-desktop |
@@ -464,9 +505,16 @@ tor-browser-zh-tw | |||
464 | torbrowser-launcher | 505 | torbrowser-launcher |
465 | totem | 506 | totem |
466 | tracker | 507 | tracker |
508 | transgui | ||
467 | transmission-cli | 509 | transmission-cli |
510 | transmission-create | ||
511 | transmission-daemon | ||
512 | transmission-edit | ||
468 | transmission-gtk | 513 | transmission-gtk |
469 | transmission-qt | 514 | transmission-qt |
515 | transmission-remote | ||
516 | transmission-remote-cli | ||
517 | transmission-remote-gtk | ||
470 | transmission-show | 518 | transmission-show |
471 | truecraft | 519 | truecraft |
472 | tuxguitar | 520 | tuxguitar |
@@ -505,6 +553,7 @@ xchat | |||
505 | xed | 553 | xed |
506 | xfburn | 554 | xfburn |
507 | xfce4-dict | 555 | xfce4-dict |
556 | xfce4-mixer | ||
508 | xfce4-notes | 557 | xfce4-notes |
509 | xiphos | 558 | xiphos |
510 | xmms | 559 | xmms |
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 | ||
216 | typedef struct config_t { | 218 | typedef 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 | ||
37 | static size_t homedir_len; // cache length of homedir string | 36 | static size_t homedir_len; // cache length of homedir string |
37 | static size_t runuser_len; // cache length of runuser string | ||
38 | static char *runuser; | ||
38 | 39 | ||
39 | 40 | ||
40 | static int mkpath(const char* path, mode_t mode) { | 41 | static 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 | ||
1017 | errexit: | 1067 | errexit: |
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 |
243 | int profile_check_line(char *ptr, int lineno, const char *fname) { | 243 | int 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 | ||
1269 | int has_handler(pid_t pid, int signal) { | 1264 | int 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 |
100 | Enable AppArmor confinement. For more information, please see \fBAPPARMOR\fR section below. | 100 | Enable AppArmor confinement. For more information, please see \fBAPPARMOR\fR section below. |
101 | .TP | 101 | .TP |
102 | \fB\-\-appimage | 102 | \fB\-\-apparmor.print=name|pid |
103 | Sandbox an AppImage (https://appimage.org/) application. If the sandbox is started | 103 | Print the AppArmor confinement status for the sandbox identified by name or by PID. |
104 | as a regular user, nonewprivs and a default capabilities filter are enabled. | ||
105 | .br | 104 | .br |
106 | 105 | ||
107 | .br | 106 | .br |
108 | Example: | 107 | Example: |
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 | 111 | 5074: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 |
118 | Print the AppArmor confinement status for the sandbox identified by name or by PID. | 117 | Sandbox an AppImage (https://appimage.org/) application. If the sandbox is started |
118 | as a regular user, nonewprivs and a default capabilities filter are enabled. | ||
119 | .br | 119 | .br |
120 | 120 | ||
121 | .br | 121 | .br |
122 | Example: | 122 | Example: |
123 | .br | 123 | .br |
124 | $ firejail \-\-apparmor.print=browser | 124 | $ firejail --appimage krita-3.0-x86_64.appimage |
125 | .br | 125 | .br |
126 | 5074: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 | ||
705 | List files in sandbox container, see \fBFILE TRANSFER\fR section for more details. | ||
706 | |||
707 | .TP | ||
708 | \fB\-\-list | 704 | \fB\-\-list |
709 | List all sandboxes, see \fBMONITORING\fR section for more details. | 705 | List all sandboxes, see \fBMONITORING\fR section for more details. |
710 | .br | 706 | .br |
@@ -720,7 +716,10 @@ $ firejail \-\-list | |||
720 | .br | 716 | .br |
721 | 7064:netblue::firejail \-\-noroot xterm | 717 | 7064:netblue::firejail \-\-noroot xterm |
722 | .br | 718 | .br |
723 | $ | 719 | .TP |
720 | \fB\-\-ls=name|pid dir_or_filename | ||
721 | List 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 |
726 | Assign MAC addresses to the last network interface defined by a \-\-net option. This option | 725 | Assign 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 |
737 | Spoof id number in /etc/machine-id file - a new random id is generated inside the sandbox. | 736 | Spoof id number in /etc/machine-id file - a new random id is generated inside the sandbox. |
737 | Note 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 | |||
747 | Install a seccomp filter to block attempts to create memory mappings | 747 | Install a seccomp filter to block attempts to create memory mappings |
748 | that are both writable and executable, to change mappings to be | 748 | that are both writable and executable, to change mappings to be |
749 | executable, or to create executable shared memory. The filter examines | 749 | executable, or to create executable shared memory. The filter examines |
750 | the arguments of mmap, mmap2, mprotect, pkey_mprotect and shmat system | 750 | the arguments of mmap, mmap2, mprotect, pkey_mprotect, memfd_create and |
751 | calls and kills the process if necessary. | 751 | shmat 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 | ||
818 | Enable a new, unconnected network namespace. The only interface | ||
819 | available in the new namespace is a new loopback interface (lo). | ||
820 | Use this option to deny | ||
821 | network access to programs that don't really need network access. | ||
822 | .br | ||
823 | |||
824 | .br | ||
825 | Example: | ||
826 | .br | ||
827 | $ firejail \-\-net=none vlc | ||
828 | .br | ||
829 | |||
830 | .br | ||
831 | Note: \-\-net=none can crash the application on some platforms. | ||
832 | In 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 |
818 | Enable a new network namespace and connect it | 836 | Enable a new network namespace and connect it |
819 | to this ethernet interface using the standard Linux macvlan|ipvaln | 837 | to 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 | ||
851 | Enable a new, unconnected network namespace. The only interface | ||
852 | available in the new namespace is a new loopback interface (lo). | ||
853 | Use this option to deny | ||
854 | network access to programs that don't really need network access. | ||
855 | .br | ||
856 | |||
857 | .br | ||
858 | Example: | ||
859 | .br | ||
860 | $ firejail \-\-net=none vlc | ||
861 | .br | ||
862 | |||
863 | .br | ||
864 | Note: \-\-net=none can crash the application on some platforms. | ||
865 | In these cases, it can be replaced with \-\-protocol=unix. | ||
866 | |||
867 | .TP | ||
868 | \fB\-\-net.print=name|pid | 868 | \fB\-\-net.print=name|pid |
869 | If a new network namespace is enabled, print network interface configuration for the sandbox specified by name or PID. Example: | 869 | If 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 | ||
1071 | Disable automatic ~/.config/pulse init, for complex setups such as remote | ||
1072 | pulse servers or non-standard socket paths. | ||
1073 | .br | ||
1074 | |||
1075 | .br | ||
1076 | Example: | ||
1077 | .br | ||
1078 | $ firejail \-\-noautopulse firefox | ||
1079 | |||
1080 | .TP | ||
1070 | \fB\-\-noblacklist=dirname_or_filename | 1081 | \fB\-\-noblacklist=dirname_or_filename |
1071 | Disable blacklist for this directory or file. | 1082 | Disable 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 | ||
1171 | Sets the NO_NEW_PRIVS prctl. This ensures that child processes | ||
1172 | cannot acquire new privileges using execve(2); in particular, | ||
1173 | this means that calling a suid binary (or one with file capabilities) | ||
1174 | does not result in an increase of privilege. This option | ||
1175 | is enabled by default if seccomp filter is activated. | ||
1176 | |||
1177 | .TP | ||
1159 | \fB\-\-noprofile | 1178 | \fB\-\-noprofile |
1160 | Do not use a security profile. | 1179 | Do 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 | ||
1212 | Sets the NO_NEW_PRIVS prctl. This ensures that child processes | ||
1213 | cannot acquire new privileges using execve(2); in particular, | ||
1214 | this means that calling a suid binary (or one with file capabilities) | ||
1215 | does not result in an increase of privilege. This option | ||
1216 | is enabled by default if seccomp filter is activated. | ||
1217 | |||
1218 | .TP | ||
1219 | \fB\-\-nosound | 1230 | \fB\-\-nosound |
1220 | Disable sound system. | 1231 | Disable 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 | ||
1230 | Disable automatic ~/.config/pulse init, for complex setups such as remote | ||
1231 | pulse servers or non-standard socket paths. | ||
1232 | .br | ||
1233 | |||
1234 | .br | ||
1235 | Example: | ||
1236 | .br | ||
1237 | $ firejail \-\-noautopulse firefox | ||
1238 | |||
1239 | .TP | ||
1240 | \fB\-\-notv | 1240 | \fB\-\-notv |
1241 | Disable DVB (Digital Video Broadcasting) TV devices. | 1241 | Disable 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 | ||
1320 | Clean all overlays stored in $HOME/.firejail directory. | ||
1321 | .br | ||
1322 | |||
1323 | .br | ||
1324 | Example: | ||
1325 | .br | ||
1326 | $ firejail \-\-overlay-clean | ||
1327 | |||
1328 | .TP | ||
1319 | \fB\-\-overlay-named=name | 1329 | \fB\-\-overlay-named=name |
1320 | Mount a filesystem overlay on top of the current filesystem. Unlike the regular filesystem container, | 1330 | Mount a filesystem overlay on top of the current filesystem. Unlike the regular filesystem container, |
1321 | the system directories are mounted read-write. All filesystem modifications go into the overlay. | 1331 | the 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 | ||
1358 | Clean all overlays stored in $HOME/.firejail directory. | ||
1359 | .br | ||
1360 | |||
1361 | .br | ||
1362 | Example: | ||
1363 | .br | ||
1364 | $ firejail \-\-overlay-clean | ||
1365 | |||
1366 | .TP | ||
1367 | \fB\-\-private | 1367 | \fB\-\-private |
1368 | Mount new /root and /home/user directories in temporary | 1368 | Mount new /root and /home/user directories in temporary |
1369 | filesystems. All modifications are discarded when the sandbox is | 1369 | filesystems. All modifications are discarded when the sandbox is |
@@ -1374,6 +1374,7 @@ closed. | |||
1374 | Example: | 1374 | Example: |
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 |
1379 | Use directory as user home. | 1380 | Use 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 |
1389 | Build a new user home in a temporary | 1390 | Build a new /bin in a temporary filesystem, and copy the programs in the list. |
1390 | filesystem, and copy the files and directories in the list in the | 1391 | If no listed file is found, /bin directory will be empty. |
1391 | new home. All modifications are discarded when the sandbox is | 1392 | The same directory is also bind-mounted over /sbin, /usr/bin, /usr/sbin and /usr/local/bin. |
1392 | closed. | 1393 | All modifications are discarded when the sandbox is closed. File globbing is supported, |
1394 | see \fBFILE GLOBBING\fR section for more details. | ||
1393 | .br | 1395 | .br |
1394 | 1396 | ||
1395 | .br | 1397 | .br |
1396 | Example: | 1398 | Example: |
1397 | .br | 1399 | .br |
1398 | $ firejail \-\-private-home=.mozilla firefox | 1400 | $ firejail \-\-private-bin=bash,sed,ls,cat |
1401 | .br | ||
1402 | Parent pid 20841, child pid 20842 | ||
1403 | .br | ||
1404 | Child process initialized | ||
1405 | .br | ||
1406 | $ ls /bin | ||
1407 | .br | ||
1408 | bash 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 |
1413 | Build a new /bin in a temporary filesystem, and copy the programs in the list. | 1423 | Create a new /dev directory. Only disc, dri, null, full, zero, tty, pts, ptmx, random, snd, urandom, video, log and shm devices are available. |
1414 | If no listed file is found, /bin directory will be empty. | ||
1415 | The same directory is also bind-mounted over /sbin, /usr/bin, /usr/sbin and /usr/local/bin. | ||
1416 | All modifications are discarded when the sandbox is closed. File globbing is supported, | ||
1417 | see \fBFILE GLOBBING\fR section for more details. | ||
1418 | .br | 1424 | .br |
1419 | 1425 | ||
1420 | .br | 1426 | .br |
1421 | Example: | 1427 | Example: |
1422 | .br | 1428 | .br |
1423 | $ firejail \-\-private-bin=bash,sed,ls,cat | 1429 | $ firejail \-\-private-dev |
1424 | .br | 1430 | .br |
1425 | Parent pid 20841, child pid 20842 | 1431 | Parent pid 9887, child pid 9888 |
1426 | .br | 1432 | .br |
1427 | Child process initialized | 1433 | Child process initialized |
1428 | .br | 1434 | .br |
1429 | $ ls /bin | 1435 | $ ls /dev |
1436 | .br | ||
1437 | cdrom 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 | ||
1442 | Build a new /etc in a temporary | ||
1443 | filesystem, and copy the files and directories in the list. | ||
1444 | If no listed file is found, /etc directory will be empty. | ||
1445 | All modifications are discarded when the sandbox is closed. | ||
1430 | .br | 1446 | .br |
1431 | bash cat ls sed | 1447 | |
1448 | .br | ||
1449 | Example: | ||
1450 | .br | ||
1451 | $ firejail --private-etc=group,hostname,localtime, \\ | ||
1452 | .br | ||
1453 | nsswitch.conf,passwd,resolv.conf | ||
1454 | |||
1455 | .TP | ||
1456 | \fB\-\-private-home=file,directory | ||
1457 | Build a new user home in a temporary | ||
1458 | filesystem, and copy the files and directories in the list in the | ||
1459 | new home. All modifications are discarded when the sandbox is | ||
1460 | closed. | ||
1461 | .br | ||
1462 | |||
1463 | .br | ||
1464 | Example: | ||
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 | ||
1486 | Create 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 | ||
1490 | Example: | ||
1491 | .br | ||
1492 | $ firejail \-\-private-dev | ||
1493 | .br | ||
1494 | Parent pid 9887, child pid 9888 | ||
1495 | .br | ||
1496 | Child process initialized | ||
1497 | .br | ||
1498 | $ ls /dev | ||
1499 | .br | ||
1500 | cdrom 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 | ||
1505 | Build a new /etc in a temporary | ||
1506 | filesystem, and copy the files and directories in the list. | ||
1507 | If no listed file is found, /etc directory will be empty. | ||
1508 | All modifications are discarded when the sandbox is closed. | ||
1509 | .br | ||
1510 | |||
1511 | .br | ||
1512 | Example: | ||
1513 | .br | ||
1514 | $ firejail --private-etc=group,hostname,localtime, \\ | ||
1515 | .br | ||
1516 | nsswitch.conf,passwd,resolv.conf | ||
1517 | |||
1518 | .TP | 1518 | .TP |
1519 | \fB\-\-private-opt=file,directory | 1519 | \fB\-\-private-opt=file,directory |
1520 | Build a new /opt in a temporary | 1520 | Build 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 | ||
1642 | A short note about mixing \-\-whitelist and \-\-read-only options. Whitelisted directories | ||
1643 | should be made read-only independently. Making a parent directory read-only, will not | ||
1644 | make 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 |
1652 | Set directory or file read-write. Only files or directories belonging to the current user are allowed for | 1642 | Set 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 | |||
2210 | Whitelist directory or file. A temporary file system is mounted on the top directory, and the | 2200 | Whitelist directory or file. A temporary file system is mounted on the top directory, and the |
2211 | whitelisted files are mount-binded inside. Modifications to whitelisted files are persistent, | 2201 | whitelisted files are mount-binded inside. Modifications to whitelisted files are persistent, |
2212 | everything else is discarded when the sandbox is closed. The top directory could be | 2202 | everything else is discarded when the sandbox is closed. The top directory could be |
2213 | user home, /dev, /etc, /media, /mnt, /opt, /srv, /sys/module, /usr/share, /var, and /tmp. | 2203 | user 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 | ||
2425 | AppArmor 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 | ||
2431 | During 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 | ||
2437 | The 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 | ||
2460 | To 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 | ||
2467 | Audit feature allows the user to point out gaps in security profiles. The | ||
2468 | implementation replaces the program to be sandboxed with a test program. By | ||
2469 | default, we use faudit program distributed with Firejail. A custom test program | ||
2470 | can also be supplied by the user. Examples: | ||
2471 | |||
2472 | Running the default audit program: | ||
2473 | .br | ||
2474 | $ firejail --audit transmission-gtk | ||
2475 | |||
2476 | Running a custom audit program: | ||
2477 | .br | ||
2478 | $ firejail --audit=~/sandbox-test transmission-gtk | ||
2479 | |||
2480 | In the examples above, the sandbox configures transmission-gtk profile and | ||
2481 | starts the test program. The real program, transmission-gtk, will not be | ||
2482 | started. | ||
2483 | |||
2484 | Limitations: audit feature is not implemented for --x11 commands. | ||
2485 | |||
2433 | .SH DESKTOP INTEGRATION | 2486 | .SH DESKTOP INTEGRATION |
2434 | A symbolic link to /usr/bin/firejail under the name of a program, will start the program in Firejail sandbox. | 2487 | A symbolic link to /usr/bin/firejail under the name of a program, will start the program in Firejail sandbox. |
2435 | The symbolic link should be placed in the first $PATH position. On most systems, a good place | 2488 | The symbolic link should be placed in the first $PATH position. On most systems, a good place |
@@ -2485,6 +2538,35 @@ $ firejail --tree | |||
2485 | 2538 | ||
2486 | We provide a tool that automates all this integration, please see \fBman 1 firecfg\fR for more details. | 2539 | We 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 | ||
2544 | Sandbox a regular /bin/bash session. | ||
2545 | .TP | ||
2546 | \f\firejail firefox | ||
2547 | Start Mozilla Firefox. | ||
2548 | .TP | ||
2549 | \f\firejail \-\-debug firefox | ||
2550 | Debug Firefox sandbox. | ||
2551 | .TP | ||
2552 | \f\firejail \-\-private firefox | ||
2553 | Start Firefox with a new, empty home directory. | ||
2554 | .TP | ||
2555 | \f\firejail --net=none vlc | ||
2556 | Start VLC in an unconnected network namespace. | ||
2557 | .TP | ||
2558 | \f\firejail \-\-net=eth0 firefox | ||
2559 | Start Firefox in a new network namespace. An IP address is | ||
2560 | assigned automatically. | ||
2561 | .TP | ||
2562 | \f\firejail \-\-net=br0 \-\-ip=10.10.20.5 \-\-net=br1 \-\-net=br2 | ||
2563 | Start a /bin/bash session in a new network namespace and connect it | ||
2564 | to br0, br1, and br2 host bridge devices. IP addresses are assigned | ||
2565 | automatically for the interfaces connected to br1 and b2 | ||
2566 | .TP | ||
2567 | \f\firejail \-\-list | ||
2568 | List all sandboxed processes. | ||
2569 | |||
2488 | .SH FILE GLOBBING | 2570 | .SH FILE GLOBBING |
2489 | .TP | 2571 | .TP |
2490 | Globbing is the operation that expands a wildcard pattern into the list of pathnames matching the pattern. Matching is defined by: | 2572 | Globbing 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 | ||
2524 | AppArmor 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 | ||
2530 | During 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 | ||
2536 | The 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 | ||
2559 | To 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 |
2566 | These features allow the user to inspect the filesystem container of an existing sandbox | 2605 | These features allow the user to inspect the filesystem container of an existing sandbox |
2567 | and transfer files from the container to the host filesystem. | 2606 | and 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 | ||
2614 | Network bandwidth is an expensive resource shared among all sandboxes running on a system. | ||
2615 | Traffic shaping allows the user to increase network performance by controlling | ||
2616 | the amount of data that flows into and out of the sandboxes. | ||
2617 | |||
2618 | Firejail implements a simple rate-limiting shaper based on Linux command tc. | ||
2619 | The shaper works at sandbox level, and can be used only for sandboxes configured with new network namespaces. | ||
2620 | |||
2621 | Set rate-limits: | ||
2622 | |||
2623 | $ firejail --bandwidth=name|pid set network download upload | ||
2624 | |||
2625 | Clear rate-limits: | ||
2626 | |||
2627 | $ firejail --bandwidth=name|pid clear network | ||
2628 | |||
2629 | Status: | ||
2630 | |||
2631 | $ firejail --bandwidth=name|pid status | ||
2632 | |||
2633 | where: | ||
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 | |||
2645 | Example: | ||
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 | ||
2656 | Audit feature allows the user to point out gaps in security profiles. The | ||
2657 | implementation replaces the program to be sandboxed with a test program. By | ||
2658 | default, we use faudit program distributed with Firejail. A custom test program | ||
2659 | can also be supplied by the user. Examples: | ||
2660 | |||
2661 | Running the default audit program: | ||
2662 | .br | ||
2663 | $ firejail --audit transmission-gtk | ||
2664 | |||
2665 | Running a custom audit program: | ||
2666 | .br | ||
2667 | $ firejail --audit=~/sandbox-test transmission-gtk | ||
2668 | |||
2669 | In the examples above, the sandbox configures transmission-gtk profile and | ||
2670 | starts the test program. The real program, transmission-gtk, will not be | ||
2671 | started. | ||
2672 | |||
2673 | Limitations: audit feature is not implemented for --x11 commands. | ||
2674 | |||
2675 | .SH MONITORING | 2652 | .SH MONITORING |
2676 | Option \-\-list prints a list of all sandboxes. The format | 2653 | Option \-\-list prints a list of all sandboxes. The format |
2677 | for each process entry is as follows: | 2654 | for each process entry is as follows: |
@@ -2807,34 +2784,48 @@ adduser \-\-shell /usr/bin/firejail username | |||
2807 | 2784 | ||
2808 | Additional arguments passed to firejail executable upon login are declared in /etc/firejail/login.users file. | 2785 | Additional 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 | 2788 | Network bandwidth is an expensive resource shared among all sandboxes running on a system. |
2812 | \f\firejail | 2789 | Traffic shaping allows the user to increase network performance by controlling |
2813 | Sandbox a regular /bin/bash session. | 2790 | the amount of data that flows into and out of the sandboxes. |
2814 | .TP | 2791 | |
2815 | \f\firejail firefox | 2792 | Firejail implements a simple rate-limiting shaper based on Linux command tc. |
2816 | Start Mozilla Firefox. | 2793 | The 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 | 2795 | Set rate-limits: |
2819 | Debug Firefox sandbox. | 2796 | |
2820 | .TP | 2797 | $ firejail --bandwidth=name|pid set network download upload |
2821 | \f\firejail \-\-private firefox | 2798 | |
2822 | Start Firefox with a new, empty home directory. | 2799 | Clear rate-limits: |
2823 | .TP | 2800 | |
2824 | \f\firejail --net=none vlc | 2801 | $ firejail --bandwidth=name|pid clear network |
2825 | Start VLC in an unconnected network namespace. | 2802 | |
2826 | .TP | 2803 | Status: |
2827 | \f\firejail \-\-net=eth0 firefox | 2804 | |
2828 | Start Firefox in a new network namespace. An IP address is | 2805 | $ firejail --bandwidth=name|pid status |
2829 | assigned automatically. | 2806 | |
2830 | .TP | 2807 | where: |
2831 | \f\firejail \-\-net=br0 \-\-ip=10.10.20.5 \-\-net=br1 \-\-net=br2 | 2808 | .br |
2832 | Start a /bin/bash session in a new network namespace and connect it | 2809 | name - sandbox name |
2833 | to br0, br1, and br2 host bridge devices. IP addresses are assigned | 2810 | .br |
2834 | automatically 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 |
2837 | List 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 | |||
2819 | Example: | ||
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 |
2839 | This 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. | 2830 | This 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 |