aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore6
-rw-r--r--Makefile.in297
-rw-r--r--README208
-rw-r--r--README.md245
-rw-r--r--RELNOTES104
-rwxr-xr-xconfigure568
-rw-r--r--configure.ac82
-rw-r--r--etc/0ad.profile29
-rw-r--r--etc/7z.profile9
-rw-r--r--etc/Cyberfox.profile3
-rw-r--r--etc/Mathematica.profile3
-rw-r--r--etc/Telegram.profile2
-rw-r--r--etc/Wire.profile3
-rw-r--r--etc/abrowser.profile16
-rw-r--r--etc/atom-beta.profile20
-rw-r--r--etc/atom.profile20
-rw-r--r--etc/atril.profile15
-rw-r--r--etc/audacious.profile5
-rw-r--r--etc/audacity.profile21
-rw-r--r--etc/aweather.profile25
-rw-r--r--etc/bitlbee.profile7
-rw-r--r--etc/brave.profile18
-rw-r--r--etc/cherrytree.profile20
-rw-r--r--etc/chromium.profile5
-rw-r--r--etc/claws-mail.profile24
-rw-r--r--etc/clementine.profile5
-rw-r--r--etc/cmus.profile5
-rw-r--r--etc/conkeror.profile5
-rw-r--r--etc/corebird.profile12
-rw-r--r--etc/cpio.profile21
-rw-r--r--etc/cyberfox.profile50
-rw-r--r--etc/deadbeef.profile5
-rw-r--r--etc/default.profile (renamed from etc/generic.profile)6
-rw-r--r--etc/deluge.profile13
-rw-r--r--etc/dillo.profile10
-rw-r--r--etc/disable-common.inc88
-rw-r--r--etc/disable-devel.inc38
-rw-r--r--etc/disable-passwdmgr.inc1
-rw-r--r--etc/display.profile23
-rw-r--r--etc/dnscrypt-proxy.profile2
-rw-r--r--etc/dnsmasq.profile8
-rw-r--r--etc/dosbox.profile21
-rw-r--r--etc/dropbox.profile16
-rw-r--r--etc/emacs.profile17
-rw-r--r--etc/empathy.profile5
-rw-r--r--etc/eog.profile23
-rw-r--r--etc/eom.profile21
-rw-r--r--etc/epiphany.profile11
-rw-r--r--etc/evince.profile15
-rw-r--r--etc/evolution.profile26
-rw-r--r--etc/fbreader.profile10
-rw-r--r--etc/feh.profile21
-rw-r--r--etc/file.profile17
-rw-r--r--etc/filezilla.profile12
-rw-r--r--etc/firefox-esr.profile2
-rw-r--r--etc/firefox.profile28
-rw-r--r--etc/firejail-default154
-rw-r--r--etc/firejail.config47
-rw-r--r--etc/flashpeak-slimjet.profile7
-rw-r--r--etc/flowblade.profile13
-rw-r--r--etc/franz.profile24
-rw-r--r--etc/gajim.profile33
-rw-r--r--etc/gimp.profile20
-rw-r--r--etc/git.profile27
-rw-r--r--etc/gitter.profile20
-rw-r--r--etc/gnome-chess.profile22
-rw-r--r--etc/gnome-mplayer.profile11
-rw-r--r--etc/google-chrome-beta.profile2
-rw-r--r--etc/google-chrome-unstable.profile2
-rw-r--r--etc/google-chrome.profile2
-rw-r--r--etc/google-play-music-desktop-player.profile18
-rw-r--r--etc/gpredict.profile25
-rw-r--r--etc/gtar.profile3
-rw-r--r--etc/gthumb.profile21
-rw-r--r--etc/gwenview.profile22
-rw-r--r--etc/gzip.profile14
-rw-r--r--etc/hedgewars.profile7
-rw-r--r--etc/hexchat.profile22
-rw-r--r--etc/icecat.profile51
-rw-r--r--etc/icedove.profile4
-rw-r--r--etc/inkscape.profile20
-rw-r--r--etc/inox.profile24
-rw-r--r--etc/jitsi.profile17
-rw-r--r--etc/keepass.profile22
-rw-r--r--etc/keepassx.profile23
-rw-r--r--etc/kmail.profile9
-rw-r--r--etc/konversation.profile15
-rw-r--r--etc/less.profile11
-rw-r--r--etc/libreoffice.profile19
-rw-r--r--etc/localc.profile5
-rw-r--r--etc/lodraw.profile5
-rw-r--r--etc/loffice.profile5
-rw-r--r--etc/lofromtemplate.profile5
-rw-r--r--etc/loimpress.profile5
-rw-r--r--etc/lomath.profile5
-rw-r--r--etc/loweb.profile5
-rw-r--r--etc/lowriter.profile5
-rw-r--r--etc/luminance-hdr.profile23
-rw-r--r--etc/lxterminal.profile4
-rw-r--r--etc/mcabber.profile21
-rw-r--r--etc/midori.profile6
-rw-r--r--etc/mpv.profile18
-rw-r--r--etc/mumble.profile26
-rw-r--r--etc/mupdf.profile28
-rw-r--r--etc/mupen64plus.profile8
-rw-r--r--etc/mutt.profile41
-rw-r--r--etc/netsurf.profile30
-rw-r--r--etc/nolocal.net3
-rw-r--r--etc/okular.profile25
-rw-r--r--etc/openbox.profile5
-rw-r--r--etc/openshot.profile13
-rw-r--r--etc/opera-beta.profile2
-rw-r--r--etc/opera.profile2
-rw-r--r--etc/palemoon.profile34
-rw-r--r--etc/parole.profile5
-rw-r--r--etc/pidgin.profile16
-rw-r--r--etc/pix.profile22
-rw-r--r--etc/polari.profile12
-rw-r--r--etc/psi-plus.profile23
-rw-r--r--etc/qbittorrent.profile11
-rw-r--r--etc/qpdfview.profile22
-rw-r--r--etc/qtox.profile14
-rw-r--r--etc/quassel.profile5
-rw-r--r--etc/quiterss.profile17
-rw-r--r--etc/qutebrowser.profile8
-rw-r--r--etc/ranger.profile23
-rw-r--r--etc/rhythmbox.profile14
-rw-r--r--etc/rtorrent.profile10
-rw-r--r--etc/seamonkey.profile17
-rw-r--r--etc/server.profile8
-rw-r--r--etc/skype.profile3
-rw-r--r--etc/skypeforlinux.profile11
-rw-r--r--etc/slack.profile31
-rw-r--r--etc/snap.profile14
-rw-r--r--etc/soffice.profile5
-rw-r--r--etc/spotify.profile33
-rw-r--r--etc/ssh.profile7
-rw-r--r--etc/start-tor-browser.profile20
-rw-r--r--etc/steam.profile3
-rw-r--r--etc/stellarium.profile28
-rw-r--r--etc/strings.profile11
-rw-r--r--etc/synfigstudio.profile19
-rw-r--r--etc/tar.profile18
-rw-r--r--etc/telegram.profile11
-rw-r--r--etc/thunderbird.profile4
-rw-r--r--etc/totem.profile8
-rw-r--r--etc/transmission-gtk.profile14
-rw-r--r--etc/transmission-qt.profile14
-rw-r--r--etc/uget-gtk.profile12
-rw-r--r--etc/unbound.profile1
-rw-r--r--etc/unrar.profile18
-rw-r--r--etc/unzip.profile16
-rw-r--r--etc/uudeview.profile15
-rw-r--r--etc/vim.profile16
-rw-r--r--etc/virtualbox.profile13
-rw-r--r--etc/vivaldi.profile3
-rw-r--r--etc/vlc.profile13
-rw-r--r--etc/warzone2100.profile26
-rw-r--r--etc/weechat.profile10
-rw-r--r--etc/wesnoth.profile12
-rw-r--r--etc/whitelist-common.inc12
-rw-r--r--etc/wine.profile1
-rw-r--r--etc/wire.profile24
-rw-r--r--etc/xchat.profile7
-rw-r--r--etc/xiphos.profile30
-rw-r--r--etc/xpdf.profile18
-rw-r--r--etc/xplayer.profile22
-rw-r--r--etc/xreader.profile23
-rw-r--r--etc/xviewer.profile20
-rw-r--r--etc/xz.profile3
-rw-r--r--etc/xzdec.profile14
-rw-r--r--etc/zathura.profile26
-rw-r--r--etc/zoom.profile23
-rwxr-xr-xgcov.sh71
-rwxr-xr-xmkasc.sh1
-rwxr-xr-xmkdeb.sh4
-rwxr-xr-xmketc.sh32
-rwxr-xr-xmkuid.sh20
-rw-r--r--platform/debian/conffiles229
-rw-r--r--platform/rpm/firejail.spec6
-rwxr-xr-xplatform/rpm/old-mkrpm.sh542
-rwxr-xr-xplatform/snap/snap.sh20
-rw-r--r--platform/snap/snapcraft.yaml21
-rw-r--r--src/bash_completion/firejail.bash_completion8
-rw-r--r--src/faudit/Makefile.in25
-rw-r--r--src/faudit/caps.c79
-rw-r--r--src/faudit/dbus.c95
-rw-r--r--src/faudit/dev.c47
-rw-r--r--src/faudit/faudit.h68
-rw-r--r--src/faudit/files.c75
-rw-r--r--src/faudit/main.c98
-rw-r--r--src/faudit/network.c101
-rw-r--r--src/faudit/pid.c101
-rw-r--r--src/faudit/seccomp.c101
-rw-r--r--src/faudit/syscall.c101
-rw-r--r--src/faudit/x11.c63
-rw-r--r--src/firecfg/Makefile.in8
-rw-r--r--src/firecfg/firecfg.config153
-rw-r--r--src/firecfg/main.c194
-rw-r--r--src/firejail/Makefile.in16
-rw-r--r--src/firejail/appimage.c176
-rw-r--r--src/firejail/appimage_size.c160
-rw-r--r--src/firejail/arp.c186
-rw-r--r--src/firejail/bandwidth.c44
-rw-r--r--src/firejail/caps.c29
-rw-r--r--src/firejail/cgroup.c3
-rw-r--r--src/firejail/checkcfg.c234
-rw-r--r--src/firejail/cmdline.c159
-rw-r--r--src/firejail/cpu.c20
-rw-r--r--src/firejail/env.c83
-rw-r--r--src/firejail/firejail.h257
-rw-r--r--src/firejail/fs.c857
-rw-r--r--src/firejail/fs_bin.c97
-rw-r--r--src/firejail/fs_dev.c181
-rw-r--r--src/firejail/fs_etc.c111
-rw-r--r--src/firejail/fs_home.c399
-rw-r--r--src/firejail/fs_hostname.c30
-rw-r--r--src/firejail/fs_logger.c22
-rw-r--r--src/firejail/fs_mkdir.c100
-rw-r--r--src/firejail/fs_trace.c25
-rw-r--r--src/firejail/fs_var.c69
-rw-r--r--src/firejail/fs_whitelist.c248
-rw-r--r--src/firejail/join.c175
-rw-r--r--src/firejail/list.c81
-rw-r--r--src/firejail/ls.c245
-rw-r--r--src/firejail/main.c1234
-rw-r--r--src/firejail/netfilter.c21
-rw-r--r--src/firejail/network.c343
-rw-r--r--src/firejail/network.txt2
-rw-r--r--src/firejail/network_main.c66
-rw-r--r--src/firejail/no_sandbox.c217
-rw-r--r--src/firejail/output.c2
-rw-r--r--src/firejail/preproc.c125
-rw-r--r--src/firejail/profile.c380
-rw-r--r--src/firejail/protocol.c278
-rw-r--r--src/firejail/pulseaudio.c52
-rw-r--r--src/firejail/restrict_users.c37
-rw-r--r--src/firejail/restricted_shell.c47
-rw-r--r--src/firejail/run_symlink.c10
-rw-r--r--src/firejail/sandbox.c618
-rw-r--r--src/firejail/sbox.c206
-rw-r--r--src/firejail/seccomp.c879
-rw-r--r--src/firejail/shutdown.c16
-rw-r--r--src/firejail/usage.c406
-rw-r--r--src/firejail/user.c115
-rw-r--r--src/firejail/util.c211
-rw-r--r--src/firejail/x11.c523
-rw-r--r--src/firemon/Makefile.in11
-rw-r--r--src/firemon/arp.c10
-rw-r--r--src/firemon/caps.c8
-rw-r--r--src/firemon/cgroup.c9
-rw-r--r--src/firemon/cpu.c9
-rw-r--r--src/firemon/firemon.c137
-rw-r--r--src/firemon/firemon.h17
-rw-r--r--src/firemon/interface.c17
-rw-r--r--src/firemon/list.c3
-rw-r--r--src/firemon/netstats.c7
-rw-r--r--src/firemon/procevent.c9
-rw-r--r--src/firemon/route.c10
-rw-r--r--src/firemon/seccomp.c8
-rw-r--r--src/firemon/top.c3
-rw-r--r--src/firemon/tree.c5
-rw-r--r--src/firemon/x11.c11
-rw-r--r--src/fnet/Makefile.in45
-rw-r--r--src/fnet/arp.c208
-rw-r--r--src/fnet/fnet.h49
-rw-r--r--src/fnet/interface.c370
-rw-r--r--src/fnet/main.c103
-rw-r--r--src/fnet/veth.c (renamed from src/firejail/veth.c)14
-rw-r--r--src/fseccomp/Makefile.in45
-rw-r--r--src/fseccomp/errno.c (renamed from src/firejail/errno.c)22
-rw-r--r--src/fseccomp/fseccomp.h68
-rw-r--r--src/fseccomp/main.c91
-rw-r--r--src/fseccomp/protocol.c219
-rw-r--r--src/fseccomp/seccomp.c292
-rw-r--r--src/fseccomp/seccomp_file.c108
-rw-r--r--src/fseccomp/seccomp_print.c116
-rw-r--r--src/fseccomp/seccomp_secondary.c183
-rw-r--r--src/fseccomp/syscall.c (renamed from src/firejail/syscall.c)126
-rw-r--r--src/ftee/Makefile.in8
-rw-r--r--src/ftee/main.c4
-rw-r--r--src/include/common.h4
-rw-r--r--src/include/euid_common.h11
-rw-r--r--src/include/seccomp.h (renamed from src/firejail/seccomp.h)0
-rw-r--r--src/include/syscall.h (renamed from src/firejail/syscall.h)136
-rw-r--r--src/lib/Makefile.in6
-rw-r--r--src/lib/common.c85
-rw-r--r--src/lib/libnetlink.c4
-rw-r--r--src/lib/pid.c17
-rw-r--r--src/libconnect/Makefile.in25
-rw-r--r--src/libconnect/libconnect.c66
-rw-r--r--src/libtrace/libtrace.c29
-rw-r--r--src/libtracelog/libtracelog.c71
-rw-r--r--src/man/firecfg.txt20
-rw-r--r--src/man/firejail-config.txt81
-rw-r--r--src/man/firejail-login.txt7
-rw-r--r--src/man/firejail-profile.txt188
-rw-r--r--src/man/firejail.txt439
-rw-r--r--src/man/firemon.txt1
-rwxr-xr-xsrc/tools/mkcoverit.sh6
-rw-r--r--test/appimage/Leafpad-0.8.17-x86_64.AppImagebin0 -> 786432 bytes
-rw-r--r--test/appimage/Leafpad-0.8.18.1.glibc2.4-x86_64.AppImagebin0 -> 231417 bytes
-rwxr-xr-xtest/appimage/appimage-v1.exp85
-rwxr-xr-xtest/appimage/appimage-v2.exp85
-rwxr-xr-xtest/appimage/appimage.sh14
-rwxr-xr-xtest/apps-x11-xorg/apps-x11-xorg.sh35
-rwxr-xr-xtest/apps-x11-xorg/firefox.exp91
-rwxr-xr-xtest/apps-x11-xorg/icedove.exp86
-rwxr-xr-xtest/apps-x11-xorg/transmission-gtk.exp86
-rwxr-xr-xtest/apps-x11/apps-x11.sh88
-rwxr-xr-xtest/apps-x11/chromium.exp (renamed from test/chromium-x11.exp)6
-rwxr-xr-xtest/apps-x11/firefox.exp91
-rwxr-xr-xtest/apps-x11/icedove.exp86
-rwxr-xr-xtest/apps-x11/transmission-gtk.exp (renamed from test/transmission-gtk-x11.exp)6
-rwxr-xr-xtest/apps-x11/x11-none.exp48
-rwxr-xr-xtest/apps-x11/x11-xephyr.exp59
-rwxr-xr-xtest/apps-x11/xterm-xephyr.exp86
-rwxr-xr-xtest/apps-x11/xterm-xorg.exp86
-rwxr-xr-xtest/apps-x11/xterm-xpra.exp98
-rwxr-xr-xtest/apps/apps.sh (renamed from test/test-apps.sh)91
-rwxr-xr-xtest/apps/chromium.exp (renamed from test/chromium.exp)10
-rwxr-xr-xtest/apps/deluge.exp (renamed from test/deluge.exp)10
-rwxr-xr-xtest/apps/evince.exp (renamed from test/evince.exp)10
-rwxr-xr-xtest/apps/fbreader.exp (renamed from test/fbreader.exp)10
-rwxr-xr-xtest/apps/filezilla.exp84
-rwxr-xr-xtest/apps/firefox.exp (renamed from test/firefox.exp)10
-rwxr-xr-xtest/apps/gnome-mplayer.exp (renamed from test/gnome-mplayer.exp)12
-rwxr-xr-xtest/apps/gthumb.exp (renamed from test/weechat.exp)22
-rwxr-xr-xtest/apps/hexchat.exp (renamed from test/hexchat.exp)10
-rwxr-xr-xtest/apps/icedove.exp (renamed from test/icedove.exp)10
-rwxr-xr-xtest/apps/midori.exp (renamed from test/midori.exp)12
-rwxr-xr-xtest/apps/opera.exp (renamed from test/opera.exp)10
-rwxr-xr-xtest/apps/qbittorrent.exp84
-rwxr-xr-xtest/apps/transmission-gtk.exp (renamed from test/transmission-gtk.exp)12
-rwxr-xr-xtest/apps/transmission-qt.exp (renamed from test/transmission-qt.exp)12
-rwxr-xr-xtest/apps/uget-gtk.exp84
-rwxr-xr-xtest/apps/vlc.exp (renamed from test/vlc.exp)10
-rwxr-xr-xtest/apps/wine.exp (renamed from test/wine.exp)3
-rwxr-xr-xtest/apps/xchat.exp (renamed from test/xchat.exp)10
-rwxr-xr-xtest/arguments/arguments.sh23
-rwxr-xr-xtest/arguments/bashrun.exp86
-rwxr-xr-xtest/arguments/bashrun.sh22
-rwxr-xr-xtest/arguments/joinrun.exp91
-rwxr-xr-xtest/arguments/joinrun.sh22
-rwxr-xr-xtest/arguments/outrun.exp90
-rwxr-xr-xtest/arguments/outrun.sh22
-rwxr-xr-xtest/arguments/symrun.exp71
-rwxr-xr-xtest/arguments/symrun.sh30
-rwxr-xr-xtest/auto/autotest.sh202
-rwxr-xr-xtest/compile/compile.sh150
-rwxr-xr-xtest/configure2
-rwxr-xr-xtest/dns.exp69
-rwxr-xr-xtest/environment/allow-debuggers.exp40
-rwxr-xr-xtest/environment/csh.exp (renamed from test/shell_csh.exp)18
-rwxr-xr-xtest/environment/dash.exp (renamed from test/shell_dash.exp)3
-rwxr-xr-xtest/environment/dns.exp30
-rwxr-xr-xtest/environment/doubledash.exp (renamed from test/doubledash.exp)10
-rwxr-xr-xtest/environment/env.exp (renamed from test/env.exp)5
-rw-r--r--test/environment/env.profile (renamed from test/env.profile)0
-rwxr-xr-xtest/environment/environment.sh87
-rwxr-xr-xtest/environment/extract_command.exp (renamed from test/extract_command.exp)4
-rwxr-xr-xtest/environment/firejail-in-firejail.exp (renamed from test/firejail-in-firejail.exp)5
-rwxr-xr-xtest/environment/firejail-in-firejail2.exp (renamed from test/firejail-in-firejail2.exp)5
-rwxr-xr-xtest/environment/nice.exp (renamed from test/nice.exp)13
-rw-r--r--test/environment/nice.profile (renamed from test/nice.profile)0
-rwxr-xr-xtest/environment/output.exp (renamed from test/output.exp)7
-rwxr-xr-xtest/environment/output.sh (renamed from test/output.sh)0
-rwxr-xr-xtest/environment/quiet.exp21
-rwxr-xr-xtest/environment/shell-none.exp48
-rw-r--r--test/environment/shell-none.profile1
-rwxr-xr-xtest/environment/sound.exp (renamed from test/sound.exp)8
-rw-r--r--test/environment/sound.profile (renamed from test/sound.profile)0
-rwxr-xr-xtest/environment/zsh.exp (renamed from test/shell_zsh.exp)20
-rwxr-xr-xtest/features/1.2.exp30
-rwxr-xr-xtest/features/1.8.exp18
-rwxr-xr-xtest/features/3.5.exp10
-rwxr-xr-xtest/features/3.6.exp11
-rwxr-xr-xtest/features/3.8.exp8
-rwxr-xr-xtest/filters/caps.exp72
-rwxr-xr-xtest/filters/filters.sh68
-rwxr-xr-xtest/filters/fseccomp.exp138
-rwxr-xr-xtest/filters/noroot.exp160
-rwxr-xr-xtest/filters/protocol.exp (renamed from test/protocol.exp)19
-rw-r--r--test/filters/protocol1.profile (renamed from test/protocol1.profile)0
-rw-r--r--test/filters/protocol2.profile (renamed from test/protocol2.profile)0
-rwxr-xr-xtest/filters/seccomp-bad-empty.exp (renamed from test/seccomp-bad-empty.exp)5
-rw-r--r--test/filters/seccomp-bad-empty.profile (renamed from test/seccomp-bad-empty.profile)0
-rw-r--r--test/filters/seccomp-bad-empty2.profile (renamed from test/seccomp-bad-empty2.profile)0
-rwxr-xr-xtest/filters/seccomp-chmod-profile.exp (renamed from test/pid.exp)36
-rwxr-xr-xtest/filters/seccomp-chmod.exp (renamed from test/seccomp-chmod.exp)35
-rwxr-xr-xtest/filters/seccomp-chown.exp (renamed from test/seccomp-chown.exp)7
-rwxr-xr-xtest/filters/seccomp-debug.exp (renamed from test/seccomp-debug.exp)3
-rwxr-xr-xtest/filters/seccomp-dualfilter.exp55
-rwxr-xr-xtest/filters/seccomp-empty.exp (renamed from test/seccomp-empty.exp)4
-rw-r--r--test/filters/seccomp-empty.profile (renamed from test/seccomp-empty.profile)0
-rwxr-xr-xtest/filters/seccomp-errno.exp54
-rwxr-xr-xtest/filters/seccomp-ptrace.exp (renamed from test/seccomp-ptrace.exp)5
-rwxr-xr-xtest/filters/seccomp-su.exp (renamed from test/seccomp-su.exp)16
-rw-r--r--test/filters/seccomp.profile (renamed from test/seccomp.profile)0
-rwxr-xr-xtest/filters/syscall_test (renamed from src/tools/syscall_test)bin9552 -> 9552 bytes
-rw-r--r--test/filters/syscall_test.c (renamed from src/tools/syscall_test.c)4
-rwxr-xr-xtest/filters/syscall_test32 (renamed from src/tools/syscall_test32)bin6868 -> 6868 bytes
-rwxr-xr-xtest/fs/fs.sh99
-rwxr-xr-xtest/fs/fs_dev_shm.exp (renamed from test/fs_dev_shm.exp)63
-rwxr-xr-xtest/fs/fs_var_lock.exp90
-rwxr-xr-xtest/fs/fs_var_tmp.exp (renamed from test/fs_var_tmp.exp)63
-rwxr-xr-xtest/fs/invalid_filename.exp (renamed from test/invalid_filename.exp)24
-rwxr-xr-xtest/fs/kmsg.exp (renamed from test/kmsg.exp)7
-rwxr-xr-xtest/fs/mkdir.exp20
-rw-r--r--test/fs/mkdir.profile2
-rwxr-xr-xtest/fs/mkdir_mkfile.exp46
-rw-r--r--test/fs/mkdir_mkfile.profile4
-rwxr-xr-xtest/fs/option_bind_user.exp (renamed from test/option_bind_user.exp)2
-rwxr-xr-xtest/fs/option_blacklist.exp (renamed from test/option_blacklist.exp)13
-rwxr-xr-xtest/fs/option_blacklist_file.exp (renamed from test/option_blacklist_file.exp)6
-rwxr-xr-xtest/fs/option_blacklist_glob.exp33
-rwxr-xr-xtest/fs/private-bin.exp (renamed from test/private-bin.exp)8
-rw-r--r--test/fs/private-bin.profile (renamed from test/private-bin.profile)0
-rwxr-xr-xtest/fs/private-etc-empty.exp42
-rw-r--r--test/fs/private-etc-empty.profile1
-rwxr-xr-xtest/fs/private-etc.exp (renamed from test/private-etc.exp)19
-rwxr-xr-xtest/fs/private-home-dir.exp70
-rwxr-xr-xtest/fs/private-home.exp45
-rwxr-xr-xtest/fs/private-homedir.exp25
-rwxr-xr-xtest/fs/private-whitelist.exp (renamed from test/private-whitelist.exp)13
-rwxr-xr-xtest/fs/private.exp58
-rwxr-xr-xtest/fs/read-write.exp51
-rwxr-xr-xtest/fs/sys_fs.exp44
-rw-r--r--test/fs/testdir1/.directory/file0
-rw-r--r--test/fs/testdir1/.file0
-rwxr-xr-xtest/fs/whitelist-double.exp42
-rwxr-xr-xtest/fs/whitelist-empty.exp (renamed from test/whitelist-empty.exp)4
-rwxr-xr-xtest/fs/whitelist.exp226
-rwxr-xr-xtest/fs_var_lock.exp87
-rwxr-xr-xtest/google-chrome.exp80
-rwxr-xr-xtest/net_interface.exp88
-rwxr-xr-xtest/network/4bridges_arp.exp (renamed from test/4bridges_arp.exp)22
-rwxr-xr-xtest/network/4bridges_ip.exp (renamed from test/4bridges_ip.exp)22
-rw-r--r--test/network/README14
-rwxr-xr-xtest/network/bandwidth.exp (renamed from test/bandwidth.exp)13
-rwxr-xr-xtest/network/configure27
-rwxr-xr-xtest/network/firemon-arp.exp50
-rwxr-xr-xtest/network/firemon-interfaces.exp67
-rwxr-xr-xtest/network/firemon-route.exp (renamed from test/firemon-route.exp)30
-rwxr-xr-xtest/network/hostname.exp (renamed from test/hostname.exp)12
-rwxr-xr-xtest/network/interface.exp66
-rwxr-xr-xtest/network/ip6.exp (renamed from test/ip6.exp)6
-rw-r--r--test/network/ipv6.net (renamed from test/ipv6.net)0
-rw-r--r--test/network/net-profile.profile10
-rwxr-xr-xtest/network/net_arp.exp (renamed from test/net_arp.exp)5
-rwxr-xr-xtest/network/net_badip.exp (renamed from test/net_badip.exp)5
-rwxr-xr-xtest/network/net_defaultgw.exp (renamed from test/net_defaultgw.exp)6
-rwxr-xr-xtest/network/net_defaultgw2.exp (renamed from test/net_defaultgw2.exp)6
-rwxr-xr-xtest/network/net_defaultgw3.exp (renamed from test/net_defaultgw3.exp)6
-rwxr-xr-xtest/network/net_ip.exp (renamed from test/net_ip.exp)10
-rwxr-xr-xtest/network/net_local.exp (renamed from test/net_local.exp)9
-rwxr-xr-xtest/network/net_mac.exp (renamed from test/net_mac.exp)6
-rwxr-xr-xtest/network/net_macvlan.exp (renamed from test/net_macvlan.exp)5
-rwxr-xr-xtest/network/net_mtu.exp (renamed from test/net_mtu.exp)5
-rwxr-xr-xtest/network/net_netfilter.exp (renamed from test/net_netfilter.exp)9
-rwxr-xr-xtest/network/net_noip.exp (renamed from test/net_noip.exp)12
-rwxr-xr-xtest/network/net_noip2.exp (renamed from test/net_noip2.exp)12
-rwxr-xr-xtest/network/net_none.exp (renamed from test/net_none.exp)24
-rw-r--r--test/network/net_none.profile (renamed from test/net_none.profile)0
-rwxr-xr-xtest/network/net_profile.exp77
-rwxr-xr-xtest/network/net_scan.exp75
-rwxr-xr-xtest/network/net_veth.exp130
-rw-r--r--test/network/netfilter.filter (renamed from test/netfilter.filter)0
-rw-r--r--test/network/netfilter.profile (renamed from test/netfilter.profile)0
-rwxr-xr-xtest/network/netstats.exp39
-rwxr-xr-xtest/network/network.sh85
-rwxr-xr-xtest/noroot.exp117
-rw-r--r--test/notes13
-rwxr-xr-xtest/option-join2.exp39
-rwxr-xr-xtest/option-join3.exp39
-rwxr-xr-xtest/option-trace.exp25
-rwxr-xr-xtest/overlay/firefox-x11-xorg.exp90
-rwxr-xr-xtest/overlay/firefox-x11.exp (renamed from test/firefox-x11.exp)7
-rwxr-xr-xtest/overlay/firefox.exp99
-rwxr-xr-xtest/overlay/fs-named.exp66
-rwxr-xr-xtest/overlay/fs-tmpfs.exp (renamed from test/fs_overlay.exp)54
-rwxr-xr-xtest/overlay/fs.exp46
-rwxr-xr-xtest/overlay/overlay.sh67
-rwxr-xr-xtest/private.exp97
-rwxr-xr-xtest/private_dir.exp2
-rwxr-xr-xtest/private_dir_profile.exp2
-rwxr-xr-xtest/profile_tmpfs.exp37
-rwxr-xr-xtest/profiles/ignore.exp (renamed from test/ignore.exp)5
-rw-r--r--test/profiles/ignore.profile (renamed from test/ignore.profile)0
-rw-r--r--test/profiles/ignore2.profile (renamed from test/ignore2.profile)0
-rwxr-xr-xtest/profiles/profile_followlnk.exp (renamed from test/profile_followlnk.exp)40
-rwxr-xr-xtest/profiles/profile_noperm.exp (renamed from test/profile_noperm.exp)4
-rwxr-xr-xtest/profiles/profile_readonly.exp (renamed from test/profile_readonly.exp)42
-rwxr-xr-xtest/profiles/profile_syntax.exp (renamed from test/profile_syntax.exp)27
-rwxr-xr-xtest/profiles/profile_syntax2.exp (renamed from test/profile_syntax2.exp)7
-rwxr-xr-xtest/profiles/profiles.sh34
-rw-r--r--test/profiles/readonly-lnk.profile (renamed from test/readonly-lnk.profile)0
-rw-r--r--test/profiles/readonly.profile (renamed from test/readonly.profile)0
-rwxr-xr-xtest/profiles/test-profile.exp (renamed from test/test-profile.exp)7
-rw-r--r--test/profiles/test.profile (renamed from test/test.profile)0
-rw-r--r--test/profiles/test2.profile (renamed from test/test2.profile)0
-rwxr-xr-xtest/quiet.exp17
-rwxr-xr-xtest/rlimit/rlimit-profile.exp (renamed from test/profile_rlimit.exp)11
-rwxr-xr-xtest/rlimit/rlimit.exp (renamed from test/option_rlimit.exp)3
-rw-r--r--test/rlimit/rlimit.profile (renamed from test/rlimit.profile)0
-rwxr-xr-xtest/rlimit/rlimit.sh14
-rwxr-xr-xtest/root/apache2.exp (renamed from test/servers3.exp)10
-rwxr-xr-xtest/root/firecfg.exp46
-rw-r--r--test/root/firejail.config20
-rwxr-xr-xtest/root/firemon-events.exp72
-rwxr-xr-xtest/root/isc-dhcp.exp (renamed from test/servers4.exp)9
-rwxr-xr-xtest/root/nginx.exp (renamed from test/servers6.exp)10
-rwxr-xr-xtest/root/option_bind_directory.exp (renamed from test/option_bind_directory.exp)0
-rwxr-xr-xtest/root/option_bind_file.exp (renamed from test/option_bind_file.exp)0
-rwxr-xr-xtest/root/option_tmpfs.exp (renamed from test/option_tmpfs.exp)10
-rwxr-xr-xtest/root/private.exp33
-rwxr-xr-xtest/root/profile_tmpfs.exp40
-rwxr-xr-xtest/root/root.sh105
-rwxr-xr-xtest/root/seccomp-chmod.exp51
-rwxr-xr-xtest/root/seccomp-chown.exp (renamed from test/seccomp-chmod-profile.exp)11
-rwxr-xr-xtest/root/seccomp-umount.exp (renamed from test/seccomp-umount.exp)13
-rwxr-xr-xtest/root/snmpd.exp (renamed from test/servers2.exp)10
-rw-r--r--test/root/tmpfs-bad.profile1
-rw-r--r--test/root/tmpfs.profile1
-rwxr-xr-xtest/root/unbound.exp (renamed from test/servers5.exp)9
-rwxr-xr-xtest/seccomp-errno.exp87
-rwxr-xr-xtest/sysrq-trigger.exp21
-rwxr-xr-xtest/sysutils/cpio.exp26
-rwxr-xr-xtest/sysutils/file.exp18
-rwxr-xr-xtest/sysutils/gzip.exp26
-rwxr-xr-xtest/sysutils/less.exp20
-rwxr-xr-xtest/sysutils/strings.exp26
-rwxr-xr-xtest/sysutils/sysutils.sh80
-rwxr-xr-xtest/sysutils/tar.exp46
-rwxr-xr-xtest/sysutils/xz.exp26
-rwxr-xr-xtest/sysutils/xzdec.exp29
-rwxr-xr-xtest/test-apps-x11.sh29
-rwxr-xr-xtest/test-nonet.sh44
-rwxr-xr-xtest/test-profiles.sh10
-rwxr-xr-xtest/test-root.sh82
-rwxr-xr-xtest/test.sh294
-rw-r--r--test/tmpfs.profile1
-rwxr-xr-xtest/utils/caps-print.exp (renamed from test/caps-print.exp)5
-rw-r--r--test/utils/caps1.profile (renamed from test/caps1.profile)0
-rw-r--r--test/utils/caps2.profile (renamed from test/caps2.profile)0
-rwxr-xr-xtest/utils/catchsignal-master.sh (renamed from test/catchsignal-master.sh)0
-rwxr-xr-xtest/utils/catchsignal.sh (renamed from test/catchsignal.sh)0
-rwxr-xr-xtest/utils/catchsignal2.sh (renamed from test/catchsignal2.sh)0
-rwxr-xr-xtest/utils/cpu-print.exp (renamed from test/cpu-print.exp)5
-rwxr-xr-xtest/utils/dns-print.exp (renamed from test/dns-print.exp)5
-rwxr-xr-xtest/utils/firemon-caps.exp (renamed from test/firemon-caps.exp)4
-rwxr-xr-xtest/utils/firemon-cgroup.exp41
-rwxr-xr-xtest/utils/firemon-cpu.exp (renamed from test/seccomp-dualfilter.exp)35
-rwxr-xr-xtest/utils/firemon-seccomp.exp (renamed from test/firemon-seccomp.exp)6
-rwxr-xr-xtest/utils/fs-print.exp (renamed from test/fs-print.exp)5
-rwxr-xr-xtest/utils/help.exp (renamed from test/option_help.exp)3
-rwxr-xr-xtest/utils/join-profile.exp (renamed from test/firemon-interface.exp)25
-rwxr-xr-xtest/utils/join.exp38
-rwxr-xr-xtest/utils/join2.exp (renamed from test/option-join-profile.exp)33
-rwxr-xr-xtest/utils/join3.exp (renamed from test/option-join.exp)31
-rwxr-xr-xtest/utils/join4.exp (renamed from test/firemon-arp.exp)30
-rwxr-xr-xtest/utils/list.exp (renamed from test/option_list.exp)3
-rwxr-xr-xtest/utils/ls.exp (renamed from test/ls.exp)48
-rwxr-xr-xtest/utils/man.exp (renamed from test/option_man.exp)3
-rw-r--r--test/utils/name.profile (renamed from test/name.profile)0
-rwxr-xr-xtest/utils/protocol-print.exp (renamed from test/protocol-print.exp)5
-rwxr-xr-xtest/utils/seccomp-print.exp (renamed from test/seccomp-print.exp)5
-rwxr-xr-xtest/utils/shutdown.exp (renamed from test/option-shutdown.exp)19
-rwxr-xr-xtest/utils/shutdown2.exp (renamed from test/option-shutdown2.exp)5
-rwxr-xr-xtest/utils/shutdown3.exp (renamed from test/option-shutdown3.exp)5
-rwxr-xr-xtest/utils/shutdown4.exp (renamed from test/option-shutdown4.exp)9
-rwxr-xr-xtest/utils/top.exp40
-rwxr-xr-xtest/utils/trace.exp (renamed from test/trace.exp)23
-rwxr-xr-xtest/utils/tree.exp (renamed from test/option_tree.exp)3
-rwxr-xr-xtest/utils/utils.sh102
-rwxr-xr-xtest/utils/version.exp (renamed from test/option_version.exp)3
-rw-r--r--todo214
577 files changed, 20917 insertions, 7828 deletions
diff --git a/.gitignore b/.gitignore
index 85e317827..459119b14 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,8 @@
3*~ 3*~
4*.swp 4*.swp
5*.rpm 5*.rpm
6*.gcda
7*.gcno
6Makefile 8Makefile
7config.log 9config.log
8config.status 10config.status
@@ -17,3 +19,7 @@ src/firemon/firemon
17src/firecfg/firecfg 19src/firecfg/firecfg
18src/ftee/ftee 20src/ftee/ftee
19src/tags 21src/tags
22src/faudit/faudit
23src/fnet/fnet
24src/fseccomp/fseccomp
25uids.h
diff --git a/Makefile.in b/Makefile.in
index 16f8e8717..86fd4f4b7 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,6 +1,7 @@
1all: apps firejail.1 firemon.1 firecfg.1 firejail-profile.5 firejail-login.5 firejail-config.5 1all: apps man
2MYLIBS = src/lib 2MYLIBS = src/lib
3APPS = src/firejail src/firemon src/firecfg src/libtrace src/libtracelog src/ftee 3APPS = src/firejail src/firemon src/firecfg src/libtrace src/libtracelog src/ftee src/faudit src/libconnect src/fnet src/fseccomp
4MANPAGES = firejail.1 firemon.1 firecfg.1 firejail-profile.5 firejail-login.5
4 5
5prefix=@prefix@ 6prefix=@prefix@
6exec_prefix=@exec_prefix@ 7exec_prefix=@exec_prefix@
@@ -14,47 +15,48 @@ VERSION=@PACKAGE_VERSION@
14NAME=@PACKAGE_NAME@ 15NAME=@PACKAGE_NAME@
15PACKAGE_TARNAME=@PACKAGE_TARNAME@ 16PACKAGE_TARNAME=@PACKAGE_TARNAME@
16DOCDIR=@docdir@ 17DOCDIR=@docdir@
18HAVE_APPARMOR=@HAVE_APPARMOR@
19BUSYBOX_WORKAROUND=@BUSYBOX_WORKAROUND@
20
21uids.h:; ./mkuid.sh
17 22
18.PHONY: mylibs $(MYLIBS) 23.PHONY: mylibs $(MYLIBS)
19mylibs: $(MYLIBS) 24mylibs: $(MYLIBS) uids.h
20$(MYLIBS): 25$(MYLIBS):
21 $(MAKE) -C $@ 26 $(MAKE) -C $@
22 27
23.PHONY: apps $(APPS) 28.PHONY: apps $(APPS)
24apps: $(APPS) 29apps: $(APPS)
25$(APPS): $(MYLIBS) 30$(APPS): $(MYLIBS) uids.h
26 $(MAKE) -C $@ 31 $(MAKE) -C $@
27 32
28firemon.1: src/man/firemon.txt 33$(MANPAGES): $(wildcard src/man/*.txt)
29 ./mkman.sh $(VERSION) src/man/firemon.txt firemon.1 34 ./mkman.sh $(VERSION) src/man/$(basename $@).txt $@
30firejail.1: src/man/firejail.txt 35
31 ./mkman.sh $(VERSION) src/man/firejail.txt firejail.1 36man: $(MANPAGES)
32firecfg.1: src/man/firecfg.txt
33 ./mkman.sh $(VERSION) src/man/firecfg.txt firecfg.1
34firejail-profile.5: src/man/firejail-profile.txt
35 ./mkman.sh $(VERSION) src/man/firejail-profile.txt firejail-profile.5
36firejail-login.5: src/man/firejail-login.txt
37 ./mkman.sh $(VERSION) src/man/firejail-login.txt firejail-login.5
38firejail-config.5: src/man/firejail-config.txt
39 ./mkman.sh $(VERSION) src/man/firejail-config.txt firejail-config.5
40 37
41clean: 38clean:
42 for dir in $(APPS); do \ 39 for dir in $(APPS) $(MYLIBS); do \
43 $(MAKE) -C $$dir clean; \ 40 $(MAKE) -C $$dir clean; \
44 done 41 done
45 for dir in $(MYLIBS); do \ 42 rm -f $(MANPAGES) $(MANPAGES:%=%.gz) firejail*.rpm
46 $(MAKE) -C $$dir clean; \ 43 rm -f test/utils/index.html*
47 done 44 rm -f test/utils/wget-log
48 rm -f firejail.1 firejail.1.gz firemon.1 firemon.1.gz firecfg.1 firecfg.gz firejail-profile.5 firejail-profile.5.gz firejail-login.5 firejail-login.5.gz firejail-config.5 firejail-config.5.gz firejail*.rpm 45 rm -f test/utils/lstesting
46 rm -f test/environment/index.html*
47 rm -f test/environment/wget-log*
48 rm -fr test/environment/-testdir
49 rm -f test/environment/logfile*
50 rm -f test/environment/index.html
51 rm -f test/environment/wget-log
52 rm -f test/sysutils/firejail_t*
53 cd test/compile; ./compile.sh --clean; cd ../..
49 54
50distclean: clean 55distclean: clean
51 for dir in $(APPS); do \ 56 for dir in $(APPS) $(MYLIBS); do \
52 $(MAKE) -C $$dir distclean; \
53 done
54 for dir in $(MYLIBS); do \
55 $(MAKE) -C $$dir distclean; \ 57 $(MAKE) -C $$dir distclean; \
56 done 58 done
57 rm -fr Makefile autom4te.cache config.log config.status config.h 59 rm -fr Makefile autom4te.cache config.log config.status config.h uids.h
58 60
59realinstall: 61realinstall:
60 # firejail executable 62 # firejail executable
@@ -69,133 +71,49 @@ realinstall:
69 install -m 0755 -d $(DESTDIR)/$(libdir)/firejail 71 install -m 0755 -d $(DESTDIR)/$(libdir)/firejail
70 install -c -m 0644 src/libtrace/libtrace.so $(DESTDIR)/$(libdir)/firejail/. 72 install -c -m 0644 src/libtrace/libtrace.so $(DESTDIR)/$(libdir)/firejail/.
71 install -c -m 0644 src/libtracelog/libtracelog.so $(DESTDIR)/$(libdir)/firejail/. 73 install -c -m 0644 src/libtracelog/libtracelog.so $(DESTDIR)/$(libdir)/firejail/.
74 install -c -m 0644 src/libconnect/libconnect.so $(DESTDIR)/$(libdir)/firejail/.
72 install -c -m 0755 src/ftee/ftee $(DESTDIR)/$(libdir)/firejail/. 75 install -c -m 0755 src/ftee/ftee $(DESTDIR)/$(libdir)/firejail/.
73 install -c -m 0755 src/fshaper/fshaper.sh $(DESTDIR)/$(libdir)/firejail/. 76 install -c -m 0755 src/fshaper/fshaper.sh $(DESTDIR)/$(libdir)/firejail/.
74 install -c -m 0644 src/firecfg/firecfg.config $(DESTDIR)/$(libdir)/firejail/. 77 install -c -m 0644 src/firecfg/firecfg.config $(DESTDIR)/$(libdir)/firejail/.
78 install -c -m 0755 src/faudit/faudit $(DESTDIR)/$(libdir)/firejail/.
79 install -c -m 0755 src/fnet/fnet $(DESTDIR)/$(libdir)/firejail/.
80 install -c -m 0755 src/fseccomp/fseccomp $(DESTDIR)/$(libdir)/firejail/.
75 # documents 81 # documents
76 install -m 0755 -d $(DESTDIR)/$(DOCDIR) 82 install -m 0755 -d $(DESTDIR)/$(DOCDIR)
77 install -c -m 0644 COPYING $(DESTDIR)/$(DOCDIR)/. 83 install -c -m 0644 COPYING $(DESTDIR)/$(DOCDIR)/.
78 install -c -m 0644 README $(DESTDIR)/$(DOCDIR)/. 84 install -c -m 0644 README $(DESTDIR)/$(DOCDIR)/.
79 install -c -m 0644 RELNOTES $(DESTDIR)/$(DOCDIR)/. 85 install -c -m 0644 RELNOTES $(DESTDIR)/$(DOCDIR)/.
80 # etc files 86 # etc files
81 ./mketc.sh $(sysconfdir) 87 ./mketc.sh $(sysconfdir) $(BUSYBOX_WORKAROUND)
82 install -m 0755 -d $(DESTDIR)/$(sysconfdir)/firejail 88 install -m 0755 -d $(DESTDIR)/$(sysconfdir)/firejail
83 install -c -m 0644 .etc/audacious.profile $(DESTDIR)/$(sysconfdir)/firejail/. 89 for file in .etc/* etc/firejail.config; do \
84 install -c -m 0644 .etc/clementine.profile $(DESTDIR)/$(sysconfdir)/firejail/. 90 install -c -m 0644 $$file $(DESTDIR)/$(sysconfdir)/firejail; \
85 install -c -m 0644 .etc/epiphany.profile $(DESTDIR)/$(sysconfdir)/firejail/. 91 done
86 install -c -m 0644 .etc/qtox.profile $(DESTDIR)/$(sysconfdir)/firejail/.
87 install -c -m 0644 .etc/polari.profile $(DESTDIR)/$(sysconfdir)/firejail/.
88 install -c -m 0644 .etc/gnome-mplayer.profile $(DESTDIR)/$(sysconfdir)/firejail/.
89 install -c -m 0644 .etc/rhythmbox.profile $(DESTDIR)/$(sysconfdir)/firejail/.
90 install -c -m 0644 .etc/totem.profile $(DESTDIR)/$(sysconfdir)/firejail/.
91 install -c -m 0644 .etc/firefox.profile $(DESTDIR)/$(sysconfdir)/firejail/.
92 install -c -m 0644 .etc/icedove.profile $(DESTDIR)/$(sysconfdir)/firejail/.
93 install -c -m 0644 .etc/iceweasel.profile $(DESTDIR)/$(sysconfdir)/firejail/.
94 install -c -m 0644 .etc/midori.profile $(DESTDIR)/$(sysconfdir)/firejail/.
95 install -c -m 0644 .etc/evince.profile $(DESTDIR)/$(sysconfdir)/firejail/.
96 install -c -m 0644 .etc/chromium-browser.profile $(DESTDIR)/$(sysconfdir)/firejail/.
97 install -c -m 0644 .etc/chromium.profile $(DESTDIR)/$(sysconfdir)/firejail/.
98 install -c -m 0644 .etc/google-chrome.profile $(DESTDIR)/$(sysconfdir)/firejail/.
99 install -c -m 0644 .etc/google-chrome-stable.profile $(DESTDIR)/$(sysconfdir)/firejail/.
100 install -c -m 0644 .etc/google-chrome-beta.profile $(DESTDIR)/$(sysconfdir)/firejail/.
101 install -c -m 0644 .etc/google-chrome-unstable.profile $(DESTDIR)/$(sysconfdir)/firejail/.
102 install -c -m 0644 .etc/disable-common.inc $(DESTDIR)/$(sysconfdir)/firejail/.
103 install -c -m 0644 .etc/dropbox.profile $(DESTDIR)/$(sysconfdir)/firejail/.
104 install -c -m 0644 .etc/opera.profile $(DESTDIR)/$(sysconfdir)/firejail/.
105 install -c -m 0644 .etc/opera-beta.profile $(DESTDIR)/$(sysconfdir)/firejail/.
106 install -c -m 0644 .etc/thunderbird.profile $(DESTDIR)/$(sysconfdir)/firejail/.
107 install -c -m 0644 .etc/transmission-gtk.profile $(DESTDIR)/$(sysconfdir)/firejail/.
108 install -c -m 0644 .etc/transmission-qt.profile $(DESTDIR)/$(sysconfdir)/firejail/.
109 install -c -m 0644 .etc/vlc.profile $(DESTDIR)/$(sysconfdir)/firejail/.
110 install -c -m 0644 .etc/deluge.profile $(DESTDIR)/$(sysconfdir)/firejail/.
111 install -c -m 0644 .etc/qbittorrent.profile $(DESTDIR)/$(sysconfdir)/firejail/.
112 install -c -m 0644 .etc/generic.profile $(DESTDIR)/$(sysconfdir)/firejail/.
113 install -c -m 0644 .etc/pidgin.profile $(DESTDIR)/$(sysconfdir)/firejail/.
114 install -c -m 0644 .etc/xchat.profile $(DESTDIR)/$(sysconfdir)/firejail/.
115 install -c -m 0644 .etc/empathy.profile $(DESTDIR)/$(sysconfdir)/firejail/.
116 install -c -m 0644 .etc/server.profile $(DESTDIR)/$(sysconfdir)/firejail/.
117 install -c -m 0644 .etc/icecat.profile $(DESTDIR)/$(sysconfdir)/firejail/.
118 install -c -m 0644 .etc/quassel.profile $(DESTDIR)/$(sysconfdir)/firejail/.
119 install -c -m 0644 .etc/deadbeef.profile $(DESTDIR)/$(sysconfdir)/firejail/.
120 install -c -m 0644 .etc/filezilla.profile $(DESTDIR)/$(sysconfdir)/firejail/.
121 install -c -m 0644 .etc/fbreader.profile $(DESTDIR)/$(sysconfdir)/firejail/.
122 install -c -m 0644 .etc/spotify.profile $(DESTDIR)/$(sysconfdir)/firejail/.
123 install -c -m 0644 .etc/steam.profile $(DESTDIR)/$(sysconfdir)/firejail/.
124 install -c -m 0644 .etc/skype.profile $(DESTDIR)/$(sysconfdir)/firejail/.
125 install -c -m 0644 .etc/wine.profile $(DESTDIR)/$(sysconfdir)/firejail/.
126 install -c -m 0644 .etc/disable-devel.inc $(DESTDIR)/$(sysconfdir)/firejail/.
127 install -c -m 0644 .etc/conkeror.profile $(DESTDIR)/$(sysconfdir)/firejail/.
128 install -c -m 0644 .etc/unbound.profile $(DESTDIR)/$(sysconfdir)/firejail/.
129 install -c -m 0644 .etc/dnscrypt-proxy.profile $(DESTDIR)/$(sysconfdir)/firejail/.
130 install -c -m 0644 .etc/whitelist-common.inc $(DESTDIR)/$(sysconfdir)/firejail/.
131 install -c -m 0644 .etc/nolocal.net $(DESTDIR)/$(sysconfdir)/firejail/.
132 install -c -m 0644 .etc/webserver.net $(DESTDIR)/$(sysconfdir)/firejail/.
133 install -c -m 0644 .etc/bitlbee.profile $(DESTDIR)/$(sysconfdir)/firejail/.
134 install -c -m 0644 .etc/weechat.profile $(DESTDIR)/$(sysconfdir)/firejail/.
135 install -c -m 0644 .etc/weechat-curses.profile $(DESTDIR)/$(sysconfdir)/firejail/.
136 install -c -m 0644 .etc/hexchat.profile $(DESTDIR)/$(sysconfdir)/firejail/.
137 install -c -m 0644 .etc/rtorrent.profile $(DESTDIR)/$(sysconfdir)/firejail/.
138 install -c -m 0644 .etc/parole.profile $(DESTDIR)/$(sysconfdir)/firejail/.
139 install -c -m 0644 .etc/kmail.profile $(DESTDIR)/$(sysconfdir)/firejail/.
140 install -c -m 0644 .etc/seamonkey.profile $(DESTDIR)/$(sysconfdir)/firejail/.
141 install -c -m 0644 .etc/seamonkey-bin.profile $(DESTDIR)/$(sysconfdir)/firejail/.
142 install -c -m 0644 .etc/telegram.profile $(DESTDIR)/$(sysconfdir)/firejail/.
143 install -c -m 0644 .etc/mathematica.profile $(DESTDIR)/$(sysconfdir)/firejail/.
144 install -c -m 0644 .etc/Mathematica.profile $(DESTDIR)/$(sysconfdir)/firejail/.
145 install -c -m 0644 .etc/uget-gtk.profile $(DESTDIR)/$(sysconfdir)/firejail/.
146 install -c -m 0644 .etc/mupen64plus.profile $(DESTDIR)/$(sysconfdir)/firejail/.
147 install -c -m 0644 .etc/disable-programs.inc $(DESTDIR)/$(sysconfdir)/firejail/.
148 install -c -m 0644 .etc/disable-passwdmgr.inc $(DESTDIR)/$(sysconfdir)/firejail/.
149 install -c -m 0644 .etc/lxterminal.profile $(DESTDIR)/$(sysconfdir)/firejail/.
150 install -c -m 0644 .etc/cherrytree.profile $(DESTDIR)/$(sysconfdir)/firejail/.
151 install -c -m 0644 .etc/wesnoth.profile $(DESTDIR)/$(sysconfdir)/firejail/.
152 install -c -m 0644 .etc/hedgewars.profile $(DESTDIR)/$(sysconfdir)/firejail/.
153 install -c -m 0644 .etc/vivaldi.profile $(DESTDIR)/$(sysconfdir)/firejail/.
154 install -c -m 0644 .etc/vivaldi-beta.profile $(DESTDIR)/$(sysconfdir)/firejail/.
155 install -c -m 0644 .etc/atril.profile $(DESTDIR)/$(sysconfdir)/firejail/.
156 install -c -m 0644 .etc/qutebrowser.profile $(DESTDIR)/$(sysconfdir)/firejail/.
157 install -c -m 0644 .etc/flashpeak-slimjet.profile $(DESTDIR)/$(sysconfdir)/firejail/.
158 install -c -m 0644 .etc/ssh.profile $(DESTDIR)/$(sysconfdir)/firejail/.
159 install -c -m 0644 .etc/openbox.profile $(DESTDIR)/$(sysconfdir)/firejail/.
160 install -c -m 0644 .etc/dillo.profile $(DESTDIR)/$(sysconfdir)/firejail/.
161 install -c -m 0644 .etc/cmus.profile $(DESTDIR)/$(sysconfdir)/firejail/.
162 install -c -m 0644 .etc/dnsmasq.profile $(DESTDIR)/$(sysconfdir)/firejail/.
163 install -c -m 0644 .etc/palemoon.profile $(DESTDIR)/$(sysconfdir)/firejail/.
164 install -c -m 0644 .etc/icedove.profile $(DESTDIR)/$(sysconfdir)/firejail/.
165 install -c -m 0644 .etc/abrowser.profile $(DESTDIR)/$(sysconfdir)/firejail/.
166 install -c -m 0644 .etc/0ad.profile $(DESTDIR)/$(sysconfdir)/firejail/.
167 sh -c "if [ ! -f $(DESTDIR)/$(sysconfdir)/firejail/login.users ]; then install -c -m 0644 etc/login.users $(DESTDIR)/$(sysconfdir)/firejail/.; fi;" 92 sh -c "if [ ! -f $(DESTDIR)/$(sysconfdir)/firejail/login.users ]; then install -c -m 0644 etc/login.users $(DESTDIR)/$(sysconfdir)/firejail/.; fi;"
168 sh -c "if [ ! -f $(DESTDIR)/$(sysconfdir)/firejail/firejail.config ]; then install -c -m 0644 etc/firejail.config $(DESTDIR)/$(sysconfdir)/firejail/.; fi;"
169 rm -fr .etc 93 rm -fr .etc
94ifeq ($(HAVE_APPARMOR),-DHAVE_APPARMOR)
95 # install apparmor profile
96 sh -c "if [ ! -d $(DESTDIR)/$(sysconfdir)/apparmor.d ]; then install -d -m 755 $(DESTDIR)/$(sysconfdir)/apparmor.d; fi;"
97 install -c -m 0644 etc/firejail-default $(DESTDIR)/$(sysconfdir)/apparmor.d/.
98endif
170 # man pages 99 # man pages
171 rm -f firejail.1.gz
172 gzip -9n firejail.1
173 rm -f firemon.1.gz
174 gzip -9n firemon.1
175 rm -f firecfg.1.gz
176 gzip -9n firecfg.1
177 rm -f firejail-profile.5.gz
178 gzip -9n firejail-profile.5
179 rm -f firejail-login.5.gz
180 gzip -9n firejail-login.5
181 rm -f firejail-config.5.gz
182 gzip -9n firejail-config.5
183 install -m 0755 -d $(DESTDIR)/$(mandir)/man1 100 install -m 0755 -d $(DESTDIR)/$(mandir)/man1
184 install -c -m 0644 firejail.1.gz $(DESTDIR)/$(mandir)/man1/.
185 install -c -m 0644 firemon.1.gz $(DESTDIR)/$(mandir)/man1/.
186 install -c -m 0644 firecfg.1.gz $(DESTDIR)/$(mandir)/man1/.
187 install -m 0755 -d $(DESTDIR)/$(mandir)/man5 101 install -m 0755 -d $(DESTDIR)/$(mandir)/man5
188 install -c -m 0644 firejail-profile.5.gz $(DESTDIR)/$(mandir)/man5/. 102 for man in $(MANPAGES); do \
189 install -c -m 0644 firejail-login.5.gz $(DESTDIR)/$(mandir)/man5/. 103 rm -f $$man.gz; \
190 install -c -m 0644 firejail-config.5.gz $(DESTDIR)/$(mandir)/man5/. 104 gzip -9n $$man; \
191 rm -f firejail.1.gz firemon.1.gz firecfg.1.gz firejail-profile.5.gz firejail-login.5.gz firejail-config.5.gz 105 case "$$man" in \
106 *.1) install -c -m 0644 $$man.gz $(DESTDIR)/$(mandir)/man1/; ;; \
107 *.5) install -c -m 0644 $$man.gz $(DESTDIR)/$(mandir)/man5/; ;; \
108 esac; \
109 done
110 rm -f $(MANPAGES) $(MANPAGES:%=%.gz)
192 # bash completion 111 # bash completion
193 install -m 0755 -d $(DESTDIR)/$(datarootdir)/bash-completion/completions 112 install -m 0755 -d $(DESTDIR)/$(datarootdir)/bash-completion/completions
194 install -c -m 0644 src/bash_completion/firejail.bash_completion $(DESTDIR)/$(datarootdir)/bash-completion/completions/firejail 113 install -c -m 0644 src/bash_completion/firejail.bash_completion $(DESTDIR)/$(datarootdir)/bash-completion/completions/firejail
195 install -c -m 0644 src/bash_completion/firemon.bash_completion $(DESTDIR)/$(datarootdir)/bash-completion/completions/firemon 114 install -c -m 0644 src/bash_completion/firemon.bash_completion $(DESTDIR)/$(datarootdir)/bash-completion/completions/firemon
196 install -c -m 0644 src/bash_completion/firecfg.bash_completion $(DESTDIR)/$(datarootdir)/bash-completion/completions/firecfg 115 install -c -m 0644 src/bash_completion/firecfg.bash_completion $(DESTDIR)/$(datarootdir)/bash-completion/completions/firecfg
197 116
198
199install: all 117install: all
200 $(MAKE) realinstall 118 $(MAKE) realinstall
201 119
@@ -205,7 +123,11 @@ install-strip: all
205 strip src/firecfg/firecfg 123 strip src/firecfg/firecfg
206 strip src/libtrace/libtrace.so 124 strip src/libtrace/libtrace.so
207 strip src/libtracelog/libtracelog.so 125 strip src/libtracelog/libtracelog.so
126 strip src/libconnect/libconnect.so
208 strip src/ftee/ftee 127 strip src/ftee/ftee
128 strip src/faudit/faudit
129 strip src/fnet/fnet
130 strip src/fseccomp/fseccomp
209 $(MAKE) realinstall 131 $(MAKE) realinstall
210 132
211uninstall: 133uninstall:
@@ -214,30 +136,44 @@ uninstall:
214 rm -f $(DESTDIR)/$(bindir)/firecfg 136 rm -f $(DESTDIR)/$(bindir)/firecfg
215 rm -fr $(DESTDIR)/$(libdir)/firejail 137 rm -fr $(DESTDIR)/$(libdir)/firejail
216 rm -fr $(DESTDIR)/$(datarootdir)/doc/firejail 138 rm -fr $(DESTDIR)/$(datarootdir)/doc/firejail
217 rm -f $(DESTDIR)/$(mandir)/man1/firejail.1* 139 for man in $(MANPAGES); do \
218 rm -f $(DESTDIR)/$(mandir)/man1/firemon.1* 140 rm -f $(DESTDIR)/$(mandir)/man5/$$man*; \
219 rm -f $(DESTDIR)/$(mandir)/man1/firecfg.1* 141 rm -f $(DESTDIR)/$(mandir)/man1/$$man*; \
220 rm -f $(DESTDIR)/$(mandir)/man5/firejail-profile.5* 142 done
221 rm -f $(DESTDIR)/$(mandir)/man5/firejail-login.5*
222 rm -f $(DESTDIR)/$(mandir)/man5/firejail-config.5*
223 rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firejail 143 rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firejail
224 rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firemon 144 rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firemon
225 rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firecfg 145 rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firecfg
226 146
147DISTFILES = "src etc platform configure configure.ac Makefile.in install.sh mkman.sh mketc.sh mkdeb.sh mkuid.sh COPYING README RELNOTES"
148DISTFILES_TEST = "test/rlimit test/apps test/apps-x11 test/apps-x11-xorg test/root test/environment test/profiles test/utils test/compile test/filters test/network test/arguments test/fs test/sysutils"
149
227dist: 150dist:
151 mv config.status config.status.old
228 make distclean 152 make distclean
229 rm -fr $(NAME)-$(VERSION) $(NAME)-$(VERSION).tar.bz2 153 mv config.status.old config.status
230 mkdir $(NAME)-$(VERSION) 154 rm -fr $(NAME)-$(VERSION) $(NAME)-$(VERSION).tar.xz
231 cd $(NAME)-$(VERSION); cp -a ../src .; cp -a ../etc .; cp -a ../platform .; rm -fr src/tools; cd .. 155 mkdir -p $(NAME)-$(VERSION)/test
232 cd $(NAME)-$(VERSION); cp -a ../configure .; cp -a ../configure.ac .; cp -a ../Makefile.in .; cp -a ../install.sh .; cp -a ../mkman.sh .; cp -a ../mketc.sh .; cp -a ../mkdeb.sh .;cd .. 156 cp -a "$(DISTFILES)" $(NAME)-$(VERSION)
233 cd $(NAME)-$(VERSION); cp -a ../COPYING .; cp -a ../README .; cp -a ../RELNOTES .; cd .. 157 cp -a "$(DISTFILES_TEST)" $(NAME)-$(VERSION)/test
234 cd $(NAME)-$(VERSION); rm -fr `find . -name .svn`; rm -fr $(NAME)-$(VERSION); cd .. 158 rm -rf $(NAME)-$(VERSION)/src/tools
235 tar -cjvf $(NAME)-$(VERSION).tar.bz2 $(NAME)-$(VERSION) 159 find $(NAME)-$(VERSION) -name .svn -delete
160 tar -cJvf $(NAME)-$(VERSION).tar.xz $(NAME)-$(VERSION)
236 rm -fr $(NAME)-$(VERSION) 161 rm -fr $(NAME)-$(VERSION)
237 162
163asc:; ./mkasc.sh $(VERSION)
164
238deb: dist 165deb: dist
239 ./mkdeb.sh $(NAME) $(VERSION) 166 ./mkdeb.sh $(NAME) $(VERSION)
240 167
168snap: all
169 cd platform/snap; ./snap.sh
170
171install-snap: snap
172 sudo snap remove faudit; sudo snap install faudit*.snap
173
174test-compile: dist
175 cd test/compile; ./compile.sh $(NAME)-$(VERSION)
176
241.PHONY: rpms 177.PHONY: rpms
242rpms: 178rpms:
243 ./platform/rpm/mkrpm.sh $(NAME) $(VERSION) 179 ./platform/rpm/mkrpm.sh $(NAME) $(VERSION)
@@ -250,5 +186,74 @@ cppcheck: clean
250 186
251scan-build: clean 187scan-build: clean
252 scan-build make 188 scan-build make
253asc:; ./mkasc.sh $(VERSION)
254 189
190
191#
192# make test
193#
194
195
196test-profiles:
197 cd test/profiles; ./profiles.sh | grep TESTING
198
199test-apps:
200 cd test/apps; ./apps.sh | grep TESTING
201
202test-apps-x11:
203 cd test/apps-x11; ./apps-x11.sh | grep TESTING
204
205test-apps-x11-xorg:
206 cd test/apps-x11-xorg; ./apps-x11-xorg.sh | grep TESTING
207
208test-sysutils:
209 cd test/sysutils; ./sysutils.sh | grep TESTING
210
211test-utils:
212 cd test/utils; ./utils.sh | grep TESTING
213
214test-environment:
215 cd test/environment; ./environment.sh | grep TESTING
216
217test-filters:
218 cd test/filters; ./filters.sh | grep TESTING
219
220test-arguments:
221 cd test/arguments; ./arguments.sh | grep TESTING
222
223test-fs:
224 cd test/fs; ./fs.sh | grep TESTING
225
226test-rlimit:
227 cd test/rlimit; ./rlimit.sh | grep TESTING
228
229test: test-profiles test-fs test-utils test-environment test-apps test-apps-x11 test-apps-x11-xorg test-filters test-arguments test-rlimit
230 echo "TEST COMPLETE"
231
232##########################################
233# Individual tests, some of them require root access
234# The tests are very intrussive, by the time you are done
235# with them you will need to restart your computer.
236##########################################
237
238# Huge appimage files, not included in "make dist" archive
239test-appimage:
240 cd test/appimage; ./appimage.sh | grep TESTING
241
242# Root access, network devices are created before the test
243# restart your computer to get rid of these devices
244test-network:
245 cd test/network; ./network.sh | grep TESTING
246
247# Tesets running a root user
248test-root:
249 cd test/root; su -c ./root.sh | grep TESTING
250
251# OverlayFS is not available on all platforms
252test-overlay:
253 cd test/overlay; ./overlay.sh | grep TESTING
254
255# For testing hidepid system, the command to set it up is "mount -o remount,rw,hidepid=2 /proc"
256
257test-all: test-root test-network test-appimage test-overlay test
258 echo "TEST COMPLETE"
259 \ No newline at end of file
diff --git a/README b/README
index 81481f512..e21e96bc7 100644
--- a/README
+++ b/README
@@ -18,18 +18,171 @@ License: GPL v2
18Firejail Authors: 18Firejail Authors:
19 19
20netblue30 (netblue30@yahoo.com) 20netblue30 (netblue30@yahoo.com)
21Joan Figueras (https://github.com/figue) 21Reiner Herrmann (https://github.com/reinerh)
22 - added abrowser profile 22 - a number of build patches
23 - man page fixes
24 - Debian and Ubuntu integration
25 - clang-analyzer fixes
26 - Debian reproducible build
27 - unit testing framework
28 - moved build to .xz
29 - detached signatures for source archive
30 - recursive mkdir
31Aleksey Manevich (https://github.com/manevich)
32 - several profile fixes
33 - fix problem with relative path in storage_find function
34 - fix build for systems without bash
35 - fix double quotes/single quotes problem
36 - big rework of argument processing subsystem
37 - --join fixes
38 - spliting up cmdline.c
39 - Busybox support
40 - X11 support rewrite
41 - gether shell selection code in one place
42 - fixed several TOCTOU security problems
43 - added --fix option to firecfg utility
44 - read_pid fix
45 - added --x11=block options
46 - x11 xpra, xphyr, none profile commands
47 - added --join-or-start command
48 - CVE-2016-7545
23Fred-Barclay (https://github.com/Fred-Barclay) 49Fred-Barclay (https://github.com/Fred-Barclay)
50 - lots of profile fixes
24 - added Vivaldi, Atril profiles 51 - added Vivaldi, Atril profiles
25 - added PaleMoon profile 52 - added PaleMoon profile
26 - split Icedove and Thunderbird profiles 53 - split Icedove and Thunderbird profiles
27 - added 0ad profile 54 - added 0ad profile
55 - fixed version for .deb packages
56 - added Warzone2100 profile
57 - blacklisted VeraCrypt
58 - added Gpredict profile
59 - added Aweather, Stellarium profiles
60 - fixed HexChat and Atril profiles
61 - fixed disable-common.inc for mate-terminal
62 - blacklisted escape-happy terminals in disable-common.inc
63 - blacklisted g++
64 - added xplayer, xreader, and xviewer profiles
65 - added Brave profile
66 - added Gitter profile
67 - various organising
68 - added LibreOffice profile
69 - added pix profile
70 - added audacity profile
71 - fixed Telegram and qtox profiles
72 - added Atom Beta and Atom profiles
73 - tightened 0ad, atril, evince, gthumb, pix, qtox, and xreader profiles
74 - several private-bin conversions
75 - added jitsi profile
76 - pidgin private-bin conversion
77 - added eom profile
78 - added gnome-chess profile
79 - added DOSBox profile
80 - evince profile enhancement
81 - tightened Spotify profile
82 - added xiphos and Tor Browser Bundle profiles
83curiosity-seeker (https://github.com/curiosity-seeker)
84 - tightening unbound and dnscrypt-proxy profiles
85 - dnsmasq profile
86 - okular and gwenview profiles
87 - cherrytree profile fixes
88 - added quiterss profile
89 - added guayadeque profile
90Simon Peter (https://github.com/probonopd)
91 - set $APPIMAGE and $APPDIR environment variables
92 - AppImage version detection
93 - Leafppad type v1 and v2 appimage packages in test/appimage
94BogDan Vatra (https://github.com/bog-dan-ro)
95 - zoom profile
96Impyy (https://github.com/Impyy)
97 - added mumble profile
98valoq (https://github.com/valoq)
99 - LibreOffice profile fixes
100 - cherrytree profile fixes
101 - added support for /srv in --whitelist feature
102 - Eye of GNOME, Evolution, display (imagemagik) and Wire profiles
103 - blacklist suid binaries in disable-common.inc
104 - fix man pages
105 - various profile improvements
106Vadim A. Misbakh-Soloviov (https://github.com/msva)
107 - profile fixes
108Rafael Cavalcanti (https://github.com/rccavalcanti)
109 - chromium profile fixes for Arch Linux
110Deelvesh Bunjun (https://github.com/DeelveshBunjun)
111 - added xpdf profile
112Dara Adib (https://github.com/daradib)
113 - ssh profile fix
114 - evince profile fix
115vismir2 (https://github.com/vismir2)
116 - feh, ranger, 7z, keepass, keepassx and zathura profiles
117 - claws-mail, mutt, git, emacs, vim profiles
118 - lots of profile fixes
119graywolf (https://github.com/graywolf)
120 - spelling fix
121Tomasz Jan Góralczyk (https://github.com/tjg)
122 - fixed Steam profile
123pwnage-pineapple (https://github.com/pwnage-pineapple)
124 - update Okular profile
125Sergey Alirzaev (https://github.com/l29ah)
126 - firejail.h enum fix
127greigdp (https://github.com/greigdp)
128 - Gajim IM client profile
129 - fix Slack profile
130Icaro Perseo (https://github.com/icaroperseo)
131 - Icecat profile
132 - several profile fixes
133hamzadis (https://github.com/hamzadis)
134 - added --overlay-named=name and --overlay-path=path
135Gaman Gabriel (https://github.com/stelariusinfinitek)
136 - inox profile
137greigdp (https://github.com/greigdp)
138 - fixed spotify profile
139 - added Slack profile
140Laurent Declercq (https://github.com/nuxwin)
141 - fixed test for shell interpreter in chroots
142Franco (nextime) Lanza (https://github.com/nextime)
143 - added --private-template/--private-home
144xee5ch (https://github.com/xee5ch)
145 - skypeforlinux profile
146Peter Hogg (https://github.com/pigmonkey)
147 - WeeChat profile
148 - rtorrent profile
149 - bitlbee profile fixes
150 - mutt profile fixes
151Thomas Jarosch (https://github.com/thomasjfox)
152 - disable keepassx in disable-passwdmgr.inc
153 - added uudeview profile
154 - added tar (gtar), unzip and unrar profile
155 - added file profile
156 - improved profile list
157 - fixed small variable glitch in stat64() / lstat64() (libtracelog)
158 - added lstat() / lstat64() support to libtrace
159 - include mkuid.sh in make dist
160Niklas Haas (https://github.com/haasn)
161 - blacklisting for keybase.io's client
162Jaykishan Mutkawoa (https://github.com/jmutkawoa)
163 - cpio profile
164Paupiah Yash (https://github.com/CaffeinatedStud)
165 - gzip profile
166Akhil Hans Maulloo (https://github.com/kouul)
167 - xz profile
168Rahul Golam (https://github.com/technoLord)
169 - strings profile
170geg2048 (https://github.com/geg2048)
171 - kwallet profile fixes
172maces (https://github.com/maces)
173 - Franz messenger profile
174KellerFuchs (https://github.com/KellerFuchs)
175 - nonewpriv support, extended profiles for this feature
176 - make `restricted-network` prevent use of netfilter
177 - disable-common.inc additions
178ValdikSS (https://github.com/ValdikSS)
179 - Psi+, Corebird, Konversation profiles
180 - various profile fixes
28avoidr (https://github.com/avoidr) 181avoidr (https://github.com/avoidr)
29 - whitelist fix 182 - whitelist fix
30 - recently-used.xbel fix 183 - recently-used.xbel fix
31 - added parole profile 184 - added parole profile
32 - blacklist ncat, manpage fixes, 185 - blacklist ncat
33 - hostname support in profile file 186 - hostname support in profile file
34 - Google Chrome profile rework 187 - Google Chrome profile rework
35 - added cmus profile 188 - added cmus profile
@@ -37,6 +190,23 @@ avoidr (https://github.com/avoidr)
37 - add net iface support in profile files 190 - add net iface support in profile files
38 - paths fix 191 - paths fix
39 - lots of profile fixes 192 - lots of profile fixes
193 - added mcabber profile
194 - fixed mpv profile
195 - various other fixes
196Ruan (https://github.com/ruany)
197 - fixed hexchat profile
198Vasya Novikov (https://github.com/vn971)
199 - Wesnoth profile
200 - Hedegewars profile
201 - manpage fixes
202 - fixed firecfg clean/clear issue
203 - found the ugliest bug so far
204Matthew Gyurgyik (https://github.com/pyther)
205 - rpm spec and several fixes
206Joan Figueras (https://github.com/figue)
207 - added abrowser profile
208 - added Google-Play-Music-Desktop-Player
209 - added cyberfox profile
40Petter Reinholdtsen (pere@hungry.com) 210Petter Reinholdtsen (pere@hungry.com)
41 - Opera profile patch 211 - Opera profile patch
42n1trux (https://github.com/n1trux) 212n1trux (https://github.com/n1trux)
@@ -52,12 +222,9 @@ dshmgh (https://github.com/dshmgh)
52yumkam (https://github.com/yumkam) 222yumkam (https://github.com/yumkam)
53 - add compile-time option to restrict --net= to root only 223 - add compile-time option to restrict --net= to root only
54 - man page fixes 224 - man page fixes
55Vasya Novikov (https://github.com/vn971)
56 - Wesnoth profile
57 - Hedegewars profile
58 - manpage fixes
59mahdi1234 (https://github.com/mahdi1234) 225mahdi1234 (https://github.com/mahdi1234)
60 - cherrytree profile 226 - cherrytree profile
227 - Seamonkey profiles
61jrabe (https://github.com/jrabe) 228jrabe (https://github.com/jrabe)
62 - disallow access to kdbx files 229 - disallow access to kdbx files
63 - Epiphany profile 230 - Epiphany profile
@@ -71,19 +238,14 @@ Tom Mellor (https://github.com/kalegrill)
71Martin Carpenter (https://github.com/mcarpenter) 238Martin Carpenter (https://github.com/mcarpenter)
72 - security audit and bug fixes 239 - security audit and bug fixes
73 - Centos 6.x support 240 - Centos 6.x support
74Aleksey Manevich (https://github.com/manevich)
75 - several profile fixes
76 - fix problem with relative path in storage_find function
77 - fix build for systems without bash
78pszxzsd (https://github.com/pszxzsd) 241pszxzsd (https://github.com/pszxzsd)
79 -uGet profile 242 -uGet profile
80Rahiel Kasim (https://github.com/rahiel) 243Rahiel Kasim (https://github.com/rahiel)
81 - Mathematica profile 244 - Mathematica profile
245 - whitelisted Dropbox profile
246 - whitelisted keysnail config for firefox
82creideiki (https://github.com/creideiki) 247creideiki (https://github.com/creideiki)
83 - make the sandbox process reap all children 248 - make the sandbox process reap all children
84curiosity-seeker (https://github.com/curiosity-seeker)
85 - tightening unbound and dnscrypt-proxy profiles
86 - dnsmasq profile
87sinkuu (https://github.com/sinkuu) 249sinkuu (https://github.com/sinkuu)
88 - blacklisting kwalletd 250 - blacklisting kwalletd
89 - fix symlink invocation for programs placing symlinks in $PATH 251 - fix symlink invocation for programs placing symlinks in $PATH
@@ -93,8 +255,7 @@ Holger Heinz (https://github.com/hheinz)
93 - manpage work 255 - manpage work
94Andrey Alekseenko (https://github.com/al42and) 256Andrey Alekseenko (https://github.com/al42and)
95 - fixing lintian warnings 257 - fixing lintian warnings
96mahdi1234 (https://github.com/mahdi1234) 258 - fixed Skype profile
97 - Seamonkey profiles
98Ivan Kozik (https://github.com/ivan) 259Ivan Kozik (https://github.com/ivan)
99 - speed up sandbox exit 260 - speed up sandbox exit
100Christian Stadelmann (https://github.com/genodeftest) 261Christian Stadelmann (https://github.com/genodeftest)
@@ -105,11 +266,6 @@ Kaan Genç (https://github.com/SeriousBug)
105 - dynamic allocation of noblacklist buffer 266 - dynamic allocation of noblacklist buffer
106Veeti Paananen (https://github.com/veeti) 267Veeti Paananen (https://github.com/veeti)
107 - fixed Spotify profile 268 - fixed Spotify profile
108Rahiel Kasim (https://github.com/rahiel)
109 - whitelist keysnail config for firefox
110Peter Hogg (https://github.com/pigmonkey)
111 - WeeChat profile
112 - rtorrent profile
113rogshdo (https://github.com/rogshdo) 269rogshdo (https://github.com/rogshdo)
114 - BitlBee profile 270 - BitlBee profile
115Bruno Nova (https://github.com/brunonova) 271Bruno Nova (https://github.com/brunonova)
@@ -117,8 +273,6 @@ Bruno Nova (https://github.com/brunonova)
117 - bash arguments fix 273 - bash arguments fix
118Matt Parnell (https://github.com/ilikenwf) 274Matt Parnell (https://github.com/ilikenwf)
119 - whitelisting for core firefox related functionality 275 - whitelisting for core firefox related functionality
120Andrey Alekseenko (https://github.com/al42and)
121 - fixed Skype profile
122Ondra Nekola (https://github.com/satai) 276Ondra Nekola (https://github.com/satai)
123 - allow firefox theming with non-global themes 277 - allow firefox theming with non-global themes
124emacsomancer (https://github.com/emacsomancer) 278emacsomancer (https://github.com/emacsomancer)
@@ -132,8 +286,6 @@ andrew160 (https://github.com/andrew160)
132 - profile and man pages fixes 286 - profile and man pages fixes
133Loïc Damien (https://github.com/dzamlo) 287Loïc Damien (https://github.com/dzamlo)
134 - small fixes 288 - small fixes
135Matthew Gyurgyik (https://github.com/pyther)
136 - rpm spec and several fixes
137greigdp (https://github.com/greigdp) 289greigdp (https://github.com/greigdp)
138 - add Spotify profile 290 - add Spotify profile
139Mattias Wadman (https://github.com/wader) 291Mattias Wadman (https://github.com/wader)
@@ -150,12 +302,6 @@ sarneaud (https://github.com/sarneaud)
150 - various enhancements and bug fixes 302 - various enhancements and bug fixes
151Patrick Toomey (http://sourceforge.net/u/ptoomey/profile/) 303Patrick Toomey (http://sourceforge.net/u/ptoomey/profile/)
152 - user namespace implementation 304 - user namespace implementation
153Reiner Herrmann
154 - a number of build patches
155 - man page fixes
156 - Debian and Ubuntu integration
157 - clang-analyzer fixes
158 - Debian reproducible build
159sshirokov (http://sourceforge.net/u/yshirokov/profile/) 305sshirokov (http://sourceforge.net/u/yshirokov/profile/)
160 - Patch to output "Reading profile" to stderr instead of stdout 306 - Patch to output "Reading profile" to stderr instead of stdout
161G4JC (http://sourceforge.net/u/gaming4jc/profile/) 307G4JC (http://sourceforge.net/u/gaming4jc/profile/)
diff --git a/README.md b/README.md
index 7f6f573b4..ad90639e2 100644
--- a/README.md
+++ b/README.md
@@ -31,255 +31,26 @@ Features: https://firejail.wordpress.com/features-3/
31Documentation: https://firejail.wordpress.com/documentation-2/ 31Documentation: https://firejail.wordpress.com/documentation-2/
32 32
33FAQ: https://firejail.wordpress.com/support/frequently-asked-questions/ 33FAQ: https://firejail.wordpress.com/support/frequently-asked-questions/
34`````
35 34
36````` 35`````
37# Current development version: 0.9.40-rc2
38Version 0.9.40-rc1 released!
39
40## X11 sandboxing support
41 36
42X11 support is built around Xpra (http://xpra.org/) or Xephyr.
43````` 37`````
44 --x11 Start a new X11 server using Xpra or Xephyr and attach the sand‐ 38## User submitted profile repositories
45 box to this server. The regular X11 server (display 0) is not
46 visible in the sandbox. This prevents screenshot and keylogger
47 applications started in the sandbox from accessing other X11
48 displays. A network namespace needs to be instantiated in order
49 to deny access to X11 abstract Unix domain socket.
50
51 Firejail will try first Xpra, and if Xpra is not installed on
52 the system, it will try to find Xephyr. This feature is not
53 available when running as root.
54
55 Example:
56 $ firejail --x11 --net=eth0 firefox
57
58 --x11=xpra
59 Start a new X11 server using Xpra (http://xpra.org) and attach
60 the sandbox to this server. Xpra is a persistent remote display
61 server and client for forwarding X11 applications and desktop
62 screens. On Debian platforms Xpra is installed with the command
63 sudo apt-get install xpra. This feature is not available when
64 running as root.
65
66 Example:
67 $ firejail --x11 --net=eth0 firefox
68
69 --x11=xephyr
70 Start a new X11 server using Xephyr and attach the sandbox to
71 this server. Xephyr is a display server implementing the X11
72 display server protocol. It runs in a window just like other X
73 applications, but it is an X server itself in which you can run
74 other software. The default Xephyr window size is 800x600. This
75 can be modified in /etc/firejail/firejail.config file, see man 5
76 firejail-config for more details.
77
78 The recommended way to use this feature is to run a window man‐
79 ager inside the sandbox. A security profile for OpenBox is pro‐
80 vided. On Debian platforms Xephyr is installed with the command
81 sudo apt-get install xserver-xephyr. This feature is not avail‐
82 able when running as root.
83
84 Example:
85 $ firejail --x11 --net=eth0 openbox
86`````
87More information here: https://firejail.wordpress.com/documentation-2/x11-guide/
88
89## File transfers
90`````
91FILE TRANSFER
92 These features allow the user to inspect the filesystem container of an
93 existing sandbox and transfer files from the container to the host
94 filesystem.
95
96 --get=name filename
97 Retrieve the container file and store it on the host in the cur‐
98 rent working directory. The container is specified by name
99 (--name option). Full path is needed for filename.
100
101 --get=pid filename
102 Retrieve the container file and store it on the host in the cur‐
103 rent working directory. The container is specified by process
104 ID. Full path is needed for filename.
105
106 --ls=name dir_or_filename
107 List container files. The container is specified by name
108 (--name option). Full path is needed for dir_or_filename.
109 39
110 --ls=pid dir_or_filename 40If you keep your Firejail profiles in a public repository, please give us a link:
111 List container files. The container is specified by process ID.
112 Full path is needed for dir_or_filename.
113 41
114 Examples: 42* https://github.com/chiraag-nataraj/firejail-profiles
115 43
116 $ firejail --name=mybrowser --private firefox 44* https://github.com/triceratops1/fe
117 45
118 $ firejail --ls=mybrowser ~/Downloads 46Use this issue to request new profiles: https://github.com/netblue30/firejail/issues/825
119 drwxr-xr-x netblue netblue 4096 .
120 drwxr-xr-x netblue netblue 4096 ..
121 -rw-r--r-- netblue netblue 7847 x11-x305.png
122 -rw-r--r-- netblue netblue 6800 x11-x642.png
123 -rw-r--r-- netblue netblue 34139 xpra-clipboard.png
124
125 $ firejail --get=mybrowser ~/Downloads/xpra-clipboard.png
126````` 47`````
127 48
128## Firecfg
129````` 49`````
130NAME 50# Current development version: 0.9.45
131 Firecfg - Desktop configuration program for Firejail software.
132
133SYNOPSIS
134 firecfg [OPTIONS]
135
136DESCRIPTION
137 Firecfg is the desktop configuration utility for Firejail software. The
138 utility creates several symbolic links to firejail executable. This
139 allows the user to sandbox applications automatically, just by clicking
140 on a regular desktop menus and icons.
141
142 The symbolic links are placed in /usr/local/bin. For more information,
143 see DESKTOP INTEGRATION section in man 1 firejail.
144
145OPTIONS
146 --clear
147 Clear all firejail symbolic links
148
149 -?, --help
150 Print options end exit.
151
152 --list List all firejail symbolic links
153
154 --version
155 Print program version and exit.
156
157 Example:
158
159 $ sudo firecfg
160 /usr/local/bin/firefox created
161 /usr/local/bin/vlc created
162 [...]
163 $ firecfg --list
164 /usr/local/bin/firefox
165 /usr/local/bin/vlc
166 [...]
167 $ sudo firecfg --clear
168 /usr/local/bin/firefox removed
169 /usr/local/bin/vlc removed
170 [...]
171````` 51`````
172 52
173
174## Compile time and run time configuration support
175
176Most Linux kernel security features require root privileges during configuration.
177The same is true for kernel networking features. Firejail (SUID binary) opens the
178access to these features to regular users. The privilege escalation is restricted
179to the sandbox being configured, and is not extended to the rest of the system.
180This arrangement works fine for user desktops or servers where the access is already limited.
181
182If you not happy with a particular feature, all the support can be eliminated from SUID binary at compile time,
183or at run time by editing /etc/firejail/firejail.config file.
184
185The following features can be enabled or disabled:
186````` 53`````
187 bind Enable or disable bind support, default enabled. 54## New Profiles
188 55xiphos, Tor Browser Bundle, display (imagemagik), Wire, mumble, zoom,Guayadeque
189 chroot Enable or disable chroot support, default enabled.
190
191 file-transfer
192 Enable or disable file transfer support, default enabled.
193
194 network
195 Enable or disable networking features, default enabled.
196
197 restricted-network
198 Enable or disable restricted network support, default disabled.
199 If enabled, networking features should also be enabled (network
200 yes). Restricted networking grants access to --interface and
201 --net=ethXXX only to root user. Regular users are only allowed
202 --net=none.
203
204 secomp Enable or disable seccomp support, default enabled.
205
206 userns Enable or disable user namespace support, default enabled.
207
208 x11 Enable or disable X11 sandboxing support, default enabled.
209
210 xephyr-screen
211 Screen size for --x11=xephyr, default 800x600. Run
212 /usr/bin/xrandr for a full list of resolutions available on your
213 specific setup. Examples:
214
215 xephyr-screen 640x480
216 xephyr-screen 800x600
217 xephyr-screen 1024x768
218 xephyr-screen 1280x1024
219`````
220
221## Default seccomp filter update
222
223Currently 50 syscalls are blacklisted by default, out of a total of 318 calls (AMD64, Debian Jessie).
224
225## STUN/WebRTC disabled in default netfilter configuration
226
227The current netfilter configuration (--netfilter option) looks like this:
228`````
229 *filter
230 :INPUT DROP [0:0]
231 :FORWARD DROP [0:0]
232 :OUTPUT ACCEPT [0:0]
233 -A INPUT -i lo -j ACCEPT
234 -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
235 # allow ping
236 -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
237 -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
238 -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
239 # drop STUN (WebRTC) requests
240 -A OUTPUT -p udp --dport 3478 -j DROP
241 -A OUTPUT -p udp --dport 3479 -j DROP
242 -A OUTPUT -p tcp --dport 3478 -j DROP
243 -A OUTPUT -p tcp --dport 3479 -j DROP
244 COMMIT
245`````
246
247The filter is loaded by default for Firefox if a network namespace is configured:
248`````
249$ firejail --net=eth0 firefox
250`````
251
252## Set sandbox nice value
253`````
254 --nice=value
255 Set nice value for all processes running inside the sandbox.
256
257 Example:
258 $ firejail --nice=-5 firefox
259`````
260
261## mkdir
262
263`````
264$ man firejail-profile
265[...]
266 mkdir directory
267 Create a directory in user home. Use this command for
268 whitelisted directories you need to preserve when the sandbox is
269 closed. Subdirectories also need to be created using mkdir.
270 Example from firefox profile:
271
272 mkdir ~/.mozilla
273 whitelist ~/.mozilla
274 mkdir ~/.cache
275 mkdir ~/.cache/mozilla
276 mkdir ~/.cache/mozilla/firefox
277 whitelist ~/.cache/mozilla/firefox
278
279[...]
280`````
281
282## New security profiles
283lxterminal, Epiphany, cherrytree, Polari, Vivaldi, Atril, qutebrowser, SlimJet, Battle for Wesnoth, Hedgewars, qTox,
284OpenSSH client, OpenBox window manager, Dillo, cmus, dnsmasq, PaleMoon, Icedove, abrowser, 0ad
285 56
diff --git a/RELNOTES b/RELNOTES
index fbd620408..e726674ec 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -1,12 +1,102 @@
1firejail (0.9.40-rc1) baseline; urgency=low 1firejail (0.9.45) baseline; urgency=low
2 * development version, work in progress
3 * security: overwrite /etc/resolv.conf found by Martin Carpenter
4 * secuirty: TOCTOU exploit for --get and --put found by Daniel Hodson
5 * security: invalid environment exploit found by Martin Carpenter
6 * security: split most of networking code in a separate executable
7 * security: split seccomp filter code configuration in a separate executable
8 * feature: allow root user access to /dev/shm (--noblacklist=/dev/shm)
9 * new profiles: xiphos, Tor Browser Bundle, display (imagemagik), Wire,
10 * new profiles: mumble, zoom, Guayadeque
11 * bugfixes
12 -- netblue30 <netblue30@yahoo.com> Sun, 23 Oct 2016 08:00:00 -0500
13
14firejail (0.9.44) baseline; urgency=low
15 * CVE-2016-7545 submitted by Aleksey Manevich
16 * modifs: removed man firejail-config
17 * modifs: --private-tmp whitelists /tmp/.X11-unix directory
18 * modifs: Nvidia drivers added to --private-dev
19 * modifs: /srv supported by --whitelist
20 * feature: allow user access to /sys/fs (--noblacklist=/sys/fs)
21 * feature: support starting/joining sandbox is a single command
22 (--join-or-start)
23 * feature: X11 detection support for --audit
24 * feature: assign a name to the interface connected to the bridge
25 (--veth-name)
26 * feature: all user home directories are visible (--allusers)
27 * feature: add files to sandbox container (--put)
28 * feature: blocking x11 (--x11=block)
29 * feature: X11 security extension (--x11=xorg)
30 * feature: disable 3D hardware acceleration (--no3d)
31 * feature: x11 xpra, x11 xephyr, x11 block, allusers, no3d profile commands
32 * feature: move files in sandbox (--put)
33 * feature: accept wildcard patterns in user name field of restricted
34 shell login feature
35 * new profiles: qpdfview, mupdf, Luminance HDR, Synfig Studio, Gimp, Inkscape
36 * new profiles: feh, ranger, zathura, 7z, keepass, keepassx,
37 * new profiles: claws-mail, mutt, git, emacs, vim, xpdf, VirtualBox, OpenShot
38 * new profiles: Flowblade, Eye of GNOME (eog), Evolution
39 * bugfixes
40 -- netblue30 <netblue30@yahoo.com> Fri, 21 Oct 2016 08:00:00 -0500
41
42firejail (0.9.42) baseline; urgency=low
43 * security: --whitelist deleted files, submitted by Vasya Novikov
44 * security: disable x32 ABI in seccomp, submitted by Jann Horn
45 * security: tighten --chroot, submitted by Jann Horn
46 * security: terminal sandbox escape, submitted by Stephan Sokolow
47 * security: several TOCTOU fixes submitted by Aleksey Manevich
48 * modifs: bringing back --private-home option
49 * modifs: deprecated --user option, please use "sudo -u username firejail"
50 * modifs: allow symlinks in home directory for --whitelist option
51 * modifs: Firejail prompt is enabled by env variable FIREJAIL_PROMPT="yes"
52 * modifs: recursive mkdir
53 * modifs: include /dev/snd in --private-dev
54 * modifs: seccomp filter update
55 * modifs: release archives moved to .xz format
56 * feature: AppImage support (--appimage)
57 * feature: AppArmor support (--apparmor)
58 * feature: Ubuntu snap support (/etc/firejail/snap.profile)
59 * feature: Sandbox auditing support (--audit)
60 * feature: remove environment variable (--rmenv)
61 * feature: noexec support (--noexec)
62 * feature: clean local overlay storage directory (--overlay-clean)
63 * feature: store and reuse overlay (--overlay-named)
64 * feature: allow debugging inside the sandbox with gdb and strace
65 (--allow-debuggers)
66 * feature: mkfile profile command
67 * feature: quiet profile command
68 * feature: x11 profile command
69 * feature: option to fix desktop files (firecfg --fix)
70 * compile time: Busybox support (--enable-busybox-workaround)
71 * compile time: disable overlayfs (--disable-overlayfs)
72 * compile time: disable whitlisting (--disable-whitelist)
73 * compile time: disable global config (--disable-globalcfg)
74 * run time: enable/disable overlayfs (overlayfs yes/no)
75 * run time: enable/disable quiet as default (quiet-by-default yes/no)
76 * run time: user-defined network filter (netfilter-default)
77 * run time: enable/disable whitelisting (whitelist yes/no)
78 * run time: enable/disable remounting of /proc and /sys
79 (remount-proc-sys yes/no)
80 * run time: enable/disable chroot desktop features (chroot-desktop yes/no)
81 * profiles: Gitter, gThumb, mpv, Franz messenger, LibreOffice
82 * profiles: pix, audacity, xz, xzdec, gzip, cpio, less
83 * profiles: Atom Beta, Atom, jitsi, eom, uudeview
84 * profiles: tar (gtar), unzip, unrar, file, skypeforlinux,
85 * profiles: inox, Slack, gnome-chess. Gajim IM client, DOSBox
86 * bugfixes
87 -- netblue30 <netblue30@yahoo.com> Thu, 8 Sept 2016 08:00:00 -0500
88
89firejail (0.9.40) baseline; urgency=low
2 * added --nice option 90 * added --nice option
3 * added --x11 option 91 * added --x11 option
4 * added --x11=xpra option 92 * added --x11=xpra option
5 * added --x11=xephyr option 93 * added --x11=xephyr option
6 * added --cpu.print option 94 * added --cpu.print option
7 * added filetransfer options --ls and --get 95 * added filetransfer options --ls and --get
96 * added --writable-etc and --writable-var options
97 * added --read-only option
8 * added mkdir, ipc-namespace, and nosound profile commands 98 * added mkdir, ipc-namespace, and nosound profile commands
9 * added net iface, and iprange profile commands 99 * added net, ip, defaultgw, ip6, mac, mtu and iprange profile commands
10 * --version also prints compile options 100 * --version also prints compile options
11 * --output option also redirects stderr 101 * --output option also redirects stderr
12 * added compile-time option to restrict --net= to root only 102 * added compile-time option to restrict --net= to root only
@@ -18,10 +108,16 @@ firejail (0.9.40-rc1) baseline; urgency=low
18 * new profiles: lxterminal, Epiphany, cherrytree, Polari, Vivaldi, Atril 108 * new profiles: lxterminal, Epiphany, cherrytree, Polari, Vivaldi, Atril
19 * new profiles: qutebrowser, SlimJet, Battle for Wesnoth, Hedgewars 109 * new profiles: qutebrowser, SlimJet, Battle for Wesnoth, Hedgewars
20 * new profiles: qTox, OpenSSH client, OpenBox, Dillo, cmus, dnsmasq 110 * new profiles: qTox, OpenSSH client, OpenBox, Dillo, cmus, dnsmasq
21 * new profiles: PaleMoon, Icedove, abrowser, 0ad 111 * new profiles: PaleMoon, Icedove, abrowser, 0ad, netsurf, Warzone2100
112 * new profiles: okular, gwenview, Google-Play-Music-Desktop-Player
113 * new profiles: Aweather, Stellarium, gpredict, quiterss, cyberfox
114 * new profiles: generic Ubuntu snap application profile, xplayer
115 * new profiles: xreader, xviewer, mcabber, Psi+, Corebird, Konversation
116 * new profiles: Brave, Gitter
117 * generic.profile renamed default.profile
22 * build rpm packages using "make rpms" 118 * build rpm packages using "make rpms"
23 * bugfixes 119 * bugfixes
24 -- netblue30 <netblue30@yahoo.com> Sun, 3 Apr 2016 08:00:00 -0500 120 -- netblue30 <netblue30@yahoo.com> Sun, 29 May 2016 08:00:00 -0500
25 121
26firejail (0.9.38) baseline; urgency=low 122firejail (0.9.38) baseline; urgency=low
27 * IPv6 support (--ip6 and --netfilter6) 123 * IPv6 support (--ip6 and --netfilter6)
diff --git a/configure b/configure
index 73a5c89e6..0aefb5c62 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
1#! /bin/sh 1#! /bin/sh
2# Guess values for system-dependent variables and create Makefiles. 2# Guess values for system-dependent variables and create Makefiles.
3# Generated by GNU Autoconf 2.69 for firejail 0.9.40-rc2. 3# Generated by GNU Autoconf 2.69 for firejail 0.9.45.
4# 4#
5# Report bugs to <netblue30@yahoo.com>. 5# Report bugs to <netblue30@yahoo.com>.
6# 6#
@@ -580,8 +580,8 @@ MAKEFLAGS=
580# Identity of this package. 580# Identity of this package.
581PACKAGE_NAME='firejail' 581PACKAGE_NAME='firejail'
582PACKAGE_TARNAME='firejail' 582PACKAGE_TARNAME='firejail'
583PACKAGE_VERSION='0.9.40-rc2' 583PACKAGE_VERSION='0.9.45'
584PACKAGE_STRING='firejail 0.9.40-rc2' 584PACKAGE_STRING='firejail 0.9.45'
585PACKAGE_BUGREPORT='netblue30@yahoo.com' 585PACKAGE_BUGREPORT='netblue30@yahoo.com'
586PACKAGE_URL='http://firejail.wordpress.com' 586PACKAGE_URL='http://firejail.wordpress.com'
587 587
@@ -625,17 +625,25 @@ ac_includes_default="\
625ac_subst_vars='LTLIBOBJS 625ac_subst_vars='LTLIBOBJS
626LIBOBJS 626LIBOBJS
627HAVE_SECCOMP_H 627HAVE_SECCOMP_H
628EGREP 628HAVE_GCOV
629GREP 629BUSYBOX_WORKAROUND
630CPP
631HAVE_FATAL_WARNINGS 630HAVE_FATAL_WARNINGS
631HAVE_WHITELIST
632HAVE_FILE_TRANSFER 632HAVE_FILE_TRANSFER
633HAVE_X11 633HAVE_X11
634HAVE_USERNS 634HAVE_USERNS
635HAVE_NETWORK 635HAVE_NETWORK
636HAVE_GLOBALCFG
636HAVE_BIND 637HAVE_BIND
637HAVE_CHROOT 638HAVE_CHROOT
638HAVE_SECCOMP 639HAVE_SECCOMP
640HAVE_PRIVATE_HOME
641HAVE_OVERLAYFS
642EXTRA_LDFLAGS
643EGREP
644GREP
645CPP
646HAVE_APPARMOR
639RANLIB 647RANLIB
640INSTALL_DATA 648INSTALL_DATA
641INSTALL_SCRIPT 649INSTALL_SCRIPT
@@ -688,14 +696,21 @@ SHELL'
688ac_subst_files='' 696ac_subst_files=''
689ac_user_opts=' 697ac_user_opts='
690enable_option_checking 698enable_option_checking
699enable_apparmor
700enable_overlayfs
701enable_private_home
691enable_seccomp 702enable_seccomp
692enable_chroot 703enable_chroot
693enable_bind 704enable_bind
705enable_globalcfg
694enable_network 706enable_network
695enable_userns 707enable_userns
696enable_x11 708enable_x11
697enable_file_transfer 709enable_file_transfer
710enable_whitelist
698enable_fatal_warnings 711enable_fatal_warnings
712enable_busybox_workaround
713enable_gcov
699' 714'
700 ac_precious_vars='build_alias 715 ac_precious_vars='build_alias
701host_alias 716host_alias
@@ -1246,7 +1261,7 @@ if test "$ac_init_help" = "long"; then
1246 # Omit some internal or obsolete options to make the list less imposing. 1261 # Omit some internal or obsolete options to make the list less imposing.
1247 # This message is too long to be a string in the A/UX 3.1 sh. 1262 # This message is too long to be a string in the A/UX 3.1 sh.
1248 cat <<_ACEOF 1263 cat <<_ACEOF
1249\`configure' configures firejail 0.9.40-rc2 to adapt to many kinds of systems. 1264\`configure' configures firejail 0.9.45 to adapt to many kinds of systems.
1250 1265
1251Usage: $0 [OPTION]... [VAR=VALUE]... 1266Usage: $0 [OPTION]... [VAR=VALUE]...
1252 1267
@@ -1307,7 +1322,7 @@ fi
1307 1322
1308if test -n "$ac_init_help"; then 1323if test -n "$ac_init_help"; then
1309 case $ac_init_help in 1324 case $ac_init_help in
1310 short | recursive ) echo "Configuration of firejail 0.9.40-rc2:";; 1325 short | recursive ) echo "Configuration of firejail 0.9.45:";;
1311 esac 1326 esac
1312 cat <<\_ACEOF 1327 cat <<\_ACEOF
1313 1328
@@ -1315,16 +1330,25 @@ Optional Features:
1315 --disable-option-checking ignore unrecognized --enable/--with options 1330 --disable-option-checking ignore unrecognized --enable/--with options
1316 --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) 1331 --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
1317 --enable-FEATURE[=ARG] include FEATURE [ARG=yes] 1332 --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
1333 --enable-apparmor enable apparmor
1334 --disable-overlayfs disable overlayfs
1335 --disable-private-home disable private home feature
1318 --disable-seccomp disable seccomp 1336 --disable-seccomp disable seccomp
1319 --disable-chroot disable chroot 1337 --disable-chroot disable chroot
1320 --disable-bind disable bind 1338 --disable-bind disable bind
1339 --disable-globalcfg if the global config file firejail.cfg is not
1340 present, continue the program using defaults
1321 --disable-network disable network 1341 --disable-network disable network
1322 --enable-network=restricted 1342 --enable-network=restricted
1323 restrict --net= to root only 1343 restrict --net= to root only
1324 --disable-userns disable user namespace 1344 --disable-userns disable user namespace
1325 --disable-x11 disable X11 sandboxing support 1345 --disable-x11 disable X11 sandboxing support
1326 --disable-file-transfer disable file transfer 1346 --disable-file-transfer disable file transfer
1347 --disable-whitelist disable whitelist
1327 --enable-fatal-warnings -W -Wall -Werror 1348 --enable-fatal-warnings -W -Wall -Werror
1349 --enable-busybox-workaround
1350 enable busybox workaround
1351 --enable-gcov Gcov instrumentation
1328 1352
1329Some influential environment variables: 1353Some influential environment variables:
1330 CC C compiler command 1354 CC C compiler command
@@ -1403,7 +1427,7 @@ fi
1403test -n "$ac_init_help" && exit $ac_status 1427test -n "$ac_init_help" && exit $ac_status
1404if $ac_init_version; then 1428if $ac_init_version; then
1405 cat <<\_ACEOF 1429 cat <<\_ACEOF
1406firejail configure 0.9.40-rc2 1430firejail configure 0.9.45
1407generated by GNU Autoconf 2.69 1431generated by GNU Autoconf 2.69
1408 1432
1409Copyright (C) 2012 Free Software Foundation, Inc. 1433Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1455,52 +1479,6 @@ fi
1455 1479
1456} # ac_fn_c_try_compile 1480} # ac_fn_c_try_compile
1457 1481
1458# ac_fn_c_try_link LINENO
1459# -----------------------
1460# Try to link conftest.$ac_ext, and return whether this succeeded.
1461ac_fn_c_try_link ()
1462{
1463 as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
1464 rm -f conftest.$ac_objext conftest$ac_exeext
1465 if { { ac_try="$ac_link"
1466case "(($ac_try" in
1467 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
1468 *) ac_try_echo=$ac_try;;
1469esac
1470eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
1471$as_echo "$ac_try_echo"; } >&5
1472 (eval "$ac_link") 2>conftest.err
1473 ac_status=$?
1474 if test -s conftest.err; then
1475 grep -v '^ *+' conftest.err >conftest.er1
1476 cat conftest.er1 >&5
1477 mv -f conftest.er1 conftest.err
1478 fi
1479 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
1480 test $ac_status = 0; } && {
1481 test -z "$ac_c_werror_flag" ||
1482 test ! -s conftest.err
1483 } && test -s conftest$ac_exeext && {
1484 test "$cross_compiling" = yes ||
1485 test -x conftest$ac_exeext
1486 }; then :
1487 ac_retval=0
1488else
1489 $as_echo "$as_me: failed program was:" >&5
1490sed 's/^/| /' conftest.$ac_ext >&5
1491
1492 ac_retval=1
1493fi
1494 # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
1495 # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
1496 # interfere with the next link command; also delete a directory that is
1497 # left behind by Apple's compiler. We do this before executing the actions.
1498 rm -rf conftest.dSYM conftest_ipa8_conftest.oo
1499 eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
1500 as_fn_set_status $ac_retval
1501
1502} # ac_fn_c_try_link
1503
1504# ac_fn_c_try_cpp LINENO 1482# ac_fn_c_try_cpp LINENO
1505# ---------------------- 1483# ----------------------
1506# Try to preprocess conftest.$ac_ext, and return whether this succeeded. 1484# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
@@ -1701,11 +1679,57 @@ $as_echo "$ac_res" >&6; }
1701 eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno 1679 eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
1702 1680
1703} # ac_fn_c_check_header_compile 1681} # ac_fn_c_check_header_compile
1682
1683# ac_fn_c_try_link LINENO
1684# -----------------------
1685# Try to link conftest.$ac_ext, and return whether this succeeded.
1686ac_fn_c_try_link ()
1687{
1688 as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
1689 rm -f conftest.$ac_objext conftest$ac_exeext
1690 if { { ac_try="$ac_link"
1691case "(($ac_try" in
1692 *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
1693 *) ac_try_echo=$ac_try;;
1694esac
1695eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
1696$as_echo "$ac_try_echo"; } >&5
1697 (eval "$ac_link") 2>conftest.err
1698 ac_status=$?
1699 if test -s conftest.err; then
1700 grep -v '^ *+' conftest.err >conftest.er1
1701 cat conftest.er1 >&5
1702 mv -f conftest.er1 conftest.err
1703 fi
1704 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
1705 test $ac_status = 0; } && {
1706 test -z "$ac_c_werror_flag" ||
1707 test ! -s conftest.err
1708 } && test -s conftest$ac_exeext && {
1709 test "$cross_compiling" = yes ||
1710 test -x conftest$ac_exeext
1711 }; then :
1712 ac_retval=0
1713else
1714 $as_echo "$as_me: failed program was:" >&5
1715sed 's/^/| /' conftest.$ac_ext >&5
1716
1717 ac_retval=1
1718fi
1719 # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
1720 # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
1721 # interfere with the next link command; also delete a directory that is
1722 # left behind by Apple's compiler. We do this before executing the actions.
1723 rm -rf conftest.dSYM conftest_ipa8_conftest.oo
1724 eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
1725 as_fn_set_status $ac_retval
1726
1727} # ac_fn_c_try_link
1704cat >config.log <<_ACEOF 1728cat >config.log <<_ACEOF
1705This file contains any messages produced by compilers while 1729This file contains any messages produced by compilers while
1706running configure, to aid debugging if configure makes a mistake. 1730running configure, to aid debugging if configure makes a mistake.
1707 1731
1708It was created by firejail $as_me 0.9.40-rc2, which was 1732It was created by firejail $as_me 0.9.45, which was
1709generated by GNU Autoconf 2.69. Invocation command line was 1733generated by GNU Autoconf 2.69. Invocation command line was
1710 1734
1711 $ $0 $@ 1735 $ $0 $@
@@ -3062,164 +3086,20 @@ else
3062fi 3086fi
3063 3087
3064 3088
3065HAVE_SECCOMP="" 3089HAVE_APPARMOR=""
3066# Check whether --enable-seccomp was given. 3090# Check whether --enable-apparmor was given.
3067if test "${enable_seccomp+set}" = set; then : 3091if test "${enable_apparmor+set}" = set; then :
3068 enableval=$enable_seccomp; 3092 enableval=$enable_apparmor;
3069fi
3070
3071if test "x$enable_seccomp" != "xno"; then :
3072
3073 HAVE_SECCOMP="-DHAVE_SECCOMP"
3074
3075
3076fi
3077
3078HAVE_CHROOT=""
3079# Check whether --enable-chroot was given.
3080if test "${enable_chroot+set}" = set; then :
3081 enableval=$enable_chroot;
3082fi
3083
3084if test "x$enable_chroot" != "xno"; then :
3085
3086 HAVE_CHROOT="-DHAVE_CHROOT"
3087
3088
3089fi
3090
3091HAVE_BIND=""
3092# Check whether --enable-bind was given.
3093if test "${enable_bind+set}" = set; then :
3094 enableval=$enable_bind;
3095fi
3096
3097if test "x$enable_bind" != "xno"; then :
3098
3099 HAVE_BIND="-DHAVE_BIND"
3100
3101
3102fi
3103
3104HAVE_NETWORK=""
3105# Check whether --enable-network was given.
3106if test "${enable_network+set}" = set; then :
3107 enableval=$enable_network;
3108fi
3109
3110# Check whether --enable-network was given.
3111if test "${enable_network+set}" = set; then :
3112 enableval=$enable_network;
3113fi
3114
3115if test "x$enable_network" != "xno"; then :
3116
3117 HAVE_NETWORK="-DHAVE_NETWORK"
3118 if test "x$enable_network" = "xrestricted"; then :
3119
3120 HAVE_NETWORK="$HAVE_NETWORK -DHAVE_NETWORK_RESTRICTED"
3121
3122fi
3123
3124
3125fi
3126
3127HAVE_USERNS=""
3128# Check whether --enable-userns was given.
3129if test "${enable_userns+set}" = set; then :
3130 enableval=$enable_userns;
3131fi
3132
3133if test "x$enable_userns" != "xno"; then :
3134
3135 HAVE_USERNS="-DHAVE_USERNS"
3136
3137
3138fi
3139
3140HAVE_X11=""
3141# Check whether --enable-x11 was given.
3142if test "${enable_x11+set}" = set; then :
3143 enableval=$enable_x11;
3144fi
3145
3146if test "x$enable_x11" != "xno"; then :
3147
3148 HAVE_X11="-DHAVE_X11"
3149
3150
3151fi
3152
3153HAVE_FILE_TRANSFER=""
3154# Check whether --enable-file-transfer was given.
3155if test "${enable_file_transfer+set}" = set; then :
3156 enableval=$enable_file_transfer;
3157fi
3158
3159if test "x$enable_file_transfer" != "xno"; then :
3160
3161 HAVE_FILE_TRANSFER="-DHAVE_FILE_TRANSFER"
3162
3163
3164fi
3165
3166HAVE_FATAL_WARNINGS=""
3167# Check whether --enable-fatal_warnings was given.
3168if test "${enable_fatal_warnings+set}" = set; then :
3169 enableval=$enable_fatal_warnings;
3170fi 3093fi
3171 3094
3172if test "x$enable_fatal_warnings" = "xyes"; then : 3095if test "x$enable_apparmor" = "xyes"; then :
3173 3096
3174 HAVE_FATAL_WARNINGS="-W -Wall -Werror" 3097 HAVE_APPARMOR="-DHAVE_APPARMOR"
3175 3098
3176 3099
3177fi 3100fi
3178 3101
3179 3102
3180# checking pthread library
3181
3182{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpthread" >&5
3183$as_echo_n "checking for main in -lpthread... " >&6; }
3184if ${ac_cv_lib_pthread_main+:} false; then :
3185 $as_echo_n "(cached) " >&6
3186else
3187 ac_check_lib_save_LIBS=$LIBS
3188LIBS="-lpthread $LIBS"
3189cat confdefs.h - <<_ACEOF >conftest.$ac_ext
3190/* end confdefs.h. */
3191
3192
3193int
3194main ()
3195{
3196return main ();
3197 ;
3198 return 0;
3199}
3200_ACEOF
3201if ac_fn_c_try_link "$LINENO"; then :
3202 ac_cv_lib_pthread_main=yes
3203else
3204 ac_cv_lib_pthread_main=no
3205fi
3206rm -f core conftest.err conftest.$ac_objext \
3207 conftest$ac_exeext conftest.$ac_ext
3208LIBS=$ac_check_lib_save_LIBS
3209fi
3210{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_main" >&5
3211$as_echo "$ac_cv_lib_pthread_main" >&6; }
3212if test "x$ac_cv_lib_pthread_main" = xyes; then :
3213 cat >>confdefs.h <<_ACEOF
3214#define HAVE_LIBPTHREAD 1
3215_ACEOF
3216
3217 LIBS="-lpthread $LIBS"
3218
3219else
3220 as_fn_error $? "*** POSIX thread support not installed ***" "$LINENO" 5
3221fi
3222
3223ac_ext=c 3103ac_ext=c
3224ac_cpp='$CPP $CPPFLAGS' 3104ac_cpp='$CPP $CPPFLAGS'
3225ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' 3105ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -3617,6 +3497,263 @@ fi
3617done 3497done
3618 3498
3619 3499
3500if test "x$enable_apparmor" = "xyes"; then :
3501
3502 ac_fn_c_check_header_mongrel "$LINENO" "sys/apparmor.h" "ac_cv_header_sys_apparmor_h" "$ac_includes_default"
3503if test "x$ac_cv_header_sys_apparmor_h" = xyes; then :
3504
3505else
3506 as_fn_error $? "Couldn't find sys/apparmor.h... please install apparmor user space library and development files " "$LINENO" 5
3507fi
3508
3509
3510
3511fi
3512if test "x$enable_apparmor" = "xyes"; then :
3513
3514 EXTRA_LDFLAGS+="-lapparmor "
3515
3516fi
3517
3518
3519HAVE_OVERLAYFS=""
3520# Check whether --enable-overlayfs was given.
3521if test "${enable_overlayfs+set}" = set; then :
3522 enableval=$enable_overlayfs;
3523fi
3524
3525if test "x$enable_overlayfs" != "xno"; then :
3526
3527 HAVE_OVERLAYFS="-DHAVE_OVERLAYFS"
3528
3529
3530fi
3531
3532HAVE_PRIVATEHOME=""
3533# Check whether --enable-private-home was given.
3534if test "${enable_private_home+set}" = set; then :
3535 enableval=$enable_private_home;
3536fi
3537
3538if test "x$enable_private_home" != "xno"; then :
3539
3540 HAVE_PRIVATE_HOME="-DHAVE_PRIVATE_HOME"
3541
3542
3543fi
3544
3545HAVE_SECCOMP=""
3546# Check whether --enable-seccomp was given.
3547if test "${enable_seccomp+set}" = set; then :
3548 enableval=$enable_seccomp;
3549fi
3550
3551if test "x$enable_seccomp" != "xno"; then :
3552
3553 HAVE_SECCOMP="-DHAVE_SECCOMP"
3554
3555
3556fi
3557
3558HAVE_CHROOT=""
3559# Check whether --enable-chroot was given.
3560if test "${enable_chroot+set}" = set; then :
3561 enableval=$enable_chroot;
3562fi
3563
3564if test "x$enable_chroot" != "xno"; then :
3565
3566 HAVE_CHROOT="-DHAVE_CHROOT"
3567
3568
3569fi
3570
3571HAVE_BIND=""
3572# Check whether --enable-bind was given.
3573if test "${enable_bind+set}" = set; then :
3574 enableval=$enable_bind;
3575fi
3576
3577if test "x$enable_bind" != "xno"; then :
3578
3579 HAVE_BIND="-DHAVE_BIND"
3580
3581
3582fi
3583
3584HAVE_GLOBALCFG=""
3585# Check whether --enable-globalcfg was given.
3586if test "${enable_globalcfg+set}" = set; then :
3587 enableval=$enable_globalcfg;
3588fi
3589
3590if test "x$enable_globalcfg" != "xno"; then :
3591
3592 HAVE_GLOBALCFG="-DHAVE_GLOBALCFG"
3593
3594
3595fi
3596
3597HAVE_NETWORK=""
3598# Check whether --enable-network was given.
3599if test "${enable_network+set}" = set; then :
3600 enableval=$enable_network;
3601fi
3602
3603# Check whether --enable-network was given.
3604if test "${enable_network+set}" = set; then :
3605 enableval=$enable_network;
3606fi
3607
3608if test "x$enable_network" != "xno"; then :
3609
3610 HAVE_NETWORK="-DHAVE_NETWORK"
3611 if test "x$enable_network" = "xrestricted"; then :
3612
3613 HAVE_NETWORK="$HAVE_NETWORK -DHAVE_NETWORK_RESTRICTED"
3614
3615fi
3616
3617
3618fi
3619
3620HAVE_USERNS=""
3621# Check whether --enable-userns was given.
3622if test "${enable_userns+set}" = set; then :
3623 enableval=$enable_userns;
3624fi
3625
3626if test "x$enable_userns" != "xno"; then :
3627
3628 HAVE_USERNS="-DHAVE_USERNS"
3629
3630
3631fi
3632
3633HAVE_X11=""
3634# Check whether --enable-x11 was given.
3635if test "${enable_x11+set}" = set; then :
3636 enableval=$enable_x11;
3637fi
3638
3639if test "x$enable_x11" != "xno"; then :
3640
3641 HAVE_X11="-DHAVE_X11"
3642
3643
3644fi
3645
3646HAVE_FILE_TRANSFER=""
3647# Check whether --enable-file-transfer was given.
3648if test "${enable_file_transfer+set}" = set; then :
3649 enableval=$enable_file_transfer;
3650fi
3651
3652if test "x$enable_file_transfer" != "xno"; then :
3653
3654 HAVE_FILE_TRANSFER="-DHAVE_FILE_TRANSFER"
3655
3656
3657fi
3658
3659HAVE_WHITELIST=""
3660# Check whether --enable-whitelist was given.
3661if test "${enable_whitelist+set}" = set; then :
3662 enableval=$enable_whitelist;
3663fi
3664
3665if test "x$enable_whitelist" != "xno"; then :
3666
3667 HAVE_WHITELIST="-DHAVE_WHITELIST"
3668
3669
3670fi
3671
3672HAVE_FATAL_WARNINGS=""
3673# Check whether --enable-fatal_warnings was given.
3674if test "${enable_fatal_warnings+set}" = set; then :
3675 enableval=$enable_fatal_warnings;
3676fi
3677
3678if test "x$enable_fatal_warnings" = "xyes"; then :
3679
3680 HAVE_FATAL_WARNINGS="-W -Wall -Werror"
3681
3682
3683fi
3684
3685BUSYBOX_WORKAROUND="no"
3686# Check whether --enable-busybox-workaround was given.
3687if test "${enable_busybox_workaround+set}" = set; then :
3688 enableval=$enable_busybox_workaround;
3689fi
3690
3691if test "x$enable_busybox_workaround" = "xyes"; then :
3692
3693 BUSYBOX_WORKAROUND="yes"
3694
3695
3696fi
3697
3698
3699HAVE_GCOV=""
3700# Check whether --enable-gcov was given.
3701if test "${enable_gcov+set}" = set; then :
3702 enableval=$enable_gcov;
3703fi
3704
3705if test "x$enable_gcov" = "xyes"; then :
3706
3707 HAVE_GCOV="--coverage -DHAVE_GCOV "
3708 EXTRA_LDFLAGS+="-lgcov --coverage "
3709
3710
3711fi
3712
3713
3714
3715# checking pthread library
3716{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpthread" >&5
3717$as_echo_n "checking for main in -lpthread... " >&6; }
3718if ${ac_cv_lib_pthread_main+:} false; then :
3719 $as_echo_n "(cached) " >&6
3720else
3721 ac_check_lib_save_LIBS=$LIBS
3722LIBS="-lpthread $LIBS"
3723cat confdefs.h - <<_ACEOF >conftest.$ac_ext
3724/* end confdefs.h. */
3725
3726
3727int
3728main ()
3729{
3730return main ();
3731 ;
3732 return 0;
3733}
3734_ACEOF
3735if ac_fn_c_try_link "$LINENO"; then :
3736 ac_cv_lib_pthread_main=yes
3737else
3738 ac_cv_lib_pthread_main=no
3739fi
3740rm -f core conftest.err conftest.$ac_objext \
3741 conftest$ac_exeext conftest.$ac_ext
3742LIBS=$ac_check_lib_save_LIBS
3743fi
3744{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_main" >&5
3745$as_echo "$ac_cv_lib_pthread_main" >&6; }
3746if test "x$ac_cv_lib_pthread_main" = xyes; then :
3747 cat >>confdefs.h <<_ACEOF
3748#define HAVE_LIBPTHREAD 1
3749_ACEOF
3750
3751 LIBS="-lpthread $LIBS"
3752
3753else
3754 as_fn_error $? "*** POSIX thread support not installed ***" "$LINENO" 5
3755fi
3756
3620ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default" 3757ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default"
3621if test "x$ac_cv_header_pthread_h" = xyes; then : 3758if test "x$ac_cv_header_pthread_h" = xyes; then :
3622 3759
@@ -3640,7 +3777,7 @@ if test "$prefix" = /usr; then
3640 sysconfdir="/etc" 3777 sysconfdir="/etc"
3641fi 3778fi
3642 3779
3643ac_config_files="$ac_config_files Makefile src/lib/Makefile src/firejail/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/ftee/Makefile" 3780ac_config_files="$ac_config_files Makefile src/lib/Makefile src/fnet/Makefile src/firejail/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/ftee/Makefile src/faudit/Makefile src/libconnect/Makefile src/fseccomp/Makefile"
3644 3781
3645cat >confcache <<\_ACEOF 3782cat >confcache <<\_ACEOF
3646# This file is a shell script that caches the results of configure 3783# This file is a shell script that caches the results of configure
@@ -4184,7 +4321,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
4184# report actual input values of CONFIG_FILES etc. instead of their 4321# report actual input values of CONFIG_FILES etc. instead of their
4185# values after options handling. 4322# values after options handling.
4186ac_log=" 4323ac_log="
4187This file was extended by firejail $as_me 0.9.40-rc2, which was 4324This file was extended by firejail $as_me 0.9.45, which was
4188generated by GNU Autoconf 2.69. Invocation command line was 4325generated by GNU Autoconf 2.69. Invocation command line was
4189 4326
4190 CONFIG_FILES = $CONFIG_FILES 4327 CONFIG_FILES = $CONFIG_FILES
@@ -4238,7 +4375,7 @@ _ACEOF
4238cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 4375cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
4239ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" 4376ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
4240ac_cs_version="\\ 4377ac_cs_version="\\
4241firejail config.status 0.9.40-rc2 4378firejail config.status 0.9.45
4242configured by $0, generated by GNU Autoconf 2.69, 4379configured by $0, generated by GNU Autoconf 2.69,
4243 with options \\"\$ac_cs_config\\" 4380 with options \\"\$ac_cs_config\\"
4244 4381
@@ -4351,12 +4488,16 @@ do
4351 case $ac_config_target in 4488 case $ac_config_target in
4352 "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; 4489 "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
4353 "src/lib/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib/Makefile" ;; 4490 "src/lib/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib/Makefile" ;;
4491 "src/fnet/Makefile") CONFIG_FILES="$CONFIG_FILES src/fnet/Makefile" ;;
4354 "src/firejail/Makefile") CONFIG_FILES="$CONFIG_FILES src/firejail/Makefile" ;; 4492 "src/firejail/Makefile") CONFIG_FILES="$CONFIG_FILES src/firejail/Makefile" ;;
4355 "src/firemon/Makefile") CONFIG_FILES="$CONFIG_FILES src/firemon/Makefile" ;; 4493 "src/firemon/Makefile") CONFIG_FILES="$CONFIG_FILES src/firemon/Makefile" ;;
4356 "src/libtrace/Makefile") CONFIG_FILES="$CONFIG_FILES src/libtrace/Makefile" ;; 4494 "src/libtrace/Makefile") CONFIG_FILES="$CONFIG_FILES src/libtrace/Makefile" ;;
4357 "src/libtracelog/Makefile") CONFIG_FILES="$CONFIG_FILES src/libtracelog/Makefile" ;; 4495 "src/libtracelog/Makefile") CONFIG_FILES="$CONFIG_FILES src/libtracelog/Makefile" ;;
4358 "src/firecfg/Makefile") CONFIG_FILES="$CONFIG_FILES src/firecfg/Makefile" ;; 4496 "src/firecfg/Makefile") CONFIG_FILES="$CONFIG_FILES src/firecfg/Makefile" ;;
4359 "src/ftee/Makefile") CONFIG_FILES="$CONFIG_FILES src/ftee/Makefile" ;; 4497 "src/ftee/Makefile") CONFIG_FILES="$CONFIG_FILES src/ftee/Makefile" ;;
4498 "src/faudit/Makefile") CONFIG_FILES="$CONFIG_FILES src/faudit/Makefile" ;;
4499 "src/libconnect/Makefile") CONFIG_FILES="$CONFIG_FILES src/libconnect/Makefile" ;;
4500 "src/fseccomp/Makefile") CONFIG_FILES="$CONFIG_FILES src/fseccomp/Makefile" ;;
4360 4501
4361 *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; 4502 *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
4362 esac 4503 esac
@@ -4818,13 +4959,22 @@ echo " prefix: $prefix"
4818echo " sysconfdir: $sysconfdir" 4959echo " sysconfdir: $sysconfdir"
4819echo " seccomp: $HAVE_SECCOMP" 4960echo " seccomp: $HAVE_SECCOMP"
4820echo " <linux/seccomp.h>: $HAVE_SECCOMP_H" 4961echo " <linux/seccomp.h>: $HAVE_SECCOMP_H"
4962echo " apparmor: $HAVE_APPARMOR"
4963echo " global config: $HAVE_GLOBALCFG"
4821echo " chroot: $HAVE_CHROOT" 4964echo " chroot: $HAVE_CHROOT"
4822echo " bind: $HAVE_BIND" 4965echo " bind: $HAVE_BIND"
4823echo " network: $HAVE_NETWORK" 4966echo " network: $HAVE_NETWORK"
4824echo " user namespace: $HAVE_USERNS" 4967echo " user namespace: $HAVE_USERNS"
4825echo " X11 sandboxing support: $HAVE_X11" 4968echo " X11 sandboxing support: $HAVE_X11"
4969echo " whitelisting: $HAVE_WHITELIST"
4970echo " private home support: $HAVE_PRIVATE_HOME"
4826echo " file transfer support: $HAVE_FILE_TRANSFER" 4971echo " file transfer support: $HAVE_FILE_TRANSFER"
4972echo " overlayfs support: $HAVE_OVERLAYFS"
4973echo " busybox workaround: $BUSYBOX_WORKAROUND"
4974echo " EXTRA_LDFLAGS: $EXTRA_LDFLAGS"
4827echo " fatal warnings: $HAVE_FATAL_WARNINGS" 4975echo " fatal warnings: $HAVE_FATAL_WARNINGS"
4976echo " Gcov instrumentation: $HAVE_GCOV"
4828echo 4977echo
4829 4978
4830 4979
4980
diff --git a/configure.ac b/configure.ac
index a4486b3ff..74ba09f43 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
1AC_PREREQ([2.68]) 1AC_PREREQ([2.68])
2AC_INIT(firejail, 0.9.40-rc2, netblue30@yahoo.com, , http://firejail.wordpress.com) 2AC_INIT(firejail, 0.9.45, netblue30@yahoo.com, , http://firejail.wordpress.com)
3AC_CONFIG_SRCDIR([src/firejail/main.c]) 3AC_CONFIG_SRCDIR([src/firejail/main.c])
4#AC_CONFIG_HEADERS([config.h]) 4#AC_CONFIG_HEADERS([config.h])
5 5
@@ -9,6 +9,39 @@ AC_PROG_CC
9AC_PROG_INSTALL 9AC_PROG_INSTALL
10AC_PROG_RANLIB 10AC_PROG_RANLIB
11 11
12HAVE_APPARMOR=""
13AC_ARG_ENABLE([apparmor],
14 AS_HELP_STRING([--enable-apparmor], [enable apparmor]))
15AS_IF([test "x$enable_apparmor" = "xyes"], [
16 HAVE_APPARMOR="-DHAVE_APPARMOR"
17 AC_SUBST(HAVE_APPARMOR)
18])
19
20AS_IF([test "x$enable_apparmor" = "xyes"], [
21 AC_CHECK_HEADER(sys/apparmor.h, , [AC_MSG_ERROR(
22 [Couldn't find sys/apparmor.h... please install apparmor user space library and development files] )])
23])
24AS_IF([test "x$enable_apparmor" = "xyes"], [
25 EXTRA_LDFLAGS+="-lapparmor "
26])
27AC_SUBST([EXTRA_LDFLAGS])
28
29HAVE_OVERLAYFS=""
30AC_ARG_ENABLE([overlayfs],
31 AS_HELP_STRING([--disable-overlayfs], [disable overlayfs]))
32AS_IF([test "x$enable_overlayfs" != "xno"], [
33 HAVE_OVERLAYFS="-DHAVE_OVERLAYFS"
34 AC_SUBST(HAVE_OVERLAYFS)
35])
36
37HAVE_PRIVATEHOME=""
38AC_ARG_ENABLE([private-home],
39 AS_HELP_STRING([--disable-private-home], [disable private home feature]))
40AS_IF([test "x$enable_private_home" != "xno"], [
41 HAVE_PRIVATE_HOME="-DHAVE_PRIVATE_HOME"
42 AC_SUBST(HAVE_PRIVATE_HOME)
43])
44
12HAVE_SECCOMP="" 45HAVE_SECCOMP=""
13AC_ARG_ENABLE([seccomp], 46AC_ARG_ENABLE([seccomp],
14 AS_HELP_STRING([--disable-seccomp], [disable seccomp])) 47 AS_HELP_STRING([--disable-seccomp], [disable seccomp]))
@@ -33,6 +66,14 @@ AS_IF([test "x$enable_bind" != "xno"], [
33 AC_SUBST(HAVE_BIND) 66 AC_SUBST(HAVE_BIND)
34]) 67])
35 68
69HAVE_GLOBALCFG=""
70AC_ARG_ENABLE([globalcfg],
71 AS_HELP_STRING([--disable-globalcfg], [if the global config file firejail.cfg is not present, continue the program using defaults]))
72AS_IF([test "x$enable_globalcfg" != "xno"], [
73 HAVE_GLOBALCFG="-DHAVE_GLOBALCFG"
74 AC_SUBST(HAVE_GLOBALCFG)
75])
76
36HAVE_NETWORK="" 77HAVE_NETWORK=""
37AC_ARG_ENABLE([network], 78AC_ARG_ENABLE([network],
38 AS_HELP_STRING([--disable-network], [disable network])) 79 AS_HELP_STRING([--disable-network], [disable network]))
@@ -70,6 +111,14 @@ AS_IF([test "x$enable_file_transfer" != "xno"], [
70 AC_SUBST(HAVE_FILE_TRANSFER) 111 AC_SUBST(HAVE_FILE_TRANSFER)
71]) 112])
72 113
114HAVE_WHITELIST=""
115AC_ARG_ENABLE([whitelist],
116 AS_HELP_STRING([--disable-whitelist], [disable whitelist]))
117AS_IF([test "x$enable_whitelist" != "xno"], [
118 HAVE_WHITELIST="-DHAVE_WHITELIST"
119 AC_SUBST(HAVE_WHITELIST)
120])
121
73HAVE_FATAL_WARNINGS="" 122HAVE_FATAL_WARNINGS=""
74AC_ARG_ENABLE([fatal_warnings], 123AC_ARG_ENABLE([fatal_warnings],
75 AS_HELP_STRING([--enable-fatal-warnings], [-W -Wall -Werror])) 124 AS_HELP_STRING([--enable-fatal-warnings], [-W -Wall -Werror]))
@@ -78,6 +127,25 @@ AS_IF([test "x$enable_fatal_warnings" = "xyes"], [
78 AC_SUBST(HAVE_FATAL_WARNINGS) 127 AC_SUBST(HAVE_FATAL_WARNINGS)
79]) 128])
80 129
130BUSYBOX_WORKAROUND="no"
131AC_ARG_ENABLE([busybox-workaround],
132 AS_HELP_STRING([--enable-busybox-workaround], [enable busybox workaround]))
133AS_IF([test "x$enable_busybox_workaround" = "xyes"], [
134 BUSYBOX_WORKAROUND="yes"
135 AC_SUBST(BUSYBOX_WORKAROUND)
136])
137
138
139HAVE_GCOV=""
140AC_ARG_ENABLE([gcov],
141 AS_HELP_STRING([--enable-gcov], [Gcov instrumentation]))
142AS_IF([test "x$enable_gcov" = "xyes"], [
143 HAVE_GCOV="--coverage -DHAVE_GCOV "
144 EXTRA_LDFLAGS+="-lgcov --coverage "
145 AC_SUBST(HAVE_GCOV)
146])
147
148
81 149
82# checking pthread library 150# checking pthread library
83AC_CHECK_LIB([pthread], [main], [], AC_MSG_ERROR([*** POSIX thread support not installed ***])) 151AC_CHECK_LIB([pthread], [main], [], AC_MSG_ERROR([*** POSIX thread support not installed ***]))
@@ -90,7 +158,8 @@ if test "$prefix" = /usr; then
90 sysconfdir="/etc" 158 sysconfdir="/etc"
91fi 159fi
92 160
93AC_OUTPUT(Makefile src/lib/Makefile src/firejail/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/ftee/Makefile) 161AC_OUTPUT(Makefile src/lib/Makefile src/fnet/Makefile src/firejail/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile \
162src/firecfg/Makefile src/ftee/Makefile src/faudit/Makefile src/libconnect/Makefile src/fseccomp/Makefile)
94 163
95echo 164echo
96echo "Configuration options:" 165echo "Configuration options:"
@@ -98,13 +167,22 @@ echo " prefix: $prefix"
98echo " sysconfdir: $sysconfdir" 167echo " sysconfdir: $sysconfdir"
99echo " seccomp: $HAVE_SECCOMP" 168echo " seccomp: $HAVE_SECCOMP"
100echo " <linux/seccomp.h>: $HAVE_SECCOMP_H" 169echo " <linux/seccomp.h>: $HAVE_SECCOMP_H"
170echo " apparmor: $HAVE_APPARMOR"
171echo " global config: $HAVE_GLOBALCFG"
101echo " chroot: $HAVE_CHROOT" 172echo " chroot: $HAVE_CHROOT"
102echo " bind: $HAVE_BIND" 173echo " bind: $HAVE_BIND"
103echo " network: $HAVE_NETWORK" 174echo " network: $HAVE_NETWORK"
104echo " user namespace: $HAVE_USERNS" 175echo " user namespace: $HAVE_USERNS"
105echo " X11 sandboxing support: $HAVE_X11" 176echo " X11 sandboxing support: $HAVE_X11"
177echo " whitelisting: $HAVE_WHITELIST"
178echo " private home support: $HAVE_PRIVATE_HOME"
106echo " file transfer support: $HAVE_FILE_TRANSFER" 179echo " file transfer support: $HAVE_FILE_TRANSFER"
180echo " overlayfs support: $HAVE_OVERLAYFS"
181echo " busybox workaround: $BUSYBOX_WORKAROUND"
182echo " EXTRA_LDFLAGS: $EXTRA_LDFLAGS"
107echo " fatal warnings: $HAVE_FATAL_WARNINGS" 183echo " fatal warnings: $HAVE_FATAL_WARNINGS"
184echo " Gcov instrumentation: $HAVE_GCOV"
108echo 185echo
109 186
110 187
188
diff --git a/etc/0ad.profile b/etc/0ad.profile
index f8a3ce23d..1e7c06879 100644
--- a/etc/0ad.profile
+++ b/etc/0ad.profile
@@ -1,30 +1,31 @@
1# Firejail profile for 0ad. 1# Firejail profile for 0ad.
2noblacklist ~/.cache/0ad
2noblacklist ~/.config/0ad 3noblacklist ~/.config/0ad
4noblacklist ~/.local/share/0ad
3include /etc/firejail/disable-common.inc 5include /etc/firejail/disable-common.inc
4include /etc/firejail/disable-devel.inc 6include /etc/firejail/disable-devel.inc
5include /etc/firejail/disable-passwdmgr.inc 7include /etc/firejail/disable-passwdmgr.inc
6include /etc/firejail/disable-programs.inc 8include /etc/firejail/disable-programs.inc
7 9
8# Call these options
9caps.drop all
10seccomp
11protocol unix,inet,inet6,netlink
12netfilter
13tracelog
14noroot
15
16# Whitelists 10# Whitelists
17noblacklist ~/.cache/0ad
18mkdir ~/.cache
19mkdir ~/.cache/0ad 11mkdir ~/.cache/0ad
20whitelist ~/.cache/0ad 12whitelist ~/.cache/0ad
21 13
22mkdir ~/.config
23mkdir ~/.config/0ad 14mkdir ~/.config/0ad
24whitelist ~/.config/0ad 15whitelist ~/.config/0ad
25 16
26noblacklist ~/.local/share/0ad
27mkdir ~/.local
28mkdir ~/.local/share
29mkdir ~/.local/share/0ad 17mkdir ~/.local/share/0ad
30whitelist ~/.local/share/0ad 18whitelist ~/.local/share/0ad
19
20caps.drop all
21netfilter
22nogroups
23nonewprivs
24noroot
25protocol unix,inet,inet6
26seccomp
27shell none
28tracelog
29
30private-dev
31private-tmp
diff --git a/etc/7z.profile b/etc/7z.profile
new file mode 100644
index 000000000..0cb72ff8d
--- /dev/null
+++ b/etc/7z.profile
@@ -0,0 +1,9 @@
1# 7zip crompression tool profile
2quiet
3ignore noroot
4include /etc/firejail/default.profile
5tracelog
6net none
7shell none
8private-dev
9nosound
diff --git a/etc/Cyberfox.profile b/etc/Cyberfox.profile
new file mode 100644
index 000000000..1f74606ce
--- /dev/null
+++ b/etc/Cyberfox.profile
@@ -0,0 +1,3 @@
1# Firejail profile for Cyberfox (based on Mozilla Firefox)
2
3include /etc/firejail/cyberfox.profile
diff --git a/etc/Mathematica.profile b/etc/Mathematica.profile
index 05131df43..e719f070f 100644
--- a/etc/Mathematica.profile
+++ b/etc/Mathematica.profile
@@ -15,5 +15,6 @@ include /etc/firejail/disable-devel.inc
15include /etc/firejail/disable-passwdmgr.inc 15include /etc/firejail/disable-passwdmgr.inc
16 16
17caps.drop all 17caps.drop all
18seccomp 18nonewprivs
19noroot 19noroot
20seccomp
diff --git a/etc/Telegram.profile b/etc/Telegram.profile
new file mode 100644
index 000000000..2e0f97821
--- /dev/null
+++ b/etc/Telegram.profile
@@ -0,0 +1,2 @@
1# Telegram IRC profile
2include /etc/firejail/telegram.profile
diff --git a/etc/Wire.profile b/etc/Wire.profile
new file mode 100644
index 000000000..bd9645c7f
--- /dev/null
+++ b/etc/Wire.profile
@@ -0,0 +1,3 @@
1# wire messenger profile
2
3include /etc/firejail/wire.profile
diff --git a/etc/abrowser.profile b/etc/abrowser.profile
index 949635258..4aa18aa90 100644
--- a/etc/abrowser.profile
+++ b/etc/abrowser.profile
@@ -7,17 +7,16 @@ include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-devel.inc 7include /etc/firejail/disable-devel.inc
8 8
9caps.drop all 9caps.drop all
10seccomp
11protocol unix,inet,inet6,netlink
12netfilter 10netfilter
13tracelog 11nonewprivs
14noroot 12noroot
13protocol unix,inet,inet6,netlink
14seccomp
15tracelog
15 16
16whitelist ${DOWNLOADS} 17whitelist ${DOWNLOADS}
17mkdir ~/.mozilla 18mkdir ~/.mozilla
18whitelist ~/.mozilla 19whitelist ~/.mozilla
19mkdir ~/.cache
20mkdir ~/.cache/mozilla
21mkdir ~/.cache/mozilla/abrowser 20mkdir ~/.cache/mozilla/abrowser
22whitelist ~/.cache/mozilla/abrowser 21whitelist ~/.cache/mozilla/abrowser
23whitelist ~/dwhelper 22whitelist ~/dwhelper
@@ -40,13 +39,12 @@ whitelist ~/.config/lastpass
40 39
41 40
42#silverlight 41#silverlight
43whitelist ~/.wine-pipelight 42whitelist ~/.wine-pipelight
44whitelist ~/.wine-pipelight64 43whitelist ~/.wine-pipelight64
45whitelist ~/.config/pipelight-widevine 44whitelist ~/.config/pipelight-widevine
46whitelist ~/.config/pipelight-silverlight5.1 45whitelist ~/.config/pipelight-silverlight5.1
47 46
48include /etc/firejail/whitelist-common.inc 47include /etc/firejail/whitelist-common.inc
49 48
50# experimental features 49# experimental features
51#private-etc passwd,group,hostname,hosts,localtime,nsswitch.conf,resolv.conf,gtk-2.0,pango,fonts,iceweasel,firefox,adobe,mime.types,mailcap,asound.conf,pulse 50#private-etc passwd,group,hostname,hosts,localtime,nsswitch.conf,resolv.conf,gtk-2.0,pango,fonts,iceweasel,firefox,adobe,mime.types,mailcap,asound.conf,pulse
52
diff --git a/etc/atom-beta.profile b/etc/atom-beta.profile
new file mode 100644
index 000000000..fa0b316bb
--- /dev/null
+++ b/etc/atom-beta.profile
@@ -0,0 +1,20 @@
1# Firejail profile for Atom Beta.
2noblacklist ~/.atom
3noblacklist ~/.config/Atom
4
5include /etc/firejail/disable-common.inc
6include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-passwdmgr.inc
8
9caps.drop all
10netfilter
11nogroups
12nonewprivs
13noroot
14nosound
15protocol unix,inet,inet6,netlink
16seccomp
17shell none
18
19private-dev
20private-tmp
diff --git a/etc/atom.profile b/etc/atom.profile
new file mode 100644
index 000000000..61930d5c1
--- /dev/null
+++ b/etc/atom.profile
@@ -0,0 +1,20 @@
1# Firejail profile for Atom.
2noblacklist ~/.atom
3noblacklist ~/.config/Atom
4
5include /etc/firejail/disable-common.inc
6include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-passwdmgr.inc
8
9caps.drop all
10netfilter
11nogroups
12nonewprivs
13noroot
14nosound
15protocol unix,inet,inet6,netlink
16seccomp
17shell none
18
19private-dev
20private-tmp
diff --git a/etc/atril.profile b/etc/atril.profile
index e078c1d20..fbcca0c1b 100644
--- a/etc/atril.profile
+++ b/etc/atril.profile
@@ -1,12 +1,21 @@
1# Atril profile 1# Atril profile
2noblacklist ~/.config/atril
3noblacklist ~/.local/share
2include /etc/firejail/disable-common.inc 4include /etc/firejail/disable-common.inc
3include /etc/firejail/disable-programs.inc 5include /etc/firejail/disable-programs.inc
4include /etc/firejail/disable-devel.inc 6include /etc/firejail/disable-devel.inc
5include /etc/firejail/disable-passwdmgr.inc 7include /etc/firejail/disable-passwdmgr.inc
6 8
7caps.drop all 9caps.drop all
8seccomp 10nogroups
9protocol unix,inet,inet6 11nonewprivs
10netfilter
11noroot 12noroot
13nosound
14protocol unix
15seccomp
16shell none
12tracelog 17tracelog
18
19private-bin atril, atril-previewer, atril-thumbnailer
20private-dev
21private-tmp
diff --git a/etc/audacious.profile b/etc/audacious.profile
index 290faa260..e5275213c 100644
--- a/etc/audacious.profile
+++ b/etc/audacious.profile
@@ -5,6 +5,7 @@ include /etc/firejail/disable-devel.inc
5include /etc/firejail/disable-passwdmgr.inc 5include /etc/firejail/disable-passwdmgr.inc
6 6
7caps.drop all 7caps.drop all
8seccomp 8nonewprivs
9protocol unix,inet,inet6
10noroot 9noroot
10protocol unix,inet,inet6
11seccomp
diff --git a/etc/audacity.profile b/etc/audacity.profile
new file mode 100644
index 000000000..827fa4301
--- /dev/null
+++ b/etc/audacity.profile
@@ -0,0 +1,21 @@
1# Audacity profile
2noblacklist ~/.audacity-data
3
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-devel.inc
6include /etc/firejail/disable-passwdmgr.inc
7include /etc/firejail/disable-programs.inc
8
9caps.drop all
10netfilter
11nogroups
12nonewprivs
13noroot
14protocol unix
15seccomp
16shell none
17tracelog
18
19private-bin audacity
20private-dev
21private-tmp
diff --git a/etc/aweather.profile b/etc/aweather.profile
new file mode 100644
index 000000000..fa8654f1e
--- /dev/null
+++ b/etc/aweather.profile
@@ -0,0 +1,25 @@
1# Firejail profile for aweather.
2noblacklist ~/.config/aweather
3include /etc/firejail/disable-common.inc
4include /etc/firejail/disable-devel.inc
5include /etc/firejail/disable-passwdmgr.inc
6include /etc/firejail/disable-programs.inc
7
8# Whitelist
9mkdir ~/.config/aweather
10whitelist ~/.config/aweather
11
12caps.drop all
13netfilter
14nogroups
15nonewprivs
16noroot
17nosound
18protocol unix,inet,inet6
19seccomp
20shell none
21tracelog
22
23private-bin aweather
24private-dev
25private-tmp
diff --git a/etc/bitlbee.profile b/etc/bitlbee.profile
index fb84c260a..87d2e843a 100644
--- a/etc/bitlbee.profile
+++ b/etc/bitlbee.profile
@@ -4,8 +4,11 @@ noblacklist /usr/sbin
4include /etc/firejail/disable-common.inc 4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc 5include /etc/firejail/disable-programs.inc
6 6
7protocol unix,inet,inet6 7netfilter
8nonewprivs
8private 9private
9private-dev 10private-dev
11protocol unix,inet,inet6
10seccomp 12seccomp
11netfilter 13nosound
14read-write /var/lib/bitlbee
diff --git a/etc/brave.profile b/etc/brave.profile
new file mode 100644
index 000000000..4fc3a5bb0
--- /dev/null
+++ b/etc/brave.profile
@@ -0,0 +1,18 @@
1# Profile for Brave browser
2
3noblacklist ~/.config/brave
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-devel.inc
7
8caps.drop all
9netfilter
10nonewprivs
11noroot
12protocol unix,inet,inet6,netlink
13seccomp
14
15whitelist ${DOWNLOADS}
16
17mkdir ~/.config/brave
18whitelist ~/.config/brave
diff --git a/etc/cherrytree.profile b/etc/cherrytree.profile
index 7bcc61e98..139dec8ec 100644
--- a/etc/cherrytree.profile
+++ b/etc/cherrytree.profile
@@ -1,22 +1,18 @@
1# cherrytree note taking application 1# cherrytree note taking application
2noblacklist /usr/bin/python2*
3noblacklist /usr/lib/python3*
4noblacklist ${HOME}/.config/cherrytree
2include /etc/firejail/disable-common.inc 5include /etc/firejail/disable-common.inc
3include /etc/firejail/disable-programs.inc 6include /etc/firejail/disable-programs.inc
4include /etc/firejail/disable-devel.inc 7include /etc/firejail/disable-devel.inc
5include /etc/firejail/disable-passwdmgr.inc 8include /etc/firejail/disable-passwdmgr.inc
6 9
7whitelist ${HOME}/cherrytree
8mkdir ~/.config
9mkdir ~/.config/cherrytree
10whitelist ${HOME}/.config/cherrytree/
11mkdir ~/.local
12mkdir ~/.local/share
13whitelist ${HOME}/.local/share/
14
15caps.drop all 10caps.drop all
16seccomp
17protocol unix,inet,inet6,netlink
18netfilter 11netfilter
19tracelog 12nogroups
13nonewprivs
20noroot 14noroot
21include /etc/firejail/whitelist-common.inc
22nosound 15nosound
16seccomp
17protocol unix,inet,inet6,netlink
18tracelog
diff --git a/etc/chromium.profile b/etc/chromium.profile
index 7cf2853ca..4109af9a4 100644
--- a/etc/chromium.profile
+++ b/etc/chromium.profile
@@ -11,10 +11,8 @@ include /etc/firejail/disable-programs.inc
11netfilter 11netfilter
12 12
13whitelist ${DOWNLOADS} 13whitelist ${DOWNLOADS}
14mkdir ~/.config
15mkdir ~/.config/chromium 14mkdir ~/.config/chromium
16whitelist ~/.config/chromium 15whitelist ~/.config/chromium
17mkdir ~/.cache
18mkdir ~/.cache/chromium 16mkdir ~/.cache/chromium
19whitelist ~/.cache/chromium 17whitelist ~/.cache/chromium
20mkdir ~/.pki 18mkdir ~/.pki
@@ -27,4 +25,7 @@ whitelist ~/keepassx.kdbx
27whitelist ~/.lastpass 25whitelist ~/.lastpass
28whitelist ~/.config/lastpass 26whitelist ~/.config/lastpass
29 27
28# specific to Arch
29whitelist ~/.config/chromium-flags.conf
30
30include /etc/firejail/whitelist-common.inc 31include /etc/firejail/whitelist-common.inc
diff --git a/etc/claws-mail.profile b/etc/claws-mail.profile
new file mode 100644
index 000000000..1b6d2f645
--- /dev/null
+++ b/etc/claws-mail.profile
@@ -0,0 +1,24 @@
1# claws-mail profile
2
3noblacklist ~/.claws-mail
4noblacklist ~/.signature
5noblacklist ~/.gnupg
6
7include /etc/firejail/disable-common.inc
8include /etc/firejail/disable-programs.inc
9include /etc/firejail/disable-devel.inc
10include /etc/firejail/disable-passwdmgr.inc
11
12caps.drop all
13netfilter
14nonewprivs
15noroot
16nogroups
17nosound
18protocol unix,inet,inet6
19seccomp
20shell none
21
22private-dev
23private-tmp
24
diff --git a/etc/clementine.profile b/etc/clementine.profile
index c6271e6e3..5ce085358 100644
--- a/etc/clementine.profile
+++ b/etc/clementine.profile
@@ -5,6 +5,7 @@ include /etc/firejail/disable-devel.inc
5include /etc/firejail/disable-passwdmgr.inc 5include /etc/firejail/disable-passwdmgr.inc
6 6
7caps.drop all 7caps.drop all
8seccomp 8nonewprivs
9protocol unix,inet,inet6
10noroot 9noroot
10protocol unix,inet,inet6
11seccomp
diff --git a/etc/cmus.profile b/etc/cmus.profile
index 72b43a70f..2e2a6940c 100644
--- a/etc/cmus.profile
+++ b/etc/cmus.profile
@@ -7,10 +7,11 @@ include /etc/firejail/disable-devel.inc
7include /etc/firejail/disable-passwdmgr.inc 7include /etc/firejail/disable-passwdmgr.inc
8 8
9caps.drop all 9caps.drop all
10seccomp
11protocol unix,inet,inet6
12netfilter 10netfilter
11nonewprivs
13noroot 12noroot
13protocol unix,inet,inet6
14seccomp
14 15
15private-bin cmus 16private-bin cmus
16private-etc group 17private-etc group
diff --git a/etc/conkeror.profile b/etc/conkeror.profile
index 007eef663..e82eeec4c 100644
--- a/etc/conkeror.profile
+++ b/etc/conkeror.profile
@@ -4,10 +4,11 @@ include /etc/firejail/disable-common.inc
4include /etc/firejail/disable-programs.inc 4include /etc/firejail/disable-programs.inc
5 5
6caps.drop all 6caps.drop all
7seccomp
8protocol unix,inet,inet6
9netfilter 7netfilter
8nonewprivs
10noroot 9noroot
10protocol unix,inet,inet6
11seccomp
11 12
12whitelist ~/.conkeror.mozdev.org 13whitelist ~/.conkeror.mozdev.org
13whitelist ~/Downloads 14whitelist ~/Downloads
diff --git a/etc/corebird.profile b/etc/corebird.profile
new file mode 100644
index 000000000..077ae30d0
--- /dev/null
+++ b/etc/corebird.profile
@@ -0,0 +1,12 @@
1# Firejail corebird profile
2
3include /etc/firejail/disable-common.inc
4include /etc/firejail/disable-programs.inc
5include /etc/firejail/disable-devel.inc
6include /etc/firejail/disable-passwdmgr.inc
7
8caps.drop all
9netfilter
10noroot
11protocol unix,inet,inet6
12seccomp
diff --git a/etc/cpio.profile b/etc/cpio.profile
new file mode 100644
index 000000000..519bd244c
--- /dev/null
+++ b/etc/cpio.profile
@@ -0,0 +1,21 @@
1# cpio profile
2# /sbin and /usr/sbin are visible inside the sandbox
3# /boot is not visible and /var is heavily modified
4quiet
5noblacklist /sbin
6noblacklist /usr/sbin
7include /etc/firejail/disable-common.inc
8include /etc/firejail/disable-programs.inc
9include /etc/firejail/disable-passwdmgr.inc
10
11private-dev
12seccomp
13caps.drop all
14net none
15shell none
16tracelog
17net none
18nosound
19
20
21
diff --git a/etc/cyberfox.profile b/etc/cyberfox.profile
new file mode 100644
index 000000000..ae487fa3c
--- /dev/null
+++ b/etc/cyberfox.profile
@@ -0,0 +1,50 @@
1# Firejail profile for Cyberfox (based on Mozilla Firefox)
2
3noblacklist ~/.8pecxstudios
4noblacklist ~/.cache/8pecxstudios
5include /etc/firejail/disable-common.inc
6include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-devel.inc
8
9caps.drop all
10netfilter
11nonewprivs
12noroot
13protocol unix,inet,inet6,netlink
14seccomp
15tracelog
16
17whitelist ${DOWNLOADS}
18mkdir ~/.8pecxstudios
19whitelist ~/.8pecxstudios
20mkdir ~/.cache/8pecxstudios
21whitelist ~/.cache/8pecxstudios
22whitelist ~/dwhelper
23whitelist ~/.zotero
24whitelist ~/.vimperatorrc
25whitelist ~/.vimperator
26whitelist ~/.pentadactylrc
27whitelist ~/.pentadactyl
28whitelist ~/.keysnail.js
29whitelist ~/.config/gnome-mplayer
30whitelist ~/.cache/gnome-mplayer/plugin
31whitelist ~/.pki
32
33# lastpass, keepassx
34whitelist ~/.keepassx
35whitelist ~/.config/keepassx
36whitelist ~/keepassx.kdbx
37whitelist ~/.lastpass
38whitelist ~/.config/lastpass
39
40
41#silverlight
42whitelist ~/.wine-pipelight
43whitelist ~/.wine-pipelight64
44whitelist ~/.config/pipelight-widevine
45whitelist ~/.config/pipelight-silverlight5.1
46
47include /etc/firejail/whitelist-common.inc
48
49# experimental features
50#private-etc passwd,group,hostname,hosts,localtime,nsswitch.conf,resolv.conf,gtk-2.0,pango,fonts,iceweasel,firefox,adobe,mime.types,mailcap,asound.conf,pulse
diff --git a/etc/deadbeef.profile b/etc/deadbeef.profile
index 2810e5323..04abd0a92 100644
--- a/etc/deadbeef.profile
+++ b/etc/deadbeef.profile
@@ -7,6 +7,7 @@ include /etc/firejail/disable-devel.inc
7include /etc/firejail/disable-passwdmgr.inc 7include /etc/firejail/disable-passwdmgr.inc
8 8
9caps.drop all 9caps.drop all
10seccomp 10nonewprivs
11protocol unix,inet,inet6
12noroot 11noroot
12protocol unix,inet,inet6
13seccomp
diff --git a/etc/generic.profile b/etc/default.profile
index f2c7d4114..a2de72695 100644
--- a/etc/generic.profile
+++ b/etc/default.profile
@@ -8,8 +8,8 @@ include /etc/firejail/disable-passwdmgr.inc
8#blacklist ${HOME}/.wine 8#blacklist ${HOME}/.wine
9 9
10caps.drop all 10caps.drop all
11seccomp
12protocol unix,inet,inet6
13netfilter 11netfilter
12nonewprivs
14noroot 13noroot
15 14protocol unix,inet,inet6
15seccomp
diff --git a/etc/deluge.profile b/etc/deluge.profile
index 4043f58f5..c6ddec3ec 100644
--- a/etc/deluge.profile
+++ b/etc/deluge.profile
@@ -1,4 +1,4 @@
1# deluge bittorernt client profile 1# deluge bittorrernt client profile
2include /etc/firejail/disable-common.inc 2include /etc/firejail/disable-common.inc
3include /etc/firejail/disable-programs.inc 3include /etc/firejail/disable-programs.inc
4# deluge is using python on Debian 4# deluge is using python on Debian
@@ -6,8 +6,15 @@ include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-passwdmgr.inc 6include /etc/firejail/disable-passwdmgr.inc
7 7
8caps.drop all 8caps.drop all
9seccomp
10protocol unix,inet,inet6
11netfilter 9netfilter
10nonewprivs
12noroot 11noroot
13nosound 12nosound
13protocol unix,inet,inet6
14seccomp
15
16shell none
17#private-bin deluge,sh,python,uname
18private-dev
19private-tmp
20
diff --git a/etc/dillo.profile b/etc/dillo.profile
index 49c33fb7a..2ddd363cb 100644
--- a/etc/dillo.profile
+++ b/etc/dillo.profile
@@ -7,11 +7,12 @@ include /etc/firejail/disable-devel.inc
7include /etc/firejail/disable-passwdmgr.inc 7include /etc/firejail/disable-passwdmgr.inc
8 8
9caps.drop all 9caps.drop all
10seccomp
11protocol unix,inet,inet6
12netfilter 10netfilter
13tracelog 11nonewprivs
14noroot 12noroot
13protocol unix,inet,inet6
14seccomp
15tracelog
15 16
16whitelist ${DOWNLOADS} 17whitelist ${DOWNLOADS}
17mkdir ~/.dillo 18mkdir ~/.dillo
@@ -20,6 +21,3 @@ mkdir ~/.fltk
20whitelist ~/.fltk 21whitelist ~/.fltk
21 22
22include /etc/firejail/whitelist-common.inc 23include /etc/firejail/whitelist-common.inc
23
24
25
diff --git a/etc/disable-common.inc b/etc/disable-common.inc
index b1133f28f..0dad8b385 100644
--- a/etc/disable-common.inc
+++ b/etc/disable-common.inc
@@ -1,6 +1,7 @@
1# History files in $HOME 1# History files in $HOME
2blacklist-nolog ${HOME}/.history 2blacklist-nolog ${HOME}/.history
3blacklist-nolog ${HOME}/.*_history 3blacklist-nolog ${HOME}/.*_history
4blacklist-nolog ${HOME}/.bash_history
4blacklist ${HOME}/.local/share/systemd 5blacklist ${HOME}/.local/share/systemd
5blacklist-nolog ${HOME}/.adobe 6blacklist-nolog ${HOME}/.adobe
6blacklist-nolog ${HOME}/.macromedia 7blacklist-nolog ${HOME}/.macromedia
@@ -14,21 +15,34 @@ blacklist /etc/xdg/autostart
14blacklist ${HOME}/.kde4/Autostart 15blacklist ${HOME}/.kde4/Autostart
15blacklist ${HOME}/.kde4/share/autostart 16blacklist ${HOME}/.kde4/share/autostart
16blacklist ${HOME}/.kde/Autostart 17blacklist ${HOME}/.kde/Autostart
18blacklist ${HOME}/.kde/share/autostart
17blacklist ${HOME}/.config/plasma-workspace/shutdown 19blacklist ${HOME}/.config/plasma-workspace/shutdown
18blacklist ${HOME}/.config/plasma-workspace/env 20blacklist ${HOME}/.config/plasma-workspace/env
19blacklist ${HOME}/.config/lxsession/LXDE/autostart 21blacklist ${HOME}/.config/lxsession/LXDE/autostart
20blacklist ${HOME}/.fluxbox/startup 22blacklist ${HOME}/.fluxbox/startup
21blacklist ${HOME}/.config/openbox/autostart 23blacklist ${HOME}/.config/openbox/autostart
22blacklist ${HOME}/.config/openbox/environment 24blacklist ${HOME}/.config/openbox/environment
25blacklist ${HOME}/.gnomerc
26blacklist /etc/X11/Xsession.d/
27blacklist ${HOME}/.xpra
23 28
24# VirtualBox 29# VirtualBox
25blacklist ${HOME}/.VirtualBox 30blacklist ${HOME}/.VirtualBox
26blacklist ${HOME}/VirtualBox VMs 31blacklist ${HOME}/VirtualBox VMs
27blacklist ${HOME}/.config/VirtualBox 32blacklist ${HOME}/.config/VirtualBox
28 33
34# VeraCrypt
35blacklist ${PATH}/veracrypt
36blacklist ${PATH}/veracrypt-uninstall.sh
37blacklist /usr/share/veracrypt
38blacklist /usr/share/applications/veracrypt.*
39blacklist /usr/share/pixmaps/veracrypt.*
40blacklist ${HOME}/.VeraCrypt
41
29# var 42# var
30blacklist /var/spool/cron 43blacklist /var/spool/cron
31blacklist /var/spool/anacron 44blacklist /var/spool/anacron
45blacklist /var/mail
32blacklist /var/run/acpid.socket 46blacklist /var/run/acpid.socket
33blacklist /var/run/minissdpd.sock 47blacklist /var/run/minissdpd.sock
34blacklist /var/run/rpcbind.sock 48blacklist /var/run/rpcbind.sock
@@ -39,7 +53,7 @@ blacklist /var/lib/mysql/mysql.sock
39blacklist /var/run/docker.sock 53blacklist /var/run/docker.sock
40 54
41# etc 55# etc
42blacklist /etc/cron.* 56blacklist /etc/cron*
43blacklist /etc/profile.d 57blacklist /etc/profile.d
44blacklist /etc/rc.local 58blacklist /etc/rc.local
45blacklist /etc/anacrontab 59blacklist /etc/anacrontab
@@ -50,11 +64,15 @@ read-only ${HOME}/.xserverrc
50read-only ${HOME}/.profile 64read-only ${HOME}/.profile
51 65
52# Shell startup files 66# Shell startup files
67read-only ${HOME}/.antigen
53read-only ${HOME}/.bash_login 68read-only ${HOME}/.bash_login
54read-only ${HOME}/.bashrc 69read-only ${HOME}/.bashrc
55read-only ${HOME}/.bash_profile 70read-only ${HOME}/.bash_profile
56read-only ${HOME}/.bash_logout 71read-only ${HOME}/.bash_logout
72read-only ${HOME}/.zsh.d
73read-only ${HOME}/.zshenv
57read-only ${HOME}/.zshrc 74read-only ${HOME}/.zshrc
75read-only ${HOME}/.zshrc.local
58read-only ${HOME}/.zlogin 76read-only ${HOME}/.zlogin
59read-only ${HOME}/.zprofile 77read-only ${HOME}/.zprofile
60read-only ${HOME}/.zlogout 78read-only ${HOME}/.zlogout
@@ -62,8 +80,12 @@ read-only ${HOME}/.zsh_files
62read-only ${HOME}/.tcshrc 80read-only ${HOME}/.tcshrc
63read-only ${HOME}/.cshrc 81read-only ${HOME}/.cshrc
64read-only ${HOME}/.csh_files 82read-only ${HOME}/.csh_files
83read-only ${HOME}/.profile
65 84
66# Initialization files that allow arbitrary command execution 85# Initialization files that allow arbitrary command execution
86read-only ${HOME}/.caffrc
87read-only ${HOME}/.dotfiles
88read-only ${HOME}/dotfiles
67read-only ${HOME}/.mailcap 89read-only ${HOME}/.mailcap
68read-only ${HOME}/.exrc 90read-only ${HOME}/.exrc
69read-only ${HOME}/_exrc 91read-only ${HOME}/_exrc
@@ -73,10 +95,11 @@ read-only ${HOME}/.gvimrc
73read-only ${HOME}/_gvimrc 95read-only ${HOME}/_gvimrc
74read-only ${HOME}/.vim 96read-only ${HOME}/.vim
75read-only ${HOME}/.emacs 97read-only ${HOME}/.emacs
98read-only ${HOME}/.emacs.d
99read-only ${HOME}/.nano
76read-only ${HOME}/.tmux.conf 100read-only ${HOME}/.tmux.conf
77read-only ${HOME}/.iscreenrc 101read-only ${HOME}/.iscreenrc
78read-only ${HOME}/.muttrc 102read-only ${HOME}/.reportbugrc
79read-only ${HOME}/.mutt/muttrc
80read-only ${HOME}/.xmonad 103read-only ${HOME}/.xmonad
81read-only ${HOME}/.xscreensaver 104read-only ${HOME}/.xscreensaver
82 105
@@ -84,16 +107,25 @@ read-only ${HOME}/.xscreensaver
84read-only ${HOME}/bin 107read-only ${HOME}/bin
85 108
86# top secret 109# top secret
110blacklist ${HOME}/.ecryptfs
111blacklist ${HOME}/.Private
87blacklist ${HOME}/.ssh 112blacklist ${HOME}/.ssh
113blacklist ${HOME}/.cert
88blacklist ${HOME}/.gnome2/keyrings 114blacklist ${HOME}/.gnome2/keyrings
89blacklist ${HOME}/kde4/share/apps/kwallet 115blacklist ${HOME}/.kde4/share/apps/kwallet
90blacklist ${HOME}/kde/share/apps/kwallet 116blacklist ${HOME}/.kde/share/apps/kwallet
91blacklist ${HOME}/.local/share/kwalletd 117blacklist ${HOME}/.local/share/kwalletd
118blacklist ${HOME}/.config/keybase
92blacklist ${HOME}/.netrc 119blacklist ${HOME}/.netrc
93blacklist ${HOME}/.gnupg 120blacklist ${HOME}/.gnupg
121blacklist ${HOME}/.caff
122blacklist ${HOME}/.smbcredentials
94blacklist ${HOME}/*.kdbx 123blacklist ${HOME}/*.kdbx
95blacklist ${HOME}/*.kdb 124blacklist ${HOME}/*.kdb
96blacklist ${HOME}/*.key 125blacklist ${HOME}/*.key
126blacklist ${HOME}/.muttrc
127blacklist ${HOME}/.mutt/muttrc
128blacklist ${HOME}/.msmtprc
97blacklist /etc/shadow 129blacklist /etc/shadow
98blacklist /etc/gshadow 130blacklist /etc/gshadow
99blacklist /etc/passwd- 131blacklist /etc/passwd-
@@ -106,11 +138,19 @@ blacklist /etc/shadow+
106blacklist /etc/gshadow+ 138blacklist /etc/gshadow+
107blacklist /etc/ssh 139blacklist /etc/ssh
108blacklist /var/backup 140blacklist /var/backup
141blacklist /home/.ecryptfs
142
143# system directories
144blacklist /sbin
145blacklist /usr/sbin
146blacklist /usr/local/sbin
109 147
110# system management 148# system management
111blacklist ${PATH}/umount 149blacklist ${PATH}/umount
112blacklist ${PATH}/mount 150blacklist ${PATH}/mount
113blacklist ${PATH}/fusermount 151blacklist ${PATH}/fusermount
152blacklist ${PATH}/ntfs-3g
153blacklist ${PATH}/at
114blacklist ${PATH}/su 154blacklist ${PATH}/su
115blacklist ${PATH}/sudo 155blacklist ${PATH}/sudo
116blacklist ${PATH}/xinput 156blacklist ${PATH}/xinput
@@ -119,17 +159,45 @@ blacklist ${PATH}/xev
119blacklist ${PATH}/strace 159blacklist ${PATH}/strace
120blacklist ${PATH}/nc 160blacklist ${PATH}/nc
121blacklist ${PATH}/ncat 161blacklist ${PATH}/ncat
162blacklist ${PATH}/gpasswd
163blacklist ${PATH}/newgidmap
164blacklist ${PATH}/newgrp
165blacklist ${PATH}/newuidmap
166blacklist ${PATH}/pkexec
167blacklist ${PATH}/sg
168blacklist ${PATH}/rsh
169blacklist ${PATH}/rlogin
170blacklist ${PATH}/rcp
171blacklist ${PATH}/crontab
172blacklist ${PATH}/ksu
173blacklist ${PATH}/chsh
174blacklist ${PATH}/chfn
175blacklist ${PATH}/chage
176blacklist ${PATH}/expiry
177blacklist ${PATH}/unix_chkpwd
178blacklist ${PATH}/procmail
122 179
123# system directories 180# other SUID binaries
124blacklist /sbin 181blacklist /usr/lib/virtualbox
125blacklist /usr/sbin
126blacklist /usr/local/sbin
127 182
128# prevent lxterminal connecting to an existing lxterminal session 183# prevent lxterminal connecting to an existing lxterminal session
129blacklist /tmp/.lxterminal-socket* 184blacklist /tmp/.lxterminal-socket*
130 185
131# disable terminals running as server 186# disable terminals running as server resulting in sandbox escape
132blacklist ${PATH}/gnome-terminal 187blacklist ${PATH}/gnome-terminal
133blacklist ${PATH}/gnome-terminal.wrapper 188blacklist ${PATH}/gnome-terminal.wrapper
134blacklist ${PATH}/xfce4-terminal 189blacklist ${PATH}/xfce4-terminal
135blacklist ${PATH}/xfce4-terminal.wrapper 190blacklist ${PATH}/xfce4-terminal.wrapper
191blacklist ${PATH}/mate-terminal
192blacklist ${PATH}/mate-terminal.wrapper
193blacklist ${PATH}/lilyterm
194blacklist ${PATH}/pantheon-terminal
195blacklist ${PATH}/roxterm
196blacklist ${PATH}/roxterm-config
197blacklist ${PATH}/terminix
198blacklist ${PATH}/urxvtc
199blacklist ${PATH}/urxvtcd
200
201# kernel files
202blacklist /vmlinuz*
203blacklist /initrd*
diff --git a/etc/disable-devel.inc b/etc/disable-devel.inc
index fa77ed8d1..2ac367f37 100644
--- a/etc/disable-devel.inc
+++ b/etc/disable-devel.inc
@@ -2,20 +2,32 @@
2 2
3# GCC 3# GCC
4blacklist /usr/include 4blacklist /usr/include
5#blacklist /usr/lib/gcc - seems to create problems on Gentoo
5blacklist /usr/bin/gcc* 6blacklist /usr/bin/gcc*
6blacklist /usr/bin/cpp* 7blacklist /usr/bin/cpp*
7blacklist /usr/bin/c9* 8blacklist /usr/bin/c9*
8blacklist /usr/bin/c8* 9blacklist /usr/bin/c8*
9blacklist /usr/bin/c++* 10blacklist /usr/bin/c++*
11blacklist /usr/bin/as
10blacklist /usr/bin/ld 12blacklist /usr/bin/ld
11blacklist /usr/bin/gdb 13blacklist /usr/bin/gdb
14blacklist /usr/bin/g++*
15blacklist /usr/bin/x86_64-linux-gnu-g++*
16blacklist /usr/bin/x86_64-linux-gnu-gcc*
17blacklist /usr/bin/x86_64-unknown-linux-gnu-g++*
18blacklist /usr/bin/x86_64-unknown-linux-gnu-gcc*
12 19
13# clang/llvm 20# clang/llvm
14blacklist /usr/bin/clang* 21blacklist /usr/bin/clang*
15blacklist /usr/bin/llvm* 22blacklist /usr/bin/llvm*
16blacklist /usb/bin/lldb* 23blacklist /usr/bin/lldb*
17blacklist /usr/lib/llvm* 24blacklist /usr/lib/llvm*
18 25
26# tcc - Tiny C Compiler
27blacklist /usr/bin/tcc
28blacklist /usr/bin/x86_64-tcc
29blacklist /usr/lib/tcc
30
19# Valgrind 31# Valgrind
20blacklist /usr/bin/valgrind* 32blacklist /usr/bin/valgrind*
21blacklist /usr/lib/valgrind 33blacklist /usr/lib/valgrind
@@ -35,17 +47,17 @@ blacklist /usr/lib/php*
35blacklist /usr/bin/ruby 47blacklist /usr/bin/ruby
36blacklist /usr/lib/ruby 48blacklist /usr/lib/ruby
37 49
50# Programs using python: deluge, firefox addons, filezilla, cherrytree, xchat, hexchat, libreoffice
38# Python 2 51# Python 2
39blacklist /usr/bin/python2* 52#blacklist /usr/bin/python2*
40blacklist /usr/lib/python2* 53#blacklist /usr/lib/python2*
41blacklist /usr/local/lib/python2* 54#blacklist /usr/local/lib/python2*
42blacklist /usr/include/python2* 55#blacklist /usr/include/python2*
43blacklist /usr/share/python2* 56#blacklist /usr/share/python2*
44 57#
45# Python 3 58# Python 3
46blacklist /usr/bin/python3* 59#blacklist /usr/bin/python3*
47blacklist /usr/lib/python3* 60#blacklist /usr/lib/python3*
48blacklist /usr/local/lib/python3* 61#blacklist /usr/local/lib/python3*
49blacklist /usr/share/python3* 62#blacklist /usr/share/python3*
50blacklist /usr/include/python3* 63#blacklist /usr/include/python3*
51
diff --git a/etc/disable-passwdmgr.inc b/etc/disable-passwdmgr.inc
index c1e68d1ec..6db9073ab 100644
--- a/etc/disable-passwdmgr.inc
+++ b/etc/disable-passwdmgr.inc
@@ -3,4 +3,5 @@ blacklist ${HOME}/.lastpass
3blacklist ${HOME}/.keepassx 3blacklist ${HOME}/.keepassx
4blacklist ${HOME}/.password-store 4blacklist ${HOME}/.password-store
5blacklist ${HOME}/keepassx.kdbx 5blacklist ${HOME}/keepassx.kdbx
6blacklist ${HOME}/.config/keepassx
6 7
diff --git a/etc/display.profile b/etc/display.profile
new file mode 100644
index 000000000..ec041bff7
--- /dev/null
+++ b/etc/display.profile
@@ -0,0 +1,23 @@
1# display (ImageMagick tool) image viewer profile
2include /etc/firejail/disable-common.inc
3include /etc/firejail/disable-programs.inc
4include /etc/firejail/disable-devel.inc
5include /etc/firejail/disable-passwdmgr.inc
6
7caps.drop all
8seccomp
9protocol unix
10netfilter
11net none
12nonewprivs
13noroot
14nogroups
15nosound
16shell none
17x11 xorg
18
19private-bin display
20private-tmp
21private-dev
22private-etc none
23
diff --git a/etc/dnscrypt-proxy.profile b/etc/dnscrypt-proxy.profile
index bd7e19dc2..926b8bfcc 100644
--- a/etc/dnscrypt-proxy.profile
+++ b/etc/dnscrypt-proxy.profile
@@ -8,5 +8,7 @@ include /etc/firejail/disable-passwdmgr.inc
8 8
9private 9private
10private-dev 10private-dev
11nosound
12no3d
11seccomp.drop mount,umount2,ptrace,kexec_load,kexec_file_load,open_by_handle_at,init_module,finit_module,delete_module,iopl,ioperm,swapon,swapoff,syslog,process_vm_readv,process_vm_writev,sysfs,_sysctl,adjtimex,clock_adjtime,lookup_dcookie,perf_event_open,fanotify_init,kcmp,add_key,request_key,keyctl,uselib,acct,modify_ldt,pivot_root,io_setup,io_destroy,io_getevents,io_submit,io_cancel,remap_file_pages,mbind,get_mempolicy,set_mempolicy,migrate_pages,move_pages,vmsplice,perf_event_open 13seccomp.drop mount,umount2,ptrace,kexec_load,kexec_file_load,open_by_handle_at,init_module,finit_module,delete_module,iopl,ioperm,swapon,swapoff,syslog,process_vm_readv,process_vm_writev,sysfs,_sysctl,adjtimex,clock_adjtime,lookup_dcookie,perf_event_open,fanotify_init,kcmp,add_key,request_key,keyctl,uselib,acct,modify_ldt,pivot_root,io_setup,io_destroy,io_getevents,io_submit,io_cancel,remap_file_pages,mbind,get_mempolicy,set_mempolicy,migrate_pages,move_pages,vmsplice,perf_event_open
12 14
diff --git a/etc/dnsmasq.profile b/etc/dnsmasq.profile
index 474bc5aca..3bd43f144 100644
--- a/etc/dnsmasq.profile
+++ b/etc/dnsmasq.profile
@@ -5,9 +5,13 @@ include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc 5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-passwdmgr.inc 6include /etc/firejail/disable-passwdmgr.inc
7include /etc/firejail/disable-devel.inc 7include /etc/firejail/disable-devel.inc
8
8caps 9caps
9seccomp
10protocol unix,inet,inet6,netlink
11netfilter 10netfilter
11nonewprivs
12private 12private
13private-dev 13private-dev
14nosound
15no3d
16protocol unix,inet,inet6,netlink
17seccomp
diff --git a/etc/dosbox.profile b/etc/dosbox.profile
new file mode 100644
index 000000000..45fbb712a
--- /dev/null
+++ b/etc/dosbox.profile
@@ -0,0 +1,21 @@
1# Firejail profile for dosbox
2noblacklist ~/.dosbox
3
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-devel.inc
7include /etc/firejail/disable-passwdmgr.inc
8
9caps.drop all
10netfilter
11nogroups
12nonewprivs
13noroot
14protocol unix,inet,inet6
15seccomp
16shell none
17tracelog
18
19private-bin dosbox
20private-dev
21private-tmp
diff --git a/etc/dropbox.profile b/etc/dropbox.profile
index a0a944dce..40efd62b2 100644
--- a/etc/dropbox.profile
+++ b/etc/dropbox.profile
@@ -1,9 +1,21 @@
1# dropbox profile 1# dropbox profile
2noblacklist ~/.config/autostart
2include /etc/firejail/disable-common.inc 3include /etc/firejail/disable-common.inc
3include /etc/firejail/disable-programs.inc 4include /etc/firejail/disable-programs.inc
4include /etc/firejail/disable-passwdmgr.inc 5include /etc/firejail/disable-passwdmgr.inc
5 6
6caps 7caps
7seccomp 8nonewprivs
8protocol unix,inet,inet6
9noroot 9noroot
10protocol unix,inet,inet6
11seccomp
12
13mkdir ~/Dropbox
14whitelist ~/Dropbox
15mkdir ~/.dropbox
16whitelist ~/.dropbox
17mkdir ~/.dropbox-dist
18whitelist ~/.dropbox-dist
19
20mkfile ~/.config/autostart/dropbox.desktop
21whitelist ~/.config/autostart/dropbox.desktop
diff --git a/etc/emacs.profile b/etc/emacs.profile
new file mode 100644
index 000000000..cbdba7712
--- /dev/null
+++ b/etc/emacs.profile
@@ -0,0 +1,17 @@
1# emacs profile
2
3noblacklist ~/.emacs
4noblacklist ~/.emacs.d
5
6include /etc/firejail/disable-common.inc
7include /etc/firejail/disable-programs.inc
8include /etc/firejail/disable-passwdmgr.inc
9
10
11caps.drop all
12netfilter
13nonewprivs
14noroot
15nogroups
16protocol unix,inet,inet6
17seccomp
diff --git a/etc/empathy.profile b/etc/empathy.profile
index 789bdda08..371100814 100644
--- a/etc/empathy.profile
+++ b/etc/empathy.profile
@@ -4,6 +4,7 @@ include /etc/firejail/disable-programs.inc
4include /etc/firejail/disable-devel.inc 4include /etc/firejail/disable-devel.inc
5 5
6caps.drop all 6caps.drop all
7seccomp
8protocol unix,inet,inet6
9netfilter 7netfilter
8nonewprivs
9protocol unix,inet,inet6
10seccomp
diff --git a/etc/eog.profile b/etc/eog.profile
new file mode 100644
index 000000000..68e950bd7
--- /dev/null
+++ b/etc/eog.profile
@@ -0,0 +1,23 @@
1# eog (gnome image viewer) profile
2
3noblacklist ~/.config/eog
4
5include /etc/firejail/disable-common.inc
6include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-devel.inc
8include /etc/firejail/disable-passwdmgr.inc
9
10caps.drop all
11netfilter
12nogroups
13nonewprivs
14noroot
15nosound
16protocol unix
17seccomp
18shell none
19
20private-bin eog
21private-dev
22private-etc fonts
23private-tmp
diff --git a/etc/eom.profile b/etc/eom.profile
new file mode 100644
index 000000000..dfcea82c1
--- /dev/null
+++ b/etc/eom.profile
@@ -0,0 +1,21 @@
1# Firejail profile for Eye of Mate (eom)
2noblacklist ~/.config/mate/eom
3
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-devel.inc
7include /etc/firejail/disable-passwdmgr.inc
8
9caps.drop all
10nogroups
11nonewprivs
12noroot
13nosound
14protocol unix
15seccomp
16shell none
17tracelog
18
19private-bin eom
20private-dev
21private-tmp
diff --git a/etc/epiphany.profile b/etc/epiphany.profile
index 95a673bf9..0e898f02b 100644
--- a/etc/epiphany.profile
+++ b/etc/epiphany.profile
@@ -8,19 +8,16 @@ include /etc/firejail/disable-programs.inc
8include /etc/firejail/disable-devel.inc 8include /etc/firejail/disable-devel.inc
9 9
10whitelist ${DOWNLOADS} 10whitelist ${DOWNLOADS}
11mkdir ${HOME}/.local
12mkdir ${HOME}/.local/share
13mkdir ${HOME}/.local/share/epiphany 11mkdir ${HOME}/.local/share/epiphany
14whitelist ${HOME}/.local/share/epiphany 12whitelist ${HOME}/.local/share/epiphany
15mkdir ${HOME}/.config
16mkdir ${HOME}/.config/epiphany 13mkdir ${HOME}/.config/epiphany
17whitelist ${HOME}/.config/epiphany 14whitelist ${HOME}/.config/epiphany
18mkdir ${HOME}/.cache
19mkdir ${HOME}/.cache/epiphany 15mkdir ${HOME}/.cache/epiphany
20whitelist ${HOME}/.cache/epiphany 16whitelist ${HOME}/.cache/epiphany
21include /etc/firejail/whitelist-common.inc 17include /etc/firejail/whitelist-common.inc
18
22caps.drop all 19caps.drop all
23seccomp
24protocol unix,inet,inet6
25netfilter 20netfilter
26 21nonewprivs
22protocol unix,inet,inet6
23seccomp
diff --git a/etc/evince.profile b/etc/evince.profile
index c390dcaf3..cbb2083f4 100644
--- a/etc/evince.profile
+++ b/etc/evince.profile
@@ -5,7 +5,18 @@ include /etc/firejail/disable-devel.inc
5include /etc/firejail/disable-passwdmgr.inc 5include /etc/firejail/disable-passwdmgr.inc
6 6
7caps.drop all 7caps.drop all
8seccomp 8netfilter
9protocol unix,inet,inet6 9#net none - creates some problems on some distributions
10nogroups
11nonewprivs
10noroot 12noroot
11nosound 13nosound
14protocol unix
15seccomp
16shell none
17tracelog
18
19private-bin evince,evince-previewer,evince-thumbnailer
20private-dev
21private-etc fonts
22private-tmp \ No newline at end of file
diff --git a/etc/evolution.profile b/etc/evolution.profile
new file mode 100644
index 000000000..d63eeed74
--- /dev/null
+++ b/etc/evolution.profile
@@ -0,0 +1,26 @@
1# evolution profile
2
3noblacklist ~/.config/evolution
4noblacklist ~/.local/share/evolution
5noblacklist ~/.cache/evolution
6noblacklist ~/.pki
7noblacklist ~/.pki/nssdb
8noblacklist ~/.gnupg
9
10include /etc/firejail/disable-common.inc
11include /etc/firejail/disable-programs.inc
12include /etc/firejail/disable-devel.inc
13include /etc/firejail/disable-passwdmgr.inc
14
15caps.drop all
16netfilter
17nogroups
18nonewprivs
19noroot
20nosound
21protocol unix,inet,inet6
22seccomp
23shell none
24
25private-dev
26private-tmp
diff --git a/etc/fbreader.profile b/etc/fbreader.profile
index cfbae1c74..ec098d5fe 100644
--- a/etc/fbreader.profile
+++ b/etc/fbreader.profile
@@ -7,8 +7,14 @@ include /etc/firejail/disable-devel.inc
7include /etc/firejail/disable-passwdmgr.inc 7include /etc/firejail/disable-passwdmgr.inc
8 8
9caps.drop all 9caps.drop all
10seccomp
11protocol unix,inet,inet6
12netfilter 10netfilter
11nonewprivs
13noroot 12noroot
14nosound 13nosound
14protocol unix,inet,inet6
15seccomp
16
17shell none
18private-bin fbreader,FBReader
19private-dev
20private-tmp
diff --git a/etc/feh.profile b/etc/feh.profile
new file mode 100644
index 000000000..2812effc9
--- /dev/null
+++ b/etc/feh.profile
@@ -0,0 +1,21 @@
1# feh image viewer profile
2include /etc/firejail/disable-common.inc
3include /etc/firejail/disable-programs.inc
4include /etc/firejail/disable-devel.inc
5include /etc/firejail/disable-passwdmgr.inc
6
7caps.drop all
8netfilter
9net none
10nogroups
11nonewprivs
12noroot
13nosound
14protocol unix
15seccomp
16shell none
17
18private-bin feh
19private-dev
20private-etc feh
21private-tmp \ No newline at end of file
diff --git a/etc/file.profile b/etc/file.profile
new file mode 100644
index 000000000..199a97fad
--- /dev/null
+++ b/etc/file.profile
@@ -0,0 +1,17 @@
1# file profile
2ignore noroot
3include /etc/firejail/default.profile
4
5blacklist /tmp/.X11-unix
6
7hostname file
8net none
9no3d
10nosound
11quiet
12shell none
13tracelog
14
15private-dev
16private-bin file
17private-etc magic.mgc,magic,localtime
diff --git a/etc/filezilla.profile b/etc/filezilla.profile
index 8542de284..a40fceec1 100644
--- a/etc/filezilla.profile
+++ b/etc/filezilla.profile
@@ -7,8 +7,14 @@ include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-devel.inc 7include /etc/firejail/disable-devel.inc
8 8
9caps.drop all 9caps.drop all
10seccomp
11protocol unix,inet,inet6
12noroot
13netfilter 10netfilter
11nonewprivs
12noroot
14nosound 13nosound
14protocol unix,inet,inet6
15seccomp
16shell none
17
18private-bin filezilla,uname,sh,python,lsb_release,fzputtygen,fzsftp
19private-dev
20private-tmp
diff --git a/etc/firefox-esr.profile b/etc/firefox-esr.profile
new file mode 100644
index 000000000..d2fde9a3f
--- /dev/null
+++ b/etc/firefox-esr.profile
@@ -0,0 +1,2 @@
1# Firejail profile for Mozilla Firefox ESR
2include /etc/firejail/firefox.profile
diff --git a/etc/firefox.profile b/etc/firefox.profile
index 1ea94a2c7..6bb581f4f 100644
--- a/etc/firefox.profile
+++ b/etc/firefox.profile
@@ -2,22 +2,24 @@
2 2
3noblacklist ~/.mozilla 3noblacklist ~/.mozilla
4noblacklist ~/.cache/mozilla 4noblacklist ~/.cache/mozilla
5noblacklist ~/.config/qpdfview
6noblacklist ~/.local/share/qpdfview
7noblacklist ~/.kde/share/apps/okular
5include /etc/firejail/disable-common.inc 8include /etc/firejail/disable-common.inc
6include /etc/firejail/disable-programs.inc 9include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-devel.inc 10include /etc/firejail/disable-devel.inc
8 11
9caps.drop all 12caps.drop all
10seccomp
11protocol unix,inet,inet6,netlink
12netfilter 13netfilter
13tracelog 14nonewprivs
14noroot 15noroot
16protocol unix,inet,inet6,netlink
17seccomp
18tracelog
15 19
16whitelist ${DOWNLOADS} 20whitelist ${DOWNLOADS}
17mkdir ~/.mozilla 21mkdir ~/.mozilla
18whitelist ~/.mozilla 22whitelist ~/.mozilla
19mkdir ~/.cache
20mkdir ~/.cache/mozilla
21mkdir ~/.cache/mozilla/firefox 23mkdir ~/.cache/mozilla/firefox
22whitelist ~/.cache/mozilla/firefox 24whitelist ~/.cache/mozilla/firefox
23whitelist ~/dwhelper 25whitelist ~/dwhelper
@@ -30,6 +32,9 @@ whitelist ~/.keysnail.js
30whitelist ~/.config/gnome-mplayer 32whitelist ~/.config/gnome-mplayer
31whitelist ~/.cache/gnome-mplayer/plugin 33whitelist ~/.cache/gnome-mplayer/plugin
32whitelist ~/.pki 34whitelist ~/.pki
35whitelist ~/.config/qpdfview
36whitelist ~/.local/share/qpdfview
37whitelist ~/.kde/share/apps/okular
33 38
34# lastpass, keepassx 39# lastpass, keepassx
35whitelist ~/.keepassx 40whitelist ~/.keepassx
@@ -40,14 +45,15 @@ whitelist ~/.config/lastpass
40 45
41 46
42#silverlight 47#silverlight
43whitelist ~/.wine-pipelight 48whitelist ~/.wine-pipelight
44whitelist ~/.wine-pipelight64 49whitelist ~/.wine-pipelight64
45whitelist ~/.config/pipelight-widevine 50whitelist ~/.config/pipelight-widevine
46whitelist ~/.config/pipelight-silverlight5.1 51whitelist ~/.config/pipelight-silverlight5.1
47 52
48include /etc/firejail/whitelist-common.inc 53include /etc/firejail/whitelist-common.inc
49 54
50# experimental features 55# experimental features
51#private-etc passwd,group,hostname,hosts,localtime,nsswitch.conf,resolv.conf,gtk-2.0,pango,fonts,iceweasel,firefox,adobe,mime.types,mailcap,asound.conf,pulse 56#private-bin firefox,which,sh,dbus-launch,dbus-send,env
52 57#private-etc passwd,group,hostname,hosts,localtime,nsswitch.conf,resolv.conf,xdg,gtk-2.0,gtk-3.0,X11,pango,fonts,firefox,mime.types,mailcap,asound.conf,pulse
53 58private-dev
59private-tmp
diff --git a/etc/firejail-default b/etc/firejail-default
new file mode 100644
index 000000000..1b0eb7658
--- /dev/null
+++ b/etc/firejail-default
@@ -0,0 +1,154 @@
1#########################################
2# Generic Firejail AppArmor profile
3#########################################
4
5##########
6# A simple PID declaration based on Ubuntu's @{pid}
7# Ubuntu keeps it under tunables/kernelvars and include it via tunables/global.
8# We don't know if this definition is available outside Debian and Ubuntu, so
9# we declare our own here.
10##########
11@{PID}={[1-9],[1-9][0-9],[1-9][0-9][0-9],[1-9][0-9][0-9][0-9],[1-9][0-9][0-9][0-9][0-9],[1-9][0-9][0-9][0-9][0-9][0-9]}
12
13profile firejail-default {
14
15##########
16# D-Bus is a huge security hole. Uncomment this line if you need D-Bus
17# functionality.
18##########
19#dbus,
20
21##########
22# Mask /proc and /sys information leakage. The configuration here is barely
23# enough to run "top" or "ps aux".
24##########
25/ r,
26/[^proc,^sys]** mrwlk,
27/{,var/}run/ r,
28/{,var/}run/** r,
29/{,var/}run/user/**/dconf/ rw,
30/{,var/}run/user/**/dconf/user rw,
31/{,var/}run/user/**/pulse/ rw,
32/{,var/}run/user/**/pulse/** rw,
33/{,var/}run/firejail/mnt/fslogger r,
34/{,var/}run/firejail/appimage r,
35/{,var/}run/firejail/appimage/** r,
36/{,var/}run/firejail/appimage/** ix,
37/{run,dev}/shm/ r,
38/{run,dev}/shm/** rmwk,
39
40/proc/ r,
41/proc/meminfo r,
42/proc/cpuinfo r,
43/proc/filesystems r,
44/proc/uptime r,
45/proc/loadavg r,
46/proc/stat r,
47
48/proc/@{PID}/ r,
49/proc/@{PID}/fd/ r,
50/proc/@{PID}/task/ r,
51/proc/@{PID}/cmdline r,
52/proc/@{PID}/comm r,
53/proc/@{PID}/stat r,
54/proc/@{PID}/statm r,
55/proc/@{PID}/status r,
56/proc/@{PID}/task/@{PID}/stat r,
57/proc/sys/kernel/pid_max r,
58/proc/sys/kernel/shmmax r,
59/proc/sys/vm/overcommit_memory r,
60/proc/sys/vm/overcommit_ratio r,
61
62/sys/ r,
63/sys/bus/ r,
64/sys/bus/** r,
65/sys/class/ r,
66/sys/class/** r,
67/sys/devices/ r,
68/sys/devices/** r,
69
70/proc/@{PID}/maps r,
71/proc/@{PID}/mounts r,
72/proc/@{PID}/mountinfo r,
73/proc/@{PID}/oom_score_adj r,
74
75##########
76# Allow running programs only from well-known system directories. If you need
77# to run programs from your home directory, uncomment /home line.
78##########
79/lib/** ix,
80/lib64/** ix,
81/bin/** ix,
82/sbin/** ix,
83/usr/bin/** ix,
84/usr/sbin/** ix,
85/usr/local/** ix,
86/usr/lib/** ix,
87/usr/games/** ix,
88/opt/ r,
89/opt/** r,
90/opt/** ix,
91#/home/** ix,
92
93##########
94# Allow all networking functionality, and control it from Firejail.
95##########
96network inet,
97network inet6,
98network unix,
99network netlink,
100network raw,
101
102##########
103# There is no equivalent in Firejail for filtering signals.
104##########
105signal,
106
107##########
108# We let Firejail deal with capabilities.
109##########
110capability chown,
111capability dac_override,
112capability dac_read_search,
113capability fowner,
114capability fsetid,
115capability kill,
116capability setgid,
117capability setuid,
118capability setpcap,
119capability linux_immutable,
120capability net_bind_service,
121capability net_broadcast,
122capability net_admin,
123capability net_raw,
124capability ipc_lock,
125capability ipc_owner,
126capability sys_module,
127capability sys_rawio,
128capability sys_chroot,
129capability sys_ptrace,
130capability sys_pacct,
131capability sys_admin,
132capability sys_boot,
133capability sys_nice,
134capability sys_resource,
135capability sys_time,
136capability sys_tty_config,
137capability mknod,
138capability lease,
139capability audit_write,
140capability audit_control,
141capability setfcap,
142capability mac_override,
143capability mac_admin,
144
145##########
146# We let Firejail deal with mount/umount functionality.
147##########
148mount,
149remount,
150umount,
151pivot_root,
152
153}
154
diff --git a/etc/firejail.config b/etc/firejail.config
index 41cd08e68..2ea767f37 100644
--- a/etc/firejail.config
+++ b/etc/firejail.config
@@ -9,24 +9,60 @@
9# Enable or disable chroot support, default enabled. 9# Enable or disable chroot support, default enabled.
10# chroot yes 10# chroot yes
11 11
12# Use chroot for desktop programs, default enabled. The sandbox will have full
13# access to system's /dev directory in order to allow video acceleration,
14# and it will harden the rest of the chroot tree.
15# chroot-desktop yes
16
12# Enable or disable file transfer support, default enabled. 17# Enable or disable file transfer support, default enabled.
13# file-transfer yes 18# file-transfer yes
14 19
20# Force use of nonewprivs. This mitigates the possibility of
21# a user abusing firejail's features to trick a privileged (suid
22# or file capabilities) process into loading code or configuration
23# that is partially under their control. Default disabled.
24# force-nonewprivs no
25
15# Enable or disable networking features, default enabled. 26# Enable or disable networking features, default enabled.
16# network yes 27# network yes
17 28
29# Enable or disable overlayfs features, default enabled.
30# overlayfs yes
31
32# Remove /usr/local directories from private-bin list, default disabled.
33# private-bin-no-local no
34
35# Enable or disable private-home feature, default enabled
36# private-home yes
37
38# Enable --quiet as default every time the sandbox is started. Default disabled.
39# quiet-by-default no
40
41# Remount /proc and /sys inside the sandbox, default enabled.
42# remount-proc-sys yes
43
18# Enable or disable restricted network support, default disabled. If enabled, 44# Enable or disable restricted network support, default disabled. If enabled,
19# networking features should also be enabled (network yes). 45# networking features should also be enabled (network yes).
20# Restricted networking grants access to --interface and --net=ethXXX 46# Restricted networking grants access to --interface, --net=ethXXX and
21# only to root user. Regular users are only allowed --net=none. 47# --netfilter only to root user. Regular users are only allowed --net=none.
22# restricted-network no 48# restricted-network no
23 49
50# Change default netfilter configuration. When using --netfilter option without
51# a file argument, the default filter is hardcoded (see man 1 firejail). This
52# configuration entry allows the user to change the default by specifying
53# a file containing the filter configuration. The filter file format is the
54# format of iptables-save and iptable-restore commands. Example:
55# netfilter-default /etc/iptables.iptables.rules
56
24# Enable or disable seccomp support, default enabled. 57# Enable or disable seccomp support, default enabled.
25# seccomp yes 58# seccomp yes
26 59
27# Enable or disable user namespace support, default enabled. 60# Enable or disable user namespace support, default enabled.
28# userns yes 61# userns yes
29 62
63# Enable or disable whitelisting support, default enabled.
64# whitelist yes
65
30# Enable or disable X11 sandboxing support, default enabled. 66# Enable or disable X11 sandboxing support, default enabled.
31# x11 yes 67# x11 yes
32 68
@@ -36,3 +72,10 @@
36# xephyr-screen 800x600 72# xephyr-screen 800x600
37# xephyr-screen 1024x768 73# xephyr-screen 1024x768
38# xephyr-screen 1280x1024 74# xephyr-screen 1280x1024
75
76# Firejail window title in Xephyr, default enabled.
77# xephyr-window-title yes
78
79# Xephyr command extra parameters. None by default, and the declaration is commented out.
80# xephyr-extra-params -keybd ephyr,,,xkbmodel=evdev
81# xephyr-extra-params -grayscale
diff --git a/etc/flashpeak-slimjet.profile b/etc/flashpeak-slimjet.profile
index 94c672acf..7e0eb486b 100644
--- a/etc/flashpeak-slimjet.profile
+++ b/etc/flashpeak-slimjet.profile
@@ -15,16 +15,15 @@ include /etc/firejail/disable-programs.inc
15# 15#
16 16
17caps.drop all 17caps.drop all
18seccomp
19protocol unix,inet,inet6,netlink
20netfilter 18netfilter
19nonewprivs
21noroot 20noroot
21protocol unix,inet,inet6,netlink
22seccomp
22 23
23whitelist ${DOWNLOADS} 24whitelist ${DOWNLOADS}
24mkdir ~/.config
25mkdir ~/.config/slimjet 25mkdir ~/.config/slimjet
26whitelist ~/.config/slimjet 26whitelist ~/.config/slimjet
27mkdir ~/.cache
28mkdir ~/.cache/slimjet 27mkdir ~/.cache/slimjet
29whitelist ~/.cache/slimjet 28whitelist ~/.cache/slimjet
30mkdir ~/.pki 29mkdir ~/.pki
diff --git a/etc/flowblade.profile b/etc/flowblade.profile
new file mode 100644
index 000000000..12afdb0aa
--- /dev/null
+++ b/etc/flowblade.profile
@@ -0,0 +1,13 @@
1# FlowBlade profile
2noblacklist ${HOME}/.flowblade
3noblacklist ${HOME}/.config/flowblade
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-passwdmgr.inc
7
8caps.drop all
9netfilter
10nonewprivs
11noroot
12protocol unix,inet,inet6,netlink
13seccomp
diff --git a/etc/franz.profile b/etc/franz.profile
new file mode 100644
index 000000000..0b3be551b
--- /dev/null
+++ b/etc/franz.profile
@@ -0,0 +1,24 @@
1# Franz profile
2noblacklist ~/.config/Franz
3noblacklist ~/.cache/Franz
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-devel.inc
7
8caps.drop all
9netfilter
10nonewprivs
11noroot
12protocol unix,inet,inet6,netlink
13seccomp
14#tracelog
15
16whitelist ${DOWNLOADS}
17mkdir ~/.config/Franz
18whitelist ~/.config/Franz
19mkdir ~/.cache/Franz
20whitelist ~/.cache/Franz
21mkdir ~/.pki
22whitelist ~/.pki
23
24include /etc/firejail/whitelist-common.inc
diff --git a/etc/gajim.profile b/etc/gajim.profile
new file mode 100644
index 000000000..809378ef9
--- /dev/null
+++ b/etc/gajim.profile
@@ -0,0 +1,33 @@
1# Firejail profile for Gajim
2
3mkdir ${HOME}/.cache/gajim
4mkdir ${HOME}/.local/share/gajim
5mkdir ${HOME}/.config/gajim
6mkdir ${HOME}/Downloads
7
8# Allow the local python 2.7 site packages, in case any plugins are using these
9mkdir ${HOME}/.local/lib/python2.7/site-packages/
10whitelist ${HOME}/.local/lib/python2.7/site-packages/
11read-only ${HOME}/.local/lib/python2.7/site-packages/
12
13whitelist ${HOME}/.cache/gajim
14whitelist ${HOME}/.local/share/gajim
15whitelist ${HOME}/.config/gajim
16whitelist ${HOME}/Downloads
17
18include /etc/firejail/disable-common.inc
19include /etc/firejail/disable-passwdmgr.inc
20include /etc/firejail/disable-programs.inc
21include /etc/firejail/disable-devel.inc
22
23caps.drop all
24netfilter
25nogroups
26nonewprivs
27noroot
28protocol unix,inet,inet6
29seccomp
30shell none
31
32#private-bin python2.7 gajim
33private-dev
diff --git a/etc/gimp.profile b/etc/gimp.profile
new file mode 100644
index 000000000..cb441fc9d
--- /dev/null
+++ b/etc/gimp.profile
@@ -0,0 +1,20 @@
1# gimp
2noblacklist ${HOME}/.gimp*
3include /etc/firejail/disable-common.inc
4include /etc/firejail/disable-programs.inc
5include /etc/firejail/disable-passwdmgr.inc
6
7caps.drop all
8netfilter
9nogroups
10nonewprivs
11noroot
12nosound
13protocol unix
14seccomp
15
16noexec ${HOME}
17noexec /tmp
18
19private-dev
20private-tmp
diff --git a/etc/git.profile b/etc/git.profile
new file mode 100644
index 000000000..73122d347
--- /dev/null
+++ b/etc/git.profile
@@ -0,0 +1,27 @@
1# git profile
2
3noblacklist ~/.gitconfig
4noblacklist ~/.ssh
5noblacklist ~/.gnupg
6noblacklist ~/.emacs
7noblacklist ~/.emacs.d
8noblacklist ~/.viminfo
9noblacklist ~/.vim
10
11include /etc/firejail/disable-common.inc
12include /etc/firejail/disable-programs.inc
13include /etc/firejail/disable-passwdmgr.inc
14
15
16caps.drop all
17netfilter
18nogroups
19nonewprivs
20noroot
21nosound
22protocol unix,inet,inet6
23quiet
24seccomp
25shell none
26
27private-dev
diff --git a/etc/gitter.profile b/etc/gitter.profile
new file mode 100644
index 000000000..f43f5f199
--- /dev/null
+++ b/etc/gitter.profile
@@ -0,0 +1,20 @@
1# Firejail profile for Gitter
2noblacklist ~/.config/Gitter
3include /etc/firejail/disable-common.inc
4include /etc/firejail/disable-passwdmgr.inc
5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-devel.inc
7
8caps.drop all
9netfilter
10nogroups
11nonewprivs
12noroot
13nosound
14protocol unix,inet,inet6,netlink
15seccomp
16shell none
17
18private-bin gitter
19private-dev
20private-tmp
diff --git a/etc/gnome-chess.profile b/etc/gnome-chess.profile
new file mode 100644
index 000000000..297f7e6a9
--- /dev/null
+++ b/etc/gnome-chess.profile
@@ -0,0 +1,22 @@
1# Firejail profile for gnome-chess
2noblacklist /.local/share/gnome-chess
3
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-devel.inc
6include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-passwdmgr.inc
8
9caps.drop all
10nogroups
11nonewprivs
12noroot
13nosound
14protocol unix
15seccomp
16shell none
17tracelog
18
19private-bin fairymax,gnome-chess,hoichess
20private-dev
21private-etc fonts,gnome-chess
22private-tmp
diff --git a/etc/gnome-mplayer.profile b/etc/gnome-mplayer.profile
index ec3698ac8..1b0fc9807 100644
--- a/etc/gnome-mplayer.profile
+++ b/etc/gnome-mplayer.profile
@@ -5,6 +5,13 @@ include /etc/firejail/disable-devel.inc
5include /etc/firejail/disable-passwdmgr.inc 5include /etc/firejail/disable-passwdmgr.inc
6 6
7caps.drop all 7caps.drop all
8seccomp 8nogroups
9protocol unix,inet,inet6 9nonewprivs
10noroot 10noroot
11protocol unix,inet,inet6
12seccomp
13shell none
14
15private-bin gnome-mplayer
16private-dev
17private-tmp
diff --git a/etc/google-chrome-beta.profile b/etc/google-chrome-beta.profile
index 11f9f9e33..fe870274f 100644
--- a/etc/google-chrome-beta.profile
+++ b/etc/google-chrome-beta.profile
@@ -11,10 +11,8 @@ include /etc/firejail/disable-programs.inc
11netfilter 11netfilter
12 12
13whitelist ${DOWNLOADS} 13whitelist ${DOWNLOADS}
14mkdir ~/.config
15mkdir ~/.config/google-chrome-beta 14mkdir ~/.config/google-chrome-beta
16whitelist ~/.config/google-chrome-beta 15whitelist ~/.config/google-chrome-beta
17mkdir ~/.cache
18mkdir ~/.cache/google-chrome-beta 16mkdir ~/.cache/google-chrome-beta
19whitelist ~/.cache/google-chrome-beta 17whitelist ~/.cache/google-chrome-beta
20mkdir ~/.pki 18mkdir ~/.pki
diff --git a/etc/google-chrome-unstable.profile b/etc/google-chrome-unstable.profile
index f253e5a90..f6680ac2d 100644
--- a/etc/google-chrome-unstable.profile
+++ b/etc/google-chrome-unstable.profile
@@ -11,10 +11,8 @@ include /etc/firejail/disable-programs.inc
11netfilter 11netfilter
12 12
13whitelist ${DOWNLOADS} 13whitelist ${DOWNLOADS}
14mkdir ~/.config
15mkdir ~/.config/google-chrome-unstable 14mkdir ~/.config/google-chrome-unstable
16whitelist ~/.config/google-chrome-unstable 15whitelist ~/.config/google-chrome-unstable
17mkdir ~/.cache
18mkdir ~/.cache/google-chrome-unstable 16mkdir ~/.cache/google-chrome-unstable
19whitelist ~/.cache/google-chrome-unstable 17whitelist ~/.cache/google-chrome-unstable
20mkdir ~/.pki 18mkdir ~/.pki
diff --git a/etc/google-chrome.profile b/etc/google-chrome.profile
index 5e168aae5..a9fcebe73 100644
--- a/etc/google-chrome.profile
+++ b/etc/google-chrome.profile
@@ -11,10 +11,8 @@ include /etc/firejail/disable-programs.inc
11netfilter 11netfilter
12 12
13whitelist ${DOWNLOADS} 13whitelist ${DOWNLOADS}
14mkdir ~/.config
15mkdir ~/.config/google-chrome 14mkdir ~/.config/google-chrome
16whitelist ~/.config/google-chrome 15whitelist ~/.config/google-chrome
17mkdir ~/.cache
18mkdir ~/.cache/google-chrome 16mkdir ~/.cache/google-chrome
19whitelist ~/.cache/google-chrome 17whitelist ~/.cache/google-chrome
20mkdir ~/.pki 18mkdir ~/.pki
diff --git a/etc/google-play-music-desktop-player.profile b/etc/google-play-music-desktop-player.profile
new file mode 100644
index 000000000..b4cf8d9ac
--- /dev/null
+++ b/etc/google-play-music-desktop-player.profile
@@ -0,0 +1,18 @@
1# Google Play Music desktop player profile
2noblacklist ~/.config/Google Play Music Desktop Player
3
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-devel.inc
7include /etc/firejail/disable-passwdmgr.inc
8
9caps.drop all
10nonewprivs
11noroot
12netfilter
13protocol unix,inet,inet6,netlink
14seccomp
15
16#whitelist ~/.pulse
17#whitelist ~/.config/pulse
18whitelist ~/.config/Google Play Music Desktop Player
diff --git a/etc/gpredict.profile b/etc/gpredict.profile
new file mode 100644
index 000000000..801304c18
--- /dev/null
+++ b/etc/gpredict.profile
@@ -0,0 +1,25 @@
1# Firejail profile for gpredict.
2noblacklist ~/.config/Gpredict
3include /etc/firejail/disable-common.inc
4include /etc/firejail/disable-devel.inc
5include /etc/firejail/disable-passwdmgr.inc
6include /etc/firejail/disable-programs.inc
7
8# Whitelist
9whitelist ~/.config/Gpredict
10
11caps.drop all
12netfilter
13nogroups
14nonewprivs
15noroot
16nosound
17protocol unix,inet,inet6
18seccomp
19shell none
20tracelog
21
22private-bin gpredict
23private-etc fonts,resolv.conf
24private-dev
25private-tmp
diff --git a/etc/gtar.profile b/etc/gtar.profile
new file mode 100644
index 000000000..2f675cd9d
--- /dev/null
+++ b/etc/gtar.profile
@@ -0,0 +1,3 @@
1# gtar profile
2quiet
3include /etc/firejail/tar.profile
diff --git a/etc/gthumb.profile b/etc/gthumb.profile
new file mode 100644
index 000000000..055d78935
--- /dev/null
+++ b/etc/gthumb.profile
@@ -0,0 +1,21 @@
1# gthumb profile
2noblacklist ${HOME}/.config/gthumb
3
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-devel.inc
7include /etc/firejail/disable-passwdmgr.inc
8
9caps.drop all
10nogroups
11nonewprivs
12noroot
13nosound
14protocol unix
15seccomp
16shell none
17tracelog
18
19private-bin gthumb
20private-dev
21private-tmp \ No newline at end of file
diff --git a/etc/gwenview.profile b/etc/gwenview.profile
new file mode 100644
index 000000000..c866c9e63
--- /dev/null
+++ b/etc/gwenview.profile
@@ -0,0 +1,22 @@
1# KDE gwenview profile
2noblacklist ~/.kde/share/apps/gwenview
3noblacklist ~/.kde/share/config/gwenviewrc
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-devel.inc
7include /etc/firejail/disable-passwdmgr.inc
8
9caps.drop all
10nogroups
11nonewprivs
12noroot
13protocol unix
14seccomp
15nosound
16
17private-dev
18
19#Experimental:
20#shell none
21#private-bin gwenview
22#private-etc X11
diff --git a/etc/gzip.profile b/etc/gzip.profile
new file mode 100644
index 000000000..d51b9a951
--- /dev/null
+++ b/etc/gzip.profile
@@ -0,0 +1,14 @@
1# gzip profile
2ignore noroot
3include /etc/firejail/default.profile
4
5blacklist /tmp/.X11-unix
6
7net none
8no3d
9nosound
10quiet
11shell none
12tracelog
13
14private-dev
diff --git a/etc/hedgewars.profile b/etc/hedgewars.profile
index 5ab7cfe72..7910b7eb0 100644
--- a/etc/hedgewars.profile
+++ b/etc/hedgewars.profile
@@ -7,11 +7,16 @@ include /etc/firejail/disable-devel.inc
7include /etc/firejail/disable-passwdmgr.inc 7include /etc/firejail/disable-passwdmgr.inc
8 8
9caps.drop all 9caps.drop all
10netfilter
11nogroups
12nonewprivs
10noroot 13noroot
11private-dev
12seccomp 14seccomp
13tracelog 15tracelog
14 16
17private-dev
18private-tmp
19
15mkdir ~/.hedgewars 20mkdir ~/.hedgewars
16whitelist ~/.hedgewars 21whitelist ~/.hedgewars
17include /etc/firejail/whitelist-common.inc 22include /etc/firejail/whitelist-common.inc
diff --git a/etc/hexchat.profile b/etc/hexchat.profile
index 8f6fd6217..5cefe45b5 100644
--- a/etc/hexchat.profile
+++ b/etc/hexchat.profile
@@ -1,10 +1,28 @@
1# HexChat instant messaging profile 1# HexChat instant messaging profile
2# Currently in testing (may not work for all users)
2noblacklist ${HOME}/.config/hexchat 3noblacklist ${HOME}/.config/hexchat
4#noblacklist /usr/lib/python2*
5#noblacklist /usr/lib/python3*
3include /etc/firejail/disable-common.inc 6include /etc/firejail/disable-common.inc
4include /etc/firejail/disable-programs.inc 7include /etc/firejail/disable-programs.inc
5include /etc/firejail/disable-devel.inc 8include /etc/firejail/disable-devel.inc
6 9
7caps.drop all 10caps.drop all
8seccomp 11netfilter
9protocol unix,inet,inet6 12nogroups
13nonewprivs
10noroot 14noroot
15nosound
16protocol unix,inet,inet6
17seccomp
18shell none
19tracelog
20
21mkdir ~/.config/hexchat
22whitelist ~/.config/hexchat
23include /etc/firejail/whitelist-common.inc
24
25private-bin hexchat
26#debug note: private-bin requires perl, python, etc on some systems
27private-dev
28private-tmp
diff --git a/etc/icecat.profile b/etc/icecat.profile
index 25d426ad2..2f8e2df7f 100644
--- a/etc/icecat.profile
+++ b/etc/icecat.profile
@@ -1,2 +1,51 @@
1# Firejail profile for GNU Icecat 1# Firejail profile for GNU Icecat
2include /etc/firejail/firefox.profile 2
3noblacklist ~/.mozilla
4noblacklist ~/.cache/mozilla
5include /etc/firejail/disable-common.inc
6include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-devel.inc
8
9caps.drop all
10netfilter
11nonewprivs
12noroot
13protocol unix,inet,inet6,netlink
14seccomp
15tracelog
16
17whitelist ${DOWNLOADS}
18mkdir ~/.mozilla
19whitelist ~/.mozilla
20mkdir ~/.cache/mozilla/icecat
21whitelist ~/.cache/mozilla/icecat
22whitelist ~/dwhelper
23whitelist ~/.zotero
24whitelist ~/.vimperatorrc
25whitelist ~/.vimperator
26whitelist ~/.pentadactylrc
27whitelist ~/.pentadactyl
28whitelist ~/.keysnail.js
29whitelist ~/.config/gnome-mplayer
30whitelist ~/.cache/gnome-mplayer/plugin
31whitelist ~/.pki
32
33# lastpass, keepassx
34whitelist ~/.keepassx
35whitelist ~/.config/keepassx
36whitelist ~/keepassx.kdbx
37whitelist ~/.lastpass
38whitelist ~/.config/lastpass
39
40
41#silverlight
42whitelist ~/.wine-pipelight
43whitelist ~/.wine-pipelight64
44whitelist ~/.config/pipelight-widevine
45whitelist ~/.config/pipelight-silverlight5.1
46
47include /etc/firejail/whitelist-common.inc
48
49# experimental features
50#private-etc passwd,group,hostname,hosts,localtime,nsswitch.conf,resolv.conf,gtk-2.0,pango,fonts,iceweasel,firefox,adobe,mime.types,mailcap,asound.conf,pulse
51
diff --git a/etc/icedove.profile b/etc/icedove.profile
index e9a63c8dd..310684bdb 100644
--- a/etc/icedove.profile
+++ b/etc/icedove.profile
@@ -11,9 +11,11 @@ mkdir ~/.icedove
11whitelist ~/.icedove 11whitelist ~/.icedove
12 12
13noblacklist ~/.cache/icedove 13noblacklist ~/.cache/icedove
14mkdir ~/.cache
15mkdir ~/.cache/icedove 14mkdir ~/.cache/icedove
16whitelist ~/.cache/icedove 15whitelist ~/.cache/icedove
17 16
17# allow browsers
18ignore private-tmp
18include /etc/firejail/firefox.profile 19include /etc/firejail/firefox.profile
20#include /etc/firejail/chromium.profile - chromium runs as suid!
19 21
diff --git a/etc/inkscape.profile b/etc/inkscape.profile
new file mode 100644
index 000000000..a0e86b6c9
--- /dev/null
+++ b/etc/inkscape.profile
@@ -0,0 +1,20 @@
1# inkscape
2noblacklist ${HOME}/.inkscape
3include /etc/firejail/disable-common.inc
4include /etc/firejail/disable-programs.inc
5include /etc/firejail/disable-passwdmgr.inc
6
7caps.drop all
8netfilter
9nogroups
10nonewprivs
11noroot
12nosound
13protocol unix
14seccomp
15
16noexec ${HOME}
17noexec /tmp
18
19private-dev
20private-tmp
diff --git a/etc/inox.profile b/etc/inox.profile
new file mode 100644
index 000000000..49d2f2835
--- /dev/null
+++ b/etc/inox.profile
@@ -0,0 +1,24 @@
1# Inox browser profile
2noblacklist ~/.config/inox
3noblacklist ~/.cache/inox
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc
6
7netfilter
8
9whitelist ${DOWNLOADS}
10mkdir ~/.config/inox
11whitelist ~/.config/inox
12mkdir ~/.cache/inox
13whitelist ~/.cache/inox
14mkdir ~/.pki
15whitelist ~/.pki
16
17# lastpass, keepassx
18whitelist ~/.keepassx
19whitelist ~/.config/keepassx
20whitelist ~/keepassx.kdbx
21whitelist ~/.lastpass
22whitelist ~/.config/lastpass
23
24include /etc/firejail/whitelist-common.inc
diff --git a/etc/jitsi.profile b/etc/jitsi.profile
new file mode 100644
index 000000000..046499abe
--- /dev/null
+++ b/etc/jitsi.profile
@@ -0,0 +1,17 @@
1# Firejail profile for jitsi
2noblacklist ~/.jitsi
3include /etc/firejail/disable-common.inc
4include /etc/firejail/disable-devel.inc
5include /etc/firejail/disable-passwdmgr.inc
6include /etc/firejail/disable-programs.inc
7
8caps.drop all
9nogroups
10nonewprivs
11noroot
12protocol unix,inet,inet6
13seccomp
14shell none
15tracelog
16
17private-tmp
diff --git a/etc/keepass.profile b/etc/keepass.profile
new file mode 100644
index 000000000..23f9a7b40
--- /dev/null
+++ b/etc/keepass.profile
@@ -0,0 +1,22 @@
1# keepass password manager profile
2
3noblacklist ${HOME}/.config/keepass
4noblacklist ${HOME}/.keepass
5
6include /etc/firejail/disable-common.inc
7include /etc/firejail/disable-programs.inc
8include /etc/firejail/disable-devel.inc
9include /etc/firejail/disable-passwdmgr.inc
10
11caps.drop all
12nogroups
13nonewprivs
14noroot
15nosound
16protocol unix,inet,inet6
17seccomp
18netfilter
19shell none
20
21private-tmp
22private-dev
diff --git a/etc/keepassx.profile b/etc/keepassx.profile
new file mode 100644
index 000000000..415160df3
--- /dev/null
+++ b/etc/keepassx.profile
@@ -0,0 +1,23 @@
1# keepassx password manager profile
2
3noblacklist ${HOME}/.config/keepassx
4noblacklist ${HOME}/.keepassx
5noblacklist ${HOME}/keepassx.kdbx
6
7include /etc/firejail/disable-common.inc
8include /etc/firejail/disable-programs.inc
9include /etc/firejail/disable-devel.inc
10include /etc/firejail/disable-passwdmgr.inc
11
12caps.drop all
13nogroups
14nonewprivs
15noroot
16nosound
17protocol unix
18seccomp
19netfilter
20shell none
21
22private-tmp
23private-dev
diff --git a/etc/kmail.profile b/etc/kmail.profile
index a7079661b..bc21ba604 100644
--- a/etc/kmail.profile
+++ b/etc/kmail.profile
@@ -7,8 +7,13 @@ include /etc/firejail/disable-devel.inc
7include /etc/firejail/disable-passwdmgr.inc 7include /etc/firejail/disable-passwdmgr.inc
8 8
9caps.drop all 9caps.drop all
10seccomp
11protocol unix,inet,inet6,netlink
12netfilter 10netfilter
11nogroups
12nonewprivs
13noroot 13noroot
14protocol unix,inet,inet6,netlink
15seccomp
14tracelog 16tracelog
17
18private-dev
19private-tmp
diff --git a/etc/konversation.profile b/etc/konversation.profile
new file mode 100644
index 000000000..e9546fd1b
--- /dev/null
+++ b/etc/konversation.profile
@@ -0,0 +1,15 @@
1# Firejail konversation profile
2
3include /etc/firejail/disable-common.inc
4include /etc/firejail/disable-programs.inc
5include /etc/firejail/disable-devel.inc
6include /etc/firejail/disable-passwdmgr.inc
7
8caps.drop all
9netfilter
10nogroups
11noroot
12seccomp
13protocol unix,inet,inet6
14
15private-tmp
diff --git a/etc/less.profile b/etc/less.profile
new file mode 100644
index 000000000..08758aead
--- /dev/null
+++ b/etc/less.profile
@@ -0,0 +1,11 @@
1# less profile
2quiet
3ignore noroot
4include /etc/firejail/default.profile
5
6net none
7nosound
8shell none
9tracelog
10
11private-dev
diff --git a/etc/libreoffice.profile b/etc/libreoffice.profile
new file mode 100644
index 000000000..d6aceb7a8
--- /dev/null
+++ b/etc/libreoffice.profile
@@ -0,0 +1,19 @@
1# Firejail profile for LibreOffice
2noblacklist ~/.config/libreoffice
3noblacklist /usr/local/sbin
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-devel.inc
7include /etc/firejail/disable-passwdmgr.inc
8
9caps.drop all
10netfilter
11nogroups
12nonewprivs
13noroot
14protocol unix,inet,inet6
15seccomp
16tracelog
17
18private-dev
19# whitelist /tmp/.X11-unix/
diff --git a/etc/localc.profile b/etc/localc.profile
new file mode 100644
index 000000000..fecd08822
--- /dev/null
+++ b/etc/localc.profile
@@ -0,0 +1,5 @@
1################################
2# LibreOffice profile
3################################
4include /etc/firejail/libreoffice.profile
5
diff --git a/etc/lodraw.profile b/etc/lodraw.profile
new file mode 100644
index 000000000..fecd08822
--- /dev/null
+++ b/etc/lodraw.profile
@@ -0,0 +1,5 @@
1################################
2# LibreOffice profile
3################################
4include /etc/firejail/libreoffice.profile
5
diff --git a/etc/loffice.profile b/etc/loffice.profile
new file mode 100644
index 000000000..fecd08822
--- /dev/null
+++ b/etc/loffice.profile
@@ -0,0 +1,5 @@
1################################
2# LibreOffice profile
3################################
4include /etc/firejail/libreoffice.profile
5
diff --git a/etc/lofromtemplate.profile b/etc/lofromtemplate.profile
new file mode 100644
index 000000000..fecd08822
--- /dev/null
+++ b/etc/lofromtemplate.profile
@@ -0,0 +1,5 @@
1################################
2# LibreOffice profile
3################################
4include /etc/firejail/libreoffice.profile
5
diff --git a/etc/loimpress.profile b/etc/loimpress.profile
new file mode 100644
index 000000000..fecd08822
--- /dev/null
+++ b/etc/loimpress.profile
@@ -0,0 +1,5 @@
1################################
2# LibreOffice profile
3################################
4include /etc/firejail/libreoffice.profile
5
diff --git a/etc/lomath.profile b/etc/lomath.profile
new file mode 100644
index 000000000..fecd08822
--- /dev/null
+++ b/etc/lomath.profile
@@ -0,0 +1,5 @@
1################################
2# LibreOffice profile
3################################
4include /etc/firejail/libreoffice.profile
5
diff --git a/etc/loweb.profile b/etc/loweb.profile
new file mode 100644
index 000000000..fecd08822
--- /dev/null
+++ b/etc/loweb.profile
@@ -0,0 +1,5 @@
1################################
2# LibreOffice profile
3################################
4include /etc/firejail/libreoffice.profile
5
diff --git a/etc/lowriter.profile b/etc/lowriter.profile
new file mode 100644
index 000000000..fecd08822
--- /dev/null
+++ b/etc/lowriter.profile
@@ -0,0 +1,5 @@
1################################
2# LibreOffice profile
3################################
4include /etc/firejail/libreoffice.profile
5
diff --git a/etc/luminance-hdr.profile b/etc/luminance-hdr.profile
new file mode 100644
index 000000000..76e864e0c
--- /dev/null
+++ b/etc/luminance-hdr.profile
@@ -0,0 +1,23 @@
1# luminance-hdr
2noblacklist ${HOME}/.config/Luminance
3include /etc/firejail/disable-common.inc
4include /etc/firejail/disable-programs.inc
5include /etc/firejail/disable-passwdmgr.inc
6
7caps.drop all
8ipc-namespace
9netfilter
10nogroups
11nonewprivs
12noroot
13nosound
14protocol unix
15seccomp
16shell none
17tracelog
18
19noexec ${HOME}
20noexec /tmp
21
22private-tmp
23private-dev
diff --git a/etc/lxterminal.profile b/etc/lxterminal.profile
index b6acf2587..d1d0b8a0d 100644
--- a/etc/lxterminal.profile
+++ b/etc/lxterminal.profile
@@ -5,7 +5,7 @@ include /etc/firejail/disable-programs.inc
5include /etc/firejail/disable-passwdmgr.inc 5include /etc/firejail/disable-passwdmgr.inc
6 6
7caps.drop all 7caps.drop all
8seccomp
9protocol unix,inet,inet6
10netfilter 8netfilter
9protocol unix,inet,inet6
10seccomp
11#noroot - somehow this breaks on Debian Jessie! 11#noroot - somehow this breaks on Debian Jessie!
diff --git a/etc/mcabber.profile b/etc/mcabber.profile
new file mode 100644
index 000000000..48b46dba0
--- /dev/null
+++ b/etc/mcabber.profile
@@ -0,0 +1,21 @@
1# mcabber profile
2noblacklist ${HOME}/.mcabber
3noblacklist ${HOME}/.mcabberrc
4
5include /etc/firejail/disable-common.inc
6include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-devel.inc
8include /etc/firejail/disable-passwdmgr.inc
9
10caps.drop all
11netfilter
12nonewprivs
13noroot
14protocol inet,inet6
15seccomp
16
17private-bin mcabber
18private-etc null
19private-dev
20shell none
21nosound
diff --git a/etc/midori.profile b/etc/midori.profile
index 7fc27e07c..046c45d94 100644
--- a/etc/midori.profile
+++ b/etc/midori.profile
@@ -5,7 +5,9 @@ include /etc/firejail/disable-programs.inc
5include /etc/firejail/disable-devel.inc 5include /etc/firejail/disable-devel.inc
6 6
7caps.drop all 7caps.drop all
8seccomp
9protocol unix,inet,inet6
10netfilter 8netfilter
9nonewprivs
10# noroot - noroot break midori on Ubuntu 14.04
11protocol unix,inet,inet6
12seccomp
11 13
diff --git a/etc/mpv.profile b/etc/mpv.profile
new file mode 100644
index 000000000..80f8de54a
--- /dev/null
+++ b/etc/mpv.profile
@@ -0,0 +1,18 @@
1# mpv media player profile
2noblacklist ${HOME}/.config/mpv
3
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-devel.inc
7include /etc/firejail/disable-passwdmgr.inc
8
9caps.drop all
10netfilter
11nonewprivs
12noroot
13protocol unix,inet,inet6
14seccomp
15
16# to test
17shell none
18private-bin mpv,youtube-dl,python2.7
diff --git a/etc/mumble.profile b/etc/mumble.profile
new file mode 100644
index 000000000..ddd70822d
--- /dev/null
+++ b/etc/mumble.profile
@@ -0,0 +1,26 @@
1# mumble profile
2noblacklist ${HOME}/.config/Mumble
3noblacklist ${HOME}/.local/share/data/Mumble
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-devel.inc
7include /etc/firejail/disable-passwdmgr.inc
8
9mkdir ${HOME}/.config/Mumble
10mkdir ${HOME}/.local/share/data/Mumble
11whitelist ${HOME}/.config/Mumble
12whitelist ${HOME}/.local/share/data/Mumble
13include /etc/firejail/whitelist-common.inc
14
15caps.drop all
16netfilter
17nonewprivs
18nogroups
19noroot
20protocol unix,inet,inet6
21seccomp
22shell none
23tracelog
24
25private-bin mumble
26private-tmp
diff --git a/etc/mupdf.profile b/etc/mupdf.profile
new file mode 100644
index 000000000..e022866e8
--- /dev/null
+++ b/etc/mupdf.profile
@@ -0,0 +1,28 @@
1# mupdf reader profile
2include /etc/firejail/disable-common.inc
3include /etc/firejail/disable-programs.inc
4include /etc/firejail/disable-devel.inc
5include /etc/firejail/disable-passwdmgr.inc
6
7caps.drop all
8nogroups
9nonewprivs
10noroot
11nosound
12protocol unix
13seccomp
14netfilter
15net none
16shell none
17tracelog
18
19#seccomp.keep access,arch_prctl,brk,clone,close,connect,execve,exit_group,fchmod,fchown,fcntl,fstat,futex,getcwd,getpeername,getrlimit,getsockname,getsockopt,lseek,lstat,mlock,mmap,mprotect,munmap,nanosleep,open,poll,prctl,read,recvfrom,recvmsg,restart_syscall,rt_sigaction,rt_sigprocmask,select,sendmsg,set_robust_list,set_tid_address,setresgid,setresuid,shmat,shmctl,shmget,shutdown,socket,stat,sysinfo,uname,unshare,wait4,write,writev
20
21private-bin mupdf
22private-tmp
23private-dev
24private-etc fonts
25
26# mupdf will never write anything
27read-only ${HOME}
28
diff --git a/etc/mupen64plus.profile b/etc/mupen64plus.profile
index 7b38b411a..acb13e6b9 100644
--- a/etc/mupen64plus.profile
+++ b/etc/mupen64plus.profile
@@ -8,15 +8,13 @@ include /etc/firejail/disable-programs.inc
8include /etc/firejail/disable-devel.inc 8include /etc/firejail/disable-devel.inc
9include /etc/firejail/disable-passwdmgr.inc 9include /etc/firejail/disable-passwdmgr.inc
10 10
11mkdir ${HOME}/.local
12mkdir ${HOME}/.local/share
13mkdir ${HOME}/.local/share/mupen64plus 11mkdir ${HOME}/.local/share/mupen64plus
14whitelist ${HOME}/.local/share/mupen64plus/ 12whitelist ${HOME}/.local/share/mupen64plus/
15mkdir ${HOME}/.config
16mkdir ${HOME}/.config/mupen64plus 13mkdir ${HOME}/.config/mupen64plus
17whitelist ${HOME}/.config/mupen64plus/ 14whitelist ${HOME}/.config/mupen64plus/
18 15
19noroot
20caps.drop all 16caps.drop all
21seccomp
22net none 17net none
18nonewprivs
19noroot
20seccomp
diff --git a/etc/mutt.profile b/etc/mutt.profile
new file mode 100644
index 000000000..54cf828b1
--- /dev/null
+++ b/etc/mutt.profile
@@ -0,0 +1,41 @@
1# mutt email client profile
2
3noblacklist ~/.muttrc
4noblacklist ~/.mutt
5noblacklist ~/.mutt/muttrc
6noblacklist ~/.mailcap
7noblacklist ~/.gnupg
8noblacklist ~/.mail
9noblacklist ~/.Mail
10noblacklist ~/mail
11noblacklist ~/Mail
12noblacklist ~/sent
13noblacklist ~/postponed
14noblacklist ~/.cache/mutt
15noblacklist ~/.w3m
16noblacklist ~/.elinks
17noblacklist ~/.vim
18noblacklist ~/.vimrc
19noblacklist ~/.viminfo
20noblacklist ~/.emacs
21noblacklist ~/.emacs.d
22noblacklist ~/.signature
23noblacklist ~/.bogofilter
24noblacklist ~/.msmtprc
25
26include /etc/firejail/disable-common.inc
27include /etc/firejail/disable-programs.inc
28include /etc/firejail/disable-passwdmgr.inc
29include /etc/firejail/disable-devel.inc
30
31caps.drop all
32netfilter
33nogroups
34nonewprivs
35noroot
36nosound
37protocol unix,inet,inet6
38seccomp
39shell none
40
41private-dev
diff --git a/etc/netsurf.profile b/etc/netsurf.profile
new file mode 100644
index 000000000..1ed2163c2
--- /dev/null
+++ b/etc/netsurf.profile
@@ -0,0 +1,30 @@
1# Firejail profile for Mozilla Firefox (Iceweasel in Debian)
2
3noblacklist ~/.config/netsurf
4noblacklist ~/.cache/netsurf
5include /etc/firejail/disable-common.inc
6include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-devel.inc
8
9caps.drop all
10netfilter
11nonewprivs
12noroot
13protocol unix,inet,inet6,netlink
14seccomp
15tracelog
16
17whitelist ${DOWNLOADS}
18mkdir ~/.config/netsurf
19whitelist ~/.config/netsurf
20mkdir ~/.cache/netsurf
21whitelist ~/.cache/netsurf
22
23# lastpass, keepassx
24whitelist ~/.keepassx
25whitelist ~/.config/keepassx
26whitelist ~/keepassx.kdbx
27whitelist ~/.lastpass
28whitelist ~/.config/lastpass
29
30include /etc/firejail/whitelist-common.inc
diff --git a/etc/nolocal.net b/etc/nolocal.net
index 9c0c6e125..9fa785450 100644
--- a/etc/nolocal.net
+++ b/etc/nolocal.net
@@ -4,7 +4,8 @@
4:OUTPUT ACCEPT [0:0] 4:OUTPUT ACCEPT [0:0]
5 5
6################################################################### 6###################################################################
7# Client filter rejecting local network traffic, with the exception of DNS traffic 7# Client filter rejecting local network traffic, with the exception of
8# DNS traffic
8# 9#
9# Usage: 10# Usage:
10# firejail --net=eth0 --netfilter=/etc/firejail/nolocal.net firefox 11# firejail --net=eth0 --netfilter=/etc/firejail/nolocal.net firefox
diff --git a/etc/okular.profile b/etc/okular.profile
new file mode 100644
index 000000000..b43a5fbea
--- /dev/null
+++ b/etc/okular.profile
@@ -0,0 +1,25 @@
1# KDE okular profile
2noblacklist ~/.kde/share/apps/okular
3noblacklist ~/.kde/share/config/okularrc
4noblacklist ~/.kde/share/config/okularpartrc
5read-only ~/.kde/share/config/kdeglobals
6include /etc/firejail/disable-common.inc
7include /etc/firejail/disable-programs.inc
8include /etc/firejail/disable-devel.inc
9include /etc/firejail/disable-passwdmgr.inc
10
11caps.drop all
12nogroups
13nonewprivs
14noroot
15protocol unix
16seccomp
17nosound
18
19private-dev
20
21#Experimental:
22#net none
23#shell none
24#private-bin okular,kbuildsycoca4,kbuildsycoca5
25#private-etc X11
diff --git a/etc/openbox.profile b/etc/openbox.profile
index 6e2e5d6fd..f812768a1 100644
--- a/etc/openbox.profile
+++ b/etc/openbox.profile
@@ -5,8 +5,7 @@
5include /etc/firejail/disable-common.inc 5include /etc/firejail/disable-common.inc
6 6
7caps.drop all 7caps.drop all
8seccomp
9protocol unix,inet,inet6
10netfilter 8netfilter
11noroot 9noroot
12 10protocol unix,inet,inet6
11seccomp
diff --git a/etc/openshot.profile b/etc/openshot.profile
new file mode 100644
index 000000000..f12bd7d11
--- /dev/null
+++ b/etc/openshot.profile
@@ -0,0 +1,13 @@
1# OpenShot profile
2noblacklist ${HOME}/.openshot
3noblacklist ${HOME}/.openshot_qt
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-passwdmgr.inc
7
8caps.drop all
9netfilter
10nonewprivs
11noroot
12protocol unix,inet,inet6,netlink
13seccomp
diff --git a/etc/opera-beta.profile b/etc/opera-beta.profile
index 3d6edb286..12c91c744 100644
--- a/etc/opera-beta.profile
+++ b/etc/opera-beta.profile
@@ -8,10 +8,8 @@ include /etc/firejail/disable-devel.inc
8netfilter 8netfilter
9 9
10whitelist ${DOWNLOADS} 10whitelist ${DOWNLOADS}
11mkdir ~/.config
12mkdir ~/.config/opera-beta 11mkdir ~/.config/opera-beta
13whitelist ~/.config/opera-beta 12whitelist ~/.config/opera-beta
14mkdir ~/.cache
15mkdir ~/.cache/opera-beta 13mkdir ~/.cache/opera-beta
16whitelist ~/.cache/opera-beta 14whitelist ~/.cache/opera-beta
17mkdir ~/.pki 15mkdir ~/.pki
diff --git a/etc/opera.profile b/etc/opera.profile
index ff00eb349..e0c89a195 100644
--- a/etc/opera.profile
+++ b/etc/opera.profile
@@ -9,10 +9,8 @@ include /etc/firejail/disable-devel.inc
9netfilter 9netfilter
10 10
11whitelist ${DOWNLOADS} 11whitelist ${DOWNLOADS}
12mkdir ~/.config
13mkdir ~/.config/opera 12mkdir ~/.config/opera
14whitelist ~/.config/opera 13whitelist ~/.config/opera
15mkdir ~/.cache
16mkdir ~/.cache/opera 14mkdir ~/.cache/opera
17whitelist ~/.cache/opera 15whitelist ~/.cache/opera
18mkdir ~/.opera 16mkdir ~/.opera
diff --git a/etc/palemoon.profile b/etc/palemoon.profile
index fc4ea453b..71deec6bc 100644
--- a/etc/palemoon.profile
+++ b/etc/palemoon.profile
@@ -1,31 +1,30 @@
1# Firejail profile for Pale Moon 1# Firejail profile for Pale Moon
2
3# Noblacklists
4noblacklist ~/.moonchild productions/pale moon 2noblacklist ~/.moonchild productions/pale moon
5noblacklist ~/.cache/moonchild productions/pale moon 3noblacklist ~/.cache/moonchild productions/pale moon
6
7# Included profiles
8include /etc/firejail/disable-common.inc 4include /etc/firejail/disable-common.inc
9include /etc/firejail/disable-programs.inc 5include /etc/firejail/disable-programs.inc
10include /etc/firejail/disable-devel.inc 6include /etc/firejail/disable-devel.inc
11include /etc/firejail/whitelist-common.inc 7include /etc/firejail/whitelist-common.inc
12 8
13# Options
14caps.drop all
15seccomp
16protocol unix,inet,inet6,netlink
17netfilter
18tracelog
19noroot
20
21whitelist ${DOWNLOADS} 9whitelist ${DOWNLOADS}
22mkdir ~/.moonchild productions 10mkdir ~/.moonchild productions
23whitelist ~/.moonchild productions 11whitelist ~/.moonchild productions
24mkdir ~/.cache
25mkdir ~/.cache/moonchild productions
26mkdir ~/.cache/moonchild productions/pale moon 12mkdir ~/.cache/moonchild productions/pale moon
27whitelist ~/.cache/moonchild productions/pale moon 13whitelist ~/.cache/moonchild productions/pale moon
28 14
15caps.drop all
16netfilter
17nogroups
18nonewprivs
19noroot
20protocol unix,inet,inet6,netlink
21seccomp
22shell none
23tracelog
24
25private-bin palemoon
26private-tmp
27
29# These are uncommented in the Firefox profile. If you run into trouble you may 28# These are uncommented in the Firefox profile. If you run into trouble you may
30# want to uncomment (some of) them. 29# want to uncomment (some of) them.
31#whitelist ~/dwhelper 30#whitelist ~/dwhelper
@@ -40,9 +39,9 @@ whitelist ~/.cache/moonchild productions/pale moon
40#whitelist ~/.pki 39#whitelist ~/.pki
41 40
42# For silverlight 41# For silverlight
43#whitelist ~/.wine-pipelight 42#whitelist ~/.wine-pipelight
44#whitelist ~/.wine-pipelight64 43#whitelist ~/.wine-pipelight64
45#whitelist ~/.config/pipelight-widevine 44#whitelist ~/.config/pipelight-widevine
46#whitelist ~/.config/pipelight-silverlight5.1 45#whitelist ~/.config/pipelight-silverlight5.1
47 46
48 47
@@ -55,3 +54,4 @@ whitelist ~/.config/lastpass
55 54
56# experimental features 55# experimental features
57#private-etc passwd,group,hostname,hosts,localtime,nsswitch.conf,resolv.conf,gtk-2.0,pango,fonts,iceweasel,firefox,adobe,mime.types,mailcap,asound.conf,pulse 56#private-etc passwd,group,hostname,hosts,localtime,nsswitch.conf,resolv.conf,gtk-2.0,pango,fonts,iceweasel,firefox,adobe,mime.types,mailcap,asound.conf,pulse
57#private-dev (disabled for now as it will interfere with webcam use in palemoon)
diff --git a/etc/parole.profile b/etc/parole.profile
index 0c9a72143..1440a9ef7 100644
--- a/etc/parole.profile
+++ b/etc/parole.profile
@@ -8,8 +8,9 @@ private-etc passwd,group,fonts
8private-bin parole,dbus-launch 8private-bin parole,dbus-launch
9 9
10caps.drop all 10caps.drop all
11seccomp
12protocol unix,inet,inet6
13netfilter 11netfilter
12nonewprivs
14noroot 13noroot
14protocol unix,inet,inet6
15seccomp
15shell none 16shell none
diff --git a/etc/pidgin.profile b/etc/pidgin.profile
index fd497f082..850706145 100644
--- a/etc/pidgin.profile
+++ b/etc/pidgin.profile
@@ -2,10 +2,20 @@
2noblacklist ${HOME}/.purple 2noblacklist ${HOME}/.purple
3 3
4include /etc/firejail/disable-common.inc 4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-devel.inc 5include /etc/firejail/disable-devel.inc
6include /etc/firejail/disable-passwdmgr.inc
7include /etc/firejail/disable-programs.inc
7 8
8caps.drop all 9caps.drop all
9seccomp 10netfilter
10protocol unix,inet,inet6 11nogroups
12nonewprivs
11noroot 13noroot
14protocol unix,inet,inet6
15seccomp
16shell none
17tracelog
18
19private-bin pidgin
20private-dev
21private-tmp
diff --git a/etc/pix.profile b/etc/pix.profile
new file mode 100644
index 000000000..dc8192b01
--- /dev/null
+++ b/etc/pix.profile
@@ -0,0 +1,22 @@
1# Firejail profile for pix
2noblacklist ${HOME}/.config/pix
3noblacklist ${HOME}/.local/share/pix
4
5include /etc/firejail/disable-common.inc
6include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-devel.inc
8include /etc/firejail/disable-passwdmgr.inc
9
10caps.drop all
11nogroups
12nonewprivs
13noroot
14nosound
15protocol unix
16seccomp
17shell none
18tracelog
19
20private-bin pix
21private-dev
22private-tmp \ No newline at end of file
diff --git a/etc/polari.profile b/etc/polari.profile
index 0bc46f3f7..ac9530c40 100644
--- a/etc/polari.profile
+++ b/etc/polari.profile
@@ -3,18 +3,14 @@ include /etc/firejail/disable-common.inc
3include /etc/firejail/disable-programs.inc 3include /etc/firejail/disable-programs.inc
4include /etc/firejail/disable-devel.inc 4include /etc/firejail/disable-devel.inc
5 5
6mkdir ${HOME}/.local
7mkdir ${HOME}/.local/share/
8mkdir ${HOME}/.local/share/Empathy 6mkdir ${HOME}/.local/share/Empathy
9whitelist ${HOME}/.local/share/Empathy 7whitelist ${HOME}/.local/share/Empathy
10mkdir ${HOME}/.local/share/telepathy 8mkdir ${HOME}/.local/share/telepathy
11whitelist ${HOME}/.local/share/telepathy 9whitelist ${HOME}/.local/share/telepathy
12mkdir ${HOME}/.local/share/TpLogger 10mkdir ${HOME}/.local/share/TpLogger
13whitelist ${HOME}/.local/share/TpLogger 11whitelist ${HOME}/.local/share/TpLogger
14mkdir ${HOME}/.config
15mkdir ${HOME}/.config/telepathy-account-widgets 12mkdir ${HOME}/.config/telepathy-account-widgets
16whitelist ${HOME}/.config/telepathy-account-widgets 13whitelist ${HOME}/.config/telepathy-account-widgets
17mkdir ${HOME}/.cache
18mkdir ${HOME}/.cache/telepathy 14mkdir ${HOME}/.cache/telepathy
19whitelist ${HOME}/.cache/telepathy 15whitelist ${HOME}/.cache/telepathy
20mkdir ${HOME}/.purple 16mkdir ${HOME}/.purple
@@ -22,8 +18,8 @@ whitelist ${HOME}/.purple
22include /etc/firejail/whitelist-common.inc 18include /etc/firejail/whitelist-common.inc
23 19
24caps.drop all 20caps.drop all
25seccomp
26protocol unix,inet,inet6
27noroot
28netfilter 21netfilter
29 22nonewprivs
23noroot
24protocol unix,inet,inet6
25seccomp
diff --git a/etc/psi-plus.profile b/etc/psi-plus.profile
new file mode 100644
index 000000000..a9323448b
--- /dev/null
+++ b/etc/psi-plus.profile
@@ -0,0 +1,23 @@
1# Firejail profile for Psi+
2
3noblacklist ${HOME}/.config/psi+
4noblacklist ${HOME}/.local/share/psi+
5include /etc/firejail/disable-common.inc
6include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-passwdmgr.inc
8
9whitelist ${DOWNLOADS}
10mkdir ~/.config/psi+
11whitelist ~/.config/psi+
12mkdir ~/.local/share/psi+
13whitelist ~/.local/share/psi+
14mkdir ~/.cache/psi+
15whitelist ~/.cache/psi+
16
17caps.drop all
18netfilter
19noroot
20protocol unix,inet,inet6
21seccomp
22
23include /etc/firejail/whitelist-common.inc
diff --git a/etc/qbittorrent.profile b/etc/qbittorrent.profile
index 8bdc745fb..89e0e4c78 100644
--- a/etc/qbittorrent.profile
+++ b/etc/qbittorrent.profile
@@ -5,8 +5,15 @@ include /etc/firejail/disable-devel.inc
5include /etc/firejail/disable-passwdmgr.inc 5include /etc/firejail/disable-passwdmgr.inc
6 6
7caps.drop all 7caps.drop all
8seccomp
9protocol unix,inet,inet6
10netfilter 8netfilter
9nonewprivs
11noroot 10noroot
12nosound 11nosound
12protocol unix,inet,inet6
13seccomp
14
15# there are some problems with "Open destination folder", see bug #536
16#shell none
17#private-bin qbittorrent
18private-dev
19private-tmp
diff --git a/etc/qpdfview.profile b/etc/qpdfview.profile
new file mode 100644
index 000000000..06c0db206
--- /dev/null
+++ b/etc/qpdfview.profile
@@ -0,0 +1,22 @@
1# qpdfview profile
2noblacklist ${HOME}/.config/qpdfview
3noblacklist ${HOME}/.local/share/qpdfview
4
5include /etc/firejail/disable-common.inc
6include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-devel.inc
8include /etc/firejail/disable-passwdmgr.inc
9
10caps.drop all
11nogroups
12nonewprivs
13noroot
14nosound
15protocol unix
16seccomp
17shell none
18tracelog
19
20private-bin qpdfview
21private-dev
22private-tmp
diff --git a/etc/qtox.profile b/etc/qtox.profile
index 80acc3873..81d8aa10e 100644
--- a/etc/qtox.profile
+++ b/etc/qtox.profile
@@ -3,13 +3,21 @@ noblacklist ${HOME}/.config/tox
3include /etc/firejail/disable-common.inc 3include /etc/firejail/disable-common.inc
4include /etc/firejail/disable-programs.inc 4include /etc/firejail/disable-programs.inc
5include /etc/firejail/disable-devel.inc 5include /etc/firejail/disable-devel.inc
6include /etc/firejail/disable-passwdmgr.inc
6 7
7mkdir ${HOME}/.config/tox 8mkdir ${HOME}/.config/tox
8whitelist ${HOME}/.config/tox 9whitelist ${HOME}/.config/tox
9whitelist ${DOWNLOADS} 10whitelist ${DOWNLOADS}
10include /etc/firejail/whitelist-common.inc
11 11
12caps.drop all 12caps.drop all
13seccomp 13netfilter
14protocol unix,inet,inet6 14nogroups
15nonewprivs
15noroot 16noroot
17protocol unix,inet,inet6
18seccomp
19shell none
20tracelog
21
22private-bin qtox
23private-tmp
diff --git a/etc/quassel.profile b/etc/quassel.profile
index 72004da7f..f92dfeb9f 100644
--- a/etc/quassel.profile
+++ b/etc/quassel.profile
@@ -4,7 +4,8 @@ include /etc/firejail/disable-programs.inc
4include /etc/firejail/disable-devel.inc 4include /etc/firejail/disable-devel.inc
5 5
6caps.drop all 6caps.drop all
7seccomp 7nonewprivs
8protocol unix,inet,inet6
9noroot 8noroot
10netfilter 9netfilter
10protocol unix,inet,inet6
11seccomp
diff --git a/etc/quiterss.profile b/etc/quiterss.profile
index 411d37dbd..2b28fce73 100644
--- a/etc/quiterss.profile
+++ b/etc/quiterss.profile
@@ -4,26 +4,27 @@ include /etc/firejail/disable-passwdmgr.inc
4include /etc/firejail/disable-devel.inc 4include /etc/firejail/disable-devel.inc
5 5
6whitelist ${HOME}/quiterssfeeds.opml 6whitelist ${HOME}/quiterssfeeds.opml
7mkdir ~/.config
8mkdir ~/.config/QuiteRss 7mkdir ~/.config/QuiteRss
9whitelist ${HOME}/.config/QuiteRss/ 8whitelist ${HOME}/.config/QuiteRss/
10whitelist ${HOME}/.config/QuiteRssrc 9whitelist ${HOME}/.config/QuiteRssrc
11mkdir ~/.local
12mkdir ~/.local/share 10mkdir ~/.local/share
13whitelist ${HOME}/.local/share/ 11whitelist ${HOME}/.local/share/
14mkdir ~/.cache
15mkdir ~/.cache/QuiteRss 12mkdir ~/.cache/QuiteRss
16whitelist ${HOME}/.cache/QuiteRss 13whitelist ${HOME}/.cache/QuiteRss
17 14
18caps.drop all 15caps.drop all
19seccomp
20protocol unix,inet,inet6
21netfilter 16netfilter
22tracelog
23noroot
24nogroups 17nogroups
18nonewprivs
19noroot
20nosound
21protocol unix,inet,inet6
22seccomp
25shell none 23shell none
26private-dev 24tracelog
25
27private-bin quiterss 26private-bin quiterss
27private-dev
28#private-etc X11,ssl 28#private-etc X11,ssl
29
29include /etc/firejail/whitelist-common.inc 30include /etc/firejail/whitelist-common.inc
diff --git a/etc/qutebrowser.profile b/etc/qutebrowser.profile
index 934a374de..0efb7b629 100644
--- a/etc/qutebrowser.profile
+++ b/etc/qutebrowser.profile
@@ -7,16 +7,16 @@ include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-devel.inc 7include /etc/firejail/disable-devel.inc
8 8
9caps.drop all 9caps.drop all
10seccomp
11protocol unix,inet,inet6,netlink
12netfilter 10netfilter
13tracelog 11nonewprivs
14noroot 12noroot
13protocol unix,inet,inet6,netlink
14seccomp
15tracelog
15 16
16whitelist ${DOWNLOADS} 17whitelist ${DOWNLOADS}
17mkdir ~/.config/qutebrowser 18mkdir ~/.config/qutebrowser
18whitelist ~/.config/qutebrowser 19whitelist ~/.config/qutebrowser
19mkdir ~/.cache
20mkdir ~/.cache/qutebrowser 20mkdir ~/.cache/qutebrowser
21whitelist ~/.cache/qutebrowser 21whitelist ~/.cache/qutebrowser
22include /etc/firejail/whitelist-common.inc 22include /etc/firejail/whitelist-common.inc
diff --git a/etc/ranger.profile b/etc/ranger.profile
new file mode 100644
index 000000000..323e64dee
--- /dev/null
+++ b/etc/ranger.profile
@@ -0,0 +1,23 @@
1# ranger file manager profile
2noblacklist /usr/bin/perl
3#noblacklist /usr/bin/cpan*
4noblacklist /usr/share/perl*
5noblacklist /usr/lib/perl*
6
7include /etc/firejail/disable-common.inc
8include /etc/firejail/disable-programs.inc
9include /etc/firejail/disable-devel.inc
10include /etc/firejail/disable-passwdmgr.inc
11
12caps.drop all
13netfilter
14net none
15nogroups
16nonewprivs
17noroot
18protocol unix
19seccomp
20nosound
21
22private-tmp
23private-dev
diff --git a/etc/rhythmbox.profile b/etc/rhythmbox.profile
index 782cd3832..e5e192486 100644
--- a/etc/rhythmbox.profile
+++ b/etc/rhythmbox.profile
@@ -5,7 +5,15 @@ include /etc/firejail/disable-devel.inc
5include /etc/firejail/disable-passwdmgr.inc 5include /etc/firejail/disable-passwdmgr.inc
6 6
7caps.drop all 7caps.drop all
8seccomp
9protocol unix,inet,inet6
10noroot
11netfilter 8netfilter
9nogroups
10nonewprivs
11noroot
12protocol unix,inet,inet6
13seccomp
14shell none
15tracelog
16
17private-bin rhythmbox
18private-dev
19private-tmp
diff --git a/etc/rtorrent.profile b/etc/rtorrent.profile
index ae0430830..55bfcd77f 100644
--- a/etc/rtorrent.profile
+++ b/etc/rtorrent.profile
@@ -5,8 +5,14 @@ include /etc/firejail/disable-devel.inc
5include /etc/firejail/disable-passwdmgr.inc 5include /etc/firejail/disable-passwdmgr.inc
6 6
7caps.drop all 7caps.drop all
8seccomp
9protocol unix,inet,inet6
10netfilter 8netfilter
9nonewprivs
11noroot 10noroot
12nosound 11nosound
12protocol unix,inet,inet6
13seccomp
14
15shell none
16private-bin rtorrent
17private-dev
18private-tmp \ No newline at end of file
diff --git a/etc/seamonkey.profile b/etc/seamonkey.profile
index a10d5b0ec..b981d9516 100644
--- a/etc/seamonkey.profile
+++ b/etc/seamonkey.profile
@@ -6,18 +6,16 @@ include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-devel.inc 6include /etc/firejail/disable-devel.inc
7 7
8caps.drop all 8caps.drop all
9seccomp
10protocol unix,inet,inet6,netlink
11netfilter 9netfilter
12tracelog 10nonewprivs
13noroot 11noroot
12protocol unix,inet,inet6,netlink
13seccomp
14tracelog
14 15
15whitelist ${DOWNLOADS} 16whitelist ${DOWNLOADS}
16mkdir ~/.mozilla
17mkdir ~/.mozilla/seamonkey 17mkdir ~/.mozilla/seamonkey
18whitelist ~/.mozilla/seamonkey 18whitelist ~/.mozilla/seamonkey
19mkdir ~/.cache
20mkdir ~/.cache/mozilla
21mkdir ~/.cache/mozilla/seamonkey 19mkdir ~/.cache/mozilla/seamonkey
22whitelist ~/.cache/mozilla/seamonkey 20whitelist ~/.cache/mozilla/seamonkey
23whitelist ~/dwhelper 21whitelist ~/dwhelper
@@ -41,11 +39,10 @@ whitelist ~/.lastpass
41whitelist ~/.config/lastpass 39whitelist ~/.config/lastpass
42 40
43#silverlight 41#silverlight
44whitelist ~/.wine-pipelight 42whitelist ~/.wine-pipelight
45whitelist ~/.wine-pipelight64 43whitelist ~/.wine-pipelight64
46whitelist ~/.config/pipelight-widevine 44whitelist ~/.config/pipelight-widevine
47whitelist ~/.config/pipelight-silverlight5.1 45whitelist ~/.config/pipelight-silverlight5.1
48 46
49# experimental features 47# experimental features
50#private-etc passwd,group,hostname,hosts,localtime,nsswitch.conf,resolv.conf,gtk-2.0,pango,fonts,iceweasel,firefox,adobe,mime.types,mailcap,asound.conf,pulse 48#private-etc passwd,group,hostname,hosts,localtime,nsswitch.conf,resolv.conf,gtk-2.0,pango,fonts,iceweasel,firefox,adobe,mime.types,mailcap,asound.conf,pulse
51
diff --git a/etc/server.profile b/etc/server.profile
index 1b3cb7207..b8a34feb2 100644
--- a/etc/server.profile
+++ b/etc/server.profile
@@ -6,8 +6,12 @@ include /etc/firejail/disable-common.inc
6include /etc/firejail/disable-programs.inc 6include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-passwdmgr.inc 7include /etc/firejail/disable-passwdmgr.inc
8 8
9blacklist /tmp/.X11-unix
10
11no3d
12nosound
13seccomp
14
9private 15private
10private-dev 16private-dev
11private-tmp 17private-tmp
12seccomp
13
diff --git a/etc/skype.profile b/etc/skype.profile
index 26feac1a4..9cbcd5117 100644
--- a/etc/skype.profile
+++ b/etc/skype.profile
@@ -6,6 +6,7 @@ include /etc/firejail/disable-devel.inc
6 6
7caps.drop all 7caps.drop all
8netfilter 8netfilter
9nonewprivs
9noroot 10noroot
10seccomp
11protocol unix,inet,inet6 11protocol unix,inet,inet6
12seccomp
diff --git a/etc/skypeforlinux.profile b/etc/skypeforlinux.profile
new file mode 100644
index 000000000..3f0a274f9
--- /dev/null
+++ b/etc/skypeforlinux.profile
@@ -0,0 +1,11 @@
1# skypeforlinux profile
2noblacklist ${HOME}/.config/skypeforlinux
3include /etc/firejail/disable-common.inc
4include /etc/firejail/disable-programs.inc
5include /etc/firejail/disable-passwdmgr.inc
6
7caps.drop all
8netfilter
9noroot
10seccomp
11protocol unix,inet,inet6,netlink
diff --git a/etc/slack.profile b/etc/slack.profile
new file mode 100644
index 000000000..a85a28f03
--- /dev/null
+++ b/etc/slack.profile
@@ -0,0 +1,31 @@
1# Firejail profile for Slack
2noblacklist ${HOME}/.config/Slack
3noblacklist ${HOME}/Downloads
4
5include /etc/firejail/disable-common.inc
6include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-devel.inc
8include /etc/firejail/disable-passwdmgr.inc
9
10blacklist /var
11
12caps.drop all
13name slack
14netfilter
15nogroups
16nonewprivs
17noroot
18protocol unix,inet,inet6,netlink
19seccomp
20shell none
21
22private-bin slack
23private-dev
24private-etc fonts,resolv.conf,ld.so.conf,ld.so.cache,localtime
25private-tmp
26
27mkdir ${HOME}/.config
28mkdir ${HOME}/.config/Slack
29whitelist ${HOME}/.config/Slack
30whitelist ${HOME}/Downloads
31include /etc/firejail/whitelist-common.inc
diff --git a/etc/snap.profile b/etc/snap.profile
new file mode 100644
index 000000000..270fdf1a5
--- /dev/null
+++ b/etc/snap.profile
@@ -0,0 +1,14 @@
1################################
2# Generic Ubuntu snap application profile
3################################
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-passwdmgr.inc
7
8whitelist ~/snap
9whitelist ${DOWNLOADS}
10include /etc/firejail/whitelist-common.inc
11
12caps.keep chown,sys_admin
13
14
diff --git a/etc/soffice.profile b/etc/soffice.profile
new file mode 100644
index 000000000..fecd08822
--- /dev/null
+++ b/etc/soffice.profile
@@ -0,0 +1,5 @@
1################################
2# LibreOffice profile
3################################
4include /etc/firejail/libreoffice.profile
5
diff --git a/etc/spotify.profile b/etc/spotify.profile
index fd4586dd5..6dbcc03ee 100644
--- a/etc/spotify.profile
+++ b/etc/spotify.profile
@@ -7,24 +7,37 @@ include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-devel.inc 7include /etc/firejail/disable-devel.inc
8include /etc/firejail/disable-passwdmgr.inc 8include /etc/firejail/disable-passwdmgr.inc
9 9
10# Whitelist the folders needed by Spotify - This is more restrictive 10# Whitelist the folders needed by Spotify
11# than a blacklist though, but this is all spotify requires for
12# streaming audio
13mkdir ${HOME}/.config
14mkdir ${HOME}/.config/spotify 11mkdir ${HOME}/.config/spotify
15whitelist ${HOME}/.config/spotify 12whitelist ${HOME}/.config/spotify
16mkdir ${HOME}/.local
17mkdir ${HOME}/.local/share
18mkdir ${HOME}/.local/share/spotify 13mkdir ${HOME}/.local/share/spotify
19whitelist ${HOME}/.local/share/spotify 14whitelist ${HOME}/.local/share/spotify
20mkdir ${HOME}/.cache
21mkdir ${HOME}/.cache/spotify 15mkdir ${HOME}/.cache/spotify
22whitelist ${HOME}/.cache/spotify 16whitelist ${HOME}/.cache/spotify
23include /etc/firejail/whitelist-common.inc
24 17
25caps.drop all 18caps.drop all
26seccomp
27protocol unix,inet,inet6,netlink
28netfilter 19netfilter
20nogroups
21nonewprivs
29noroot 22noroot
23protocol unix,inet,inet6,netlink
24seccomp
25shell none
26
27private-bin spotify
28private-etc fonts,machine-id,pulse,resolv.conf
29private-dev
30private-tmp
30 31
32blacklist ${HOME}/.Xauthority
33blacklist ${HOME}/.bashrc
34blacklist /boot
35blacklist /lost+found
36blacklist /media
37blacklist /mnt
38blacklist /opt
39blacklist /root
40blacklist /sbin
41blacklist /srv
42blacklist /sys
43blacklist /var
diff --git a/etc/ssh.profile b/etc/ssh.profile
index 7b282bde6..d3558ead3 100644
--- a/etc/ssh.profile
+++ b/etc/ssh.profile
@@ -1,12 +1,15 @@
1# ssh client 1# ssh client
2quiet
2noblacklist ~/.ssh 3noblacklist ~/.ssh
4noblacklist /tmp/ssh-*
3 5
4include /etc/firejail/disable-common.inc 6include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc 7include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-passwdmgr.inc 8include /etc/firejail/disable-passwdmgr.inc
7 9
8caps.drop all 10caps.drop all
9seccomp
10protocol unix,inet,inet6
11netfilter 11netfilter
12nonewprivs
12noroot 13noroot
14protocol unix,inet,inet6
15seccomp
diff --git a/etc/start-tor-browser.profile b/etc/start-tor-browser.profile
new file mode 100644
index 000000000..ee19cee25
--- /dev/null
+++ b/etc/start-tor-browser.profile
@@ -0,0 +1,20 @@
1# Firejail profile for the Tor Brower Bundle
2include /etc/firejail/disable-common.inc
3include /etc/firejail/disable-devel.inc
4include /etc/firejail/disable-passwdmgr.inc
5include /etc/firejail/disable-programs.inc
6
7caps.drop all
8netfilter
9nogroups
10nonewprivs
11noroot
12protocol unix,inet,inet6
13seccomp
14shell none
15tracelog
16
17private-bin bash,grep,sed,tail,env,gpg,id,readlink,dirname,test,mkdir,ln,sed,cp,rm,getconf
18private-etc fonts
19private-dev
20private-tmp
diff --git a/etc/steam.profile b/etc/steam.profile
index 4c96e8258..5dc5e80ff 100644
--- a/etc/steam.profile
+++ b/etc/steam.profile
@@ -8,6 +8,7 @@ include /etc/firejail/disable-passwdmgr.inc
8 8
9caps.drop all 9caps.drop all
10netfilter 10netfilter
11nonewprivs
11noroot 12noroot
13protocol unix,inet,inet6,netlink
12seccomp 14seccomp
13protocol unix,inet,inet6
diff --git a/etc/stellarium.profile b/etc/stellarium.profile
new file mode 100644
index 000000000..d57c9e5f7
--- /dev/null
+++ b/etc/stellarium.profile
@@ -0,0 +1,28 @@
1# Firejail profile for Stellarium.
2noblacklist ~/.stellarium
3noblacklist ~/.config/stellarium
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-devel.inc
6include /etc/firejail/disable-passwdmgr.inc
7include /etc/firejail/disable-programs.inc
8
9# Whitelist
10mkdir ~/.stellarium
11whitelist ~/.stellarium
12mkdir ~/.config/stellarium
13whitelist ~/.config/stellarium
14
15caps.drop all
16netfilter
17nogroups
18nonewprivs
19noroot
20nosound
21protocol unix,inet,inet6,netlink
22seccomp
23shell none
24tracelog
25
26private-bin stellarium
27private-dev
28private-tmp
diff --git a/etc/strings.profile b/etc/strings.profile
new file mode 100644
index 000000000..7c464bf88
--- /dev/null
+++ b/etc/strings.profile
@@ -0,0 +1,11 @@
1# strings profile
2ignore noroot
3include /etc/firejail/default.profile
4
5net none
6nosound
7quiet
8shell none
9tracelog
10
11private-dev
diff --git a/etc/synfigstudio.profile b/etc/synfigstudio.profile
new file mode 100644
index 000000000..69b2a0db2
--- /dev/null
+++ b/etc/synfigstudio.profile
@@ -0,0 +1,19 @@
1# synfigstudio
2noblacklist ${HOME}/.config/synfig
3noblacklist ${HOME}/.synfig
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-passwdmgr.inc
7
8caps.drop all
9netfilter
10nonewprivs
11noroot
12protocol unix
13seccomp
14
15noexec ${HOME}
16noexec /tmp
17
18private-dev
19private-tmp
diff --git a/etc/tar.profile b/etc/tar.profile
new file mode 100644
index 000000000..91fdaf48d
--- /dev/null
+++ b/etc/tar.profile
@@ -0,0 +1,18 @@
1# tar profile
2ignore noroot
3include /etc/firejail/default.profile
4
5blacklist /tmp/.X11-unix
6
7hostname tar
8net none
9no3d
10nosound
11quiet
12shell none
13tracelog
14
15# support compressed archives
16private-bin sh,tar,gtar,compress,gzip,lzma,xz,bzip2,lbzip2,lzip,lzop
17private-dev
18private-etc passwd,group,localtime
diff --git a/etc/telegram.profile b/etc/telegram.profile
index df6b6a270..7615c8eef 100644
--- a/etc/telegram.profile
+++ b/etc/telegram.profile
@@ -5,11 +5,8 @@ include /etc/firejail/disable-programs.inc
5include /etc/firejail/disable-devel.inc 5include /etc/firejail/disable-devel.inc
6 6
7caps.drop all 7caps.drop all
8seccomp
9protocol unix,inet,inet6
10noroot
11netfilter 8netfilter
12 9nonewprivs
13whitelist ~/Downloads/Telegram Desktop 10noroot
14mkdir ${HOME}/.TelegramDesktop 11protocol unix,inet,inet6
15whitelist ~/.TelegramDesktop 12seccomp
diff --git a/etc/thunderbird.profile b/etc/thunderbird.profile
index 7882367b9..568343ba6 100644
--- a/etc/thunderbird.profile
+++ b/etc/thunderbird.profile
@@ -11,9 +11,11 @@ mkdir ~/.thunderbird
11whitelist ~/.thunderbird 11whitelist ~/.thunderbird
12 12
13noblacklist ~/.cache/thunderbird 13noblacklist ~/.cache/thunderbird
14mkdir ~/.cache
15mkdir ~/.cache/thunderbird 14mkdir ~/.cache/thunderbird
16whitelist ~/.cache/thunderbird 15whitelist ~/.cache/thunderbird
17 16
17# allow browsers
18ignore private-tmp
18include /etc/firejail/firefox.profile 19include /etc/firejail/firefox.profile
20#include /etc/firejail/chromium.profile - chromium runs as suid!
19 21
diff --git a/etc/totem.profile b/etc/totem.profile
index 4d87cbb85..252b46979 100644
--- a/etc/totem.profile
+++ b/etc/totem.profile
@@ -1,11 +1,15 @@
1# Totem media player profile 1# Totem media player profile
2noblacklist ~/.config/totem
3noblacklist ~/.local/share/totem
4
2include /etc/firejail/disable-common.inc 5include /etc/firejail/disable-common.inc
3include /etc/firejail/disable-programs.inc 6include /etc/firejail/disable-programs.inc
4include /etc/firejail/disable-devel.inc 7include /etc/firejail/disable-devel.inc
5include /etc/firejail/disable-passwdmgr.inc 8include /etc/firejail/disable-passwdmgr.inc
6 9
7caps.drop all 10caps.drop all
8seccomp 11nonewprivs
9protocol unix,inet,inet6
10noroot 12noroot
11netfilter 13netfilter
14protocol unix,inet,inet6
15seccomp
diff --git a/etc/transmission-gtk.profile b/etc/transmission-gtk.profile
index d61d36a8c..fa54ea81b 100644
--- a/etc/transmission-gtk.profile
+++ b/etc/transmission-gtk.profile
@@ -1,4 +1,4 @@
1# transmission-gtk profile 1# transmission-gtk bittorrent profile
2noblacklist ${HOME}/.config/transmission 2noblacklist ${HOME}/.config/transmission
3noblacklist ${HOME}/.cache/transmission 3noblacklist ${HOME}/.cache/transmission
4 4
@@ -8,9 +8,15 @@ include /etc/firejail/disable-devel.inc
8include /etc/firejail/disable-passwdmgr.inc 8include /etc/firejail/disable-passwdmgr.inc
9 9
10caps.drop all 10caps.drop all
11seccomp
12protocol unix,inet,inet6
13netfilter 11netfilter
12nonewprivs
14noroot 13noroot
15tracelog
16nosound 14nosound
15protocol unix,inet,inet6
16seccomp
17shell none
18tracelog
19
20private-bin transmission-gtk
21private-dev
22private-tmp
diff --git a/etc/transmission-qt.profile b/etc/transmission-qt.profile
index 3db7a5452..100fadc27 100644
--- a/etc/transmission-qt.profile
+++ b/etc/transmission-qt.profile
@@ -1,4 +1,4 @@
1# transmission-qt profile 1# transmission-qt bittorrent profile
2noblacklist ${HOME}/.config/transmission 2noblacklist ${HOME}/.config/transmission
3noblacklist ${HOME}/.cache/transmission 3noblacklist ${HOME}/.cache/transmission
4 4
@@ -8,9 +8,15 @@ include /etc/firejail/disable-devel.inc
8include /etc/firejail/disable-passwdmgr.inc 8include /etc/firejail/disable-passwdmgr.inc
9 9
10caps.drop all 10caps.drop all
11seccomp
12protocol unix,inet,inet6
13netfilter 11netfilter
12nonewprivs
14noroot 13noroot
15tracelog
16nosound 14nosound
15protocol unix,inet,inet6
16seccomp
17shell none
18tracelog
19
20private-bin transmission-qt
21private-dev
22private-tmp
diff --git a/etc/uget-gtk.profile b/etc/uget-gtk.profile
index ef5aa7d4a..3ba28f772 100644
--- a/etc/uget-gtk.profile
+++ b/etc/uget-gtk.profile
@@ -6,13 +6,19 @@ include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-devel.inc 6include /etc/firejail/disable-devel.inc
7 7
8caps.drop all 8caps.drop all
9seccomp
10protocol unix,inet,inet6
11netfilter 9netfilter
10nonewprivs
12noroot 11noroot
12nosound
13protocol unix,inet,inet6
14seccomp
15shell none
16
17private-bin uget-gtk
18private-dev
19private-tmp
13 20
14whitelist ${DOWNLOADS} 21whitelist ${DOWNLOADS}
15mkdir ~/.config
16mkdir ~/.config/uGet 22mkdir ~/.config/uGet
17whitelist ~/.config/uGet 23whitelist ~/.config/uGet
18include /etc/firejail/whitelist-common.inc 24include /etc/firejail/whitelist-common.inc
diff --git a/etc/unbound.profile b/etc/unbound.profile
index 4365e4fee..5e2cb5f65 100644
--- a/etc/unbound.profile
+++ b/etc/unbound.profile
@@ -8,5 +8,6 @@ include /etc/firejail/disable-passwdmgr.inc
8 8
9private 9private
10private-dev 10private-dev
11nosound
11seccomp.drop mount,umount2,ptrace,kexec_load,kexec_file_load,open_by_handle_at,init_module,finit_module,delete_module,iopl,ioperm,swapon,swapoff,syslog,process_vm_readv,process_vm_writev,sysfs,_sysctl,adjtimex,clock_adjtime,lookup_dcookie,perf_event_open,fanotify_init,kcmp,add_key,request_key,keyctl,uselib,acct,modify_ldt,pivot_root,io_setup,io_destroy,io_getevents,io_submit,io_cancel,remap_file_pages,mbind,get_mempolicy,set_mempolicy,migrate_pages,move_pages,vmsplice,perf_event_open 12seccomp.drop mount,umount2,ptrace,kexec_load,kexec_file_load,open_by_handle_at,init_module,finit_module,delete_module,iopl,ioperm,swapon,swapoff,syslog,process_vm_readv,process_vm_writev,sysfs,_sysctl,adjtimex,clock_adjtime,lookup_dcookie,perf_event_open,fanotify_init,kcmp,add_key,request_key,keyctl,uselib,acct,modify_ldt,pivot_root,io_setup,io_destroy,io_getevents,io_submit,io_cancel,remap_file_pages,mbind,get_mempolicy,set_mempolicy,migrate_pages,move_pages,vmsplice,perf_event_open
12 13
diff --git a/etc/unrar.profile b/etc/unrar.profile
new file mode 100644
index 000000000..0700cafe9
--- /dev/null
+++ b/etc/unrar.profile
@@ -0,0 +1,18 @@
1# unrar profile
2ignore noroot
3include /etc/firejail/default.profile
4
5blacklist /tmp/.X11-unix
6
7hostname unrar
8net none
9no3d
10nosound
11quiet
12shell none
13tracelog
14
15private-bin unrar
16private-dev
17private-etc passwd,group,localtime
18private-tmp
diff --git a/etc/unzip.profile b/etc/unzip.profile
new file mode 100644
index 000000000..a43785795
--- /dev/null
+++ b/etc/unzip.profile
@@ -0,0 +1,16 @@
1# unzip profile
2ignore noroot
3include /etc/firejail/default.profile
4blacklist /tmp/.X11-unix
5
6hostname unzip
7net none
8no3d
9nosound
10quiet
11shell none
12tracelog
13
14private-bin unzip
15private-dev
16private-etc passwd,group,localtime
diff --git a/etc/uudeview.profile b/etc/uudeview.profile
new file mode 100644
index 000000000..5ba0896ab
--- /dev/null
+++ b/etc/uudeview.profile
@@ -0,0 +1,15 @@
1# uudeview profile
2ignore noroot
3include /etc/firejail/default.profile
4
5blacklist /etc
6
7hostname uudeview
8net none
9nosound
10quiet
11shell none
12tracelog
13
14private-bin uudeview
15private-dev
diff --git a/etc/vim.profile b/etc/vim.profile
new file mode 100644
index 000000000..b161fcbb0
--- /dev/null
+++ b/etc/vim.profile
@@ -0,0 +1,16 @@
1# vim profile
2noblacklist ~/.vim
3noblacklist ~/.vimrc
4noblacklist ~/.viminfo
5
6include /etc/firejail/disable-common.inc
7include /etc/firejail/disable-programs.inc
8include /etc/firejail/disable-passwdmgr.inc
9
10caps.drop all
11netfilter
12nogroups
13nonewprivs
14noroot
15protocol unix,inet,inet6
16seccomp
diff --git a/etc/virtualbox.profile b/etc/virtualbox.profile
new file mode 100644
index 000000000..49f8f8b24
--- /dev/null
+++ b/etc/virtualbox.profile
@@ -0,0 +1,13 @@
1# VirtualBox profile
2
3noblacklist ${HOME}/.VirtualBox
4noblacklist ${HOME}/VirtualBox VMs
5noblacklist ${HOME}/.config/VirtualBox
6noblacklist /usr/bin/virtualbox
7include /etc/firejail/disable-common.inc
8include /etc/firejail/disable-programs.inc
9include /etc/firejail/disable-passwdmgr.inc
10
11caps.drop all
12
13
diff --git a/etc/vivaldi.profile b/etc/vivaldi.profile
index 449d9a168..3c608dccb 100644
--- a/etc/vivaldi.profile
+++ b/etc/vivaldi.profile
@@ -6,12 +6,11 @@ include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-devel.inc 6include /etc/firejail/disable-devel.inc
7 7
8netfilter 8netfilter
9nonewprivs
9 10
10whitelist ${DOWNLOADS} 11whitelist ${DOWNLOADS}
11mkdir ~/.config
12mkdir ~/.config/vivaldi 12mkdir ~/.config/vivaldi
13whitelist ~/.config/vivaldi 13whitelist ~/.config/vivaldi
14mkdir ~/.cache
15mkdir ~/.cache/vivaldi 14mkdir ~/.cache/vivaldi
16whitelist ~/.cache/vivaldi 15whitelist ~/.cache/vivaldi
17include /etc/firejail/whitelist-common.inc 16include /etc/firejail/whitelist-common.inc
diff --git a/etc/vlc.profile b/etc/vlc.profile
index 061ae6f78..2fd763f25 100644
--- a/etc/vlc.profile
+++ b/etc/vlc.profile
@@ -7,7 +7,14 @@ include /etc/firejail/disable-devel.inc
7include /etc/firejail/disable-passwdmgr.inc 7include /etc/firejail/disable-passwdmgr.inc
8 8
9caps.drop all 9caps.drop all
10seccomp
11protocol unix,inet,inet6
12noroot
13netfilter 10netfilter
11nogroups
12nonewprivs
13noroot
14protocol unix,inet,inet6,netlink
15seccomp
16shell none
17
18private-bin vlc,cvlc,nvlc,rvlc,qvlc,svlc
19private-dev
20private-tmp
diff --git a/etc/warzone2100.profile b/etc/warzone2100.profile
new file mode 100644
index 000000000..7c7efade8
--- /dev/null
+++ b/etc/warzone2100.profile
@@ -0,0 +1,26 @@
1# Firejail profile for warzone2100
2# Currently supports warzone2100-3.1
3noblacklist ~/.warzone2100-3.1
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-devel.inc
6include /etc/firejail/disable-passwdmgr.inc
7include /etc/firejail/disable-programs.inc
8
9# Whitelist
10mkdir ~/.warzone2100-3.1
11whitelist ~/.warzone2100-3.1
12
13# Call these options
14caps.drop all
15netfilter
16nogroups
17nonewprivs
18noroot
19protocol unix,inet,inet6,netlink
20seccomp
21shell none
22tracelog
23
24private-bin warzone2100
25private-dev
26private-tmp
diff --git a/etc/weechat.profile b/etc/weechat.profile
index 280a5f9d8..410061278 100644
--- a/etc/weechat.profile
+++ b/etc/weechat.profile
@@ -4,8 +4,12 @@ include /etc/firejail/disable-common.inc
4include /etc/firejail/disable-programs.inc 4include /etc/firejail/disable-programs.inc
5 5
6caps.drop all 6caps.drop all
7seccomp
8protocol unix,inet,inet6
9netfilter 7netfilter
8nonewprivs
10noroot 9noroot
11netfilter 10protocol unix,inet,inet6
11seccomp
12
13# no private-bin support for various reasons:
14# Plugins loaded: alias, aspell, charset, exec, fifo, guile, irc,
15# logger, lua, perl, python, relay, ruby, script, tcl, trigger, xferloading plugins \ No newline at end of file
diff --git a/etc/wesnoth.profile b/etc/wesnoth.profile
index 340ba0db5..bb489ddeb 100644
--- a/etc/wesnoth.profile
+++ b/etc/wesnoth.profile
@@ -9,20 +9,16 @@ include /etc/firejail/disable-devel.inc
9include /etc/firejail/disable-passwdmgr.inc 9include /etc/firejail/disable-passwdmgr.inc
10 10
11caps.drop all 11caps.drop all
12seccomp 12nonewprivs
13protocol unix,inet,inet6
14noroot 13noroot
14protocol unix,inet,inet6
15seccomp
15 16
16private-dev 17private-dev
18private-tmp
17 19
18whitelist /tmp/.X11-unix
19
20mkdir ${HOME}/.local
21mkdir ${HOME}/.local/share
22mkdir ${HOME}/.local/share/wesnoth 20mkdir ${HOME}/.local/share/wesnoth
23mkdir ${HOME}/.config
24mkdir ${HOME}/.config/wesnoth 21mkdir ${HOME}/.config/wesnoth
25mkdir ${HOME}/.cache
26mkdir ${HOME}/.cache/wesnoth 22mkdir ${HOME}/.cache/wesnoth
27whitelist ${HOME}/.local/share/wesnoth 23whitelist ${HOME}/.local/share/wesnoth
28whitelist ${HOME}/.config/wesnoth 24whitelist ${HOME}/.config/wesnoth
diff --git a/etc/whitelist-common.inc b/etc/whitelist-common.inc
index 9d5ef3d96..d4e69948e 100644
--- a/etc/whitelist-common.inc
+++ b/etc/whitelist-common.inc
@@ -1,5 +1,6 @@
1# common whitelist for all profiles 1# common whitelist for all profiles
2 2
3whitelist ~/.XCompose
3whitelist ~/.config/mimeapps.list 4whitelist ~/.config/mimeapps.list
4whitelist ~/.icons 5whitelist ~/.icons
5whitelist ~/.config/user-dirs.dirs 6whitelist ~/.config/user-dirs.dirs
@@ -13,16 +14,25 @@ whitelist ~/.fonts.d
13whitelist ~/.fontconfig 14whitelist ~/.fontconfig
14whitelist ~/.fonts.conf 15whitelist ~/.fonts.conf
15whitelist ~/.fonts.conf.d 16whitelist ~/.fonts.conf.d
17whitelist ~/.local/share/fonts
16whitelist ~/.config/fontconfig 18whitelist ~/.config/fontconfig
17whitelist ~/.cache/fontconfig 19whitelist ~/.cache/fontconfig
18 20
19# gtk 21# gtk
20whitelist ~/.gtkrc 22whitelist ~/.gtkrc
21whitelist ~/.gtkrc-2.0 23whitelist ~/.gtkrc-2.0
24whitelist ~/.config/gtk-2.0
22whitelist ~/.config/gtk-3.0 25whitelist ~/.config/gtk-3.0
23whitelist ~/.themes 26whitelist ~/.themes
27whitelist ~/.kde/share/config/gtkrc
28whitelist ~/.kde/share/config/gtkrc-2.0
24 29
25# dconf 30# dconf
26mkdir ~/.config
27mkdir ~/.config/dconf 31mkdir ~/.config/dconf
28whitelist ~/.config/dconf 32whitelist ~/.config/dconf
33
34# qt/kde
35whitelist ~/.config/kdeglobals
36whitelist ~/.kde/share/config/oxygenrc
37whitelist ~/.kde/share/config/kdeglobals
38whitelist ~/.kde/share/icons
diff --git a/etc/wine.profile b/etc/wine.profile
index ea6db8511..18e5346af 100644
--- a/etc/wine.profile
+++ b/etc/wine.profile
@@ -9,5 +9,6 @@ include /etc/firejail/disable-devel.inc
9 9
10caps.drop all 10caps.drop all
11netfilter 11netfilter
12nonewprivs
12noroot 13noroot
13seccomp 14seccomp
diff --git a/etc/wire.profile b/etc/wire.profile
new file mode 100644
index 000000000..c84b4cc28
--- /dev/null
+++ b/etc/wire.profile
@@ -0,0 +1,24 @@
1# wire messenger profile
2
3noblacklist ~/.config/Wire
4noblacklist ~/.config/wire
5
6include /etc/firejail/disable-common.inc
7include /etc/firejail/disable-programs.inc
8include /etc/firejail/disable-devel.inc
9include /etc/firejail/disable-passwdmgr.inc
10
11caps.drop all
12netfilter
13nonewprivs
14nogroups
15noroot
16protocol unix,inet,inet6,netlink
17seccomp
18shell none
19
20private-tmp
21private-dev
22
23# Note: the current beta version of wire is located in /opt/Wire/wire and therefore not in PATH.
24# To use wire with firejail run "firejail /opt/Wire/wire"
diff --git a/etc/xchat.profile b/etc/xchat.profile
index fcea4245e..1f2865cab 100644
--- a/etc/xchat.profile
+++ b/etc/xchat.profile
@@ -6,6 +6,9 @@ include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-devel.inc 6include /etc/firejail/disable-devel.inc
7 7
8caps.drop all 8caps.drop all
9seccomp 9nonewprivs
10protocol unix,inet,inet6
11noroot 10noroot
11protocol unix,inet,inet6
12seccomp
13
14# private-bin requires perl, python, etc.
diff --git a/etc/xiphos.profile b/etc/xiphos.profile
new file mode 100644
index 000000000..b7fb6ecf3
--- /dev/null
+++ b/etc/xiphos.profile
@@ -0,0 +1,30 @@
1# Firejail profile for xiphos
2noblacklist ~/.sword
3noblacklist ~/.xiphos
4
5include /etc/firejail/disable-common.inc
6include /etc/firejail/disable-devel.inc
7include /etc/firejail/disable-passwdmgr.inc
8include /etc/firejail/disable-programs.inc
9
10blacklist ~/.bashrc
11blacklist ~/.Xauthority
12
13caps.drop all
14netfilter
15nogroups
16nonewprivs
17noroot
18nosound
19protocol unix,inet,inet6
20seccomp
21shell none
22tracelog
23
24private-bin xiphos
25private-etc fonts,resolv.conf,sword
26private-dev
27private-tmp
28
29whitelist ${HOME}/.sword
30whitelist ${HOME}/.xiphos
diff --git a/etc/xpdf.profile b/etc/xpdf.profile
new file mode 100644
index 000000000..7ea368bbe
--- /dev/null
+++ b/etc/xpdf.profile
@@ -0,0 +1,18 @@
1################################
2# xpdf application profile
3################################
4noblacklist ${HOME}/.xpdfrc
5include /etc/firejail/disable-common.inc
6include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-passwdmgr.inc
8
9caps.drop all
10net none
11nonewprivs
12noroot
13protocol unix
14shell none
15seccomp
16
17private-dev
18private-tmp
diff --git a/etc/xplayer.profile b/etc/xplayer.profile
new file mode 100644
index 000000000..191d2f67f
--- /dev/null
+++ b/etc/xplayer.profile
@@ -0,0 +1,22 @@
1# Xplayer profile
2noblacklist ~/.config/xplayer
3noblacklist ~/.local/share/xplayer
4
5include /etc/firejail/disable-common.inc
6include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-devel.inc
8include /etc/firejail/disable-passwdmgr.inc
9
10caps.drop all
11netfilter
12nogroups
13nonewprivs
14noroot
15protocol unix,inet,inet6
16seccomp
17shell none
18tracelog
19
20private-bin xplayer,xplayer-audio-preview,xplayer-video-thumbnailer
21private-dev
22private-tmp
diff --git a/etc/xreader.profile b/etc/xreader.profile
new file mode 100644
index 000000000..d2a000bd0
--- /dev/null
+++ b/etc/xreader.profile
@@ -0,0 +1,23 @@
1# Xreader profile
2noblacklist ~/.config/xreader
3noblacklist ~/.cache/xreader
4noblacklist ~/.local/share
5
6include /etc/firejail/disable-common.inc
7include /etc/firejail/disable-programs.inc
8include /etc/firejail/disable-devel.inc
9include /etc/firejail/disable-passwdmgr.inc
10
11caps.drop all
12nogroups
13nonewprivs
14noroot
15nosound
16protocol unix
17seccomp
18shell none
19tracelog
20
21private-bin xreader, xreader-previewer, xreader-thumbnailer
22private-dev
23private-tmp
diff --git a/etc/xviewer.profile b/etc/xviewer.profile
new file mode 100644
index 000000000..cbb59d16e
--- /dev/null
+++ b/etc/xviewer.profile
@@ -0,0 +1,20 @@
1noblacklist ~/.config/xviewer
2
3include /etc/firejail/disable-common.inc
4include /etc/firejail/disable-programs.inc
5include /etc/firejail/disable-devel.inc
6include /etc/firejail/disable-passwdmgr.inc
7
8caps.drop all
9nogroups
10nonewprivs
11noroot
12nosound
13protocol unix
14seccomp
15shell none
16tracelog
17
18private-dev
19private-bin xviewer
20private-tmp
diff --git a/etc/xz.profile b/etc/xz.profile
new file mode 100644
index 000000000..5b29f7338
--- /dev/null
+++ b/etc/xz.profile
@@ -0,0 +1,3 @@
1# xz profile
2quiet
3include /etc/firejail/cpio.profile
diff --git a/etc/xzdec.profile b/etc/xzdec.profile
new file mode 100644
index 000000000..04f98cef6
--- /dev/null
+++ b/etc/xzdec.profile
@@ -0,0 +1,14 @@
1# xzdec profile
2ignore noroot
3include /etc/firejail/default.profile
4
5blacklist /tmp/.X11-unix
6
7net none
8no3d
9nosound
10quiet
11shell none
12tracelog
13
14private-dev
diff --git a/etc/zathura.profile b/etc/zathura.profile
new file mode 100644
index 000000000..6c93a2480
--- /dev/null
+++ b/etc/zathura.profile
@@ -0,0 +1,26 @@
1# zathura document viewer profile
2noblacklist ~/.config/zathura
3noblacklist ~/.local/share/zathura
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-devel.inc
7include /etc/firejail/disable-passwdmgr.inc
8
9caps.drop all
10netfilter
11net none
12nogroups
13nonewprivs
14noroot
15nosound
16shell none
17seccomp
18protocol unix
19
20private-bin zathura
21private-dev
22private-etc fonts
23private-tmp
24
25read-only ~/
26read-write ~/.local/share/zathura/
diff --git a/etc/zoom.profile b/etc/zoom.profile
new file mode 100644
index 000000000..f5831dd88
--- /dev/null
+++ b/etc/zoom.profile
@@ -0,0 +1,23 @@
1# Firejail profile for zoom.us
2
3noblacklist ~/.config/zoomus.conf
4
5include /etc/firejail/disable-common.inc
6include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-devel.inc
8
9
10# Whitelists
11
12mkdir ~/.zoom
13whitelist ~/.zoom
14
15
16caps.drop all
17netfilter
18nonewprivs
19noroot
20protocol unix,inet,inet6
21seccomp
22
23private-tmp
diff --git a/gcov.sh b/gcov.sh
new file mode 100755
index 000000000..ffacce6b5
--- /dev/null
+++ b/gcov.sh
@@ -0,0 +1,71 @@
1#!/bin/bash
2
3generate() {
4 lcov --capture -d src/firejail -d src/firemon -d src/fseccomp -d src/fnet -d src/ftee -d src/lib -d src/firecfg --output-file gcov-file
5 rm -fr gcov-dir
6 genhtml gcov-file --output-directory gcov-dir
7}
8
9# init
10USER=`whoami`
11firejail --help
12firemon --help
13/usr/lib/firejail/fnet --help
14/usr/lib/firejail/fseccomp --help
15/usr/lib/firejail/ftee --help
16firecfg --help
17sudo chown $USER:$USER `find .`
18generate
19
20# running tests
21make test-root
22generate
23sleep 2
24
25make test-network
26generate
27sleep 2
28
29make test-appimage
30generate
31sleep 2
32
33make test-overlay
34generate
35sleep 2
36
37make test-profiles
38generate
39sleep 2
40
41make test-fs
42generate
43sleep 2
44
45make test-utils
46generate
47sleep 2
48
49make test-environment
50generate
51sleep 2
52
53make test-apps
54generate
55sleep 2
56
57make test-apps-x11
58generate
59sleep 2
60
61make test-apps-x11-xorg
62generate
63sleep 2
64
65make test-filters
66generate
67sleep 2
68
69make test-arguments
70generate
71sleep 2
diff --git a/mkasc.sh b/mkasc.sh
index 2c9836f17..4d5b73e20 100755
--- a/mkasc.sh
+++ b/mkasc.sh
@@ -6,5 +6,6 @@ cd /transfer
6sha256sum * > firejail-$1-unsigned 6sha256sum * > firejail-$1-unsigned
7gpg --clearsign --digest-algo SHA256 < firejail-$1-unsigned > firejail-$1.asc 7gpg --clearsign --digest-algo SHA256 < firejail-$1-unsigned > firejail-$1.asc
8gpg --verify firejail-$1.asc 8gpg --verify firejail-$1.asc
9gpg --detach-sign --armor firejail-$1.tar.xz
9rm firejail-$1-unsigned 10rm firejail-$1-unsigned
10 11
diff --git a/mkdeb.sh b/mkdeb.sh
index 71c3b9a04..be8d618e1 100755
--- a/mkdeb.sh
+++ b/mkdeb.sh
@@ -3,7 +3,7 @@
3# a code archive should already be available 3# a code archive should already be available
4 4
5TOP=`pwd` 5TOP=`pwd`
6CODE_ARCHIVE="$1-$2.tar.bz2" 6CODE_ARCHIVE="$1-$2.tar.xz"
7CODE_DIR="$1-$2" 7CODE_DIR="$1-$2"
8INSTALL_DIR="${INSTALL_DIR}${CODE_DIR}/debian" 8INSTALL_DIR="${INSTALL_DIR}${CODE_DIR}/debian"
9DEBIAN_CTRL_DIR="${DEBIAN_CTRL_DIR}${CODE_DIR}/debian/DEBIAN" 9DEBIAN_CTRL_DIR="${DEBIAN_CTRL_DIR}${CODE_DIR}/debian/DEBIAN"
@@ -15,7 +15,7 @@ echo "install directory: $INSTALL_DIR"
15echo "debian control directory: $DEBIAN_CTRL_DIR" 15echo "debian control directory: $DEBIAN_CTRL_DIR"
16echo "*****************************************" 16echo "*****************************************"
17 17
18tar -xjvf $CODE_ARCHIVE 18tar -xJvf $CODE_ARCHIVE
19#mkdir -p $INSTALL_DIR 19#mkdir -p $INSTALL_DIR
20cd $CODE_DIR 20cd $CODE_DIR
21./configure --prefix=/usr 21./configure --prefix=/usr
diff --git a/mketc.sh b/mketc.sh
index f44238968..f98c5479f 100755
--- a/mketc.sh
+++ b/mketc.sh
@@ -2,23 +2,21 @@
2rm -fr .etc 2rm -fr .etc
3mkdir .etc 3mkdir .etc
4 4
5result=$(echo $1 | sed 's/\//\\\//g') 5for file in etc/*.profile etc/*.inc etc/*.net;
6echo $result
7
8FILES=`ls etc/*.profile`
9for file in $FILES
10do
11 sed "s/\/etc\/firejail/$result\/firejail/g" $file > .$file
12done
13
14FILES=`ls etc/*.inc`
15for file in $FILES
16do 6do
17 sed "s/\/etc\/firejail/$result\/firejail/g" $file > .$file 7 sed "s;/etc/firejail;$1/firejail;g" $file > .$file
18done 8done
19 9
20FILES=`ls etc/*.net` 10if [ "x$2" = "xyes" ]
21for file in $FILES 11then
22do 12sed -i -e '
23 sed "s/\/etc\/firejail/$result\/firejail/g" $file > .$file 131i# Workaround for systems where common UNIX utilities are symlinks to busybox.\
24done 14# If this is not your case you can remove --enable-busybox-workaround from\
15# ./configure options, for added security.\
16noblacklist \${PATH}/mount\
17noblacklist \${PATH}/umount\
18noblacklist \${PATH}/su\
19noblacklist \${PATH}/sudo\
20noblacklist \${PATH}/nc\
21' .etc/disable-common.inc
22fi
diff --git a/mkuid.sh b/mkuid.sh
new file mode 100755
index 000000000..a59f58143
--- /dev/null
+++ b/mkuid.sh
@@ -0,0 +1,20 @@
1#!/bin/sh
2
3echo "extracting UID_MIN and GID_MIN"
4echo "#ifndef FIREJAIL_UIDS_H" > uids.h
5echo "#define FIREJAIL_UIDS_H" >> uids.h
6
7if [ -r /etc/login.defs ]
8then
9 echo "// using values extracted from /etc/login.defs" >> uids.h
10 UID_MIN=`awk '/^\s*UID_MIN\s*([0-9]*).*?$/ {print $2}' /etc/login.defs`
11 GID_MIN=`awk '/^\s*GID_MIN\s*([0-9]*).*?$/ {print $2}' /etc/login.defs`
12 echo "#define UID_MIN $UID_MIN" >> uids.h
13 echo "#define GID_MIN $GID_MIN" >> uids.h
14else
15 echo "// using default values" >> uids.h
16 echo "#define UID_MIN 1000" >> uids.h
17 echo "#define GID_MIN 1000" >> uids.h
18fi
19
20echo "#endif" >> uids.h
diff --git a/platform/debian/conffiles b/platform/debian/conffiles
index dc8640147..321a96f80 100644
--- a/platform/debian/conffiles
+++ b/platform/debian/conffiles
@@ -1,85 +1,176 @@
1/etc/firejail/evince.profile 1/etc/firejail/0ad.profile
2/etc/firejail/chromium.profile 2/etc/firejail/Cyberfox.profile
3/etc/firejail/Mathematica.profile
4/etc/firejail/Telegram.profile
5/etc/firejail/abrowser.profile
6/etc/firejail/atom-beta.profile
7/etc/firejail/atom.profile
8/etc/firejail/atril.profile
9/etc/firejail/audacious.profile
10/etc/firejail/audacity.profile
11/etc/firejail/aweather.profile
12/etc/firejail/bitlbee.profile
13/etc/firejail/brave.profile
14/etc/firejail/cherrytree.profile
3/etc/firejail/chromium-browser.profile 15/etc/firejail/chromium-browser.profile
4/etc/firejail/google-chrome.profile 16/etc/firejail/chromium.profile
5/etc/firejail/google-chrome-stable.profile 17/etc/firejail/clementine.profile
18/etc/firejail/cmus.profile
19/etc/firejail/conkeror.profile
20/etc/firejail/corebird.profile
21/etc/firejail/cpio.profile
22/etc/firejail/cyberfox.profile
23/etc/firejail/deadbeef.profile
24/etc/firejail/default.profile
25/etc/firejail/deluge.profile
26/etc/firejail/dillo.profile
27/etc/firejail/disable-common.inc
28/etc/firejail/disable-devel.inc
29/etc/firejail/disable-passwdmgr.inc
30/etc/firejail/disable-programs.inc
31/etc/firejail/dnscrypt-proxy.profile
32/etc/firejail/dnsmasq.profile
33/etc/firejail/dosbox.profile
34/etc/firejail/dropbox.profile
35/etc/firejail/empathy.profile
36/etc/firejail/eom.profile
37/etc/firejail/epiphany.profile
38/etc/firejail/evince.profile
39/etc/firejail/fbreader.profile
40/etc/firejail/feh.profile
41/etc/firejail/file.profile
42/etc/firejail/filezilla.profile
43/etc/firejail/firefox-esr.profile
44/etc/firejail/firefox.profile
45/etc/firejail/firejail.config
46/etc/firejail/flashpeak-slimjet.profile
47/etc/firejail/franz.profile
48/etc/firejail/gajim.profile
49/etc/firejail/gimp.profile
50/etc/firejail/gitter.profile
51/etc/firejail/gnome-chess.profile
52/etc/firejail/gnome-mplayer.profile
6/etc/firejail/google-chrome-beta.profile 53/etc/firejail/google-chrome-beta.profile
54/etc/firejail/google-chrome-stable.profile
7/etc/firejail/google-chrome-unstable.profile 55/etc/firejail/google-chrome-unstable.profile
8/etc/firejail/midori.profile 56/etc/firejail/google-chrome.profile
57/etc/firejail/google-play-music-desktop-player.profile
58/etc/firejail/gpredict.profile
59/etc/firejail/gtar.profile
60/etc/firejail/gthumb.profile
61/etc/firejail/gwenview.profile
62/etc/firejail/gzip.profile
63/etc/firejail/hedgewars.profile
64/etc/firejail/hexchat.profile
65/etc/firejail/icecat.profile
9/etc/firejail/icedove.profile 66/etc/firejail/icedove.profile
10/etc/firejail/iceweasel.profile 67/etc/firejail/iceweasel.profile
11/etc/firejail/dropbox.profile 68/etc/firejail/inkscape.profile
69/etc/firejail/inox.profile
70/etc/firejail/jitsi.profile
71/etc/firejail/kmail.profile
72/etc/firejail/konversation.profile
73/etc/firejail/less.profile
74/etc/firejail/libreoffice.profile
75/etc/firejail/localc.profile
76/etc/firejail/lodraw.profile
77/etc/firejail/loffice.profile
78/etc/firejail/lofromtemplate.profile
12/etc/firejail/login.users 79/etc/firejail/login.users
13/etc/firejail/firefox.profile 80/etc/firejail/loimpress.profile
14/etc/firejail/opera.profile 81/etc/firejail/lomath.profile
82/etc/firejail/loweb.profile
83/etc/firejail/lowriter.profile
84/etc/firejail/luminance-hdr.profile
85/etc/firejail/lxterminal.profile
86/etc/firejail/mathematica.profile
87/etc/firejail/mcabber.profile
88/etc/firejail/midori.profile
89/etc/firejail/mpv.profile
90/etc/firejail/mupdf.profile
91/etc/firejail/mupen64plus.profile
92/etc/firejail/netsurf.profile
93/etc/firejail/nolocal.net
94/etc/firejail/okular.profile
95/etc/firejail/openbox.profile
15/etc/firejail/opera-beta.profile 96/etc/firejail/opera-beta.profile
16/etc/firejail/thunderbird.profile 97/etc/firejail/opera.profile
17/etc/firejail/transmission-gtk.profile 98/etc/firejail/palemoon.profile
18/etc/firejail/transmission-qt.profile 99/etc/firejail/parole.profile
19/etc/firejail/vlc.profile 100/etc/firejail/pidgin.profile
20/etc/firejail/audacious.profile 101/etc/firejail/pix.profile
21/etc/firejail/clementine.profile
22/etc/firejail/epiphany.profile
23/etc/firejail/qtox.profile
24/etc/firejail/polari.profile 102/etc/firejail/polari.profile
25/etc/firejail/gnome-mplayer.profile 103/etc/firejail/psi-plus.profile
26/etc/firejail/rhythmbox.profile
27/etc/firejail/totem.profile
28/etc/firejail/deluge.profile
29/etc/firejail/qbittorrent.profile 104/etc/firejail/qbittorrent.profile
30/etc/firejail/generic.profile 105/etc/firejail/qpdfview.profile
31/etc/firejail/xchat.profile 106/etc/firejail/qtox.profile
32/etc/firejail/server.profile
33/etc/firejail/quassel.profile 107/etc/firejail/quassel.profile
34/etc/firejail/pidgin.profile 108/etc/firejail/quiterss.profile
35/etc/firejail/filezilla.profile 109/etc/firejail/qutebrowser.profile
36/etc/firejail/empathy.profile 110/etc/firejail/ranger.profile
37/etc/firejail/disable-common.inc 111/etc/firejail/rhythmbox.profile
38/etc/firejail/deadbeef.profile 112/etc/firejail/rtorrent.profile
39/etc/firejail/icecat.profile 113/etc/firejail/seamonkey-bin.profile
40/etc/firejail/fbreader.profile 114/etc/firejail/seamonkey.profile
41/etc/firejail/spotify.profile 115/etc/firejail/server.profile
42/etc/firejail/skype.profile 116/etc/firejail/skype.profile
117/etc/firejail/skypeforlinux.profile
118/etc/firejail/slack.profile
119/etc/firejail/snap.profile
120/etc/firejail/soffice.profile
121/etc/firejail/spotify.profile
122/etc/firejail/ssh.profile
43/etc/firejail/steam.profile 123/etc/firejail/steam.profile
44/etc/firejail/wine.profile 124/etc/firejail/stellarium.profile
45/etc/firejail/disable-devel.inc 125/etc/firejail/strings.profile
46/etc/firejail/conkeror.profile 126/etc/firejail/synfigstudio.profile
127/etc/firejail/tar.profile
128/etc/firejail/telegram.profile
129/etc/firejail/thunderbird.profile
130/etc/firejail/totem.profile
131/etc/firejail/transmission-gtk.profile
132/etc/firejail/transmission-qt.profile
133/etc/firejail/uget-gtk.profile
47/etc/firejail/unbound.profile 134/etc/firejail/unbound.profile
48/etc/firejail/dnscrypt-proxy.profile 135/etc/firejail/unrar.profile
49/etc/firejail/whitelist-common.inc 136/etc/firejail/unzip.profile
50/etc/firejail/nolocal.net 137/etc/firejail/uudeview.profile
138/etc/firejail/vivaldi-beta.profile
139/etc/firejail/vivaldi.profile
140/etc/firejail/vlc.profile
141/etc/firejail/warzone2100.profile
51/etc/firejail/webserver.net 142/etc/firejail/webserver.net
52/etc/firejail/bitlbee.profile
53/etc/firejail/weechat.profile
54/etc/firejail/weechat-curses.profile 143/etc/firejail/weechat-curses.profile
55/etc/firejail/hexchat.profile 144/etc/firejail/weechat.profile
56/etc/firejail/rtorrent.profile
57/etc/firejail/parole.profile
58/etc/firejail/kmail.profile
59/etc/firejail/seamonkey.profile
60/etc/firejail/seamonkey-bin.profile
61/etc/firejail/telegram.profile
62/etc/firejail/mathematica.profile
63/etc/firejail/Mathematica.profile
64/etc/firejail/uget-gtk.profile
65/etc/firejail/mupen64plus.profile
66/etc/firejail/lxterminal.profile
67/etc/firejail/cherrytree.profile
68/etc/firejail/wesnoth.profile 145/etc/firejail/wesnoth.profile
69/etc/firejail/hedgewars.profile 146/etc/firejail/whitelist-common.inc
70/etc/firejail/vivaldi.profile 147/etc/firejail/wine.profile
71/etc/firejail/vivaldi-beta.profile 148/etc/firejail/xchat.profile
72/etc/firejail/atril.profile 149/etc/firejail/xplayer.profile
73/etc/firejail/firejail.config 150/etc/firejail/xreader.profile
74/etc/firejail/qutebrowser.profile 151/etc/firejail/xviewer.profile
75/etc/firejail/flashpeak-slimjet.profile 152/etc/firejail/xz.profile
76/etc/firejail/ssh.profile 153/etc/firejail/xzdec.profile
77/etc/firejail/openbox.profile 154/etc/firejail/zathura.profile
78/etc/firejail/disable-programs.inc 155/etc/firejail/7z.profile
79/etc/firejail/disable-passwdmgr.inc 156/etc/firejail/keepass.profile
80/etc/firejail/dillo.profile 157/etc/firejail/keepassx.profile
81/etc/firejail/cmus.profile 158/etc/firejail/claws-mail.profile
82/etc/firejail/dnsmasq.profile 159/etc/firejail/mutt.profile
83/etc/firejail/palemoon.profile 160/etc/firejail/git.profile
84/etc/firejail/abrowser.profile 161/etc/firejail/emacs.profile
85/etc/firejail/0ad.profile 162/etc/firejail/vim.profile
163/etc/firejail/xpdf.profile
164/etc/firejail/virtualbox.profile
165/etc/firejail/openshot.profile
166/etc/firejail/flowblade.profile
167/etc/firejail/eog.profile
168/etc/firejail/evolution.profile
169/etc/firejail/start-tor-browser.profile
170/etc/firejail/xiphos.profile
171/etc/firejail/display.profile
172/etc/firejail/Wire.profile
173/etc/firejail/wire.profile
174/etc/firejail/mumble.profile
175/etc/firejail/zoom.profile
176/etc/firejail/guayadeque.profile
diff --git a/platform/rpm/firejail.spec b/platform/rpm/firejail.spec
index e365af2d6..67280921a 100644
--- a/platform/rpm/firejail.spec
+++ b/platform/rpm/firejail.spec
@@ -33,16 +33,22 @@ rm -rf %{buildroot}
33%doc 33%doc
34%defattr(-, root, root, -) 34%defattr(-, root, root, -)
35%attr(4755, -, -) %{_bindir}/__NAME__ 35%attr(4755, -, -) %{_bindir}/__NAME__
36%{_bindir}/firecfg
36%{_bindir}/firemon 37%{_bindir}/firemon
38%{_libdir}/__NAME__/firecfg.config
37%{_libdir}/__NAME__/ftee 39%{_libdir}/__NAME__/ftee
40%{_libdir}/__NAME__/faudit
38%{_libdir}/__NAME__/fshaper.sh 41%{_libdir}/__NAME__/fshaper.sh
39%{_libdir}/__NAME__/libtrace.so 42%{_libdir}/__NAME__/libtrace.so
40%{_libdir}/__NAME__/libtracelog.so 43%{_libdir}/__NAME__/libtracelog.so
41%{_datarootdir}/bash-completion/completions/__NAME__ 44%{_datarootdir}/bash-completion/completions/__NAME__
45%{_datarootdir}/bash-completion/completions/firecfg
42%{_datarootdir}/bash-completion/completions/firemon 46%{_datarootdir}/bash-completion/completions/firemon
43%{_docdir}/__NAME__ 47%{_docdir}/__NAME__
44%{_mandir}/man1/__NAME__.1.gz 48%{_mandir}/man1/__NAME__.1.gz
49%{_mandir}/man1/firecfg.1.gz
45%{_mandir}/man1/firemon.1.gz 50%{_mandir}/man1/firemon.1.gz
51%{_mandir}/man5/__NAME__-config.5.gz
46%{_mandir}/man5/__NAME__-login.5.gz 52%{_mandir}/man5/__NAME__-login.5.gz
47%{_mandir}/man5/__NAME__-profile.5.gz 53%{_mandir}/man5/__NAME__-profile.5.gz
48%config %{_sysconfdir}/__NAME__ 54%config %{_sysconfdir}/__NAME__
diff --git a/platform/rpm/old-mkrpm.sh b/platform/rpm/old-mkrpm.sh
new file mode 100755
index 000000000..017d5e1c3
--- /dev/null
+++ b/platform/rpm/old-mkrpm.sh
@@ -0,0 +1,542 @@
1#!/bin/bash
2VERSION="0.9.44"
3rm -fr ~/rpmbuild
4rm -f firejail-$VERSION-1.x86_64.rpm
5
6mkdir -p ~/rpmbuild/{RPMS,SRPMS,BUILD,SOURCES,SPECS,tmp}
7cat <<EOF >~/.rpmmacros
8%_topdir %(echo $HOME)/rpmbuild
9%_tmppath %{_topdir}/tmp
10EOF
11
12cd ~/rpmbuild
13echo "building directory tree"
14
15mkdir -p firejail-$VERSION/usr/bin
16install -m 755 /usr/bin/firejail firejail-$VERSION/usr/bin/.
17install -m 755 /usr/bin/firemon firejail-$VERSION/usr/bin/.
18install -m 755 /usr/bin/firecfg firejail-$VERSION/usr/bin/.
19
20mkdir -p firejail-$VERSION/usr/lib/firejail
21install -m 755 /usr/lib/firejail/faudit firejail-$VERSION/usr/lib/firejail/.
22install -m 644 /usr/lib/firejail/firecfg.config firejail-$VERSION/usr/lib/firejail/.
23install -m 755 /usr/lib/firejail/fshaper.sh firejail-$VERSION/usr/lib/firejail/.
24install -m 755 /usr/lib/firejail/ftee firejail-$VERSION/usr/lib/firejail/.
25install -m 644 /usr/lib/firejail/libtrace.so firejail-$VERSION/usr/lib/firejail/.
26install -m 644 /usr/lib/firejail/libtracelog.so firejail-$VERSION/usr/lib/firejail/.
27install -m 644 /usr/lib/firejail/libconnect.so firejail-$VERSION/usr/lib/firejail/.
28
29mkdir -p firejail-$VERSION/usr/share/man/man1
30install -m 644 /usr/share/man/man1/firejail.1.gz firejail-$VERSION/usr/share/man/man1/.
31install -m 644 /usr/share/man/man1/firemon.1.gz firejail-$VERSION/usr/share/man/man1/.
32install -m 644 /usr/share/man/man1/firecfg.1.gz firejail-$VERSION/usr/share/man/man1/.
33
34mkdir -p firejail-$VERSION/usr/share/man/man5
35install -m 644 /usr/share/man/man5/firejail-profile.5.gz firejail-$VERSION/usr/share/man/man5/.
36install -m 644 /usr/share/man/man5/firejail-login.5.gz firejail-$VERSION/usr/share/man/man5/.
37
38mkdir -p firejail-$VERSION/usr/share/doc/packages/firejail
39install -m 644 /usr/share/doc/firejail/COPYING firejail-$VERSION/usr/share/doc/packages/firejail/.
40install -m 644 /usr/share/doc/firejail/README firejail-$VERSION/usr/share/doc/packages/firejail/.
41install -m 644 /usr/share/doc/firejail/RELNOTES firejail-$VERSION/usr/share/doc/packages/firejail/.
42
43mkdir -p firejail-$VERSION/etc/firejail
44install -m 644 /etc/firejail/0ad.profile firejail-$VERSION/etc/firejail/.
45install -m 644 /etc/firejail/abrowser.profile firejail-$VERSION/etc/firejail/.
46install -m 644 /etc/firejail/atom-beta.profile firejail-$VERSION/etc/firejail/.
47install -m 644 /etc/firejail/atom.profile firejail-$VERSION/etc/firejail/.
48install -m 644 /etc/firejail/atril.profile firejail-$VERSION/etc/firejail/.
49install -m 644 /etc/firejail/audacious.profile firejail-$VERSION/etc/firejail/.
50install -m 644 /etc/firejail/audacity.profile firejail-$VERSION/etc/firejail/.
51install -m 644 /etc/firejail/aweather.profile firejail-$VERSION/etc/firejail/.
52install -m 644 /etc/firejail/bitlbee.profile firejail-$VERSION/etc/firejail/.
53install -m 644 /etc/firejail/brave.profile firejail-$VERSION/etc/firejail/.
54install -m 644 /etc/firejail/cherrytree.profile firejail-$VERSION/etc/firejail/.
55install -m 644 /etc/firejail/chromium-browser.profile firejail-$VERSION/etc/firejail/.
56install -m 644 /etc/firejail/chromium.profile firejail-$VERSION/etc/firejail/.
57install -m 644 /etc/firejail/clementine.profile firejail-$VERSION/etc/firejail/.
58install -m 644 /etc/firejail/cmus.profile firejail-$VERSION/etc/firejail/.
59install -m 644 /etc/firejail/conkeror.profile firejail-$VERSION/etc/firejail/.
60install -m 644 /etc/firejail/corebird.profile firejail-$VERSION/etc/firejail/.
61install -m 644 /etc/firejail/cpio.profile firejail-$VERSION/etc/firejail/.
62install -m 644 /etc/firejail/cyberfox.profile firejail-$VERSION/etc/firejail/.
63install -m 644 /etc/firejail/Cyberfox.profile firejail-$VERSION/etc/firejail/.
64install -m 644 /etc/firejail/deadbeef.profile firejail-$VERSION/etc/firejail/.
65install -m 644 /etc/firejail/default.profile firejail-$VERSION/etc/firejail/.
66install -m 644 /etc/firejail/deluge.profile firejail-$VERSION/etc/firejail/.
67install -m 644 /etc/firejail/dillo.profile firejail-$VERSION/etc/firejail/.
68install -m 644 /etc/firejail/disable-common.inc firejail-$VERSION/etc/firejail/.
69install -m 644 /etc/firejail/disable-devel.inc firejail-$VERSION/etc/firejail/.
70install -m 644 /etc/firejail/disable-passwdmgr.inc firejail-$VERSION/etc/firejail/.
71install -m 644 /etc/firejail/disable-programs.inc firejail-$VERSION/etc/firejail/.
72install -m 644 /etc/firejail/dnscrypt-proxy.profile firejail-$VERSION/etc/firejail/.
73install -m 644 /etc/firejail/dnsmasq.profile firejail-$VERSION/etc/firejail/.
74install -m 644 /etc/firejail/dosbox.profile firejail-$VERSION/etc/firejail/.
75install -m 644 /etc/firejail/dropbox.profile firejail-$VERSION/etc/firejail/.
76install -m 644 /etc/firejail/empathy.profile firejail-$VERSION/etc/firejail/.
77install -m 644 /etc/firejail/eom.profile firejail-$VERSION/etc/firejail/.
78install -m 644 /etc/firejail/epiphany.profile firejail-$VERSION/etc/firejail/.
79install -m 644 /etc/firejail/evince.profile firejail-$VERSION/etc/firejail/.
80install -m 644 /etc/firejail/fbreader.profile firejail-$VERSION/etc/firejail/.
81install -m 644 /etc/firejail/file.profile firejail-$VERSION/etc/firejail/.
82install -m 644 /etc/firejail/filezilla.profile firejail-$VERSION/etc/firejail/.
83install -m 644 /etc/firejail/firefox-esr.profile firejail-$VERSION/etc/firejail/.
84install -m 644 /etc/firejail/firefox.profile firejail-$VERSION/etc/firejail/.
85install -m 644 /etc/firejail/firejail.config firejail-$VERSION/etc/firejail/.
86install -m 644 /etc/firejail/flashpeak-slimjet.profile firejail-$VERSION/etc/firejail/.
87install -m 644 /etc/firejail/franz.profile firejail-$VERSION/etc/firejail/.
88install -m 644 /etc/firejail/gajim.profile firejail-$VERSION/etc/firejail/.
89install -m 644 /etc/firejail/gitter.profile firejail-$VERSION/etc/firejail/.
90install -m 644 /etc/firejail/gnome-chess.profile firejail-$VERSION/etc/firejail/.
91install -m 644 /etc/firejail/gnome-mplayer.profile firejail-$VERSION/etc/firejail/.
92install -m 644 /etc/firejail/google-chrome-beta.profile firejail-$VERSION/etc/firejail/.
93install -m 644 /etc/firejail/google-chrome.profile firejail-$VERSION/etc/firejail/.
94install -m 644 /etc/firejail/google-chrome-stable.profile firejail-$VERSION/etc/firejail/.
95install -m 644 /etc/firejail/google-chrome-unstable.profile firejail-$VERSION/etc/firejail/.
96install -m 644 /etc/firejail/google-play-music-desktop-player.profile firejail-$VERSION/etc/firejail/.
97install -m 644 /etc/firejail/gpredict.profile firejail-$VERSION/etc/firejail/.
98install -m 644 /etc/firejail/gtar.profile firejail-$VERSION/etc/firejail/.
99install -m 644 /etc/firejail/gthumb.profile firejail-$VERSION/etc/firejail/.
100install -m 644 /etc/firejail/gwenview.profile firejail-$VERSION/etc/firejail/.
101install -m 644 /etc/firejail/gzip.profile firejail-$VERSION/etc/firejail/.
102install -m 644 /etc/firejail/hedgewars.profile firejail-$VERSION/etc/firejail/.
103install -m 644 /etc/firejail/hexchat.profile firejail-$VERSION/etc/firejail/.
104install -m 644 /etc/firejail/icecat.profile firejail-$VERSION/etc/firejail/.
105install -m 644 /etc/firejail/icedove.profile firejail-$VERSION/etc/firejail/.
106install -m 644 /etc/firejail/iceweasel.profile firejail-$VERSION/etc/firejail/.
107install -m 644 /etc/firejail/inox.profile firejail-$VERSION/etc/firejail/.
108install -m 644 /etc/firejail/jitsi.profile firejail-$VERSION/etc/firejail/.
109install -m 644 /etc/firejail/kmail.profile firejail-$VERSION/etc/firejail/.
110install -m 644 /etc/firejail/konversation.profile firejail-$VERSION/etc/firejail/.
111install -m 644 /etc/firejail/less.profile firejail-$VERSION/etc/firejail/.
112install -m 644 /etc/firejail/libreoffice.profile firejail-$VERSION/etc/firejail/.
113install -m 644 /etc/firejail/localc.profile firejail-$VERSION/etc/firejail/.
114install -m 644 /etc/firejail/lodraw.profile firejail-$VERSION/etc/firejail/.
115install -m 644 /etc/firejail/loffice.profile firejail-$VERSION/etc/firejail/.
116install -m 644 /etc/firejail/lofromtemplate.profile firejail-$VERSION/etc/firejail/.
117install -m 644 /etc/firejail/login.users firejail-$VERSION/etc/firejail/.
118install -m 644 /etc/firejail/loimpress.profile firejail-$VERSION/etc/firejail/.
119install -m 644 /etc/firejail/lomath.profile firejail-$VERSION/etc/firejail/.
120install -m 644 /etc/firejail/loweb.profile firejail-$VERSION/etc/firejail/.
121install -m 644 /etc/firejail/lowriter.profile firejail-$VERSION/etc/firejail/.
122install -m 644 /etc/firejail/lxterminal.profile firejail-$VERSION/etc/firejail/.
123install -m 644 /etc/firejail/mathematica.profile firejail-$VERSION/etc/firejail/.
124install -m 644 /etc/firejail/Mathematica.profile firejail-$VERSION/etc/firejail/.
125install -m 644 /etc/firejail/mcabber.profile firejail-$VERSION/etc/firejail/.
126install -m 644 /etc/firejail/midori.profile firejail-$VERSION/etc/firejail/.
127install -m 644 /etc/firejail/mpv.profile firejail-$VERSION/etc/firejail/.
128install -m 644 /etc/firejail/mupen64plus.profile firejail-$VERSION/etc/firejail/.
129install -m 644 /etc/firejail/netsurf.profile firejail-$VERSION/etc/firejail/.
130install -m 644 /etc/firejail/nolocal.net firejail-$VERSION/etc/firejail/.
131install -m 644 /etc/firejail/okular.profile firejail-$VERSION/etc/firejail/.
132install -m 644 /etc/firejail/openbox.profile firejail-$VERSION/etc/firejail/.
133install -m 644 /etc/firejail/opera-beta.profile firejail-$VERSION/etc/firejail/.
134install -m 644 /etc/firejail/opera.profile firejail-$VERSION/etc/firejail/.
135install -m 644 /etc/firejail/palemoon.profile firejail-$VERSION/etc/firejail/.
136install -m 644 /etc/firejail/parole.profile firejail-$VERSION/etc/firejail/.
137install -m 644 /etc/firejail/pidgin.profile firejail-$VERSION/etc/firejail/.
138install -m 644 /etc/firejail/pix.profile firejail-$VERSION/etc/firejail/.
139install -m 644 /etc/firejail/polari.profile firejail-$VERSION/etc/firejail/.
140install -m 644 /etc/firejail/psi-plus.profile firejail-$VERSION/etc/firejail/.
141install -m 644 /etc/firejail/qbittorrent.profile firejail-$VERSION/etc/firejail/.
142install -m 644 /etc/firejail/qtox.profile firejail-$VERSION/etc/firejail/.
143install -m 644 /etc/firejail/quassel.profile firejail-$VERSION/etc/firejail/.
144install -m 644 /etc/firejail/quiterss.profile firejail-$VERSION/etc/firejail/.
145install -m 644 /etc/firejail/qutebrowser.profile firejail-$VERSION/etc/firejail/.
146install -m 644 /etc/firejail/rhythmbox.profile firejail-$VERSION/etc/firejail/.
147install -m 644 /etc/firejail/rtorrent.profile firejail-$VERSION/etc/firejail/.
148install -m 644 /etc/firejail/seamonkey-bin.profile firejail-$VERSION/etc/firejail/.
149install -m 644 /etc/firejail/seamonkey.profile firejail-$VERSION/etc/firejail/.
150install -m 644 /etc/firejail/server.profile firejail-$VERSION/etc/firejail/.
151install -m 644 /etc/firejail/skypeforlinux.profile firejail-$VERSION/etc/firejail/.
152install -m 644 /etc/firejail/skype.profile firejail-$VERSION/etc/firejail/.
153install -m 644 /etc/firejail/slack.profile firejail-$VERSION/etc/firejail/.
154install -m 644 /etc/firejail/snap.profile firejail-$VERSION/etc/firejail/.
155install -m 644 /etc/firejail/soffice.profile firejail-$VERSION/etc/firejail/.
156install -m 644 /etc/firejail/spotify.profile firejail-$VERSION/etc/firejail/.
157install -m 644 /etc/firejail/ssh.profile firejail-$VERSION/etc/firejail/.
158install -m 644 /etc/firejail/steam.profile firejail-$VERSION/etc/firejail/.
159install -m 644 /etc/firejail/stellarium.profile firejail-$VERSION/etc/firejail/.
160install -m 644 /etc/firejail/strings.profile firejail-$VERSION/etc/firejail/.
161install -m 644 /etc/firejail/tar.profile firejail-$VERSION/etc/firejail/.
162install -m 644 /etc/firejail/telegram.profile firejail-$VERSION/etc/firejail/.
163install -m 644 /etc/firejail/Telegram.profile firejail-$VERSION/etc/firejail/.
164install -m 644 /etc/firejail/thunderbird.profile firejail-$VERSION/etc/firejail/.
165install -m 644 /etc/firejail/totem.profile firejail-$VERSION/etc/firejail/.
166install -m 644 /etc/firejail/transmission-gtk.profile firejail-$VERSION/etc/firejail/.
167install -m 644 /etc/firejail/transmission-qt.profile firejail-$VERSION/etc/firejail/.
168install -m 644 /etc/firejail/uget-gtk.profile firejail-$VERSION/etc/firejail/.
169install -m 644 /etc/firejail/unbound.profile firejail-$VERSION/etc/firejail/.
170install -m 644 /etc/firejail/unrar.profile firejail-$VERSION/etc/firejail/.
171install -m 644 /etc/firejail/unzip.profile firejail-$VERSION/etc/firejail/.
172install -m 644 /etc/firejail/uudeview.profile firejail-$VERSION/etc/firejail/.
173install -m 644 /etc/firejail/vivaldi-beta.profile firejail-$VERSION/etc/firejail/.
174install -m 644 /etc/firejail/vivaldi.profile firejail-$VERSION/etc/firejail/.
175install -m 644 /etc/firejail/vlc.profile firejail-$VERSION/etc/firejail/.
176install -m 644 /etc/firejail/warzone2100.profile firejail-$VERSION/etc/firejail/.
177install -m 644 /etc/firejail/webserver.net firejail-$VERSION/etc/firejail/.
178install -m 644 /etc/firejail/weechat-curses.profile firejail-$VERSION/etc/firejail/.
179install -m 644 /etc/firejail/weechat.profile firejail-$VERSION/etc/firejail/.
180install -m 644 /etc/firejail/wesnoth.profile firejail-$VERSION/etc/firejail/.
181install -m 644 /etc/firejail/whitelist-common.inc firejail-$VERSION/etc/firejail/.
182install -m 644 /etc/firejail/wine.profile firejail-$VERSION/etc/firejail/.
183install -m 644 /etc/firejail/xchat.profile firejail-$VERSION/etc/firejail/.
184install -m 644 /etc/firejail/xplayer.profile firejail-$VERSION/etc/firejail/.
185install -m 644 /etc/firejail/xreader.profile firejail-$VERSION/etc/firejail/.
186install -m 644 /etc/firejail/xviewer.profile firejail-$VERSION/etc/firejail/.
187install -m 644 /etc/firejail/xzdec.profile firejail-$VERSION/etc/firejail/.
188install -m 644 /etc/firejail/xz.profile firejail-$VERSION/etc/firejail/.
189install -m 644 /etc/firejail/zathura.profile firejail-$VERSION/etc/firejail/.
190install -m 644 /etc/firejail/7z.profile firejail-$VERSION/etc/firejail/.
191install -m 644 /etc/firejail/keepass.profile firejail-$VERSION/etc/firejail/.
192install -m 644 /etc/firejail/keepassx.profile firejail-$VERSION/etc/firejail/.
193install -m 644 /etc/firejail/claws-mail.profile firejail-$VERSION/etc/firejail/.
194install -m 644 /etc/firejail/mutt.profile firejail-$VERSION/etc/firejail/.
195install -m 644 /etc/firejail/git.profile firejail-$VERSION/etc/firejail/.
196install -m 644 /etc/firejail/emacs.profile firejail-$VERSION/etc/firejail/.
197install -m 644 /etc/firejail/vim.profile firejail-$VERSION/etc/firejail/.
198install -m 644 /etc/firejail/xpdf.profile firejail-$VERSION/etc/firejail/.
199install -m 644 /etc/firejail/virtualbox.profile firejail-$VERSION/etc/firejail/.
200install -m 644 /etc/firejail/openshot.profile firejail-$VERSION/etc/firejail/.
201install -m 644 /etc/firejail/flowblade.profile firejail-$VERSION/etc/firejail/.
202install -m 644 /etc/firejail/eog.profile firejail-$VERSION/etc/firejail/.
203install -m 644 /etc/firejail/evolution.profile firejail-$VERSION/etc/firejail/.
204install -m 644 /etc/firejail/feh.profile firejail-$VERSION/etc/firejail/.
205install -m 644 /etc/firejail/gimp.profile firejail-$VERSION/etc/firejail/.
206install -m 644 /etc/firejail/inkscape.profile firejail-$VERSION/etc/firejail/.
207install -m 644 /etc/firejail/luminance-hdr.profile firejail-$VERSION/etc/firejail/.
208install -m 644 /etc/firejail/mupdf.profile firejail-$VERSION/etc/firejail/.
209install -m 644 /etc/firejail/qpdfview.profile firejail-$VERSION/etc/firejail/.
210install -m 644 /etc/firejail/ranger.profile firejail-$VERSION/etc/firejail/.
211install -m 644 /etc/firejail/synfigstudio.profile firejail-$VERSION/etc/firejail/.
212
213
214mkdir -p firejail-$VERSION/usr/share/bash-completion/completions
215install -m 644 /usr/share/bash-completion/completions/firejail firejail-$VERSION/usr/share/bash-completion/completions/.
216install -m 644 /usr/share/bash-completion/completions/firemon firejail-$VERSION/usr/share/bash-completion/completions/.
217install -m 644 /usr/share/bash-completion/completions/firecfg firejail-$VERSION/usr/share/bash-completion/completions/.
218
219echo "building tar.gz archive"
220tar -czvf firejail-$VERSION.tar.gz firejail-$VERSION
221
222cp firejail-$VERSION.tar.gz SOURCES/.
223
224echo "building config spec"
225cat <<EOF > SPECS/firejail.spec
226%define __spec_install_post %{nil}
227%define debug_package %{nil}
228%define __os_install_post %{_dbpath}/brp-compress
229
230Summary: Linux namepaces sandbox program
231Name: firejail
232Version: $VERSION
233Release: 1
234License: GPL+
235Group: Development/Tools
236SOURCE0 : %{name}-%{version}.tar.gz
237URL: http://firejail.wordpress.com
238
239BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
240
241%description
242Firejail is a SUID sandbox program that reduces the risk of security
243breaches by restricting the running environment of untrusted applications
244using Linux namespaces. It includes a sandbox profile for Mozilla Firefox.
245
246%prep
247%setup -q
248
249%build
250
251%install
252rm -rf %{buildroot}
253mkdir -p %{buildroot}
254
255cp -a * %{buildroot}
256
257
258%clean
259rm -rf %{buildroot}
260
261
262%files
263%defattr(-,root,root,-)
264%config(noreplace) %{_sysconfdir}/%{name}/0ad.profile
265%config(noreplace) %{_sysconfdir}/%{name}/abrowser.profile
266%config(noreplace) %{_sysconfdir}/%{name}/atom-beta.profile
267%config(noreplace) %{_sysconfdir}/%{name}/atom.profile
268%config(noreplace) %{_sysconfdir}/%{name}/atril.profile
269%config(noreplace) %{_sysconfdir}/%{name}/audacious.profile
270%config(noreplace) %{_sysconfdir}/%{name}/audacity.profile
271%config(noreplace) %{_sysconfdir}/%{name}/aweather.profile
272%config(noreplace) %{_sysconfdir}/%{name}/bitlbee.profile
273%config(noreplace) %{_sysconfdir}/%{name}/brave.profile
274%config(noreplace) %{_sysconfdir}/%{name}/cherrytree.profile
275%config(noreplace) %{_sysconfdir}/%{name}/chromium-browser.profile
276%config(noreplace) %{_sysconfdir}/%{name}/chromium.profile
277%config(noreplace) %{_sysconfdir}/%{name}/clementine.profile
278%config(noreplace) %{_sysconfdir}/%{name}/cmus.profile
279%config(noreplace) %{_sysconfdir}/%{name}/conkeror.profile
280%config(noreplace) %{_sysconfdir}/%{name}/corebird.profile
281%config(noreplace) %{_sysconfdir}/%{name}/cpio.profile
282%config(noreplace) %{_sysconfdir}/%{name}/cyberfox.profile
283%config(noreplace) %{_sysconfdir}/%{name}/Cyberfox.profile
284%config(noreplace) %{_sysconfdir}/%{name}/deadbeef.profile
285%config(noreplace) %{_sysconfdir}/%{name}/default.profile
286%config(noreplace) %{_sysconfdir}/%{name}/deluge.profile
287%config(noreplace) %{_sysconfdir}/%{name}/dillo.profile
288%config(noreplace) %{_sysconfdir}/%{name}/disable-common.inc
289%config(noreplace) %{_sysconfdir}/%{name}/disable-devel.inc
290%config(noreplace) %{_sysconfdir}/%{name}/disable-passwdmgr.inc
291%config(noreplace) %{_sysconfdir}/%{name}/disable-programs.inc
292%config(noreplace) %{_sysconfdir}/%{name}/dnscrypt-proxy.profile
293%config(noreplace) %{_sysconfdir}/%{name}/dnsmasq.profile
294%config(noreplace) %{_sysconfdir}/%{name}/dosbox.profile
295%config(noreplace) %{_sysconfdir}/%{name}/dropbox.profile
296%config(noreplace) %{_sysconfdir}/%{name}/empathy.profile
297%config(noreplace) %{_sysconfdir}/%{name}/eom.profile
298%config(noreplace) %{_sysconfdir}/%{name}/epiphany.profile
299%config(noreplace) %{_sysconfdir}/%{name}/evince.profile
300%config(noreplace) %{_sysconfdir}/%{name}/fbreader.profile
301%config(noreplace) %{_sysconfdir}/%{name}/file.profile
302%config(noreplace) %{_sysconfdir}/%{name}/filezilla.profile
303%config(noreplace) %{_sysconfdir}/%{name}/firefox-esr.profile
304%config(noreplace) %{_sysconfdir}/%{name}/firefox.profile
305%config(noreplace) %{_sysconfdir}/%{name}/firejail.config
306%config(noreplace) %{_sysconfdir}/%{name}/flashpeak-slimjet.profile
307%config(noreplace) %{_sysconfdir}/%{name}/franz.profile
308%config(noreplace) %{_sysconfdir}/%{name}/gajim.profile
309%config(noreplace) %{_sysconfdir}/%{name}/gitter.profile
310%config(noreplace) %{_sysconfdir}/%{name}/gnome-chess.profile
311%config(noreplace) %{_sysconfdir}/%{name}/gnome-mplayer.profile
312%config(noreplace) %{_sysconfdir}/%{name}/google-chrome-beta.profile
313%config(noreplace) %{_sysconfdir}/%{name}/google-chrome.profile
314%config(noreplace) %{_sysconfdir}/%{name}/google-chrome-stable.profile
315%config(noreplace) %{_sysconfdir}/%{name}/google-chrome-unstable.profile
316%config(noreplace) %{_sysconfdir}/%{name}/google-play-music-desktop-player.profile
317%config(noreplace) %{_sysconfdir}/%{name}/gpredict.profile
318%config(noreplace) %{_sysconfdir}/%{name}/gtar.profile
319%config(noreplace) %{_sysconfdir}/%{name}/gthumb.profile
320%config(noreplace) %{_sysconfdir}/%{name}/gwenview.profile
321%config(noreplace) %{_sysconfdir}/%{name}/gzip.profile
322%config(noreplace) %{_sysconfdir}/%{name}/hedgewars.profile
323%config(noreplace) %{_sysconfdir}/%{name}/hexchat.profile
324%config(noreplace) %{_sysconfdir}/%{name}/icecat.profile
325%config(noreplace) %{_sysconfdir}/%{name}/icedove.profile
326%config(noreplace) %{_sysconfdir}/%{name}/iceweasel.profile
327%config(noreplace) %{_sysconfdir}/%{name}/inox.profile
328%config(noreplace) %{_sysconfdir}/%{name}/jitsi.profile
329%config(noreplace) %{_sysconfdir}/%{name}/kmail.profile
330%config(noreplace) %{_sysconfdir}/%{name}/konversation.profile
331%config(noreplace) %{_sysconfdir}/%{name}/less.profile
332%config(noreplace) %{_sysconfdir}/%{name}/libreoffice.profile
333%config(noreplace) %{_sysconfdir}/%{name}/localc.profile
334%config(noreplace) %{_sysconfdir}/%{name}/lodraw.profile
335%config(noreplace) %{_sysconfdir}/%{name}/loffice.profile
336%config(noreplace) %{_sysconfdir}/%{name}/lofromtemplate.profile
337%config(noreplace) %{_sysconfdir}/%{name}/login.users
338%config(noreplace) %{_sysconfdir}/%{name}/loimpress.profile
339%config(noreplace) %{_sysconfdir}/%{name}/lomath.profile
340%config(noreplace) %{_sysconfdir}/%{name}/loweb.profile
341%config(noreplace) %{_sysconfdir}/%{name}/lowriter.profile
342%config(noreplace) %{_sysconfdir}/%{name}/lxterminal.profile
343%config(noreplace) %{_sysconfdir}/%{name}/mathematica.profile
344%config(noreplace) %{_sysconfdir}/%{name}/Mathematica.profile
345%config(noreplace) %{_sysconfdir}/%{name}/mcabber.profile
346%config(noreplace) %{_sysconfdir}/%{name}/midori.profile
347%config(noreplace) %{_sysconfdir}/%{name}/mpv.profile
348%config(noreplace) %{_sysconfdir}/%{name}/mupen64plus.profile
349%config(noreplace) %{_sysconfdir}/%{name}/netsurf.profile
350%config(noreplace) %{_sysconfdir}/%{name}/nolocal.net
351%config(noreplace) %{_sysconfdir}/%{name}/okular.profile
352%config(noreplace) %{_sysconfdir}/%{name}/openbox.profile
353%config(noreplace) %{_sysconfdir}/%{name}/opera-beta.profile
354%config(noreplace) %{_sysconfdir}/%{name}/opera.profile
355%config(noreplace) %{_sysconfdir}/%{name}/palemoon.profile
356%config(noreplace) %{_sysconfdir}/%{name}/parole.profile
357%config(noreplace) %{_sysconfdir}/%{name}/pidgin.profile
358%config(noreplace) %{_sysconfdir}/%{name}/pix.profile
359%config(noreplace) %{_sysconfdir}/%{name}/polari.profile
360%config(noreplace) %{_sysconfdir}/%{name}/psi-plus.profile
361%config(noreplace) %{_sysconfdir}/%{name}/qbittorrent.profile
362%config(noreplace) %{_sysconfdir}/%{name}/qtox.profile
363%config(noreplace) %{_sysconfdir}/%{name}/quassel.profile
364%config(noreplace) %{_sysconfdir}/%{name}/quiterss.profile
365%config(noreplace) %{_sysconfdir}/%{name}/qutebrowser.profile
366%config(noreplace) %{_sysconfdir}/%{name}/rhythmbox.profile
367%config(noreplace) %{_sysconfdir}/%{name}/rtorrent.profile
368%config(noreplace) %{_sysconfdir}/%{name}/seamonkey-bin.profile
369%config(noreplace) %{_sysconfdir}/%{name}/seamonkey.profile
370%config(noreplace) %{_sysconfdir}/%{name}/server.profile
371%config(noreplace) %{_sysconfdir}/%{name}/skypeforlinux.profile
372%config(noreplace) %{_sysconfdir}/%{name}/skype.profile
373%config(noreplace) %{_sysconfdir}/%{name}/slack.profile
374%config(noreplace) %{_sysconfdir}/%{name}/snap.profile
375%config(noreplace) %{_sysconfdir}/%{name}/soffice.profile
376%config(noreplace) %{_sysconfdir}/%{name}/spotify.profile
377%config(noreplace) %{_sysconfdir}/%{name}/ssh.profile
378%config(noreplace) %{_sysconfdir}/%{name}/steam.profile
379%config(noreplace) %{_sysconfdir}/%{name}/stellarium.profile
380%config(noreplace) %{_sysconfdir}/%{name}/strings.profile
381%config(noreplace) %{_sysconfdir}/%{name}/tar.profile
382%config(noreplace) %{_sysconfdir}/%{name}/telegram.profile
383%config(noreplace) %{_sysconfdir}/%{name}/Telegram.profile
384%config(noreplace) %{_sysconfdir}/%{name}/thunderbird.profile
385%config(noreplace) %{_sysconfdir}/%{name}/totem.profile
386%config(noreplace) %{_sysconfdir}/%{name}/transmission-gtk.profile
387%config(noreplace) %{_sysconfdir}/%{name}/transmission-qt.profile
388%config(noreplace) %{_sysconfdir}/%{name}/uget-gtk.profile
389%config(noreplace) %{_sysconfdir}/%{name}/unbound.profile
390%config(noreplace) %{_sysconfdir}/%{name}/unrar.profile
391%config(noreplace) %{_sysconfdir}/%{name}/unzip.profile
392%config(noreplace) %{_sysconfdir}/%{name}/uudeview.profile
393%config(noreplace) %{_sysconfdir}/%{name}/vivaldi-beta.profile
394%config(noreplace) %{_sysconfdir}/%{name}/vivaldi.profile
395%config(noreplace) %{_sysconfdir}/%{name}/vlc.profile
396%config(noreplace) %{_sysconfdir}/%{name}/warzone2100.profile
397%config(noreplace) %{_sysconfdir}/%{name}/webserver.net
398%config(noreplace) %{_sysconfdir}/%{name}/weechat-curses.profile
399%config(noreplace) %{_sysconfdir}/%{name}/weechat.profile
400%config(noreplace) %{_sysconfdir}/%{name}/wesnoth.profile
401%config(noreplace) %{_sysconfdir}/%{name}/whitelist-common.inc
402%config(noreplace) %{_sysconfdir}/%{name}/wine.profile
403%config(noreplace) %{_sysconfdir}/%{name}/xchat.profile
404%config(noreplace) %{_sysconfdir}/%{name}/xplayer.profile
405%config(noreplace) %{_sysconfdir}/%{name}/xreader.profile
406%config(noreplace) %{_sysconfdir}/%{name}/xviewer.profile
407%config(noreplace) %{_sysconfdir}/%{name}/xzdec.profile
408%config(noreplace) %{_sysconfdir}/%{name}/xz.profile
409%config(noreplace) %{_sysconfdir}/%{name}/zathura.profile
410%config(noreplace) %{_sysconfdir}/%{name}/7z.profile
411%config(noreplace) %{_sysconfdir}/%{name}/keepass.profile
412%config(noreplace) %{_sysconfdir}/%{name}/keepassx.profile
413%config(noreplace) %{_sysconfdir}/%{name}/claws-mail.profile
414%config(noreplace) %{_sysconfdir}/%{name}/mutt.profile
415%config(noreplace) %{_sysconfdir}/%{name}/git.profile
416%config(noreplace) %{_sysconfdir}/%{name}/emacs.profile
417%config(noreplace) %{_sysconfdir}/%{name}/vim.profile
418%config(noreplace) %{_sysconfdir}/%{name}/xpdf.profile
419%config(noreplace) %{_sysconfdir}/%{name}/virtualbox.profile
420%config(noreplace) %{_sysconfdir}/%{name}/openshot.profile
421%config(noreplace) %{_sysconfdir}/%{name}/flowblade.profile
422%config(noreplace) %{_sysconfdir}/%{name}/eog.profile
423%config(noreplace) %{_sysconfdir}/%{name}/evolution.profile
424%config(noreplace) %{_sysconfdir}/%{name}/feh.profile
425%config(noreplace) %{_sysconfdir}/%{name}/inkscape.profile
426%config(noreplace) %{_sysconfdir}/%{name}/gimp.profile
427%config(noreplace) %{_sysconfdir}/%{name}/luminance-hdr.profile
428%config(noreplace) %{_sysconfdir}/%{name}/mupdf.profile
429%config(noreplace) %{_sysconfdir}/%{name}/qpdfview.profile
430%config(noreplace) %{_sysconfdir}/%{name}/ranger.profile
431%config(noreplace) %{_sysconfdir}/%{name}/synfigstudio.profile
432
433/usr/bin/firejail
434/usr/bin/firemon
435/usr/bin/firecfg
436
437/usr/lib/firejail/libtrace.so
438/usr/lib/firejail/libtracelog.so
439/usr/lib/firejail/libconnect.so
440/usr/lib/firejail/faudit
441/usr/lib/firejail/ftee
442/usr/lib/firejail/firecfg.config
443/usr/lib/firejail/fshaper.sh
444
445/usr/share/doc/packages/firejail/COPYING
446/usr/share/doc/packages/firejail/README
447/usr/share/doc/packages/firejail/RELNOTES
448/usr/share/man/man1/firejail.1.gz
449/usr/share/man/man1/firemon.1.gz
450/usr/share/man/man1/firecfg.1.gz
451/usr/share/man/man5/firejail-profile.5.gz
452/usr/share/man/man5/firejail-login.5.gz
453/usr/share/bash-completion/completions/firejail
454/usr/share/bash-completion/completions/firemon
455/usr/share/bash-completion/completions/firecfg
456
457%post
458chmod u+s /usr/bin/firejail
459
460%changelog
461* Fri Oct 21 2016 netblue30 <netblue30@yahoo.com> 0.9.44-1
462 - CVE-2016-7545 submitted by Aleksey Manevich
463 - modifs: removed man firejail-config
464 - modifs: --private-tmp whitelists /tmp/.X11-unix directory
465 - modifs: Nvidia drivers added to --private-dev
466 - modifs: /srv supported by --whitelist
467 - feature: allow user access to /sys/fs (--noblacklist=/sys/fs)
468 - feature: support starting/joining sandbox is a single command
469 (--join-or-start)
470 - feature: X11 detection support for --audit
471 - feature: assign a name to the interface connected to the bridge
472 (--veth-name)
473 - feature: all user home directories are visible (--allusers)
474 - feature: add files to sandbox container (--put)
475 - feature: blocking x11 (--x11=block)
476 - feature: X11 security extension (--x11=xorg)
477 - feature: disable 3D hardware acceleration (--no3d)
478 - feature: x11 xpra, x11 xephyr, x11 block, allusers, no3d profile commands
479 - feature: move files in sandbox (--put)
480 - feature: accept wildcard patterns in user name field of restricted
481 shell login feature
482 - new profiles: qpdfview, mupdf, Luminance HDR, Synfig Studio, Gimp, Inkscape
483 - new profiles: feh, ranger, zathura, 7z, keepass, keepassx,
484 - new profiles: claws-mail, mutt, git, emacs, vim, xpdf, VirtualBox, OpenShot
485 - new profiles: Flowblade, Eye of GNOME (eog), Evolution
486 - bugfixes
487
488* Thu Sep 8 2016 netblue30 <netblue30@yahoo.com> 0.9.42-1
489 - security: --whitelist deleted files, submitted by Vasya Novikov
490 - security: disable x32 ABI in seccomp, submitted by Jann Horn
491 - security: tighten --chroot, submitted by Jann Horn
492 - security: terminal sandbox escape, submitted by Stephan Sokolow
493 - security: several TOCTOU fixes submitted by Aleksey Manevich
494 - modifs: bringing back --private-home option
495 - modifs: deprecated --user option, please use "sudo -u username firejail"
496 - modifs: allow symlinks in home directory for --whitelist option
497 - modifs: Firejail prompt is enabled by env variable FIREJAIL_PROMPT="yes"
498 - modifs: recursive mkdir
499 - modifs: include /dev/snd in --private-dev
500 - modifs: seccomp filter update
501 - modifs: release archives moved to .xz format
502 - feature: AppImage support (--appimage)
503 - feature: AppArmor support (--apparmor)
504 - feature: Ubuntu snap support (/etc/firejail/snap.profile)
505 - feature: Sandbox auditing support (--audit)
506 - feature: remove environment variable (--rmenv)
507 - feature: noexec support (--noexec)
508 - feature: clean local overlay storage directory (--overlay-clean)
509 - feature: store and reuse overlay (--overlay-named)
510 - feature: allow debugging inside the sandbox with gdb and strace
511 (--allow-debuggers)
512 - feature: mkfile profile command
513 - feature: quiet profile command
514 - feature: x11 profile command
515 - feature: option to fix desktop files (firecfg --fix)
516 - compile time: Busybox support (--enable-busybox-workaround)
517 - compile time: disable overlayfs (--disable-overlayfs)
518 - compile time: disable whitlisting (--disable-whitelist)
519 - compile time: disable global config (--disable-globalcfg)
520 - run time: enable/disable overlayfs (overlayfs yes/no)
521 - run time: enable/disable quiet as default (quiet-by-default yes/no)
522 - run time: user-defined network filter (netfilter-default)
523 - run time: enable/disable whitelisting (whitelist yes/no)
524 - run time: enable/disable remounting of /proc and /sys
525 (remount-proc-sys yes/no)
526 - run time: enable/disable chroot desktop features (chroot-desktop yes/no)
527 - profiles: Gitter, gThumb, mpv, Franz messenger, LibreOffice
528 - profiles: pix, audacity, xz, xzdec, gzip, cpio, less
529 - profiles: Atom Beta, Atom, jitsi, eom, uudeview
530 - profiles: tar (gtar), unzip, unrar, file, skypeforlinux,
531 - profiles: inox, Slack, gnome-chess. Gajim IM client, DOSBox
532 - bugfixes
533
534EOF
535
536echo "building rpm"
537rpmbuild -ba SPECS/firejail.spec
538rpm -qpl RPMS/x86_64/firejail-$VERSION-1.x86_64.rpm
539cd ..
540rm -f firejail-$VERSION-1.x86_64.rpm
541cp rpmbuild/RPMS/x86_64/firejail-$VERSION-1.x86_64.rpm .
542
diff --git a/platform/snap/snap.sh b/platform/snap/snap.sh
new file mode 100755
index 000000000..d7f924293
--- /dev/null
+++ b/platform/snap/snap.sh
@@ -0,0 +1,20 @@
1#!/bin/bash
2
3rm -fr faudit-snap
4rm -f faudit_*.snap
5mkdir faudit-snap
6cd faudit-snap
7snapcraft init
8cp ../snapcraft.yaml .
9#snapcraft stage
10mkdir -p stage/usr/lib/firejail
11cp ../../../src/faudit/faudit stage/usr/lib/firejail/.
12find stage
13snapcraft stage
14snapcraft snap
15cd ..
16mv faudit-snap/faudit_*.snap ../../.
17rm -fr faudit-snap
18
19
20
diff --git a/platform/snap/snapcraft.yaml b/platform/snap/snapcraft.yaml
new file mode 100644
index 000000000..7b04a2ca1
--- /dev/null
+++ b/platform/snap/snapcraft.yaml
@@ -0,0 +1,21 @@
1name: faudit # the name of the snap
2version: 0 # the version of the snap
3summary: Fireajail audit snap edition # 79 char long summary
4description: faudit program extracted from Firejail and packaged as a snap # a longer description for the snap
5confinement: strict # use "strict" to enforce system access only via declared interfaces
6
7apps:
8 faudit:
9 command: /usr/lib/firejail/faudit
10
11parts:
12 faudit: # Replace with a part name of your liking
13 # Get more information about plugins by running
14 # snapcraft help plugins
15 # and more information about the available plugins
16 # by running
17 # snapcraft list-plugins
18 plugin: nil
19 snap:
20 - usr/lib/firejail/faudit
21
diff --git a/src/bash_completion/firejail.bash_completion b/src/bash_completion/firejail.bash_completion
index 21e28c98b..d3dcd57d0 100644
--- a/src/bash_completion/firejail.bash_completion
+++ b/src/bash_completion/firejail.bash_completion
@@ -47,6 +47,10 @@ _firejail()
47 _filedir 47 _filedir
48 return 0 48 return 0
49 ;; 49 ;;
50 --read-write)
51 _filedir
52 return 0
53 ;;
50 --bind) 54 --bind)
51 _filedir 55 _filedir
52 return 0 56 return 0
@@ -63,6 +67,10 @@ _firejail()
63 _filedir 67 _filedir
64 return 0 68 return 0
65 ;; 69 ;;
70 --audit)
71 _filedir
72 return 0
73 ;;
66 --net) 74 --net)
67 comps=$(__interfaces) 75 comps=$(__interfaces)
68 COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) 76 COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
diff --git a/src/faudit/Makefile.in b/src/faudit/Makefile.in
new file mode 100644
index 000000000..995a0bf49
--- /dev/null
+++ b/src/faudit/Makefile.in
@@ -0,0 +1,25 @@
1all: faudit
2
3PREFIX=@prefix@
4VERSION=@PACKAGE_VERSION@
5NAME=@PACKAGE_NAME@
6HAVE_FATAL_WARNINGS=@HAVE_FATAL_WARNINGS@
7
8H_FILE_LIST = $(sort $(wildcard *.[h]))
9C_FILE_LIST = $(sort $(wildcard *.c))
10OBJS = $(C_FILE_LIST:.c=.o)
11BINOBJS = $(foreach file, $(OBJS), $file)
12CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -DPREFIX='"$(PREFIX)"' -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security
13LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread
14
15%.o : %.c $(H_FILE_LIST)
16 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
17
18faudit: $(OBJS)
19 $(CC) $(LDFLAGS) -o $@ $(OBJS)
20
21clean:; rm -f *.o faudit
22
23distclean: clean
24 rm -fr Makefile
25
diff --git a/src/faudit/caps.c b/src/faudit/caps.c
new file mode 100644
index 000000000..d4a62b34f
--- /dev/null
+++ b/src/faudit/caps.c
@@ -0,0 +1,79 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20
21#include "faudit.h"
22#include <linux/capability.h>
23
24#define MAXBUF 4098
25static int extract_caps(uint64_t *val) {
26 FILE *fp = fopen("/proc/self/status", "r");
27 if (!fp)
28 return 1;
29
30 char buf[MAXBUF];
31 while (fgets(buf, MAXBUF, fp)) {
32 if (strncmp(buf, "CapBnd:\t", 8) == 0) {
33 char *ptr = buf + 8;
34 unsigned long long tmp;
35 sscanf(ptr, "%llx", &tmp);
36 *val = tmp;
37 fclose(fp);
38 return 0;
39 }
40 }
41
42 fclose(fp);
43 return 1;
44}
45
46// return 1 if the capability is in tbe map
47static int check_capability(uint64_t map, int cap) {
48 int i;
49 uint64_t mask = 1ULL;
50
51 for (i = 0; i < 64; i++, mask <<= 1) {
52 if ((i == cap) && (mask & map))
53 return 1;
54 }
55
56 return 0;
57}
58
59void caps_test(void) {
60 uint64_t caps_val;
61
62 if (extract_caps(&caps_val)) {
63 printf("SKIP: cannot extract capabilities on this platform.\n");
64 return;
65 }
66
67 if (caps_val) {
68 printf("BAD: the capability map is %llx, it should be all zero. ", (unsigned long long) caps_val);
69 printf("Use \"firejail --caps.drop=all\" to fix it.\n");
70
71 if (check_capability(caps_val, CAP_SYS_ADMIN))
72 printf("UGLY: CAP_SYS_ADMIN is enabled.\n");
73 if (check_capability(caps_val, CAP_SYS_BOOT))
74 printf("UGLY: CAP_SYS_BOOT is enabled.\n");
75 }
76 else
77 printf("GOOD: all capabilities are disabled.\n");
78}
79
diff --git a/src/faudit/dbus.c b/src/faudit/dbus.c
new file mode 100644
index 000000000..4debf2ff6
--- /dev/null
+++ b/src/faudit/dbus.c
@@ -0,0 +1,95 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "faudit.h"
21#include <sys/socket.h>
22#include <sys/un.h>
23
24// return 0 if the connection is possible
25int check_unix(const char *sockfile) {
26 assert(sockfile);
27 int rv = -1;
28
29 // open socket
30 int sock = socket(AF_UNIX, SOCK_STREAM, 0);
31 if (sock == -1)
32 return rv;
33
34 // connect
35 struct sockaddr_un remote;
36 memset(&remote, 0, sizeof(struct sockaddr_un));
37 remote.sun_family = AF_UNIX;
38 strcpy(remote.sun_path, sockfile);
39 int len = strlen(remote.sun_path) + sizeof(remote.sun_family);
40 if (*sockfile == '@')
41 remote.sun_path[0] = '\0';
42 if (connect(sock, (struct sockaddr *)&remote, len) == 0)
43 rv = 0;
44
45 close(sock);
46 return rv;
47}
48
49void dbus_test(void) {
50 // check the session bus
51 char *str = getenv("DBUS_SESSION_BUS_ADDRESS");
52 if (str) {
53 int rv = 0;
54 char *bus = strdup(str);
55 if (!bus)
56 errExit("strdup");
57 char *sockfile;
58 if ((sockfile = strstr(bus, "unix:abstract=")) != NULL) {
59 sockfile += 13;
60 *sockfile = '@';
61 char *ptr = strchr(sockfile, ',');
62 if (ptr)
63 *ptr = '\0';
64 rv = check_unix(sockfile);
65 *sockfile = '@';
66 if (rv == 0)
67 printf("MAYBE: D-Bus socket %s is available\n", sockfile);
68 else if (rv == -1)
69 printf("GOOD: cannot connect to D-Bus socket %s\n", sockfile);
70 }
71 else if ((sockfile = strstr(bus, "unix:path=")) != NULL) {
72 sockfile += 10;
73 char *ptr = strchr(sockfile, ',');
74 if (ptr)
75 *ptr = '\0';
76 rv = check_unix(sockfile);
77 if (rv == 0)
78 printf("MAYBE: D-Bus socket %s is available\n", sockfile);
79 else if (rv == -1)
80 printf("GOOD: cannot connect to D-Bus socket %s\n", sockfile);
81 }
82 else if ((sockfile = strstr(bus, "tcp:host=")) != NULL)
83 printf("UGLY: session bus configured for TCP communication.\n");
84 else
85 printf("GOOD: cannot find a D-Bus socket\n");
86
87
88 free(bus);
89 }
90 else
91 printf("GOOD: DBUS_SESSION_BUS_ADDRESS environment variable not configured.");
92}
93
94
95
diff --git a/src/faudit/dev.c b/src/faudit/dev.c
new file mode 100644
index 000000000..92f615958
--- /dev/null
+++ b/src/faudit/dev.c
@@ -0,0 +1,47 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "faudit.h"
21#include <dirent.h>
22
23void dev_test(void) {
24 DIR *dir;
25 if (!(dir = opendir("/dev"))) {
26 fprintf(stderr, "Error: cannot open /dev directory\n");
27 return;
28 }
29
30 struct dirent *entry;
31 printf("INFO: files visible in /dev directory: ");
32 int cnt = 0;
33 while ((entry = readdir(dir)) != NULL) {
34 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
35 continue;
36
37 printf("%s, ", entry->d_name);
38 cnt++;
39 }
40 printf("\n");
41
42 if (cnt > 20)
43 printf("MAYBE: /dev directory seems to be fully populated. Use --private-dev or --whitelist to restrict the access.\n");
44 else
45 printf("GOOD: Access to /dev directory is restricted.\n");
46 closedir(dir);
47}
diff --git a/src/faudit/faudit.h b/src/faudit/faudit.h
new file mode 100644
index 000000000..17c754c3b
--- /dev/null
+++ b/src/faudit/faudit.h
@@ -0,0 +1,68 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20
21#ifndef FAUDIT_H
22#define FAUDIT_H
23#define _GNU_SOURCE
24#include <stdio.h>
25#include <stdlib.h>
26#include <stdint.h>
27#include <string.h>
28#include <unistd.h>
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <sys/mount.h>
32#include <assert.h>
33
34#define errExit(msg) do { char msgout[500]; sprintf(msgout, "Error %s:%s(%d)", msg, __FUNCTION__, __LINE__); perror(msgout); exit(1);} while (0)
35
36// main.c
37extern char *prog;
38
39// pid.c
40void pid_test(void);
41
42// caps.c
43void caps_test(void);
44
45// seccomp.c
46void seccomp_test(void);
47
48// syscall.c
49void syscall_helper(int argc, char **argv);
50void syscall_run(const char *name);
51
52// files.c
53void files_test(void);
54
55// network.c
56void network_test(void);
57
58// dbus.c
59int check_unix(const char *sockfile);
60void dbus_test(void);
61
62// dev.c
63void dev_test(void);
64
65// x11.c
66void x11_test(void);
67
68#endif
diff --git a/src/faudit/files.c b/src/faudit/files.c
new file mode 100644
index 000000000..67b43f22b
--- /dev/null
+++ b/src/faudit/files.c
@@ -0,0 +1,75 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "faudit.h"
21#include <fcntl.h>
22#include <pwd.h>
23
24static char *username = NULL;
25static char *homedir = NULL;
26
27static void check_home_file(const char *name) {
28 assert(homedir);
29
30 char *fname;
31 if (asprintf(&fname, "%s/%s", homedir, name) == -1)
32 errExit("asprintf");
33
34 if (access(fname, R_OK) == 0) {
35 printf("UGLY: I can access files in %s directory. ", fname);
36 printf("Use \"firejail --blacklist=%s\" to block it.\n", fname);
37 }
38 else
39 printf("GOOD: I cannot access files in %s directory.\n", fname);
40
41 free(fname);
42}
43
44void files_test(void) {
45 struct passwd *pw = getpwuid(getuid());
46 if (!pw) {
47 fprintf(stderr, "Error: cannot retrieve user account information\n");
48 return;
49 }
50
51 username = strdup(pw->pw_name);
52 if (!username)
53 errExit("strdup");
54 homedir = strdup(pw->pw_dir);
55 if (!homedir)
56 errExit("strdup");
57
58 // check access to .ssh directory
59 check_home_file(".ssh");
60
61 // check access to .gnupg directory
62 check_home_file(".gnupg");
63
64 // check access to Firefox browser directory
65 check_home_file(".mozilla");
66
67 // check access to Chromium browser directory
68 check_home_file(".config/chromium");
69
70 // check access to Debian Icedove directory
71 check_home_file(".icedove");
72
73 // check access to Thunderbird directory
74 check_home_file(".thunderbird");
75}
diff --git a/src/faudit/main.c b/src/faudit/main.c
new file mode 100644
index 000000000..7f47ccaf0
--- /dev/null
+++ b/src/faudit/main.c
@@ -0,0 +1,98 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "faudit.h"
21char *prog;
22
23int main(int argc, char **argv) {
24 // make test-arguments helper
25 if (getenv("FIREJAIL_TEST_ARGUMENTS")) {
26 printf("Arguments:\n");
27
28 int i;
29 for (i = 0; i < argc; i++) {
30 printf("#%s#\n", argv[i]);
31 }
32
33 return 0;
34 }
35
36
37 if (argc != 1) {
38 int i;
39
40 for (i = 1; i < argc; i++) {
41 if (strcmp(argv[i], "syscall")) {
42 syscall_helper(argc, argv);
43 return 0;
44 }
45 }
46 return 1;
47 }
48
49 printf("\n---------------- Firejail Audit: the GOOD, the BAD and the UGLY ----------------\n");
50
51 // extract program name
52 prog = realpath(argv[0], NULL);
53 if (prog == NULL) {
54 prog = strdup("faudit");
55 if (!prog)
56 errExit("strdup");
57 }
58 printf("INFO: starting %s.\n", prog);
59
60
61 // check pid namespace
62 pid_test();
63 printf("\n");
64
65 // check seccomp
66 seccomp_test();
67 printf("\n");
68
69 // check capabilities
70 caps_test();
71 printf("\n");
72
73 // check some well-known problematic files and directories
74 files_test();
75 printf("\n");
76
77 // network
78 network_test();
79 printf("\n");
80
81 // dbus
82 dbus_test();
83 printf("\n");
84
85 // x11 test
86 x11_test();
87 printf("\n");
88
89 // /dev test
90 dev_test();
91 printf("\n");
92
93
94 free(prog);
95 printf("--------------------------------------------------------------------------------\n");
96
97 return 0;
98}
diff --git a/src/faudit/network.c b/src/faudit/network.c
new file mode 100644
index 000000000..cf1eede69
--- /dev/null
+++ b/src/faudit/network.c
@@ -0,0 +1,101 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "faudit.h"
21#include <sys/socket.h>
22#include <arpa/inet.h>
23#include <linux/netlink.h>
24#include <linux/rtnetlink.h>
25
26static void check_ssh(void) {
27 // open socket
28 int sock = socket(AF_INET, SOCK_STREAM, 0);
29 if (sock == -1) {
30 printf("GOOD: SSH server not available on localhost.\n");
31 return;
32 }
33
34 // connect to localhost
35 struct sockaddr_in server;
36 server.sin_addr.s_addr = inet_addr("127.0.0.1");
37 server.sin_family = AF_INET;
38 server.sin_port = htons(22);
39
40 if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
41 printf("GOOD: SSH server not available on localhost.\n");
42 else {
43 printf("MAYBE: an SSH server is accessible on localhost. ");
44 printf("It could be a good idea to create a new network namespace using \"--net=none\" or \"--net=eth0\".\n");
45 }
46
47 close(sock);
48}
49
50static void check_http(void) {
51 // open socket
52 int sock = socket(AF_INET, SOCK_STREAM, 0);
53 if (sock == -1) {
54 printf("GOOD: HTTP server not available on localhost.\n");
55 return;
56 }
57
58 // connect to localhost
59 struct sockaddr_in server;
60 server.sin_addr.s_addr = inet_addr("127.0.0.1");
61 server.sin_family = AF_INET;
62 server.sin_port = htons(80);
63
64 if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
65 printf("GOOD: HTTP server not available on localhost.\n");
66 else {
67 printf("MAYBE: an HTTP server is accessible on localhost. ");
68 printf("It could be a good idea to create a new network namespace using \"--net=none\" or \"--net=eth0\".\n");
69 }
70
71 close(sock);
72}
73
74void check_netlink(void) {
75 int sock = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, 0);
76 if (sock == -1) {
77 printf("GOOD: I cannot connect to netlink socket. Network utilities such as iproute2 will not work in the sandbox.\n");
78 return;
79 }
80
81 struct sockaddr_nl local;
82 memset(&local, 0, sizeof(local));
83 local.nl_family = AF_NETLINK;
84 local.nl_groups = 0; //subscriptions;
85
86 if (bind(sock, (struct sockaddr*)&local, sizeof(local)) < 0) {
87 printf("GOOD: I cannot connect to netlink socket. Network utilities such as iproute2 will not work in the sandbox.\n");
88 close(sock);
89 return;
90 }
91
92 close(sock);
93 printf("MAYBE: I can connect to netlink socket. Network utilities such as iproute2 will work fine in the sandbox. ");
94 printf("You can use \"--protocol\" to disable the socket.\n");
95}
96
97void network_test(void) {
98 check_ssh();
99 check_http();
100 check_netlink();
101}
diff --git a/src/faudit/pid.c b/src/faudit/pid.c
new file mode 100644
index 000000000..a0fb1d921
--- /dev/null
+++ b/src/faudit/pid.c
@@ -0,0 +1,101 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "faudit.h"
21
22void pid_test(void) {
23 char *kern_proc[] = {
24 "kthreadd",
25 "ksoftirqd",
26 "kworker",
27 "rcu_sched",
28 "rcu_bh",
29 NULL // NULL terminated list
30 };
31 int i;
32
33 // look at the first 10 processes
34 int not_visible = 1;
35 for (i = 1; i <= 10; i++) {
36 struct stat s;
37 char *fname;
38 if (asprintf(&fname, "/proc/%d/comm", i) == -1)
39 errExit("asprintf");
40 if (stat(fname, &s) == -1) {
41 free(fname);
42 continue;
43 }
44
45 // open file
46 /* coverity[toctou] */
47 FILE *fp = fopen(fname, "r");
48 if (!fp) {
49// fprintf(stderr, "Warning: cannot open %s\n", fname);
50 free(fname);
51 continue;
52 }
53
54 // read file
55 char buf[100];
56 if (fgets(buf, 10, fp) == NULL) {
57// fprintf(stderr, "Warning: cannot read %s\n", fname);
58 fclose(fp);
59 free(fname);
60 continue;
61 }
62 not_visible = 0;
63
64 // clean /n
65 char *ptr;
66 if ((ptr = strchr(buf, '\n')) != NULL)
67 *ptr = '\0';
68
69 // check process name against the kernel list
70 int j = 0;
71 while (kern_proc[j] != NULL) {
72 if (strncmp(buf, kern_proc[j], strlen(kern_proc[j])) == 0) {
73 fclose(fp);
74 free(fname);
75 printf("BAD: Process %d is not running in a PID namespace. ", getpid());
76 printf("Are you sure you're running in a sandbox?\n");
77 return;
78 }
79 j++;
80 }
81
82 fclose(fp);
83 free(fname);
84 }
85
86 pid_t pid = getpid();
87 if (not_visible && pid > 100)
88 printf("BAD: Process %d is not running in a PID namespace.\n", pid);
89 else
90 printf("GOOD: process %d is running in a PID namespace.\n", pid);
91
92 // try to guess the type of container/sandbox
93 char *str = getenv("container");
94 if (str)
95 printf("INFO: container/sandbox %s.\n", str);
96 else {
97 str = getenv("SNAP");
98 if (str)
99 printf("INFO: this is a snap package\n");
100 }
101}
diff --git a/src/faudit/seccomp.c b/src/faudit/seccomp.c
new file mode 100644
index 000000000..7b2999467
--- /dev/null
+++ b/src/faudit/seccomp.c
@@ -0,0 +1,101 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "faudit.h"
21
22#define MAXBUF 4098
23static int extract_seccomp(int *val) {
24 FILE *fp = fopen("/proc/self/status", "r");
25 if (!fp)
26 return 1;
27
28 char buf[MAXBUF];
29 while (fgets(buf, MAXBUF, fp)) {
30 if (strncmp(buf, "Seccomp:\t", 8) == 0) {
31 char *ptr = buf + 8;
32 int tmp;
33 sscanf(ptr, "%d", &tmp);
34 *val = tmp;
35 fclose(fp);
36 return 0;
37 }
38 }
39
40 fclose(fp);
41 return 1;
42}
43
44void seccomp_test(void) {
45 int seccomp_status;
46 int rv = extract_seccomp(&seccomp_status);
47
48 if (rv) {
49 printf("INFO: cannot extract seccomp configuration on this platform.\n");
50 return;
51 }
52
53 if (seccomp_status == 0) {
54 printf("BAD: seccomp disabled. Use \"firejail --seccomp\" to enable it.\n");
55 }
56 else if (seccomp_status == 1)
57 printf("GOOD: seccomp strict mode - only read, write, _exit, and sigreturn are allowd.\n");
58 else if (seccomp_status == 2) {
59 printf("GOOD: seccomp BPF enabled.\n");
60
61 printf("checking syscalls: "); fflush(0);
62 printf("mount... "); fflush(0);
63 syscall_run("mount");
64
65 printf("umount2... "); fflush(0);
66 syscall_run("umount2");
67
68 printf("ptrace... "); fflush(0);
69 syscall_run("ptrace");
70
71 printf("swapon... "); fflush(0);
72 syscall_run("swapon");
73
74 printf("swapoff... "); fflush(0);
75 syscall_run("swapoff");
76
77 printf("init_module... "); fflush(0);
78 syscall_run("init_module");
79
80 printf("delete_module... "); fflush(0);
81 syscall_run("delete_module");
82
83 printf("chroot... "); fflush(0);
84 syscall_run("chroot");
85
86 printf("pivot_root... "); fflush(0);
87 syscall_run("pivot_root");
88
89#if defined(__i386__) || defined(__x86_64__)
90 printf("iopl... "); fflush(0);
91 syscall_run("iopl");
92
93 printf("ioperm... "); fflush(0);
94 syscall_run("ioperm");
95#endif
96 printf("\n");
97 }
98 else
99 fprintf(stderr, "Error: unrecognized seccomp mode\n");
100
101}
diff --git a/src/faudit/syscall.c b/src/faudit/syscall.c
new file mode 100644
index 000000000..3c87305df
--- /dev/null
+++ b/src/faudit/syscall.c
@@ -0,0 +1,101 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "faudit.h"
21#include <sys/ptrace.h>
22#include <sys/swap.h>
23#if defined(__i386__) || defined(__x86_64__)
24#include <sys/io.h>
25#endif
26#include <sys/wait.h>
27extern int init_module(void *module_image, unsigned long len,
28 const char *param_values);
29extern int finit_module(int fd, const char *param_values,
30 int flags);
31extern int delete_module(const char *name, int flags);
32extern int pivot_root(const char *new_root, const char *put_old);
33
34void syscall_helper(int argc, char **argv) {
35 (void) argc;
36
37 if (strcmp(argv[2], "mount") == 0) {
38 mount(NULL, NULL, NULL, 0, NULL);
39 printf("\nUGLY: mount syscall permitted.\n");
40 }
41 else if (strcmp(argv[2], "umount2") == 0) {
42 umount2(NULL, 0);
43 printf("\nUGLY: umount2 syscall permitted.\n");
44 }
45 else if (strcmp(argv[2], "ptrace") == 0) {
46 ptrace(0, 0, NULL, NULL);
47 printf("\nUGLY: ptrace syscall permitted.\n");
48 }
49 else if (strcmp(argv[2], "swapon") == 0) {
50 swapon(NULL, 0);
51 printf("\nUGLY: swapon syscall permitted.\n");
52 }
53 else if (strcmp(argv[2], "swapoff") == 0) {
54 swapoff(NULL);
55 printf("\nUGLY: swapoff syscall permitted.\n");
56 }
57 else if (strcmp(argv[2], "init_module") == 0) {
58 init_module(NULL, 0, NULL);
59 printf("\nUGLY: init_module syscall permitted.\n");
60 }
61 else if (strcmp(argv[2], "delete_module") == 0) {
62 delete_module(NULL, 0);
63 printf("\nUGLY: delete_module syscall permitted.\n");
64 }
65 else if (strcmp(argv[2], "chroot") == 0) {
66 int rv = chroot("/blablabla-57281292");
67 (void) rv;
68 printf("\nUGLY: chroot syscall permitted.\n");
69 }
70 else if (strcmp(argv[2], "pivot_root") == 0) {
71 pivot_root(NULL, NULL);
72 printf("\nUGLY: pivot_root syscall permitted.\n");
73 }
74#if defined(__i386__) || defined(__x86_64__)
75 else if (strcmp(argv[2], "iopl") == 0) {
76 iopl(0L);
77 printf("\nUGLY: iopl syscall permitted.\n");
78 }
79 else if (strcmp(argv[2], "ioperm") == 0) {
80 ioperm(0, 0, 0);
81 printf("\nUGLY: ioperm syscall permitted.\n");
82 }
83#endif
84 exit(0);
85}
86
87void syscall_run(const char *name) {
88 assert(prog);
89
90 pid_t child = fork();
91 if (child < 0)
92 errExit("fork");
93 if (child == 0) {
94 execl(prog, prog, "syscall", name, NULL);
95 perror("execl");
96 _exit(1);
97 }
98
99 // wait for the child to finish
100 waitpid(child, NULL, 0);
101}
diff --git a/src/faudit/x11.c b/src/faudit/x11.c
new file mode 100644
index 000000000..43f40f4e9
--- /dev/null
+++ b/src/faudit/x11.c
@@ -0,0 +1,63 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "faudit.h"
21#include <sys/socket.h>
22#include <dirent.h>
23
24
25void x11_test(void) {
26 // check regular display 0 sockets
27 if (check_unix("/tmp/.X11-unix/X0") == 0)
28 printf("MAYBE: X11 socket /tmp/.X11-unix/X0 is available\n");
29
30 if (check_unix("@/tmp/.X11-unix/X0") == 0)
31 printf("MAYBE: X11 socket @/tmp/.X11-unix/X0 is available\n");
32
33 // check all unix sockets in /tmp/.X11-unix directory
34 DIR *dir;
35 if (!(dir = opendir("/tmp/.X11-unix"))) {
36 // sleep 2 seconds and try again
37 sleep(2);
38 if (!(dir = opendir("/tmp/.X11-unix"))) {
39 ;
40 }
41 }
42
43 if (dir == NULL)
44 printf("GOOD: cannot open /tmp/.X11-unix directory\n");
45 else {
46 struct dirent *entry;
47 while ((entry = readdir(dir)) != NULL) {
48 if (strcmp(entry->d_name, "X0") == 0)
49 continue;
50 if (strcmp(entry->d_name, ".") == 0)
51 continue;
52 if (strcmp(entry->d_name, "..") == 0)
53 continue;
54 char *name;
55 if (asprintf(&name, "/tmp/.X11-unix/%s", entry->d_name) == -1)
56 errExit("asprintf");
57 if (check_unix(name) == 0)
58 printf("MAYBE: X11 socket %s is available\n", name);
59 free(name);
60 }
61 closedir(dir);
62 }
63}
diff --git a/src/firecfg/Makefile.in b/src/firecfg/Makefile.in
index 11f8b1e8d..f9fe08768 100644
--- a/src/firecfg/Makefile.in
+++ b/src/firecfg/Makefile.in
@@ -16,22 +16,24 @@ HAVE_NETWORK=@HAVE_NETWORK@
16HAVE_USERNS=@HAVE_USERNS@ 16HAVE_USERNS=@HAVE_USERNS@
17HAVE_X11=@HAVE_X11@ 17HAVE_X11=@HAVE_X11@
18HAVE_FILE_TRANSFER=@HAVE_FILE_TRANSFER@ 18HAVE_FILE_TRANSFER=@HAVE_FILE_TRANSFER@
19HAVE_GCOV=@HAVE_GCOV@
20EXTRA_LDFLAGS +=@EXTRA_LDFLAGS@
19 21
20 22
21H_FILE_LIST = $(sort $(wildcard *.[h])) 23H_FILE_LIST = $(sort $(wildcard *.[h]))
22C_FILE_LIST = $(sort $(wildcard *.c)) 24C_FILE_LIST = $(sort $(wildcard *.c))
23OBJS = $(C_FILE_LIST:.c=.o) 25OBJS = $(C_FILE_LIST:.c=.o)
24BINOBJS = $(foreach file, $(OBJS), $file) 26BINOBJS = $(foreach file, $(OBJS), $file)
25CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' $(HAVE_X11) $(HAVE_SECCOMP) $(HAVE_SECCOMP_H) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_BIND) $(HAVE_FILE_TRANSFER) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security 27CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' $(HAVE_GCOV) -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' $(HAVE_X11) $(HAVE_SECCOMP) $(HAVE_SECCOMP_H) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_BIND) $(HAVE_FILE_TRANSFER) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security
26LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread 28LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread
27 29
28%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/euid_common.h ../include/libnetlink.h ../include/pid.h 30%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/euid_common.h ../include/libnetlink.h ../include/pid.h
29 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ 31 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
30 32
31firecfg: $(OBJS) ../lib/common.o 33firecfg: $(OBJS) ../lib/common.o
32 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o $(LIBS) 34 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o $(LIBS) $(EXTRA_LDFLAGS)
33 35
34clean:; rm -f *.o firecfg firecfg.1 firecfg.1.gz 36clean:; rm -f *.o firecfg firecfg.1 firecfg.1.gz *.gcov *.gcda *.gcno
35 37
36distclean: clean 38distclean: clean
37 rm -fr Makefile 39 rm -fr Makefile
diff --git a/src/firecfg/firecfg.config b/src/firecfg/firecfg.config
index c28f8e352..e3e333497 100644
--- a/src/firecfg/firecfg.config
+++ b/src/firecfg/firecfg.config
@@ -2,44 +2,124 @@
2# This is the list of programs handled by firecfg utility 2# This is the list of programs handled by firecfg utility
3# 3#
4 4
5# astronomy
6gpredict
7stellarium
8
9# bittorrent/ftp
10deluge
11dropbox
12filezilla
13qbittorrent
14rtorrent
15transmission-gtk
16transmission-qt
17uget-gtk
18
5# browsers/email 19# browsers/email
6firefox 20abrowser
7iceweasel 21brave
8chromium-browser
9chromium 22chromium
23chromium-browser
10conkeror 24conkeror
11thunderbird 25cyberfox
12epiphany 26firefox
27firefox-esr
13flashpeak-slimjet 28flashpeak-slimjet
29epiphany
30dillo
31google-chrome
14google-chrome-beta 32google-chrome-beta
15google-chrome-stable 33google-chrome-stable
16google-chrome-unstable 34google-chrome-unstable
17google-chrome 35iceweasel
18icecat 36icecat
19icedove 37icedove
20kmail 38kmail
21midori 39midori
40netsurf
22opera-beta 41opera-beta
23opera 42opera
43palemoon
24qutebrowser 44qutebrowser
45start-tor-browser
25seamonkey 46seamonkey
26seamonkey-bin 47seamonkey-bin
48thunderbird
27vivaldi-beta 49vivaldi-beta
28vivaldi 50vivaldi
29dillo 51evolution
30 52
31# bittorrent/ftp 53# chat/messaging
32deluge 54bitlbee
33filezilla 55corebird
34qbittorrent 56empathy
35rtorrent 57gitter
36transmission-gtk 58hexchat
37transmission-qt 59jitsi
60konversation
61pidgin
62polari
63psi-plus
64qtox
65quassel
66skype
67telegram
68weechat
69weechat-curses
70xchat
71
72# dns
73dnscrypt-proxy
74dnsmaq
75unbound
76
77# emulators/compatibility layers
78mupen64plus
79wine
80dosbox
81virtualbox
82
83# games
840ad
85gnome-chess
86hedgewars
87steam
88wesnot
89warzone2100
90
91# Media
92audacious
93audacity
94clementine
95cmus
96deadbeef
97feh
98gnome-mplayer
99google-play-music-desktop-player
100mpv
101parole
102rhythmbox
103spotify
104totem
105vlc
106xplayer
107xviewer
108eom
109
110# news readers
111quiterss
38 112
39# office 113# office
114atril
40cherrytree 115cherrytree
41evince 116evince
42fbreader 117fbreader
118gimp
119gthumb
120gwenview
121inkscape
122libreoffice
43localc 123localc
44lodraw 124lodraw
45loffice 125loffice
@@ -48,29 +128,30 @@ loimpress
48lomath 128lomath
49loweb 129loweb
50lowriter 130lowriter
131luminance-hdr
132mupdf
133qpdfview
134soffice
135synfigstudio
51Mathematica 136Mathematica
52mathematica 137mathematica
138okular
139pix
140xpdf
141xreader
142zathura
143openshot
144flowblade
145eog
53 146
54# Media 147# other
55vlc 148ssh
56audacious 149atom-beta
57clementine 150atom
58deadbeef 151ranger
59parole 152keepass
60rhythmbox 153keepassx
61totem 154xiphos
62cmus
63 155
64# chat/messaging 156# weather/climate
65bitlbee 157aweather
66empathy
67gnome-mplayer
68hexchat
69pidgin
70qtox
71quassel
72xchat
73
74# games
75hedgewars
76wesnot
diff --git a/src/firecfg/main.c b/src/firecfg/main.c
index 70d29a3ed..d2566ce22 100644
--- a/src/firecfg/main.c
+++ b/src/firecfg/main.c
@@ -24,8 +24,13 @@
24#include <dirent.h> 24#include <dirent.h>
25#include <sys/types.h> 25#include <sys/types.h>
26#include <sys/stat.h> 26#include <sys/stat.h>
27#include <fcntl.h>
27#include <unistd.h> 28#include <unistd.h>
29#include <string.h>
30#include <errno.h>
31#include <sys/mman.h>
28#include "../include/common.h" 32#include "../include/common.h"
33static int arg_debug = 0;
29 34
30static void usage(void) { 35static void usage(void) {
31 printf("firecfg - version %s\n\n", VERSION); 36 printf("firecfg - version %s\n\n", VERSION);
@@ -37,8 +42,10 @@ static void usage(void) {
37 printf("DESKTOP INTEGRATION section in man 1 firejail.\n\n"); 42 printf("DESKTOP INTEGRATION section in man 1 firejail.\n\n");
38 printf("Usage: firecfg [OPTIONS]\n\n"); 43 printf("Usage: firecfg [OPTIONS]\n\n");
39 printf(" --clean - remove all firejail symbolic links.\n\n"); 44 printf(" --clean - remove all firejail symbolic links.\n\n");
45 printf(" --debug - print debug messages.\n\n");
40 printf(" --help, -? - this help screen.\n\n"); 46 printf(" --help, -? - this help screen.\n\n");
41 printf(" --list - list all firejail symbolic links.\n\n"); 47 printf(" --list - list all firejail symbolic links.\n\n");
48 printf(" --fix - fix .desktop files.\n\n");
42 printf(" --version - print program version and exit.\n\n"); 49 printf(" --version - print program version and exit.\n\n");
43 printf("Example:\n\n"); 50 printf("Example:\n\n");
44 printf(" $ sudo firecfg\n"); 51 printf(" $ sudo firecfg\n");
@@ -49,10 +56,14 @@ static void usage(void) {
49 printf(" /usr/local/bin/firefox\n"); 56 printf(" /usr/local/bin/firefox\n");
50 printf(" /usr/local/bin/vlc\n"); 57 printf(" /usr/local/bin/vlc\n");
51 printf(" [...]\n"); 58 printf(" [...]\n");
52 printf(" $ sudo firecfg --clear\n"); 59 printf(" $ sudo firecfg --clean\n");
53 printf(" /usr/local/bin/firefox removed\n"); 60 printf(" /usr/local/bin/firefox removed\n");
54 printf(" /usr/local/bin/vlc removed\n"); 61 printf(" /usr/local/bin/vlc removed\n");
55 printf(" [...]\n"); 62 printf(" [...]\n");
63 printf(" $ firecfg --fix\n");
64 printf(" /home/user/.local/share/applications/chromium.desktop created\n");
65 printf(" /home/user/.local/share/applications/vlc.desktop created\n");
66 printf(" [...]\n");
56 printf("\n"); 67 printf("\n");
57 printf("License GPL version 2 or later\n"); 68 printf("License GPL version 2 or later\n");
58 printf("Homepage: http://firejail.wordpress.com\n\n"); 69 printf("Homepage: http://firejail.wordpress.com\n\n");
@@ -67,9 +78,12 @@ static int find(const char *program, const char *directory) {
67 errExit("asprintf"); 78 errExit("asprintf");
68 79
69 struct stat s; 80 struct stat s;
70 if (stat(fname, &s) == 0) 81 if (stat(fname, &s) == 0) {
82 if (arg_debug)
83 printf("found %s in directory %s\n", program, directory);
71 retval = 1; 84 retval = 1;
72 85 }
86
73 free(fname); 87 free(fname);
74 return retval; 88 return retval;
75} 89}
@@ -79,7 +93,8 @@ static int find(const char *program, const char *directory) {
79static int which(const char *program) { 93static int which(const char *program) {
80 // check some well-known paths 94 // check some well-known paths
81 if (find(program, "/bin") || find(program, "/usr/bin") || 95 if (find(program, "/bin") || find(program, "/usr/bin") ||
82 find(program, "/sbin") || find(program, "/usr/sbin")) 96 find(program, "/sbin") || find(program, "/usr/sbin") ||
97 find(program, "/usr/games"))
83 return 1; 98 return 1;
84 99
85 // check environment 100 // check environment
@@ -205,8 +220,9 @@ static void set_file(const char *name, const char *firejail_exec) {
205 errExit("asprintf"); 220 errExit("asprintf");
206 221
207 struct stat s; 222 struct stat s;
208 if (stat(fname, &s) == 0) 223 if (stat(fname, &s) == 0) {
209 ; //printf("%s already present\n", fname); 224 printf("%s is already present, skipping...\n", fname);
225 }
210 else { 226 else {
211 int rv = symlink(firejail_exec, fname); 227 int rv = symlink(firejail_exec, fname);
212 if (rv) { 228 if (rv) {
@@ -268,7 +284,7 @@ static void set(void) {
268 // empty line 284 // empty line
269 if (*start == '\0') 285 if (*start == '\0')
270 continue; 286 continue;
271 287
272 // set link 288 // set link
273 set_file(start, firejail_exec); 289 set_file(start, firejail_exec);
274 } 290 }
@@ -278,6 +294,164 @@ static void set(void) {
278 free(firejail_exec); 294 free(firejail_exec);
279} 295}
280 296
297static void fix_desktop_files(void) {
298 if (getuid() == 0) {
299 fprintf(stderr, "Error: you should run --fix as user\n");
300 exit(1);
301 }
302
303 char *homedir = getenv("HOME");
304 if (!homedir)
305 errExit("getenv");
306
307 char *user_apps_dir;
308 if (asprintf(&user_apps_dir, "%s/.local/share/applications", homedir) == -1)
309 errExit("asprintf");
310
311 DIR *dir = opendir("/usr/share/applications");
312 if (!dir) {
313 perror("Error: cannot open /usr/share/applications directory");
314 exit(1);
315 }
316
317 if (chdir("/usr/share/applications")) {
318 perror("Error: cannot chdir to /usr/share/applications");
319 exit(1);
320 }
321
322 struct dirent *entry;
323 while ((entry = readdir(dir)) != NULL) {
324 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
325 continue;
326
327 // skip if not regular file or link
328 if (entry->d_type != DT_REG && entry->d_type != DT_LNK)
329 continue;
330
331 // skip if not .desktop file
332 if (strstr(entry->d_name,".desktop") != (entry->d_name+strlen(entry->d_name)-8))
333 continue;
334
335 char *filename = entry->d_name;
336
337 // skip links
338 if (is_link(filename))
339 continue;
340
341 struct stat sb;
342 if (stat(filename, &sb) == -1)
343 errExit("stat");
344
345 int fd = open(filename, O_RDONLY);
346 if (fd == -1)
347 errExit("open");
348
349 char *buf = mmap(NULL, sb.st_size + 1, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
350 if (buf == MAP_FAILED)
351 errExit("mmap");
352
353 close(fd);
354
355 // check format
356 if (strstr(buf, "[Desktop Entry]\n") == NULL) {
357 if (arg_debug)
358 fprintf(stderr, "/usr/share/applications/%s - SKIPPED: wrong format?\n", filename);
359 munmap(buf, sb.st_size + 1);
360 continue;
361 }
362
363 // get executable name
364 char *ptr1 = strstr(buf,"\nExec=");
365 if (!ptr1 || strlen(ptr1) < 7) {
366 if (arg_debug)
367 fprintf(stderr, "/usr/share/applications/%s - SKIPPED: wrong format?\n", filename);
368 munmap(buf, sb.st_size + 1);
369 continue;
370 }
371
372 char *execname = ptr1 + 6;
373 // https://specifications.freedesktop.org/desktop-entry-spec/latest/ar01s06.html
374 // The executable program can either be specified with its full path
375 // or with the name of the executable only
376 if (execname[0] != '/') {
377 if (arg_debug)
378 fprintf(stderr, "/usr/share/applications/%s - already OK\n", filename);
379 continue;
380 }
381 // executable name can be quoted, this is rare and currently unsupported, TODO
382 if (execname[0] == '"') {
383 if (arg_debug)
384 fprintf(stderr, "/usr/share/applications/%s - skipped: path quoting unsupported\n", filename);
385 continue;
386 }
387
388 // put '\0' at end of filename
389 char *tail = NULL;
390 char endchar = ' ';
391 if (execname[0] == '/') {
392 char *ptr2 = index(execname, ' ');
393 char *ptr3 = index(execname, '\n');
394 if (ptr2 && (!ptr3 || (ptr2 < ptr3))) {
395 endchar = ptr2[0];
396 ptr2[0] = '\0';
397 tail = ptr2 + 1;
398 } else if (ptr3 && (!ptr2 || (ptr3 < ptr2))) {
399 endchar = ptr3[0];
400 ptr3[0] = '\0';
401 tail = ptr3 + 1;
402 }
403 ptr1[5] = '\0';
404 }
405
406 char *bname = basename(execname);
407 assert(bname);
408
409 // check if basename in PATH
410 if (!which(bname)) {
411 fprintf(stderr, "/usr/share/applications/%s - skipped, %s not in PATH\n", filename, bname);
412 continue;
413 }
414
415 char *outname;
416 if (asprintf(&outname ,"%s/%s", user_apps_dir, filename) == -1)
417 errExit("asprintf");
418
419 int fd1 = open(outname, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
420 free(outname);
421
422 if (fd1 == -1) {
423 fprintf(stderr, "%s/%s skipped: %s\n", user_apps_dir, filename, strerror(errno));
424 munmap(buf, sb.st_size + 1);
425 continue;
426 }
427
428 FILE *outfile = fdopen(fd1, "w");
429 if (!outfile) {
430 fprintf(stderr, "%s/%s skipped: %s\n", user_apps_dir, filename, strerror(errno));
431 munmap(buf, sb.st_size + 1);
432 close(fd1);
433 continue;
434 }
435
436 if (fprintf(outfile,\
437 "# Converted by firecfg --fix from /usr/share/applications/%s\n\n%s=%s%c%s",\
438 filename, buf, bname, endchar, tail) < 0) {
439 fprintf(stderr, "Unable to write %s/%s: %s\n", user_apps_dir, filename, strerror(errno));
440 munmap(buf, sb.st_size + 1);
441 fclose(outfile);
442 continue;
443 }
444
445 fclose(outfile);
446 munmap(buf, sb.st_size + 1);
447
448 printf("%s/%s created\n", user_apps_dir, filename);
449 }
450
451 closedir(dir);
452 free(user_apps_dir);
453}
454
281int main(int argc, char **argv) { 455int main(int argc, char **argv) {
282 int i; 456 int i;
283 457
@@ -288,6 +462,8 @@ int main(int argc, char **argv) {
288 usage(); 462 usage();
289 return 0; 463 return 0;
290 } 464 }
465 else if (strcmp(argv[i], "--debug") == 0)
466 arg_debug = 1;
291 else if (strcmp(argv[i], "--version") == 0) { 467 else if (strcmp(argv[i], "--version") == 0) {
292 printf("firecfg version %s\n\n", VERSION); 468 printf("firecfg version %s\n\n", VERSION);
293 return 0; 469 return 0;
@@ -300,6 +476,10 @@ int main(int argc, char **argv) {
300 list(); 476 list();
301 return 0; 477 return 0;
302 } 478 }
479 else if (strcmp(argv[i], "--fix") == 0) {
480 fix_desktop_files();
481 return 0;
482 }
303 else { 483 else {
304 fprintf(stderr, "Error: invalid command line option\n"); 484 fprintf(stderr, "Error: invalid command line option\n");
305 usage(); 485 usage();
diff --git a/src/firejail/Makefile.in b/src/firejail/Makefile.in
index 3ad4ba75e..6e5071925 100644
--- a/src/firejail/Makefile.in
+++ b/src/firejail/Makefile.in
@@ -16,22 +16,28 @@ HAVE_NETWORK=@HAVE_NETWORK@
16HAVE_USERNS=@HAVE_USERNS@ 16HAVE_USERNS=@HAVE_USERNS@
17HAVE_X11=@HAVE_X11@ 17HAVE_X11=@HAVE_X11@
18HAVE_FILE_TRANSFER=@HAVE_FILE_TRANSFER@ 18HAVE_FILE_TRANSFER=@HAVE_FILE_TRANSFER@
19 19HAVE_WHITELIST=@HAVE_WHITELIST@
20HAVE_GLOBALCFG=@HAVE_GLOBALCFG@
21HAVE_APPARMOR=@HAVE_APPARMOR@
22HAVE_OVERLAYFS=@HAVE_OVERLAYFS@
23HAVE_PRIVATE_HOME=@HAVE_PRIVATE_HOME@
24HAVE_GCOV=@HAVE_GCOV@
25EXTRA_LDFLAGS +=@EXTRA_LDFLAGS@
20 26
21H_FILE_LIST = $(sort $(wildcard *.[h])) 27H_FILE_LIST = $(sort $(wildcard *.[h]))
22C_FILE_LIST = $(sort $(wildcard *.c)) 28C_FILE_LIST = $(sort $(wildcard *.c))
23OBJS = $(C_FILE_LIST:.c=.o) 29OBJS = $(C_FILE_LIST:.c=.o)
24BINOBJS = $(foreach file, $(OBJS), $file) 30BINOBJS = $(foreach file, $(OBJS), $file)
25CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' $(HAVE_X11) $(HAVE_SECCOMP) $(HAVE_SECCOMP_H) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_BIND) $(HAVE_FILE_TRANSFER) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security 31CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' $(HAVE_GCOV) -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' $(HAVE_X11) $(HAVE_PRIVATE_HOME) $(HAVE_APPARMOR) $(HAVE_OVERLAYFS) $(HAVE_SECCOMP) $(HAVE_GLOBALCFG) $(HAVE_SECCOMP_H) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_BIND) $(HAVE_FILE_TRANSFER) $(HAVE_WHITELIST) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security
26LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread 32LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread
27 33
28%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/euid_common.h ../include/libnetlink.h ../include/pid.h 34%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/euid_common.h ../include/pid.h ../include/seccomp.h ../include/syscall.h
29 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ 35 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
30 36
31firejail: $(OBJS) ../lib/libnetlink.o ../lib/common.o 37firejail: $(OBJS) ../lib/libnetlink.o ../lib/common.o
32 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/libnetlink.o ../lib/common.o $(LIBS) 38 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o $(LIBS) $(EXTRA_LDFLAGS)
33 39
34clean:; rm -f *.o firejail firejail.1 firejail.1.gz 40clean:; rm -f *.o firejail firejail.1 firejail.1.gz *.gcov *.gcda *.gcno
35 41
36distclean: clean 42distclean: clean
37 rm -fr Makefile 43 rm -fr Makefile
diff --git a/src/firejail/appimage.c b/src/firejail/appimage.c
new file mode 100644
index 000000000..a658173eb
--- /dev/null
+++ b/src/firejail/appimage.c
@@ -0,0 +1,176 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20// http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=770fe30a46a12b6fb6b63fbe1737654d28e84844
21// sudo mount -o loop krita-3.0-x86_64.appimage mnt
22
23#include "firejail.h"
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <sys/mount.h>
27#include <fcntl.h>
28#include <linux/loop.h>
29#include <errno.h>
30
31static char *devloop = NULL; // device file
32static char *mntdir = NULL; // mount point in /tmp directory
33
34const char *appimage_getdir(void) {
35 return mntdir;
36}
37
38void appimage_set(const char *appimage_path) {
39 assert(appimage_path);
40 assert(devloop == NULL); // don't call this twice!
41 EUID_ASSERT();
42
43#ifdef LOOP_CTL_GET_FREE // test for older kernels; this definition is found in /usr/include/linux/loop.h
44 // check appimage_path
45 if (access(appimage_path, R_OK) == -1) {
46 fprintf(stderr, "Error: cannot access AppImage file\n");
47 exit(1);
48 }
49
50 // get appimage type and ELF size
51 // a value of 0 means we are dealing with a type1 appimage
52 long unsigned int size = appimage2_size(appimage_path);
53 if (arg_debug)
54 printf("AppImage ELF size %lu\n", size);
55
56 // open as user to prevent race condition
57 int ffd = open(appimage_path, O_RDONLY|O_CLOEXEC);
58 if (ffd == -1) {
59 fprintf(stderr, "Error: /dev/loop-control interface is not supported by your kernel\n");
60 exit(1);
61 }
62
63 // find or allocate a free loop device to use
64 EUID_ROOT();
65 int cfd = open("/dev/loop-control", O_RDWR);
66 int devnr = ioctl(cfd, LOOP_CTL_GET_FREE);
67 if (devnr == -1) {
68 fprintf(stderr, "Error: cannot allocate a new loopback device\n");
69 exit(1);
70 }
71 close(cfd);
72 if (asprintf(&devloop, "/dev/loop%d", devnr) == -1)
73 errExit("asprintf");
74
75 int lfd = open(devloop, O_RDONLY);
76 if (ioctl(lfd, LOOP_SET_FD, ffd) == -1) {
77 fprintf(stderr, "Error: cannot configure the loopback device\n");
78 exit(1);
79 }
80
81 if (size) {
82 struct loop_info64 info;
83 memset(&info, 0, sizeof(struct loop_info64));
84 info.lo_offset = size;
85 if (ioctl(lfd, LOOP_SET_STATUS64, &info) == -1)
86 errExit("configure appimage offset");
87 }
88
89 close(lfd);
90 close(ffd);
91 EUID_USER();
92
93 // creates appimage mount point perms 0700
94 if (asprintf(&mntdir, "%s/.appimage-%u", RUN_FIREJAIL_APPIMAGE_DIR, getpid()) == -1)
95 errExit("asprintf");
96 EUID_ROOT();
97 mkdir_attr(mntdir, 0700, getuid(), getgid());
98 EUID_USER();
99
100 // mount
101 char *mode;
102 if (asprintf(&mode, "mode=700,uid=%d,gid=%d", getuid(), getgid()) == -1)
103 errExit("asprintf");
104 EUID_ROOT();
105
106 if (size == 0) {
107 if (mount(devloop, mntdir, "iso9660",MS_MGC_VAL|MS_RDONLY, mode) < 0)
108 errExit("mounting appimage");
109 }
110 else {
111 if (mount(devloop, mntdir, "squashfs",MS_MGC_VAL|MS_RDONLY, mode) < 0)
112 errExit("mounting appimage");
113 }
114
115 if (arg_debug)
116 printf("appimage mounted on %s\n", mntdir);
117 EUID_USER();
118
119 // set environment
120 if (appimage_path && setenv("APPIMAGE", appimage_path, 1) < 0)
121 errExit("setenv");
122 if (mntdir && setenv("APPDIR", mntdir, 1) < 0)
123 errExit("setenv");
124
125 // build new command line
126 if (asprintf(&cfg.command_line, "%s/AppRun", mntdir) == -1)
127 errExit("asprintf");
128
129 free(mode);
130#ifdef HAVE_GCOV
131 __gcov_flush();
132#endif
133#else
134 fprintf(stderr, "Error: /dev/loop-control interface is not supported by your kernel\n");
135 exit(1);
136#endif
137}
138
139void appimage_clear(void) {
140 int rv;
141
142 EUID_ROOT();
143 if (mntdir) {
144 int i;
145 int rv = 0;
146 for (i = 0; i < 5; i++) {
147 rv = umount2(mntdir, MNT_FORCE);
148 if (rv == 0)
149 break;
150 if (rv == -1 && errno == EBUSY) {
151 if (!arg_quiet)
152 printf("Warning: EBUSY error trying to unmount %s\n", mntdir);
153 sleep(2);
154 continue;
155 }
156
157 // rv = -1
158 if (!arg_quiet) {
159 printf("Warning: error trying to unmount %s\n", mntdir);
160 perror("umount");
161 }
162 }
163
164 if (rv == 0) {
165 rmdir(mntdir);
166 free(mntdir);
167 }
168 }
169
170 if (devloop) {
171 int lfd = open(devloop, O_RDONLY);
172 rv = ioctl(lfd, LOOP_CLR_FD, 0);
173 (void) rv;
174 close(lfd);
175 }
176}
diff --git a/src/firejail/appimage_size.c b/src/firejail/appimage_size.c
new file mode 100644
index 000000000..3f5c3150c
--- /dev/null
+++ b/src/firejail/appimage_size.c
@@ -0,0 +1,160 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20/*
21Compile with:
22gcc elfsize.c -o elfsize
23Example:
24ls -l 126584
25Calculation using the values also reported by readelf -h:
26Start of section headers e_shoff 124728
27Size of section headers e_shentsize 64
28Number of section headers e_shnum 29
29e_shoff + ( e_shentsize * e_shnum ) = 126584
30*/
31#include <elf.h>
32#include <byteswap.h>
33#include <stdio.h>
34#include <stdint.h>
35#include <errno.h>
36#include <stdlib.h>
37#include <unistd.h>
38#include <string.h>
39#include <fcntl.h>
40
41typedef Elf32_Nhdr Elf_Nhdr;
42
43static Elf64_Ehdr ehdr;
44
45#if __BYTE_ORDER == __LITTLE_ENDIAN
46#define ELFDATANATIVE ELFDATA2LSB
47#elif __BYTE_ORDER == __BIG_ENDIAN
48#define ELFDATANATIVE ELFDATA2MSB
49#else
50#error "Unknown machine endian"
51#endif
52
53static uint16_t file16_to_cpu(uint16_t val) {
54 if (ehdr.e_ident[EI_DATA] != ELFDATANATIVE)
55 val = bswap_16(val);
56 return val;
57}
58
59
60static uint32_t file32_to_cpu(uint32_t val) {
61 if (ehdr.e_ident[EI_DATA] != ELFDATANATIVE)
62 val = bswap_32(val);
63 return val;
64}
65
66
67static uint64_t file64_to_cpu(uint64_t val) {
68 if (ehdr.e_ident[EI_DATA] != ELFDATANATIVE)
69 val = bswap_64(val);
70 return val;
71}
72
73
74// return 0 if error
75static long unsigned int read_elf32(int fd) {
76 Elf32_Ehdr ehdr32;
77 ssize_t ret;
78
79 ret = pread(fd, &ehdr32, sizeof(ehdr32), 0);
80 if (ret < 0 || (size_t)ret != sizeof(ehdr))
81 return 0;
82
83 ehdr.e_shoff = file32_to_cpu(ehdr32.e_shoff);
84 ehdr.e_shentsize = file16_to_cpu(ehdr32.e_shentsize);
85 ehdr.e_shnum = file16_to_cpu(ehdr32.e_shnum);
86
87 return(ehdr.e_shoff + (ehdr.e_shentsize * ehdr.e_shnum));
88}
89
90
91// return 0 if error
92static long unsigned int read_elf64(int fd) {
93 Elf64_Ehdr ehdr64;
94 ssize_t ret;
95
96 ret = pread(fd, &ehdr64, sizeof(ehdr64), 0);
97 if (ret < 0 || (size_t)ret != sizeof(ehdr))
98 return 0;
99
100 ehdr.e_shoff = file64_to_cpu(ehdr64.e_shoff);
101 ehdr.e_shentsize = file16_to_cpu(ehdr64.e_shentsize);
102 ehdr.e_shnum = file16_to_cpu(ehdr64.e_shnum);
103
104 return(ehdr.e_shoff + (ehdr.e_shentsize * ehdr.e_shnum));
105}
106
107
108// return 0 if error
109// return 0 if this is not an appimgage2 file
110long unsigned int appimage2_size(const char *fname) {
111/* TODO, FIXME: This assumes that the section header table (SHT) is
112the last part of the ELF. This is usually the case but
113it could also be that the last section is the last part
114of the ELF. This should be checked for.
115*/
116 ssize_t ret;
117 int fd;
118 long unsigned int size = 0;
119
120 fd = open(fname, O_RDONLY);
121 if (fd < 0)
122 return 0;
123
124 ret = pread(fd, ehdr.e_ident, EI_NIDENT, 0);
125 if (ret != EI_NIDENT)
126 goto getout;
127
128 if ((ehdr.e_ident[EI_DATA] != ELFDATA2LSB) &&
129 (ehdr.e_ident[EI_DATA] != ELFDATA2MSB))
130 goto getout;
131
132 if(ehdr.e_ident[EI_CLASS] == ELFCLASS32) {
133 size = read_elf32(fd);
134 }
135 else if(ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
136 size = read_elf64(fd);
137 }
138 else {
139 goto getout;
140 }
141 if (size == 0)
142 goto getout;
143
144
145 // look for a LZMA header at this location
146 unsigned char buf[4];
147 ret = pread(fd, buf, 4, size);
148 if (ret != 4) {
149 size = 0;
150 goto getout;
151 }
152 if (memcmp(buf, "hsqs", 4) != 0)
153 size = 0;
154
155getout:
156 close(fd);
157 return size;
158}
159
160
diff --git a/src/firejail/arp.c b/src/firejail/arp.c
index fb5e426b0..ddb75905f 100644
--- a/src/firejail/arp.c
+++ b/src/firejail/arp.c
@@ -40,6 +40,7 @@ typedef struct arp_hdr_t {
40 uint8_t target_ip[4]; 40 uint8_t target_ip[4];
41} ArpHdr; 41} ArpHdr;
42 42
43
43// returns 0 if the address is not in use, -1 otherwise 44// returns 0 if the address is not in use, -1 otherwise
44int arp_check(const char *dev, uint32_t destaddr, uint32_t srcaddr) { 45int arp_check(const char *dev, uint32_t destaddr, uint32_t srcaddr) {
45 if (strlen(dev) > IFNAMSIZ) { 46 if (strlen(dev) > IFNAMSIZ) {
@@ -286,189 +287,4 @@ uint32_t arp_assign(const char *dev, Bridge *br) {
286 return ip; 287 return ip;
287} 288}
288 289
289// scan interface (--scan option)
290void arp_scan(const char *dev, uint32_t ifip, uint32_t ifmask) {
291 assert(dev);
292 assert(ifip);
293
294// printf("Scanning interface %s (%d.%d.%d.%d/%d)\n",
295// dev, PRINT_IP(ifip & ifmask), mask2bits(ifmask));
296
297 if (strlen(dev) > IFNAMSIZ) {
298 fprintf(stderr, "Error: invalid network device name %s\n", dev);
299 exit(1);
300 }
301
302 // find interface mac address
303 int sock;
304 if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
305 errExit("socket");
306 struct ifreq ifr;
307 memset(&ifr, 0, sizeof (ifr));
308 strncpy(ifr.ifr_name, dev, IFNAMSIZ);
309 if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0)
310 errExit("ioctl");
311 close(sock);
312 uint8_t mac[6];
313 memcpy (mac, ifr.ifr_hwaddr.sa_data, 6);
314
315 // open layer2 socket
316 if ((sock = socket(PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 0)
317 errExit("socket");
318
319 // try all possible ip addresses in ascending order
320 uint32_t range = ~ifmask + 1; // the number of potential addresses
321 // this software is not supported for /31 networks
322 if (range < 4) {
323 fprintf(stderr, "Warning: this option is not supported for /31 networks\n");
324 close(sock);
325 return;
326 }
327
328 uint32_t dest = (ifip & ifmask) + 1;
329 uint32_t last = dest + range - 1;
330 uint32_t src = htonl(ifip);
331
332 // wait not more than one second for an answer
333 int header_printed = 0;
334 uint32_t last_ip = 0;
335 struct timeval ts;
336 ts.tv_sec = 2; // 2 seconds receive timeout
337 ts.tv_usec = 0;
338
339 while (1) {
340 fd_set rfds;
341 FD_ZERO(&rfds);
342 FD_SET(sock, &rfds);
343 fd_set wfds;
344 FD_ZERO(&wfds);
345 FD_SET(sock, &wfds);
346 int maxfd = sock;
347
348 uint8_t frame[ETH_FRAME_LEN]; // includes eht header, vlan, and crc
349 memset(frame, 0, ETH_FRAME_LEN);
350
351 int nready;
352 if (dest < last)
353 nready = select(maxfd + 1, &rfds, &wfds, (fd_set *) 0, NULL);
354 else
355 nready = select(maxfd + 1, &rfds, (fd_set *) 0, (fd_set *) 0, &ts);
356
357 if (nready < 0)
358 errExit("select");
359
360 if (nready == 0) { // timeout
361 break;
362 }
363
364 if (FD_ISSET(sock, &wfds) && dest < last) {
365 // configure layer2 socket address information
366 struct sockaddr_ll addr;
367 memset(&addr, 0, sizeof(addr));
368 if ((addr.sll_ifindex = if_nametoindex(dev)) == 0)
369 errExit("if_nametoindex");
370 addr.sll_family = AF_PACKET;
371 memcpy (addr.sll_addr, mac, 6);
372 addr.sll_halen = htons(6);
373
374 // build the arp packet header
375 ArpHdr hdr;
376 memset(&hdr, 0, sizeof(hdr));
377 hdr.htype = htons(1);
378 hdr.ptype = htons(ETH_P_IP);
379 hdr.hlen = 6;
380 hdr.plen = 4;
381 hdr.opcode = htons(1); //ARPOP_REQUEST
382 memcpy(hdr.sender_mac, mac, 6);
383 memcpy(hdr.sender_ip, (uint8_t *)&src, 4);
384 uint32_t dst = htonl(dest);
385 memcpy(hdr.target_ip, (uint8_t *)&dst, 4);
386
387 // build ethernet frame
388 uint8_t frame[ETH_FRAME_LEN]; // includes eht header, vlan, and crc
389 memset(frame, 0, sizeof(frame));
390 frame[0] = frame[1] = frame[2] = frame[3] = frame[4] = frame[5] = 0xff;
391 memcpy(frame + 6, mac, 6);
392 frame[12] = ETH_P_ARP / 256;
393 frame[13] = ETH_P_ARP % 256;
394 memcpy (frame + 14, &hdr, sizeof(hdr));
395
396 // send packet
397 int len;
398 if ((len = sendto (sock, frame, 14 + sizeof(ArpHdr), 0, (struct sockaddr *) &addr, sizeof (addr))) <= 0)
399 errExit("send");
400//printf("send %d bytes to %d.%d.%d.%d\n", len, PRINT_IP(dest));
401 fflush(0);
402 dest++;
403 }
404
405 if (FD_ISSET(sock, &rfds)) {
406 // read the incoming packet
407 int len = recvfrom(sock, frame, ETH_FRAME_LEN, 0, NULL, NULL);
408 if (len < 0) {
409 perror("recvfrom");
410 }
411
412 // parse the incoming packet
413 if ((unsigned int) len < 14 + sizeof(ArpHdr))
414 continue;
415
416 // look only at ARP packets
417 if (frame[12] != (ETH_P_ARP / 256) || frame[13] != (ETH_P_ARP % 256))
418 continue;
419
420 ArpHdr hdr;
421 memcpy(&hdr, frame + 14, sizeof(ArpHdr));
422
423 if (hdr.opcode == htons(2)) {
424 // check my mac and my address
425 if (memcmp(mac, hdr.target_mac, 6) != 0)
426 continue;
427 uint32_t ip;
428 memcpy(&ip, hdr.target_ip, 4);
429 if (ip != src)
430 continue;
431 memcpy(&ip, hdr.sender_ip, 4);
432 ip = ntohl(ip);
433
434 if (ip == last_ip) // filter duplicates
435 continue;
436 last_ip = ip;
437
438 // printing
439 if (header_printed == 0) {
440 printf(" Network scan:\n");
441
442 // print parent interface
443 if (cfg.bridge0.configured && cfg.bridge0.ip && cfg.bridge0.macvlan &&
444 (cfg.bridge0.ip & cfg.bridge0.mask) == (ifip & cfg.bridge0.mask))
445 printf(" %02x:%02x:%02x:%02x:%02x:%02x\t%d.%d.%d.%d\n",
446 PRINT_MAC(cfg.bridge0.mac), PRINT_IP(cfg.bridge0.ip));
447
448 if (cfg.bridge1.configured && cfg.bridge1.ip && cfg.bridge1.macvlan &&
449 (cfg.bridge1.ip & cfg.bridge1.mask) == (ifip & cfg.bridge1.mask))
450 printf(" %02x:%02x:%02x:%02x:%02x:%02x\t%d.%d.%d.%d\n",
451 PRINT_MAC(cfg.bridge1.mac), PRINT_IP(cfg.bridge1.ip));
452
453 if (cfg.bridge2.configured && cfg.bridge2.ip && cfg.bridge2.macvlan &&
454 (cfg.bridge2.ip & cfg.bridge2.mask) == (ifip & cfg.bridge2.mask))
455 printf(" %02x:%02x:%02x:%02x:%02x:%02x\t%d.%d.%d.%d\n",
456 PRINT_MAC(cfg.bridge2.mac), PRINT_IP(cfg.bridge2.ip));
457
458 if (cfg.bridge3.configured && cfg.bridge3.ip && cfg.bridge3.macvlan &&
459 (cfg.bridge3.ip & cfg.bridge3.mask) == (ifip & cfg.bridge3.mask))
460 printf(" %02x:%02x:%02x:%02x:%02x:%02x\t%d.%d.%d.%d\n",
461 PRINT_MAC(cfg.bridge3.mac), PRINT_IP(cfg.bridge3.ip));
462
463 header_printed = 1;
464 }
465 printf(" %02x:%02x:%02x:%02x:%02x:%02x\t%d.%d.%d.%d\n",
466 PRINT_MAC(hdr.sender_mac), PRINT_IP(ip));
467 }
468 }
469 }
470
471 close(sock);
472}
473
474 290
diff --git a/src/firejail/bandwidth.c b/src/firejail/bandwidth.c
index 34c5ca509..5e9002f22 100644
--- a/src/firejail/bandwidth.c
+++ b/src/firejail/bandwidth.c
@@ -130,14 +130,8 @@ static void bandwidth_create_run_file(pid_t pid) {
130 /* coverity[toctou] */ 130 /* coverity[toctou] */
131 FILE *fp = fopen(fname, "w"); 131 FILE *fp = fopen(fname, "w");
132 if (fp) { 132 if (fp) {
133 SET_PERMS_STREAM(fp, 0, 0, 0644);
133 fclose(fp); 134 fclose(fp);
134
135 /* coverity[toctou] */
136 if (chmod(fname, 0644) == -1)
137 errExit("chmod");
138 /* coverity[toctou] */
139 if (chown(fname, 0, 0) == -1)
140 errExit("chown");
141 } 135 }
142 else { 136 else {
143 fprintf(stderr, "Error: cannot create bandwidth file\n"); 137 fprintf(stderr, "Error: cannot create bandwidth file\n");
@@ -180,12 +174,9 @@ void network_set_run_file(pid_t pid) {
180 fprintf(fp, "%s:%s\n", cfg.bridge2.dev, cfg.bridge2.devsandbox); 174 fprintf(fp, "%s:%s\n", cfg.bridge2.dev, cfg.bridge2.devsandbox);
181 if (cfg.bridge3.configured) 175 if (cfg.bridge3.configured)
182 fprintf(fp, "%s:%s\n", cfg.bridge3.dev, cfg.bridge3.devsandbox); 176 fprintf(fp, "%s:%s\n", cfg.bridge3.dev, cfg.bridge3.devsandbox);
183 fclose(fp);
184 177
185 if (chmod(fname, 0644) == -1) 178 SET_PERMS_STREAM(fp, 0, 0, 0644);
186 errExit("chmod"); 179 fclose(fp);
187 if (chown(fname, 0, 0) == -1)
188 errExit("chown");
189 } 180 }
190 else { 181 else {
191 fprintf(stderr, "Error: cannot create network map file\n"); 182 fprintf(stderr, "Error: cannot create network map file\n");
@@ -320,21 +311,6 @@ void bandwidth_set(pid_t pid, const char *dev, int down, int up) {
320//*********************************** 311//***********************************
321// command execution 312// command execution
322//*********************************** 313//***********************************
323void bandwidth_name(const char *name, const char *command, const char *dev, int down, int up) {
324 EUID_ASSERT();
325 if (!name || strlen(name) == 0) {
326 fprintf(stderr, "Error: invalid sandbox name\n");
327 exit(1);
328 }
329 pid_t pid;
330 if (name2pid(name, &pid)) {
331 fprintf(stderr, "Error: cannot find sandbox %s\n", name);
332 exit(1);
333 }
334
335 bandwidth_pid(pid, command, dev, down, up);
336}
337
338void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, int up) { 314void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, int up) {
339 EUID_ASSERT(); 315 EUID_ASSERT();
340 //************************ 316 //************************
@@ -459,13 +435,21 @@ void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, in
459 if (setregid(0, 0)) 435 if (setregid(0, 0))
460 errExit("setregid"); 436 errExit("setregid");
461 437
438 if (!cfg.shell)
439 cfg.shell = guess_shell();
440 if (!cfg.shell) {
441 fprintf(stderr, "Error: no POSIX shell found, please use --shell command line option\n");
442 exit(1);
443 }
444
462 char *arg[4]; 445 char *arg[4];
463 arg[0] = "/bin/bash"; 446 arg[0] = cfg.shell;
464 arg[1] = "-c"; 447 arg[1] = "-c";
465 arg[2] = cmd; 448 arg[2] = cmd;
466 arg[3] = NULL; 449 arg[3] = NULL;
467 execvp("/bin/bash", arg); 450 clearenv();
451 execvp(arg[0], arg);
468 452
469 // it will never get here 453 // it will never get here
470 exit(0); 454 errExit("execvp");
471} 455}
diff --git a/src/firejail/caps.c b/src/firejail/caps.c
index 2d42c7d8a..ba811cada 100644
--- a/src/firejail/caps.c
+++ b/src/firejail/caps.c
@@ -168,17 +168,6 @@ static CapsEntry capslist[] = {
168// 168//
169}; // end of capslist 169}; // end of capslist
170 170
171const char *caps_find_nr(int nr) {
172 int i;
173 int elems = sizeof(capslist) / sizeof(capslist[0]);
174 for (i = 0; i < elems; i++) {
175 if (nr == capslist[i].nr)
176 return capslist[i].name;
177 }
178
179 return "unknown";
180}
181
182// return -1 if error, or syscall number 171// return -1 if error, or syscall number
183static int caps_find_name(const char *name) { 172static int caps_find_name(const char *name) {
184 int i; 173 int i;
@@ -397,26 +386,10 @@ static uint64_t extract_caps(int pid) {
397 } 386 }
398 fclose(fp); 387 fclose(fp);
399 free(file); 388 free(file);
400 printf("Error: cannot read caps configuration\n"); 389 fprintf(stderr, "Error: cannot read caps configuration\n");
401 exit(1); 390 exit(1);
402} 391}
403 392
404
405void caps_print_filter_name(const char *name) {
406 EUID_ASSERT();
407 if (!name || strlen(name) == 0) {
408 fprintf(stderr, "Error: invalid sandbox name\n");
409 exit(1);
410 }
411 pid_t pid;
412 if (name2pid(name, &pid)) {
413 fprintf(stderr, "Error: cannot find sandbox %s\n", name);
414 exit(1);
415 }
416
417 caps_print_filter(pid);
418}
419
420void caps_print_filter(pid_t pid) { 393void caps_print_filter(pid_t pid) {
421 EUID_ASSERT(); 394 EUID_ASSERT();
422 395
diff --git a/src/firejail/cgroup.c b/src/firejail/cgroup.c
index ebd87f0d2..d9c7af9cf 100644
--- a/src/firejail/cgroup.c
+++ b/src/firejail/cgroup.c
@@ -30,10 +30,9 @@ void save_cgroup(void) {
30 if (fp) { 30 if (fp) {
31 fprintf(fp, "%s", cfg.cgroup); 31 fprintf(fp, "%s", cfg.cgroup);
32 fflush(0); 32 fflush(0);
33 SET_PERMS_STREAM(fp, 0, 0, 0644);
33 if (fclose(fp)) 34 if (fclose(fp))
34 goto errout; 35 goto errout;
35 if (chown(RUN_CGROUP_CFG, 0, 0) < 0)
36 errExit("chown");
37 } 36 }
38 else 37 else
39 goto errout; 38 goto errout;
diff --git a/src/firejail/checkcfg.c b/src/firejail/checkcfg.c
index 430b0c5a6..78c0e5c60 100644
--- a/src/firejail/checkcfg.c
+++ b/src/firejail/checkcfg.c
@@ -19,15 +19,17 @@
19*/ 19*/
20#include "firejail.h" 20#include "firejail.h"
21#include <sys/stat.h> 21#include <sys/stat.h>
22#include <linux/loop.h>
22 23
23#define MAX_READ 8192 // line buffer for profile files 24#define MAX_READ 8192 // line buffer for profile files
24 25
25static int initialized = 0; 26static int initialized = 0;
26static int cfg_val[CFG_MAX]; 27static int cfg_val[CFG_MAX];
27char *xephyr_screen = "800x600"; 28char *xephyr_screen = "800x600";
29char *xephyr_extra_params = "";
30char *netfilter_default = NULL;
28 31
29int checkcfg(int val) { 32int checkcfg(int val) {
30 EUID_ASSERT();
31 assert(val < CFG_MAX); 33 assert(val < CFG_MAX);
32 int line = 0; 34 int line = 0;
33 35
@@ -37,6 +39,8 @@ int checkcfg(int val) {
37 for (i = 0; i < CFG_MAX; i++) 39 for (i = 0; i < CFG_MAX; i++)
38 cfg_val[i] = 1; // most of them are enabled by default 40 cfg_val[i] = 1; // most of them are enabled by default
39 cfg_val[CFG_RESTRICTED_NETWORK] = 0; // disabled by default 41 cfg_val[CFG_RESTRICTED_NETWORK] = 0; // disabled by default
42 cfg_val[CFG_FORCE_NONEWPRIVS] = 0; // disabled by default
43 cfg_val[CFG_PRIVATE_BIN_NO_LOCAL] = 0; // disabled by default
40 44
41 // open configuration file 45 // open configuration file
42 char *fname; 46 char *fname;
@@ -45,10 +49,24 @@ int checkcfg(int val) {
45 49
46 FILE *fp = fopen(fname, "r"); 50 FILE *fp = fopen(fname, "r");
47 if (!fp) { 51 if (!fp) {
52#ifdef HAVE_GLOBALCFG
48 fprintf(stderr, "Error: Firejail configuration file %s not found\n", fname); 53 fprintf(stderr, "Error: Firejail configuration file %s not found\n", fname);
49 exit(1); 54 exit(1);
55#else
56 initialized = 1;
57 return cfg_val[val];
58#endif
50 } 59 }
51 60
61 // if the file exists, it should be owned by root
62 struct stat s;
63 if (stat(fname, &s) == -1)
64 errExit("stat");
65 if (s.st_uid != 0) {
66 fprintf(stderr, "Error: configuration file should be owned by root\n");
67 exit(1);
68 }
69
52 // read configuration file 70 // read configuration file
53 char buf[MAX_READ]; 71 char buf[MAX_READ];
54 while (fgets(buf,MAX_READ, fp)) { 72 while (fgets(buf,MAX_READ, fp)) {
@@ -106,6 +124,15 @@ int checkcfg(int val) {
106 else 124 else
107 goto errout; 125 goto errout;
108 } 126 }
127 // nonewprivs
128 else if (strncmp(ptr, "force-nonewprivs ", 17) == 0) {
129 if (strcmp(ptr + 17, "yes") == 0)
130 cfg_val[CFG_SECCOMP] = 1;
131 else if (strcmp(ptr + 17, "no") == 0)
132 cfg_val[CFG_SECCOMP] = 0;
133 else
134 goto errout;
135 }
109 // seccomp 136 // seccomp
110 else if (strncmp(ptr, "seccomp ", 8) == 0) { 137 else if (strncmp(ptr, "seccomp ", 8) == 0) {
111 if (strcmp(ptr + 8, "yes") == 0) 138 if (strcmp(ptr + 8, "yes") == 0)
@@ -115,6 +142,15 @@ int checkcfg(int val) {
115 else 142 else
116 goto errout; 143 goto errout;
117 } 144 }
145 // whitelist
146 else if (strncmp(ptr, "whitelist ", 10) == 0) {
147 if (strcmp(ptr + 10, "yes") == 0)
148 cfg_val[CFG_WHITELIST] = 1;
149 else if (strcmp(ptr + 10, "no") == 0)
150 cfg_val[CFG_WHITELIST] = 0;
151 else
152 goto errout;
153 }
118 // network 154 // network
119 else if (strncmp(ptr, "network ", 8) == 0) { 155 else if (strncmp(ptr, "network ", 8) == 0) {
120 if (strcmp(ptr + 8, "yes") == 0) 156 if (strcmp(ptr + 8, "yes") == 0)
@@ -133,6 +169,28 @@ int checkcfg(int val) {
133 else 169 else
134 goto errout; 170 goto errout;
135 } 171 }
172 // netfilter
173 else if (strncmp(ptr, "netfilter-default ", 18) == 0) {
174 char *fname = ptr + 18;
175 while (*fname == ' ' || *fname == '\t')
176 ptr++;
177 char *end = strchr(fname, ' ');
178 if (end)
179 *end = '\0';
180
181 // is the file present?
182 struct stat s;
183 if (stat(fname, &s) == -1) {
184 fprintf(stderr, "Error: netfilter-default file %s not available\n", fname);
185 exit(1);
186 }
187
188 netfilter_default = strdup(fname);
189 if (!netfilter_default)
190 errExit("strdup");
191 if (arg_debug)
192 printf("netfilter default file %s\n", fname);
193 }
136 194
137 // Xephyr screen size 195 // Xephyr screen size
138 else if (strncmp(ptr, "xephyr-screen ", 14) == 0) { 196 else if (strncmp(ptr, "xephyr-screen ", 14) == 0) {
@@ -145,9 +203,73 @@ int checkcfg(int val) {
145 if (asprintf(&xephyr_screen, "%dx%d", n1, n2) == -1) 203 if (asprintf(&xephyr_screen, "%dx%d", n1, n2) == -1)
146 errExit("asprintf"); 204 errExit("asprintf");
147 } 205 }
206
207 // xephyr window title
208 else if (strncmp(ptr, "xephyr-window-title ", 20) == 0) {
209 if (strcmp(ptr + 20, "yes") == 0)
210 cfg_val[CFG_XEPHYR_WINDOW_TITLE] = 1;
211 else if (strcmp(ptr + 20, "no") == 0)
212 cfg_val[CFG_XEPHYR_WINDOW_TITLE] = 0;
213 else
214 goto errout;
215 }
216
217 // Xephyr command extra parameters
218 else if (strncmp(ptr, "xephyr-extra-params ", 19) == 0) {
219 xephyr_extra_params = strdup(ptr + 19);
220 if (!xephyr_extra_params)
221 errExit("strdup");
222 }
223
224 // quiet by default
225 else if (strncmp(ptr, "quiet-by-default ", 17) == 0) {
226 if (strcmp(ptr + 17, "yes") == 0)
227 arg_quiet = 1;
228 }
229 // remount /proc and /sys
230 else if (strncmp(ptr, "remount-proc-sys ", 17) == 0) {
231 if (strcmp(ptr + 17, "yes") == 0)
232 cfg_val[CFG_REMOUNT_PROC_SYS] = 1;
233 else if (strcmp(ptr + 17, "no") == 0)
234 cfg_val[CFG_REMOUNT_PROC_SYS] = 0;
235 else
236 goto errout;
237 }
238 else if (strncmp(ptr, "overlayfs ", 10) == 0) {
239 if (strcmp(ptr + 10, "yes") == 0)
240 cfg_val[CFG_OVERLAYFS] = 1;
241 else if (strcmp(ptr + 10, "no") == 0)
242 cfg_val[CFG_OVERLAYFS] = 0;
243 else
244 goto errout;
245 }
246 else if (strncmp(ptr, "private-home ", 13) == 0) {
247 if (strcmp(ptr + 13, "yes") == 0)
248 cfg_val[CFG_PRIVATE_HOME] = 1;
249 else if (strcmp(ptr + 13, "no") == 0)
250 cfg_val[CFG_PRIVATE_HOME] = 0;
251 else
252 goto errout;
253 }
254 else if (strncmp(ptr, "chroot-desktop ", 15) == 0) {
255 if (strcmp(ptr + 15, "yes") == 0)
256 cfg_val[CFG_CHROOT_DESKTOP] = 1;
257 else if (strcmp(ptr + 15, "no") == 0)
258 cfg_val[CFG_CHROOT_DESKTOP] = 0;
259 else
260 goto errout;
261 }
262 else if (strncmp(ptr, "private-bin-no-local ", 21) == 0) {
263 if (strcmp(ptr + 21, "yes") == 0)
264 cfg_val[CFG_PRIVATE_BIN_NO_LOCAL] = 1;
265 else if (strcmp(ptr + 21, "no") == 0)
266 cfg_val[CFG_PRIVATE_BIN_NO_LOCAL] = 0;
267 else
268 goto errout;
269 }
148 else 270 else
149 goto errout; 271 goto errout;
150 272
151 free(ptr); 273 free(ptr);
152 } 274 }
153 275
@@ -163,3 +285,111 @@ errout:
163 exit(1); 285 exit(1);
164} 286}
165 287
288
289void print_compiletime_support(void) {
290 printf("Compile time support:\n");
291 printf("\t- AppArmor support is %s\n",
292#ifdef HAVE_APPARMOR
293 "enabled"
294#else
295 "disabled"
296#endif
297 );
298
299 printf("\t- AppImage support is %s\n",
300#ifdef LOOP_CTL_GET_FREE // test for older kernels; this definition is found in /usr/include/linux/loop.h
301 "enabled"
302#else
303 "disabled"
304#endif
305 );
306
307
308
309
310
311 printf("\t- bind support is %s\n",
312#ifdef HAVE_BIND
313 "enabled"
314#else
315 "disabled"
316#endif
317 );
318
319 printf("\t- chroot support is %s\n",
320#ifdef HAVE_CHROOT
321 "enabled"
322#else
323 "disabled"
324#endif
325 );
326
327 printf("\t- file and directory whitelisting support is %s\n",
328#ifdef HAVE_WHITELIST
329 "enabled"
330#else
331 "disabled"
332#endif
333 );
334
335 printf("\t- file transfer support is %s\n",
336#ifdef HAVE_FILE_TRANSFER
337 "enabled"
338#else
339 "disabled"
340#endif
341 );
342
343 printf("\t- networking support is %s\n",
344#ifdef HAVE_NETWORK
345 "enabled"
346#else
347 "disabled"
348#endif
349 );
350
351
352#ifdef HAVE_NETWORK_RESTRICTED
353 printf("\t- networking features are available only to root user\n");
354#endif
355
356 printf("\t- overlayfs support is %s\n",
357#ifdef HAVE_OVERLAYFS
358 "enabled"
359#else
360 "disabled"
361#endif
362 );
363
364 printf("\t- private-home support is %s\n",
365#ifdef HAVE_PRIVATE_HOME
366 "enabled"
367#else
368 "disabled"
369#endif
370 );
371
372 printf("\t- seccomp-bpf support is %s\n",
373#ifdef HAVE_SECCOMP
374 "enabled"
375#else
376 "disabled"
377#endif
378 );
379
380 printf("\t- user namespace support is %s\n",
381#ifdef HAVE_USERNS
382 "enabled"
383#else
384 "disabled"
385#endif
386 );
387
388 printf("\t- X11 sandboxing support is %s\n",
389#ifdef HAVE_X11
390 "enabled"
391#else
392 "disabled"
393#endif
394 );
395}
diff --git a/src/firejail/cmdline.c b/src/firejail/cmdline.c
new file mode 100644
index 000000000..cadf4795d
--- /dev/null
+++ b/src/firejail/cmdline.c
@@ -0,0 +1,159 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20
21#include "firejail.h"
22#include <string.h>
23#include <stdbool.h>
24#include <stdio.h>
25#include <linux/limits.h>
26#include <assert.h>
27#include <errno.h>
28
29static int cmdline_length(int argc, char **argv, int index) {
30 assert(index != -1);
31
32 unsigned i,j;
33 int len = 0;
34 unsigned argcnt = argc - index;
35 bool in_quotes = false;
36
37 for (i = 0; i < argcnt; i++) {
38 in_quotes = false;
39 for (j = 0; j < strlen(argv[i + index]); j++) {
40 if (argv[i + index][j] == '\'') {
41 if (in_quotes)
42 len++;
43 if (j > 0 && argv[i + index][j-1] == '\'')
44 len++;
45 else
46 len += 3;
47 in_quotes = false;
48 } else {
49 if (!in_quotes)
50 len++;
51 len++;
52 in_quotes = true;
53 }
54 }
55 if (in_quotes) {
56 len++;
57 }
58 if (strlen(argv[i + index]) == 0) {
59 len += 2;
60 }
61 len++;
62 }
63
64 return len;
65}
66
67static void quote_cmdline(char *command_line, char *window_title, int len, int argc, char **argv, int index) {
68 assert(index != -1);
69
70 unsigned i,j;
71 unsigned argcnt = argc - index;
72 bool in_quotes = false;
73 char *ptr1 = command_line;
74 char *ptr2 = window_title;
75
76 for (i = 0; i < argcnt; i++) {
77
78 // enclose args by single quotes,
79 // and since single quote can't be represented in single quoted text
80 // each occurence of it should be enclosed by double quotes
81 in_quotes = false;
82 for (j = 0; j < strlen(argv[i + index]); j++) {
83 // single quote
84 if (argv[i + index][j] == '\'') {
85 if (in_quotes) {
86 // close quotes
87 ptr1[0] = '\'';
88 ptr1++;
89 }
90 // previous char was single quote too
91 if (j > 0 && argv[i + index][j-1] == '\'') {
92 ptr1--;
93 sprintf(ptr1, "\'\"");
94 }
95 // this first in series
96 else
97 {
98 sprintf(ptr1, "\"\'\"");
99 }
100 ptr1 += strlen(ptr1);
101 in_quotes = false;
102 }
103 // anything other
104 else
105 {
106 if (!in_quotes) {
107 // open quotes
108 ptr1[0] = '\'';
109 ptr1++;
110 }
111 ptr1[0] = argv[i + index][j];
112 ptr1++;
113 in_quotes = true;
114 }
115 }
116 // close quotes
117 if (in_quotes) {
118 ptr1[0] = '\'';
119 ptr1++;
120 }
121 // handle empty argument case
122 if (strlen(argv[i + index]) == 0) {
123 sprintf(ptr1, "\'\'");
124 ptr1 += strlen(ptr1);
125 }
126 // add space
127 sprintf(ptr1, " ");
128 ptr1 += strlen(ptr1);
129
130 sprintf(ptr2, "%s ", argv[i + index]);
131 ptr2 += strlen(ptr2);
132 }
133
134 assert((unsigned) len == strlen(command_line));
135}
136
137void build_cmdline(char **command_line, char **window_title, int argc, char **argv, int index) {
138 // index == -1 could happen if we have --shell=none and no program was specified
139 // the program should exit with an error before entering this function
140 assert(index != -1);
141
142 int len = cmdline_length(argc, argv, index);
143 if (len > ARG_MAX) {
144 errno = E2BIG;
145 errExit("cmdline_length");
146 }
147
148 *command_line = malloc(len + 1);
149 if (!*command_line)
150 errExit("malloc");
151 *window_title = malloc(len + 1);
152 if (!*window_title)
153 errExit("malloc");
154
155 quote_cmdline(*command_line, *window_title, len, argc, argv, index);
156
157 assert(*command_line);
158 assert(*window_title);
159}
diff --git a/src/firejail/cpu.c b/src/firejail/cpu.c
index 1802ad5e1..7f53fed0f 100644
--- a/src/firejail/cpu.c
+++ b/src/firejail/cpu.c
@@ -78,11 +78,8 @@ void save_cpu(void) {
78 FILE *fp = fopen(RUN_CPU_CFG, "w"); 78 FILE *fp = fopen(RUN_CPU_CFG, "w");
79 if (fp) { 79 if (fp) {
80 fprintf(fp, "%x\n", cfg.cpus); 80 fprintf(fp, "%x\n", cfg.cpus);
81 SET_PERMS_STREAM(fp, 0, 0, 0600);
81 fclose(fp); 82 fclose(fp);
82 if (chmod(RUN_CPU_CFG, 0600) < 0)
83 errExit("chmod");
84 if (chown(RUN_CPU_CFG, 0, 0) < 0)
85 errExit("chown");
86 } 83 }
87 else { 84 else {
88 fprintf(stderr, "Error: cannot save cpu affinity mask\n"); 85 fprintf(stderr, "Error: cannot save cpu affinity mask\n");
@@ -171,21 +168,6 @@ static void print_cpu(int pid) {
171 free(file); 168 free(file);
172} 169}
173 170
174void cpu_print_filter_name(const char *name) {
175 EUID_ASSERT();
176 if (!name || strlen(name) == 0) {
177 fprintf(stderr, "Error: invalid sandbox name\n");
178 exit(1);
179 }
180 pid_t pid;
181 if (name2pid(name, &pid)) {
182 fprintf(stderr, "Error: cannot find sandbox %s\n", name);
183 exit(1);
184 }
185
186 cpu_print_filter(pid);
187}
188
189void cpu_print_filter(pid_t pid) { 171void cpu_print_filter(pid_t pid) {
190 EUID_ASSERT(); 172 EUID_ASSERT();
191 173
diff --git a/src/firejail/env.c b/src/firejail/env.c
index 54a6b0036..a02c67ae1 100644
--- a/src/firejail/env.c
+++ b/src/firejail/env.c
@@ -27,12 +27,27 @@ typedef struct env_t {
27 struct env_t *next; 27 struct env_t *next;
28 char *name; 28 char *name;
29 char *value; 29 char *value;
30 ENV_OP op;
30} Env; 31} Env;
31static Env *envlist = NULL; 32static Env *envlist = NULL;
32 33
33static void env_add(Env *env) { 34static void env_add(Env *env) {
34 env->next = envlist; 35 env->next = NULL;
35 envlist = env; 36
37 // add the new entry at the end of the list
38 if (envlist == NULL) {
39 envlist = env;
40 return;
41 }
42
43 Env *ptr = envlist;
44 while (1) {
45 if (ptr->next == NULL) {
46 ptr->next = env;
47 break;
48 }
49 ptr = ptr->next;
50 }
36} 51}
37 52
38// load IBUS env variables 53// load IBUS env variables
@@ -87,7 +102,7 @@ void env_ibus_load(void) {
87 if (arg_debug) 102 if (arg_debug)
88 printf("%s\n", buf); 103 printf("%s\n", buf);
89 EUID_USER(); 104 EUID_USER();
90 env_store(buf); 105 env_store(buf, SETENV);
91 EUID_ROOT(); 106 EUID_ROOT();
92 } 107 }
93 108
@@ -104,29 +119,31 @@ void env_defaults(void) {
104 // fix qt 4.8 119 // fix qt 4.8
105 if (setenv("QT_X11_NO_MITSHM", "1", 1) < 0) 120 if (setenv("QT_X11_NO_MITSHM", "1", 1) < 0)
106 errExit("setenv"); 121 errExit("setenv");
122// if (setenv("MOZ_NO_REMOTE, "1", 1) < 0)
123// errExit("setenv");
107 if (setenv("container", "firejail", 1) < 0) // LXC sets container=lxc, 124 if (setenv("container", "firejail", 1) < 0) // LXC sets container=lxc,
108 errExit("setenv"); 125 errExit("setenv");
109 if (arg_zsh && setenv("SHELL", "/usr/bin/zsh", 1) < 0) 126 if (!cfg.shell)
110 errExit("setenv"); 127 cfg.shell = guess_shell();
111 if (arg_csh && setenv("SHELL", "/bin/csh", 1) < 0)
112 errExit("setenv");
113 if (cfg.shell && setenv("SHELL", cfg.shell, 1) < 0) 128 if (cfg.shell && setenv("SHELL", cfg.shell, 1) < 0)
114 errExit("setenv"); 129 errExit("setenv");
130
115 // set prompt color to green 131 // set prompt color to green
116 //export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] ' 132 char *prompt = getenv("FIREJAIL_PROMPT");
117 if (setenv("PROMPT_COMMAND", "export PS1=\"\\[\\e[1;32m\\][\\u@\\h \\W]\\$\\[\\e[0m\\] \"", 1) < 0) 133 if (prompt && strcmp(prompt, "yes") == 0) {
118 errExit("setenv"); 134 //export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] '
135 if (setenv("PROMPT_COMMAND", "export PS1=\"\\[\\e[1;32m\\][\\u@\\h \\W]\\$\\[\\e[0m\\] \"", 1) < 0)
136 errExit("setenv");
137 }
119 138
120 // build the window title and set it 139 // set the window title
121 char *title; 140 if (!arg_quiet)
122 if (asprintf(&title, "\033]0;firejail %s\007\n", cfg.window_title) == -1) 141 printf("\033]0;firejail %s\007", cfg.window_title);
123 errExit("asprintf"); 142 fflush(0);
124 printf("%s", title);
125 free(title);
126} 143}
127 144
128// parse and store the environment setting 145// parse and store the environment setting
129void env_store(const char *str) { 146void env_store(const char *str, ENV_OP op) {
130 EUID_ASSERT(); 147 EUID_ASSERT();
131 assert(str); 148 assert(str);
132 149
@@ -134,11 +151,13 @@ void env_store(const char *str) {
134 if (*str == '\0') 151 if (*str == '\0')
135 goto errexit; 152 goto errexit;
136 char *ptr = strchr(str, '='); 153 char *ptr = strchr(str, '=');
137 if (!ptr) 154 if (op == SETENV) {
138 goto errexit; 155 if (!ptr)
139 ptr++; 156 goto errexit;
140 if (*ptr == '\0') 157 ptr++;
141 goto errexit; 158 if (*ptr == '\0')
159 goto errexit;
160 }
142 161
143 // build list entry 162 // build list entry
144 Env *env = malloc(sizeof(Env)); 163 Env *env = malloc(sizeof(Env));
@@ -148,10 +167,13 @@ void env_store(const char *str) {
148 env->name = strdup(str); 167 env->name = strdup(str);
149 if (env->name == NULL) 168 if (env->name == NULL)
150 errExit("strdup"); 169 errExit("strdup");
151 char *ptr2 = strchr(env->name, '='); 170 if (op == SETENV) {
152 assert(ptr2); 171 char *ptr2 = strchr(env->name, '=');
153 *ptr2 = '\0'; 172 assert(ptr2);
154 env->value = ptr2 + 1; 173 *ptr2 = '\0';
174 env->value = ptr2 + 1;
175 }
176 env->op = op;
155 177
156 // add entry to the list 178 // add entry to the list
157 env_add(env); 179 env_add(env);
@@ -167,8 +189,13 @@ void env_apply(void) {
167 Env *env = envlist; 189 Env *env = envlist;
168 190
169 while (env) { 191 while (env) {
170 if (setenv(env->name, env->value, 1) < 0) 192 if (env->op == SETENV) {
171 errExit("setenv"); 193 if (setenv(env->name, env->value, 1) < 0)
194 errExit("setenv");
195 }
196 else if (env->op == RMENV) {
197 unsetenv(env->name);
198 }
172 env = env->next; 199 env = env->next;
173 } 200 }
174} 201}
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 24ea53476..d7ba539e6 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -22,10 +22,13 @@
22#include "../include/common.h" 22#include "../include/common.h"
23#include "../include/euid_common.h" 23#include "../include/euid_common.h"
24 24
25// debug restricted shell
26//#define DEBUG_RESTRICTED_SHELL
25 27
26// filesystem 28// filesystem
27#define RUN_FIREJAIL_BASEDIR "/run" 29#define RUN_FIREJAIL_BASEDIR "/run"
28#define RUN_FIREJAIL_DIR "/run/firejail" 30#define RUN_FIREJAIL_DIR "/run/firejail"
31#define RUN_FIREJAIL_APPIMAGE_DIR "/run/firejail/appimage"
29#define RUN_FIREJAIL_NAME_DIR "/run/firejail/name" 32#define RUN_FIREJAIL_NAME_DIR "/run/firejail/name"
30#define RUN_FIREJAIL_X11_DIR "/run/firejail/x11" 33#define RUN_FIREJAIL_X11_DIR "/run/firejail/x11"
31#define RUN_FIREJAIL_NETWORK_DIR "/run/firejail/network" 34#define RUN_FIREJAIL_NETWORK_DIR "/run/firejail/network"
@@ -34,7 +37,6 @@
34#define RUN_RO_DIR "/run/firejail/firejail.ro.dir" 37#define RUN_RO_DIR "/run/firejail/firejail.ro.dir"
35#define RUN_RO_FILE "/run/firejail/firejail.ro.file" 38#define RUN_RO_FILE "/run/firejail/firejail.ro.file"
36#define RUN_MNT_DIR "/run/firejail/mnt" // a tmpfs is mounted on this directory before any of the files below are created 39#define RUN_MNT_DIR "/run/firejail/mnt" // a tmpfs is mounted on this directory before any of the files below are created
37#define RUN_SECCOMP_CFG "/run/firejail/mnt/seccomp"
38#define RUN_CGROUP_CFG "/run/firejail/mnt/cgroup" 40#define RUN_CGROUP_CFG "/run/firejail/mnt/cgroup"
39#define RUN_CPU_CFG "/run/firejail/mnt/cpu" 41#define RUN_CPU_CFG "/run/firejail/mnt/cpu"
40#define RUN_GROUPS_CFG "/run/firejail/mnt/groups" 42#define RUN_GROUPS_CFG "/run/firejail/mnt/groups"
@@ -43,8 +45,15 @@
43#define RUN_HOME_DIR "/run/firejail/mnt/home" 45#define RUN_HOME_DIR "/run/firejail/mnt/home"
44#define RUN_ETC_DIR "/run/firejail/mnt/etc" 46#define RUN_ETC_DIR "/run/firejail/mnt/etc"
45#define RUN_BIN_DIR "/run/firejail/mnt/bin" 47#define RUN_BIN_DIR "/run/firejail/mnt/bin"
46#define RUN_DRI_DIR "/run/firejail/mnt/dri"
47#define RUN_PULSE_DIR "/run/firejail/mnt/pulse" 48#define RUN_PULSE_DIR "/run/firejail/mnt/pulse"
49
50#define RUN_SECCOMP_CFG "/run/firejail/mnt/seccomp" // configured filter
51#define RUN_SECCOMP_PROTOCOL "/run/firejail/mnt/seccomp.protocol" // protocol filter
52#define RUN_SECCOMP_AMD64 "/run/firejail/mnt/seccomp.amd64" // amd64 filter installed on i386 architectures
53#define RUN_SECCOMP_I386 "/run/firejail/mnt/seccomp.i386" // i386 filter installed on amd64 architectures
54
55
56#define RUN_DEV_DIR "/run/firejail/mnt/dev"
48#define RUN_DEVLOG_FILE "/run/firejail/mnt/devlog" 57#define RUN_DEVLOG_FILE "/run/firejail/mnt/devlog"
49 58
50#define RUN_WHITELIST_X11_DIR "/run/firejail/mnt/orig-x11" 59#define RUN_WHITELIST_X11_DIR "/run/firejail/mnt/orig-x11"
@@ -52,11 +61,14 @@
52#define RUN_WHITELIST_HOME_USER_DIR "/run/firejail/mnt/orig-home-user" // home directory whitelisting 61#define RUN_WHITELIST_HOME_USER_DIR "/run/firejail/mnt/orig-home-user" // home directory whitelisting
53#define RUN_WHITELIST_TMP_DIR "/run/firejail/mnt/orig-tmp" 62#define RUN_WHITELIST_TMP_DIR "/run/firejail/mnt/orig-tmp"
54#define RUN_WHITELIST_MEDIA_DIR "/run/firejail/mnt/orig-media" 63#define RUN_WHITELIST_MEDIA_DIR "/run/firejail/mnt/orig-media"
64#define RUN_WHITELIST_MNT_DIR "/run/firejail/mnt/orig-mnt"
55#define RUN_WHITELIST_VAR_DIR "/run/firejail/mnt/orig-var" 65#define RUN_WHITELIST_VAR_DIR "/run/firejail/mnt/orig-var"
56#define RUN_WHITELIST_DEV_DIR "/run/firejail/mnt/orig-dev" 66#define RUN_WHITELIST_DEV_DIR "/run/firejail/mnt/orig-dev"
57#define RUN_WHITELIST_OPT_DIR "/run/firejail/mnt/orig-opt" 67#define RUN_WHITELIST_OPT_DIR "/run/firejail/mnt/orig-opt"
68#define RUN_WHITELIST_SRV_DIR "/run/firejail/mnt/orig-srv"
58 69
59#define RUN_XAUTHORITY_FILE "/run/firejail/mnt/.Xauthority" 70#define RUN_XAUTHORITY_FILE "/run/firejail/mnt/.Xauthority"
71#define RUN_XAUTHORITY_SEC_FILE "/run/firejail/mnt/sec.Xauthority"
60#define RUN_ASOUNDRC_FILE "/run/firejail/mnt/.asoundrc" 72#define RUN_ASOUNDRC_FILE "/run/firejail/mnt/.asoundrc"
61#define RUN_HOSTNAME_FILE "/run/firejail/mnt/hostname" 73#define RUN_HOSTNAME_FILE "/run/firejail/mnt/hostname"
62#define RUN_HOSTS_FILE "/run/firejail/mnt/hosts" 74#define RUN_HOSTS_FILE "/run/firejail/mnt/hosts"
@@ -67,11 +79,59 @@
67#define RUN_GROUP_FILE "/run/firejail/mnt/group" 79#define RUN_GROUP_FILE "/run/firejail/mnt/group"
68#define RUN_FSLOGGER_FILE "/run/firejail/mnt/fslogger" 80#define RUN_FSLOGGER_FILE "/run/firejail/mnt/fslogger"
69 81
82
83
70// profiles 84// profiles
71#define DEFAULT_USER_PROFILE "generic" 85#define DEFAULT_USER_PROFILE "default"
72#define DEFAULT_ROOT_PROFILE "server" 86#define DEFAULT_ROOT_PROFILE "server"
73#define MAX_INCLUDE_LEVEL 6 // include levels in profile files 87#define MAX_INCLUDE_LEVEL 6 // include levels in profile files
74 88
89
90#define ASSERT_PERMS(file, uid, gid, mode) \
91 do { \
92 assert(file);\
93 struct stat s;\
94 if (stat(file, &s) == -1) errExit("stat");\
95 assert(s.st_uid == uid);\
96 assert(s.st_gid == gid);\
97 assert((s.st_mode & 07777) == (mode));\
98 } while (0)
99#define ASSERT_PERMS_FD(fd, uid, gid, mode) \
100 do { \
101 struct stat s;\
102 if (stat(fd, &s) == -1) errExit("stat");\
103 assert(s.st_uid == uid);\
104 assert(s.st_gid == gid);\
105 assert((s.st_mode & 07777) == (mode));\
106 } while (0)
107#define ASSERT_PERMS_STREAM(file, uid, gid, mode) \
108 do { \
109 int fd = fileno(file);\
110 if (fd == -1) errExit("fileno");\
111 ASSERT_PERMS_FD(fd, uid, gid, (mode));\
112 } while (0)
113
114#define SET_PERMS_FD(fd, uid, gid, mode) \
115 do { \
116 if (fchmod(fd, (mode)) == -1) errExit("chmod");\
117 if (fchown(fd, uid, gid) == -1) errExit("chown");\
118 } while (0)
119#define SET_PERMS_STREAM(stream, uid, gid, mode) \
120 do { \
121 int fd = fileno(stream);\
122 if (fd == -1) errExit("fileno");\
123 SET_PERMS_FD(fd, uid, gid, (mode));\
124 } while (0)
125#define SET_PERMS_STREAM_NOERR(stream, uid, gid, mode) \
126 do { \
127 int fd = fileno(stream);\
128 if (fd == -1) continue;\
129 int rv = fchmod(fd, (mode));\
130 (void) rv;\
131 rv = fchown(fd, uid, gid);\
132 (void) rv;\
133 } while (0)
134
75// main.c 135// main.c
76typedef struct bridge_t { 136typedef struct bridge_t {
77 // on the host 137 // on the host
@@ -81,6 +141,8 @@ typedef struct bridge_t {
81 uint8_t mac[6]; // interface mac address 141 uint8_t mac[6]; // interface mac address
82 int mtu; // interface mtu 142 int mtu; // interface mtu
83 143
144 char *veth_name; // veth name for the device connected to the bridge
145
84 // inside the sandbox 146 // inside the sandbox
85 char *devsandbox; // name of the device inside the sandbox 147 char *devsandbox; // name of the device inside the sandbox
86 uint32_t ipsandbox; // ip address inside the sandbox 148 uint32_t ipsandbox; // ip address inside the sandbox
@@ -115,9 +177,11 @@ typedef struct profile_entry_t {
115 unsigned home_dir:1; // whitelist in /home/user directory 177 unsigned home_dir:1; // whitelist in /home/user directory
116 unsigned tmp_dir:1; // whitelist in /tmp directory 178 unsigned tmp_dir:1; // whitelist in /tmp directory
117 unsigned media_dir:1; // whitelist in /media directory 179 unsigned media_dir:1; // whitelist in /media directory
180 unsigned mnt_dir:1; // whitelist in /mnt directory
118 unsigned var_dir:1; // whitelist in /var directory 181 unsigned var_dir:1; // whitelist in /var directory
119 unsigned dev_dir:1; // whitelist in /dev directory 182 unsigned dev_dir:1; // whitelist in /dev directory
120 unsigned opt_dir:1; // whitelist in /opt directory 183 unsigned opt_dir:1; // whitelist in /opt directory
184 unsigned srv_dir:1; // whitelist in /srv directory
121}ProfileEntry; 185}ProfileEntry;
122 186
123typedef struct config_t { 187typedef struct config_t {
@@ -131,10 +195,12 @@ typedef struct config_t {
131 char *profile_ignore[MAX_PROFILE_IGNORE]; 195 char *profile_ignore[MAX_PROFILE_IGNORE];
132 char *chrootdir; // chroot directory 196 char *chrootdir; // chroot directory
133 char *home_private; // private home directory 197 char *home_private; // private home directory
198 char *home_private_keep; // keep list for private home directory
134 char *etc_private_keep; // keep list for private etc directory 199 char *etc_private_keep; // keep list for private etc directory
135 char *bin_private_keep; // keep list for private bin directory 200 char *bin_private_keep; // keep list for private bin directory
136 char *cwd; // current working directory 201 char *cwd; // current working directory
137 char *overlay_dir; 202 char *overlay_dir;
203 char *private_template; // template dir for tmpfs home
138 204
139 // networking 205 // networking
140 char *name; // sandbox name 206 char *name; // sandbox name
@@ -156,7 +222,6 @@ typedef struct config_t {
156 char *seccomp_list;// optional seccomp list on top of default filter 222 char *seccomp_list;// optional seccomp list on top of default filter
157 char *seccomp_list_drop; // seccomp drop list 223 char *seccomp_list_drop; // seccomp drop list
158 char *seccomp_list_keep; // seccomp keep list 224 char *seccomp_list_keep; // seccomp keep list
159 char **seccomp_list_errno; // seccomp errno[nr] lists
160 char *protocol; // protocol list 225 char *protocol; // protocol list
161 226
162 // rlimits 227 // rlimits
@@ -211,6 +276,7 @@ static inline int any_interface_configured(void) {
211void clear_run_files(pid_t pid); 276void clear_run_files(pid_t pid);
212 277
213extern int arg_private; // mount private /home 278extern int arg_private; // mount private /home
279extern int arg_private_template; // private /home template
214extern int arg_debug; // print debug messages 280extern int arg_debug; // print debug messages
215extern int arg_debug_check_filename; // print debug messages for filename checking 281extern int arg_debug_check_filename; // print debug messages for filename checking
216extern int arg_debug_blacklists; // print debug messages for blacklists 282extern int arg_debug_blacklists; // print debug messages for blacklists
@@ -218,9 +284,8 @@ extern int arg_debug_whitelists; // print debug messages for whitelists
218extern int arg_nonetwork; // --net=none 284extern int arg_nonetwork; // --net=none
219extern int arg_command; // -c 285extern int arg_command; // -c
220extern int arg_overlay; // overlay option 286extern int arg_overlay; // overlay option
221extern int arg_overlay_keep; // place overlay diff directory in ~/.firejail 287extern int arg_overlay_keep; // place overlay diff in a known directory
222extern int arg_zsh; // use zsh as default shell 288extern int arg_overlay_reuse; // allow the reuse of overlays
223extern int arg_csh; // use csh as default shell
224 289
225extern int arg_seccomp; // enable default seccomp filter 290extern int arg_seccomp; // enable default seccomp filter
226 291
@@ -237,6 +302,7 @@ extern int arg_rlimit_nproc; // rlimit nproc
237extern int arg_rlimit_fsize; // rlimit fsize 302extern int arg_rlimit_fsize; // rlimit fsize
238extern int arg_rlimit_sigpending;// rlimit sigpending 303extern int arg_rlimit_sigpending;// rlimit sigpending
239extern int arg_nogroups; // disable supplementary groups 304extern int arg_nogroups; // disable supplementary groups
305extern int arg_nonewprivs; // set the NO_NEW_PRIVS prctl
240extern int arg_noroot; // create a new user namespace and disable root user 306extern int arg_noroot; // create a new user namespace and disable root user
241extern int arg_netfilter; // enable netfilter 307extern int arg_netfilter; // enable netfilter
242extern int arg_netfilter6; // enable netfilter6 308extern int arg_netfilter6; // enable netfilter6
@@ -251,12 +317,24 @@ extern int arg_private_tmp; // private tmp directory
251extern int arg_scan; // arp-scan all interfaces 317extern int arg_scan; // arp-scan all interfaces
252extern int arg_whitelist; // whitelist commad 318extern int arg_whitelist; // whitelist commad
253extern int arg_nosound; // disable sound 319extern int arg_nosound; // disable sound
320extern int arg_no3d; // disable 3d hardware acceleration
254extern int arg_quiet; // no output for scripting 321extern int arg_quiet; // no output for scripting
255extern int arg_join_network; // join only the network namespace 322extern int arg_join_network; // join only the network namespace
256extern int arg_join_filesystem; // join only the mount namespace 323extern int arg_join_filesystem; // join only the mount namespace
257extern int arg_nice; // nice value configured 324extern int arg_nice; // nice value configured
258extern int arg_ipc; // enable ipc namespace 325extern int arg_ipc; // enable ipc namespace
259 326extern int arg_writable_etc; // writable etc
327extern int arg_writable_var; // writable var
328extern int arg_appimage; // appimage
329extern int arg_audit; // audit
330extern char *arg_audit_prog; // audit
331extern int arg_apparmor; // apparmor
332extern int arg_allow_debuggers; // allow debuggers
333extern int arg_x11_block; // block X11
334extern int arg_x11_xorg; // use X11 security extention
335extern int arg_allusers; // all user home directories visible
336
337extern int login_shell;
260extern int parent_to_child_fds[2]; 338extern int parent_to_child_fds[2];
261extern int child_to_parent_fds[2]; 339extern int child_to_parent_fds[2];
262extern pid_t sandbox_pid; 340extern pid_t sandbox_pid;
@@ -267,16 +345,17 @@ extern int fullargc;
267 345
268// main.c 346// main.c
269void check_user_namespace(void); 347void check_user_namespace(void);
348char *guess_shell(void);
270 349
271// sandbox.c 350// sandbox.c
272int sandbox(void* sandbox_arg); 351int sandbox(void* sandbox_arg);
352void start_application(void);
273 353
274// network_main.c 354// network_main.c
275void net_configure_bridge(Bridge *br, char *dev_name); 355void net_configure_bridge(Bridge *br, char *dev_name);
276void net_configure_sandbox_ip(Bridge *br); 356void net_configure_sandbox_ip(Bridge *br);
277void net_configure_veth_pair(Bridge *br, const char *ifname, pid_t child); 357void net_configure_veth_pair(Bridge *br, const char *ifname, pid_t child);
278void net_check_cfg(void); 358void net_check_cfg(void);
279void net_dns_print_name(const char *name);
280void net_dns_print(pid_t pid); 359void net_dns_print(pid_t pid);
281void network_main(pid_t child); 360void network_main(pid_t child);
282 361
@@ -287,35 +366,35 @@ void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask, int mtu);
287void net_if_ip6(const char *ifname, const char *addr6); 366void net_if_ip6(const char *ifname, const char *addr6);
288int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t mac[6], int *mtu); 367int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t mac[6], int *mtu);
289int net_add_route(uint32_t dest, uint32_t mask, uint32_t gw); 368int net_add_route(uint32_t dest, uint32_t mask, uint32_t gw);
290void net_ifprint(void);
291void net_bridge_add_interface(const char *bridge, const char *dev);
292uint32_t network_get_defaultgw(void); 369uint32_t network_get_defaultgw(void);
293int net_config_mac(const char *ifname, const unsigned char mac[6]); 370int net_config_mac(const char *ifname, const unsigned char mac[6]);
294int net_get_mac(const char *ifname, unsigned char mac[6]); 371int net_get_mac(const char *ifname, unsigned char mac[6]);
372void net_config_interface(const char *dev, uint32_t ip, uint32_t mask, int mtu);
373
374// preproc.c
375void preproc_build_firejail_dir(void);
376void preproc_mount_mnt_dir(void);
377void preproc_build_cp_command(void);
378void preproc_delete_cp_command(void) ;
379void preproc_remount_mnt_dir(void);
295 380
296// fs.c 381// fs.c
297// build /run/firejail directory
298void fs_build_firejail_dir(void);
299// build /run/firejail/mnt directory
300void fs_build_mnt_dir(void);
301// grab a copy of cp command
302void fs_build_cp_command(void);
303// delete the temporary cp command
304void fs_delete_cp_command(void) ;
305// blacklist files or directoies by mounting empty files on top of them 382// blacklist files or directoies by mounting empty files on top of them
306void fs_blacklist(void); 383void fs_blacklist(void);
307// remount a directory read-only 384// remount a directory read-only
308void fs_rdonly(const char *dir); 385void fs_rdonly(const char *dir);
386// remount a directory noexec, nodev and nosuid
387void fs_noexec(const char *dir);
309// mount /proc and /sys directories 388// mount /proc and /sys directories
310void fs_proc_sys_dev_boot(void); 389void fs_proc_sys_dev_boot(void);
311// build a basic read-only filesystem 390// build a basic read-only filesystem
312void fs_basic_fs(void); 391void fs_basic_fs(void);
313// mount overlayfs on top of / directory 392// mount overlayfs on top of / directory
393char *fs_check_overlay_dir(const char *subdirname, int allow_reuse);
314void fs_overlayfs(void); 394void fs_overlayfs(void);
315// chroot into an existing directory; mount exiting /dev and update /etc/resolv.conf 395// chroot into an existing directory; mount exiting /dev and update /etc/resolv.conf
316void fs_chroot(const char *rootdir); 396void fs_chroot(const char *rootdir);
317int fs_check_chroot_dir(const char *rootdir); 397int fs_check_chroot_dir(const char *rootdir);
318void fs_private_tmp(void);
319 398
320// profile.c 399// profile.c
321// find and read the profile specified by name from dir directory 400// find and read the profile specified by name from dir directory
@@ -340,12 +419,11 @@ void usage(void);
340 419
341// join.c 420// join.c
342void join(pid_t pid, int argc, char **argv, int index); 421void join(pid_t pid, int argc, char **argv, int index);
343void join_name(const char *name, int argc, char **argv, int index); 422
423// shutdown.c
344void shut(pid_t pid); 424void shut(pid_t pid);
345void shut_name(const char *name);
346 425
347// restricted_shell.c 426// restricted_shell.c
348extern char *restricted_user;
349int restricted_shell(const char *user); 427int restricted_shell(const char *user);
350 428
351// arp.c 429// arp.c
@@ -353,13 +431,6 @@ int restricted_shell(const char *user);
353int arp_check(const char *dev, uint32_t destaddr, uint32_t srcaddr); 431int arp_check(const char *dev, uint32_t destaddr, uint32_t srcaddr);
354// assign an IP address using arp scanning 432// assign an IP address using arp scanning
355uint32_t arp_assign(const char *dev, Bridge *br); 433uint32_t arp_assign(const char *dev, Bridge *br);
356// scan interface (--scan option)
357void arp_scan(const char *dev, uint32_t srcaddr, uint32_t srcmask);
358
359// veth.c
360int net_create_veth(const char *dev, const char *nsdev, unsigned pid);
361int net_create_macvlan(const char *dev, const char *parent, unsigned pid);
362int net_move_interface(const char *dev, unsigned pid);
363 434
364// util.c 435// util.c
365void drop_privs(int nogroups); 436void drop_privs(int nogroups);
@@ -369,7 +440,7 @@ void logsignal(int s);
369void logmsg(const char *msg); 440void logmsg(const char *msg);
370void logargs(int argc, char **argv) ; 441void logargs(int argc, char **argv) ;
371void logerr(const char *msg); 442void logerr(const char *msg);
372int copy_file(const char *srcname, const char *destname); 443int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode);
373int is_dir(const char *fname); 444int is_dir(const char *fname);
374int is_link(const char *fname); 445int is_link(const char *fname);
375char *line_remove_spaces(const char *buf); 446char *line_remove_spaces(const char *buf);
@@ -384,8 +455,13 @@ char *expand_home(const char *path, const char* homedir);
384const char *gnu_basename(const char *path); 455const char *gnu_basename(const char *path);
385uid_t pid_get_uid(pid_t pid); 456uid_t pid_get_uid(pid_t pid);
386void invalid_filename(const char *fname); 457void invalid_filename(const char *fname);
387uid_t get_tty_gid(void); 458uid_t get_group_id(const char *group);
388uid_t get_audio_gid(void); 459int remove_directory(const char *path);
460void flush_stdin(void);
461void create_empty_dir_as_root(const char *dir, mode_t mode);
462void create_empty_file_as_root(const char *dir, mode_t mode);
463int set_perms(const char *fname, uid_t uid, gid_t gid, mode_t mode);
464void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid);
389 465
390// fs_var.c 466// fs_var.c
391void fs_var_log(void); // mounting /var/log 467void fs_var_log(void); // mounting /var/log
@@ -400,23 +476,33 @@ void dbg_test_dir(const char *dir);
400// fs_dev.c 476// fs_dev.c
401void fs_dev_shm(void); 477void fs_dev_shm(void);
402void fs_private_dev(void); 478void fs_private_dev(void);
479void fs_dev_disable_sound(void);
480void fs_dev_disable_3d(void);
403 481
404// fs_home.c 482// fs_home.c
405// private mode (--private) 483// private mode (--private)
406void fs_private(void); 484void fs_private(void);
407// private mode (--private=homedir) 485// private mode (--private=homedir)
408void fs_private_homedir(void); 486void fs_private_homedir(void);
487// private template (--private-template=templatedir)
488void fs_private_template(void);
409// check new private home directory (--private= option) - exit if it fails 489// check new private home directory (--private= option) - exit if it fails
410void fs_check_private_dir(void); 490void fs_check_private_dir(void);
491// check new private template home directory (--private-template= option) exit if it fails
492void fs_check_private_template(void);
493// check directory list specified by user (--private-home option) - exit if it fails
494void fs_check_home_list(void);
495void fs_private_home_list(void);
411 496
412 497
413// seccomp.c 498// seccomp.c
499char *seccomp_check_list(const char *str);
500int seccomp_load(const char *fname);
501void seccomp_filter_32(void);
502void seccomp_filter_64(void);
414int seccomp_filter_drop(int enforce_seccomp); 503int seccomp_filter_drop(int enforce_seccomp);
415int seccomp_filter_keep(void); 504int seccomp_filter_keep(void);
416void seccomp_set(void);
417void seccomp_print_filter_name(const char *name);
418void seccomp_print_filter(pid_t pid); 505void seccomp_print_filter(pid_t pid);
419int seccomp_filter_errno(void);
420 506
421// caps.c 507// caps.c
422int caps_default_filter(void); 508int caps_default_filter(void);
@@ -427,14 +513,11 @@ int caps_check_list(const char *clist, void (*callback)(int));
427void caps_drop_list(const char *clist); 513void caps_drop_list(const char *clist);
428void caps_keep_list(const char *clist); 514void caps_keep_list(const char *clist);
429void caps_print_filter(pid_t pid); 515void caps_print_filter(pid_t pid);
430void caps_print_filter_name(const char *name);
431 516
432// syscall.c 517// syscall.c
433const char *syscall_find_nr(int nr); 518const char *syscall_find_nr(int nr);
434// return -1 if error, 0 if no error 519// return -1 if error, 0 if no error
435int syscall_check_list(const char *slist, void (*callback)(int syscall, int arg), int arg); 520int syscall_check_list(const char *slist, void (*callback)(int syscall, int arg), int arg);
436// print all available syscallsseccomp
437void syscall_print(void);
438 521
439// fs_trace.c 522// fs_trace.c
440void fs_trace_preload(void); 523void fs_trace_preload(void);
@@ -452,7 +535,6 @@ void read_cpu_list(const char *str);
452void set_cpu_affinity(void); 535void set_cpu_affinity(void);
453void load_cpu(const char *fname); 536void load_cpu(const char *fname);
454void save_cpu(void); 537void save_cpu(void);
455void cpu_print_filter_name(const char *name);
456void cpu_print_filter(pid_t pid); 538void cpu_print_filter(pid_t pid);
457 539
458// cgroup.c 540// cgroup.c
@@ -470,7 +552,6 @@ void netfilter6(const char *fname);
470 552
471// bandwidth.c 553// bandwidth.c
472void bandwidth_del_run_file(pid_t pid); 554void bandwidth_del_run_file(pid_t pid);
473void bandwidth_name(const char *name, const char *command, const char *dev, int down, int up);
474void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, int up); 555void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, int up);
475void network_del_run_file(pid_t pid); 556void network_del_run_file(pid_t pid);
476void network_set_run_file(pid_t pid); 557void network_set_run_file(pid_t pid);
@@ -480,11 +561,17 @@ void fs_check_etc_list(void);
480void fs_private_etc_list(void); 561void fs_private_etc_list(void);
481 562
482// no_sandbox.c 563// no_sandbox.c
564int check_namespace_virt(void);
483int check_kernel_procs(void); 565int check_kernel_procs(void);
484void run_no_sandbox(int argc, char **argv); 566void run_no_sandbox(int argc, char **argv);
485 567
486// env.c 568// env.c
487void env_store(const char *str); 569typedef enum {
570 SETENV = 0,
571 RMENV
572} ENV_OP;
573
574void env_store(const char *str, ENV_OP op);
488void env_apply(void); 575void env_apply(void);
489void env_defaults(void); 576void env_defaults(void);
490void env_ibus_load(void); 577void env_ibus_load(void);
@@ -507,13 +594,9 @@ void fs_check_bin_list(void);
507void fs_private_bin_list(void); 594void fs_private_bin_list(void);
508 595
509// protocol.c 596// protocol.c
510void protocol_list();
511void protocol_print_filter_name(const char *name);
512void protocol_print_filter(pid_t pid);
513void protocol_store(const char *prlist);
514void protocol_filter(void);
515void protocol_filter_save(void); 597void protocol_filter_save(void);
516void protocol_filter_load(const char *fname); 598void protocol_filter_load(const char *fname);
599void protocol_print_filter(pid_t pid);
517 600
518// restrict_users.c 601// restrict_users.c
519void restrict_users(void); 602void restrict_users(void);
@@ -525,46 +608,90 @@ void fs_logger2int(const char *msg1, int d);
525void fs_logger3(const char *msg1, const char *msg2, const char *msg3); 608void fs_logger3(const char *msg1, const char *msg2, const char *msg3);
526void fs_logger_print(void); 609void fs_logger_print(void);
527void fs_logger_change_owner(void); 610void fs_logger_change_owner(void);
528void fs_logger_print_log_name(const char *name);
529void fs_logger_print_log(pid_t pid); 611void fs_logger_print_log(pid_t pid);
530 612
531// run_symlink.c 613// run_symlink.c
532void run_symlink(int argc, char **argv); 614void run_symlink(int argc, char **argv);
533 615
534// user.c
535void check_user(int argc, char **argv);
536
537// paths.c 616// paths.c
538char **build_paths(void); 617char **build_paths(void);
539 618
540// fs_mkdir.c 619// fs_mkdir.c
541void fs_mkdir(const char *name); 620void fs_mkdir(const char *name);
621void fs_mkfile(const char *name);
542 622
543// x11.c 623// x11.c
624extern int mask_x11_abstract_socket;
544void fs_x11(void); 625void fs_x11(void);
545int x11_display(void); 626int x11_display(void);
546void x11_start(int argc, char **argv); 627void x11_start(int argc, char **argv);
547void x11_start_xpra(int argc, char **argv); 628void x11_start_xpra(int argc, char **argv);
548void x11_start_xephyr(int argc, char **argv); 629void x11_start_xephyr(int argc, char **argv);
549extern char *xephyr_screen; 630void x11_block(void);
550 631
551// ls.c 632// ls.c
552#define SANDBOX_FS_LS 0 633enum {
553#define SANDBOX_FS_GET 1 634 SANDBOX_FS_LS = 0,
554void sandboxfs_name(int op, const char *name, const char *path); 635 SANDBOX_FS_GET,
555void sandboxfs(int op, pid_t pid, const char *patqh); 636 SANDBOX_FS_PUT,
637 SANDBOX_FS_MAX // this should always be the last entry
638};
639void sandboxfs(int op, pid_t pid, const char *path1, const char *path2);
556 640
557// checkcfg.c 641// checkcfg.c
558#define CFG_FILE_TRANSFER 0 642enum {
559#define CFG_X11 1 643 CFG_FILE_TRANSFER = 0,
560#define CFG_BIND 2 644 CFG_X11,
561#define CFG_USERNS 3 645 CFG_BIND,
562#define CFG_CHROOT 4 646 CFG_USERNS,
563#define CFG_SECCOMP 5 647 CFG_CHROOT,
564#define CFG_NETWORK 6 648 CFG_SECCOMP,
565#define CFG_RESTRICTED_NETWORK 7 649 CFG_NETWORK,
566#define CFG_MAX 8 // this should always be the last entry 650 CFG_RESTRICTED_NETWORK,
651 CFG_FORCE_NONEWPRIVS,
652 CFG_WHITELIST,
653 CFG_XEPHYR_WINDOW_TITLE,
654 CFG_REMOUNT_PROC_SYS,
655 CFG_OVERLAYFS,
656 CFG_CHROOT_DESKTOP,
657 CFG_PRIVATE_HOME,
658 CFG_PRIVATE_BIN_NO_LOCAL,
659 CFG_MAX // this should always be the last entry
660};
661extern char *xephyr_screen;
662extern char *xephyr_extra_params;
663extern char *netfilter_default;
567int checkcfg(int val); 664int checkcfg(int val);
665void print_compiletime_support(void);
666void x11_xorg(void);
667
668// appimage.c
669void appimage_set(const char *appimage_path);
670void appimage_clear(void);
671const char *appimage_getdir(void);
672
673// appimage_size.c
674long unsigned int appimage2_size(const char *fname);
675
676// cmdline.c
677void build_cmdline(char **command_line, char **window_title, int argc, char **argv, int index);
678
679// sbox.c
680// programs
681#define PATH_FNET (LIBDIR "/firejail/fnet")
682#define PATH_FIREMON (PREFIX "/bin/firemon")
683#define PATH_FSECCOMP (LIBDIR "/firejail/fseccomp")
684// bitmapped filters for sbox_run
685#define SBOX_ROOT (1 << 0) // run the sandbox as root
686#define SBOX_USER (1 << 1) // run the sandbox as a regular user
687#define SBOX_SECCOMP (1 << 2) // install seccomp
688#define SBOX_CAPS_NONE (1 << 3) // drop all capabilities
689#define SBOX_CAPS_NETWORK (1 << 4) // caps filter for programs running network programs
690#define SBOX_ALLOW_STDIN (1 << 5) // don't close stdin
691
692// run sbox
693int sbox_run(unsigned filter, int num, ...);
694
568 695
569#endif 696#endif
570 697
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index 7ee76d096..7ff7e3c59 100644
--- a/src/firejail/fs.c
+++ b/src/firejail/fs.c
@@ -27,198 +27,9 @@
27#include <fcntl.h> 27#include <fcntl.h>
28#include <errno.h> 28#include <errno.h>
29 29
30static void create_empty_dir(void) { 30static void fs_rdwr(const char *dir);
31 struct stat s;
32
33 if (stat(RUN_RO_DIR, &s)) {
34 /* coverity[toctou] */
35 int rv = mkdir(RUN_RO_DIR, S_IRUSR | S_IXUSR);
36 if (rv == -1)
37 errExit("mkdir");
38 if (chown(RUN_RO_DIR, 0, 0) < 0)
39 errExit("chown");
40 }
41}
42
43static void create_empty_file(void) {
44 struct stat s;
45
46 if (stat(RUN_RO_FILE, &s)) {
47 /* coverity[toctou] */
48 FILE *fp = fopen(RUN_RO_FILE, "w");
49 if (!fp)
50 errExit("fopen");
51 fclose(fp);
52 if (chown(RUN_RO_FILE, 0, 0) < 0)
53 errExit("chown");
54 if (chmod(RUN_RO_FILE, S_IRUSR) < 0)
55 errExit("chown");
56 }
57}
58
59// build /run/firejail directory
60void fs_build_firejail_dir(void) {
61 struct stat s;
62
63 // CentOS 6 doesn't have /run directory
64 if (stat(RUN_FIREJAIL_BASEDIR, &s)) {
65 if (arg_debug)
66 printf("Creating %s directory\n", RUN_FIREJAIL_BASEDIR);
67 /* coverity[toctou] */
68 int rv = mkdir(RUN_FIREJAIL_BASEDIR, 0755);
69 if (rv == -1)
70 errExit("mkdir");
71 if (chown(RUN_FIREJAIL_BASEDIR, 0, 0) < 0)
72 errExit("chown");
73 if (chmod(RUN_FIREJAIL_BASEDIR, 0755) < 0)
74 errExit("chmod");
75 }
76 else { // check /tmp/firejail directory belongs to root end exit if doesn't!
77 if (s.st_uid != 0 || s.st_gid != 0) {
78 fprintf(stderr, "Error: non-root %s directory, exiting...\n", RUN_FIREJAIL_DIR);
79 exit(1);
80 }
81 }
82
83 if (stat(RUN_FIREJAIL_DIR, &s)) {
84 if (arg_debug)
85 printf("Creating %s directory\n", RUN_FIREJAIL_DIR);
86 /* coverity[toctou] */
87 int rv = mkdir(RUN_FIREJAIL_DIR, 0755);
88 if (rv == -1)
89 errExit("mkdir");
90 if (chown(RUN_FIREJAIL_DIR, 0, 0) < 0)
91 errExit("chown");
92 if (chmod(RUN_FIREJAIL_DIR, 0755) < 0)
93 errExit("chmod");
94 }
95
96 if (stat(RUN_FIREJAIL_NETWORK_DIR, &s)) {
97 if (arg_debug)
98 printf("Creating %s directory\n", RUN_FIREJAIL_NETWORK_DIR);
99
100 if (mkdir(RUN_FIREJAIL_NETWORK_DIR, 0755) == -1)
101 errExit("mkdir");
102 if (chown(RUN_FIREJAIL_NETWORK_DIR, 0, 0) < 0)
103 errExit("chown");
104 if (chmod(RUN_FIREJAIL_NETWORK_DIR, 0755) < 0)
105 errExit("chmod");
106 }
107
108 if (stat(RUN_FIREJAIL_BANDWIDTH_DIR, &s)) {
109 if (arg_debug)
110 printf("Creating %s directory\n", RUN_FIREJAIL_BANDWIDTH_DIR);
111 if (mkdir(RUN_FIREJAIL_BANDWIDTH_DIR, 0755) == -1)
112 errExit("mkdir");
113 if (chown(RUN_FIREJAIL_BANDWIDTH_DIR, 0, 0) < 0)
114 errExit("chown");
115 if (chmod(RUN_FIREJAIL_BANDWIDTH_DIR, 0755) < 0)
116 errExit("chmod");
117 }
118
119 if (stat(RUN_FIREJAIL_NAME_DIR, &s)) {
120 if (arg_debug)
121 printf("Creating %s directory\n", RUN_FIREJAIL_NAME_DIR);
122 if (mkdir(RUN_FIREJAIL_NAME_DIR, 0755) == -1)
123 errExit("mkdir");
124 if (chown(RUN_FIREJAIL_NAME_DIR, 0, 0) < 0)
125 errExit("chown");
126 if (chmod(RUN_FIREJAIL_NAME_DIR, 0755) < 0)
127 errExit("chmod");
128 }
129
130 if (stat(RUN_FIREJAIL_X11_DIR, &s)) {
131 if (arg_debug)
132 printf("Creating %s directory\n", RUN_FIREJAIL_X11_DIR);
133 if (mkdir(RUN_FIREJAIL_X11_DIR, 0755) == -1)
134 errExit("mkdir");
135 if (chown(RUN_FIREJAIL_X11_DIR, 0, 0) < 0)
136 errExit("chown");
137 if (chmod(RUN_FIREJAIL_X11_DIR, 0755) < 0)
138 errExit("chmod");
139 }
140
141 create_empty_dir();
142 create_empty_file();
143}
144 31
145 32
146// build /tmp/firejail/mnt directory
147static int tmpfs_mounted = 0;
148#ifdef HAVE_CHROOT
149static void fs_build_remount_mnt_dir(void) {
150 tmpfs_mounted = 0;
151 fs_build_mnt_dir();
152}
153#endif
154
155void fs_build_mnt_dir(void) {
156 struct stat s;
157 fs_build_firejail_dir();
158
159 // create /run/firejail/mnt directory
160 if (stat(RUN_MNT_DIR, &s)) {
161 if (arg_debug)
162 printf("Creating %s directory\n", RUN_MNT_DIR);
163 /* coverity[toctou] */
164 int rv = mkdir(RUN_MNT_DIR, 0755);
165 if (rv == -1)
166 errExit("mkdir");
167 if (chown(RUN_MNT_DIR, 0, 0) < 0)
168 errExit("chown");
169 if (chmod(RUN_MNT_DIR, 0755) < 0)
170 errExit("chmod");
171 }
172
173 // ... and mount tmpfs on top of it
174 if (!tmpfs_mounted) {
175 // mount tmpfs on top of /run/firejail/mnt
176 if (arg_debug)
177 printf("Mounting tmpfs on %s directory\n", RUN_MNT_DIR);
178 if (mount("tmpfs", RUN_MNT_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
179 errExit("mounting /tmp/firejail/mnt");
180 tmpfs_mounted = 1;
181 fs_logger2("tmpfs", RUN_MNT_DIR);
182 }
183}
184
185// grab a copy of cp command
186void fs_build_cp_command(void) {
187 struct stat s;
188 fs_build_mnt_dir();
189 if (stat(RUN_CP_COMMAND, &s)) {
190 char* fname = realpath("/bin/cp", NULL);
191 if (fname == NULL) {
192 fprintf(stderr, "Error: /bin/cp not found\n");
193 exit(1);
194 }
195 if (stat(fname, &s)) {
196 fprintf(stderr, "Error: /bin/cp not found\n");
197 exit(1);
198 }
199 if (is_link(fname)) {
200 fprintf(stderr, "Error: invalid /bin/cp file\n");
201 exit(1);
202 }
203 int rv = copy_file(fname, RUN_CP_COMMAND);
204 if (rv) {
205 fprintf(stderr, "Error: cannot access /bin/cp\n");
206 exit(1);
207 }
208 /* coverity[toctou] */
209 if (chown(RUN_CP_COMMAND, 0, 0))
210 errExit("chown");
211 if (chmod(RUN_CP_COMMAND, 0755))
212 errExit("chmod");
213
214 free(fname);
215 }
216}
217
218// delete the temporary cp command
219void fs_delete_cp_command(void) {
220 unlink(RUN_CP_COMMAND);
221}
222 33
223//*********************************************** 34//***********************************************
224// process profile file 35// process profile file
@@ -228,6 +39,8 @@ typedef enum {
228 BLACKLIST_NOLOG, 39 BLACKLIST_NOLOG,
229 MOUNT_READONLY, 40 MOUNT_READONLY,
230 MOUNT_TMPFS, 41 MOUNT_TMPFS,
42 MOUNT_NOEXEC,
43 MOUNT_RDWR,
231 OPERATION_MAX 44 OPERATION_MAX
232} OPERATION; 45} OPERATION;
233 46
@@ -242,14 +55,9 @@ static void disable_file(OPERATION op, const char *filename) {
242 assert(op <OPERATION_MAX); 55 assert(op <OPERATION_MAX);
243 last_disable = UNSUCCESSFUL; 56 last_disable = UNSUCCESSFUL;
244 57
245 // rebuild /run/firejail directory in case tmpfs was mounted on top of /run
246 fs_build_firejail_dir();
247
248 // Resolve all symlinks 58 // Resolve all symlinks
249 char* fname = realpath(filename, NULL); 59 char* fname = realpath(filename, NULL);
250 if (fname == NULL && errno != EACCES) { 60 if (fname == NULL && errno != EACCES) {
251 if (arg_debug)
252 printf("Warning (realpath): %s is an invalid file, skipping...\n", filename);
253 return; 61 return;
254 } 62 }
255 if (fname == NULL && errno == EACCES) { 63 if (fname == NULL && errno == EACCES) {
@@ -298,9 +106,10 @@ static void disable_file(OPERATION op, const char *filename) {
298 // some distros put all executables under /usr/bin and make /bin a symbolic link 106 // some distros put all executables under /usr/bin and make /bin a symbolic link
299 if ((strcmp(fname, "/bin") == 0 || strcmp(fname, "/usr/bin") == 0) && 107 if ((strcmp(fname, "/bin") == 0 || strcmp(fname, "/usr/bin") == 0) &&
300 is_link(filename) && 108 is_link(filename) &&
301 S_ISDIR(s.st_mode)) 109 S_ISDIR(s.st_mode)) {
302 fprintf(stderr, "Warning: %s directory link was not blacklisted\n", filename); 110 if (!arg_quiet)
303 111 fprintf(stderr, "Warning: %s directory link was not blacklisted\n", filename);
112 }
304 else { 113 else {
305 if (arg_debug) 114 if (arg_debug)
306 printf("Disable %s\n", fname); 115 printf("Disable %s\n", fname);
@@ -332,6 +141,18 @@ static void disable_file(OPERATION op, const char *filename) {
332 fs_rdonly(fname); 141 fs_rdonly(fname);
333// todo: last_disable = SUCCESSFUL; 142// todo: last_disable = SUCCESSFUL;
334 } 143 }
144 else if (op == MOUNT_RDWR) {
145 if (arg_debug)
146 printf("Mounting read-only %s\n", fname);
147 fs_rdwr(fname);
148// todo: last_disable = SUCCESSFUL;
149 }
150 else if (op == MOUNT_NOEXEC) {
151 if (arg_debug)
152 printf("Mounting noexec %s\n", fname);
153 fs_noexec(fname);
154// todo: last_disable = SUCCESSFUL;
155 }
335 else if (op == MOUNT_TMPFS) { 156 else if (op == MOUNT_TMPFS) {
336 if (S_ISDIR(s.st_mode)) { 157 if (S_ISDIR(s.st_mode)) {
337 if (arg_debug) 158 if (arg_debug)
@@ -361,7 +182,7 @@ static void globbing(OPERATION op, const char *pattern, const char *noblacklist[
361 glob_t globbuf; 182 glob_t globbuf;
362 // Profiles contain blacklists for files that might not exist on a user's machine. 183 // Profiles contain blacklists for files that might not exist on a user's machine.
363 // GLOB_NOCHECK makes that okay. 184 // GLOB_NOCHECK makes that okay.
364 int globerr = glob(pattern, GLOB_NOCHECK | GLOB_NOSORT, NULL, &globbuf); 185 int globerr = glob(pattern, GLOB_NOCHECK | GLOB_NOSORT | GLOB_PERIOD, NULL, &globbuf);
365 if (globerr) { 186 if (globerr) {
366 fprintf(stderr, "Error: failed to glob pattern %s\n", pattern); 187 fprintf(stderr, "Error: failed to glob pattern %s\n", pattern);
367 exit(1); 188 exit(1);
@@ -426,21 +247,13 @@ void fs_blacklist(void) {
426 247
427 // process bind command 248 // process bind command
428 if (strncmp(entry->data, "bind ", 5) == 0) { 249 if (strncmp(entry->data, "bind ", 5) == 0) {
250 struct stat s;
429 char *dname1 = entry->data + 5; 251 char *dname1 = entry->data + 5;
430 char *dname2 = split_comma(dname1); 252 char *dname2 = split_comma(dname1);
431 if (dname2 == NULL) { 253 if (dname2 == NULL ||
432 fprintf(stderr, "Error: second directory missing in bind command\n"); 254 stat(dname1, &s) == -1 ||
433 entry = entry->next; 255 stat(dname2, &s) == -1) {
434 continue; 256 fprintf(stderr, "Error: invalid bind command, directory missing\n");
435 }
436 struct stat s;
437 if (stat(dname1, &s) == -1) {
438 fprintf(stderr, "Error: cannot find %s for bind command\n", dname1);
439 entry = entry->next;
440 continue;
441 }
442 if (stat(dname2, &s) == -1) {
443 fprintf(stderr, "Error: cannot find %s for bind command\n", dname2);
444 entry = entry->next; 257 entry = entry->next;
445 continue; 258 continue;
446 } 259 }
@@ -452,11 +265,8 @@ void fs_blacklist(void) {
452 if (mount(dname1, dname2, NULL, MS_BIND|MS_REC, NULL) < 0) 265 if (mount(dname1, dname2, NULL, MS_BIND|MS_REC, NULL) < 0)
453 errExit("mount bind"); 266 errExit("mount bind");
454 /* coverity[toctou] */ 267 /* coverity[toctou] */
455 if (chown(dname2, s.st_uid, s.st_gid) == -1) 268 if (set_perms(dname2, s.st_uid, s.st_gid,s.st_mode))
456 errExit("mount-bind chown"); 269 errExit("set_perms");
457 /* coverity[toctou] */
458 if (chmod(dname2, s.st_mode) == -1)
459 errExit("mount-bind chmod");
460 270
461 entry = entry->next; 271 entry = entry->next;
462 continue; 272 continue;
@@ -464,12 +274,40 @@ void fs_blacklist(void) {
464 274
465 // Process noblacklist command 275 // Process noblacklist command
466 if (strncmp(entry->data, "noblacklist ", 12) == 0) { 276 if (strncmp(entry->data, "noblacklist ", 12) == 0) {
467 if (noblacklist_c >= noblacklist_m) { 277 char **paths = build_paths();
468 noblacklist_m *= 2; 278
469 noblacklist = realloc(noblacklist, sizeof(*noblacklist) * noblacklist_m); 279 char *enames[sizeof(paths)+1] = {0};
470 if (noblacklist == NULL) 280 int i = 0;
471 errExit("failed increasing memory for noblacklist entries");} 281
472 noblacklist[noblacklist_c++] = expand_home(entry->data + 12, homedir); 282 if (strncmp(entry->data + 12, "${PATH}", 7) == 0) {
283 // expand ${PATH} macro
284 while (paths[i] != NULL) {
285 if (asprintf(&enames[i], "%s%s", paths[i], entry->data + 19) == -1)
286 errExit("asprintf");
287 i++;
288 }
289 } else {
290 // expand ${HOME} macro if found or pass as is
291 enames[0] = expand_home(entry->data + 12, homedir);
292 enames[1] = NULL;
293 }
294
295 i = 0;
296 while (enames[i] != NULL) {
297 if (noblacklist_c >= noblacklist_m) {
298 noblacklist_m *= 2;
299 noblacklist = realloc(noblacklist, sizeof(*noblacklist) * noblacklist_m);
300 if (noblacklist == NULL)
301 errExit("failed increasing memory for noblacklist entries");
302 }
303 noblacklist[noblacklist_c++] = enames[i];
304 i++;
305 }
306
307 while (enames[i] != NULL) {
308 free(enames[i]);
309 }
310
473 entry = entry->next; 311 entry = entry->next;
474 continue; 312 continue;
475 } 313 }
@@ -487,10 +325,32 @@ void fs_blacklist(void) {
487 ptr = entry->data + 10; 325 ptr = entry->data + 10;
488 op = MOUNT_READONLY; 326 op = MOUNT_READONLY;
489 } 327 }
328 else if (strncmp(entry->data, "read-write ", 11) == 0) {
329 ptr = entry->data + 11;
330 op = MOUNT_RDWR;
331 }
332 else if (strncmp(entry->data, "noexec ", 7) == 0) {
333 ptr = entry->data + 7;
334 op = MOUNT_NOEXEC;
335 }
490 else if (strncmp(entry->data, "tmpfs ", 6) == 0) { 336 else if (strncmp(entry->data, "tmpfs ", 6) == 0) {
491 ptr = entry->data + 6; 337 ptr = entry->data + 6;
492 op = MOUNT_TMPFS; 338 op = MOUNT_TMPFS;
493 } 339 }
340 else if (strncmp(entry->data, "mkdir ", 6) == 0) {
341 EUID_USER();
342 fs_mkdir(entry->data + 6);
343 EUID_ROOT();
344 entry = entry->next;
345 continue;
346 }
347 else if (strncmp(entry->data, "mkfile ", 7) == 0) {
348 EUID_USER();
349 fs_mkfile(entry->data + 7);
350 EUID_ROOT();
351 entry = entry->next;
352 continue;
353 }
494 else { 354 else {
495 fprintf(stderr, "Error: invalid profile line %s\n", entry->data); 355 fprintf(stderr, "Error: invalid profile line %s\n", entry->data);
496 entry = entry->next; 356 entry = entry->next;
@@ -542,38 +402,56 @@ void fs_rdonly(const char *dir) {
542 int rv = stat(dir, &s); 402 int rv = stat(dir, &s);
543 if (rv == 0) { 403 if (rv == 0) {
544 // mount --bind /bin /bin 404 // mount --bind /bin /bin
545 if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0)
546 errExit("mount read-only");
547 // mount --bind -o remount,ro /bin 405 // mount --bind -o remount,ro /bin
548 if (mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_REC, NULL) < 0) 406 if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0 ||
407 mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_REC, NULL) < 0)
549 errExit("mount read-only"); 408 errExit("mount read-only");
550 fs_logger2("read-only", dir); 409 fs_logger2("read-only", dir);
551 } 410 }
552} 411}
553void fs_rdonly_noexit(const char *dir) { 412
413static void fs_rdwr(const char *dir) {
414 assert(dir);
415 // check directory exists
416 struct stat s;
417 int rv = stat(dir, &s);
418 if (rv == 0) {
419 // if the file is outside /home directory, allow only root user
420 uid_t u = getuid();
421 if (u != 0 && s.st_uid != u) {
422 if (!arg_quiet)
423 fprintf(stderr, "Warning: you are not allowed to change %s to read-write\n", dir);
424 return;
425 }
426
427 // mount --bind /bin /bin
428 // mount --bind -o remount,rw /bin
429 if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0 ||
430 mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_REC, NULL) < 0)
431 errExit("mount read-write");
432 fs_logger2("read-write", dir);
433 }
434}
435
436void fs_noexec(const char *dir) {
554 assert(dir); 437 assert(dir);
555 // check directory exists 438 // check directory exists
556 struct stat s; 439 struct stat s;
557 int rv = stat(dir, &s); 440 int rv = stat(dir, &s);
558 if (rv == 0) { 441 if (rv == 0) {
559 int merr = 0;
560 // mount --bind /bin /bin 442 // mount --bind /bin /bin
561 if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0)
562 merr = 1;
563 // mount --bind -o remount,ro /bin 443 // mount --bind -o remount,ro /bin
564 if (mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_REC, NULL) < 0) 444 if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0 ||
565 merr = 1; 445 mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_NOEXEC|MS_NODEV|MS_NOSUID|MS_REC, NULL) < 0)
566 if (merr) 446 errExit("mount noexec");
567 fprintf(stderr, "Warning: cannot mount %s read-only\n", dir); 447 fs_logger2("noexec", dir);
568 else
569 fs_logger2("read-only", dir);
570 } 448 }
571} 449}
572 450
451
452
573// mount /proc and /sys directories 453// mount /proc and /sys directories
574void fs_proc_sys_dev_boot(void) { 454void fs_proc_sys_dev_boot(void) {
575 struct stat s;
576
577 if (arg_debug) 455 if (arg_debug)
578 printf("Remounting /proc and /proc/sys filesystems\n"); 456 printf("Remounting /proc and /proc/sys filesystems\n");
579 if (mount("proc", "/proc", "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_REC, NULL) < 0) 457 if (mount("proc", "/proc", "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_REC, NULL) < 0)
@@ -581,10 +459,8 @@ void fs_proc_sys_dev_boot(void) {
581 fs_logger("remount /proc"); 459 fs_logger("remount /proc");
582 460
583 // remount /proc/sys readonly 461 // remount /proc/sys readonly
584 if (mount("/proc/sys", "/proc/sys", NULL, MS_BIND | MS_REC, NULL) < 0) 462 if (mount("/proc/sys", "/proc/sys", NULL, MS_BIND | MS_REC, NULL) < 0 ||
585 errExit("mounting /proc/sys"); 463 mount(NULL, "/proc/sys", NULL, MS_BIND | MS_REMOUNT | MS_RDONLY | MS_REC, NULL) < 0)
586
587 if (mount(NULL, "/proc/sys", NULL, MS_BIND | MS_REMOUNT | MS_RDONLY | MS_REC, NULL) < 0)
588 errExit("mounting /proc/sys"); 464 errExit("mounting /proc/sys");
589 fs_logger("read-only /proc/sys"); 465 fs_logger("read-only /proc/sys");
590 466
@@ -601,114 +477,71 @@ void fs_proc_sys_dev_boot(void) {
601 fs_logger("remount /sys"); 477 fs_logger("remount /sys");
602 } 478 }
603 479
604 if (stat("/sys/firmware", &s) == 0) { 480 disable_file(BLACKLIST_FILE, "/sys/firmware");
605 disable_file(BLACKLIST_FILE, "/sys/firmware"); 481 disable_file(BLACKLIST_FILE, "/sys/hypervisor");
606 } 482 { // allow user access to /sys/fs if "--noblacklist=/sys/fs" is present on the command line
607 483 EUID_USER();
608 if (stat("/sys/hypervisor", &s) == 0) { 484 profile_add("blacklist /sys/fs");
609 disable_file(BLACKLIST_FILE, "/sys/hypervisor"); 485 EUID_ROOT();
610 }
611
612 if (stat("/sys/fs", &s) == 0) {
613 disable_file(BLACKLIST_FILE, "/sys/fs");
614 }
615
616 if (stat("/sys/module", &s) == 0) {
617 disable_file(BLACKLIST_FILE, "/sys/module");
618 } 486 }
619 487 disable_file(BLACKLIST_FILE, "/sys/module");
620 if (stat("/sys/power", &s) == 0) { 488 disable_file(BLACKLIST_FILE, "/sys/power");
621 disable_file(BLACKLIST_FILE, "/sys/power"); 489 disable_file(BLACKLIST_FILE, "/sys/kernel/debug");
622 } 490 disable_file(BLACKLIST_FILE, "/sys/kernel/vmcoreinfo");
623 491 disable_file(BLACKLIST_FILE, "/sys/kernel/uevent_helper");
624// if (mount("sysfs", "/sys", "sysfs", MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REC, NULL) < 0) 492
625// errExit("mounting /sys"); 493 // various /proc/sys files
626 494 disable_file(BLACKLIST_FILE, "/proc/sys/security");
627 // Disable SysRq 495 disable_file(BLACKLIST_FILE, "/proc/sys/efi/vars");
628 // a linux box can be shut down easily using the following commands (as root): 496 disable_file(BLACKLIST_FILE, "/proc/sys/fs/binfmt_misc");
629 // # echo 1 > /proc/sys/kernel/sysrq 497 disable_file(BLACKLIST_FILE, "/proc/sys/kernel/core_pattern");
630 // #echo b > /proc/sysrq-trigger 498 disable_file(BLACKLIST_FILE, "/proc/sys/kernel/modprobe");
631 // for more information see https://www.kernel.org/doc/Documentation/sysrq.txt 499 disable_file(BLACKLIST_FILE, "/proc/sysrq-trigger");
632 if (arg_debug) 500 disable_file(BLACKLIST_FILE, "/proc/sys/kernel/hotplug");
633 printf("Disable /proc/sysrq-trigger\n"); 501 disable_file(BLACKLIST_FILE, "/proc/sys/vm/panic_on_oom");
634 fs_rdonly_noexit("/proc/sysrq-trigger"); 502
635 503 // various /proc files
636 // disable hotplug and uevent_helper 504 disable_file(BLACKLIST_FILE, "/proc/irq");
637 if (arg_debug) 505 disable_file(BLACKLIST_FILE, "/proc/bus");
638 printf("Disable /proc/sys/kernel/hotplug\n"); 506 disable_file(BLACKLIST_FILE, "/proc/config.gz");
639 fs_rdonly_noexit("/proc/sys/kernel/hotplug"); 507 disable_file(BLACKLIST_FILE, "/proc/sched_debug");
640 if (arg_debug) 508 disable_file(BLACKLIST_FILE, "/proc/timer_list");
641 printf("Disable /sys/kernel/uevent_helper\n"); 509 disable_file(BLACKLIST_FILE, "/proc/timer_stats");
642 fs_rdonly_noexit("/sys/kernel/uevent_helper");
643
644 // read-only /proc/irq and /proc/bus
645 if (arg_debug)
646 printf("Disable /proc/irq\n");
647 fs_rdonly_noexit("/proc/irq");
648 if (arg_debug)
649 printf("Disable /proc/bus\n");
650 fs_rdonly_noexit("/proc/bus");
651
652 // disable /proc/kcore
653 disable_file(BLACKLIST_FILE, "/proc/kcore"); 510 disable_file(BLACKLIST_FILE, "/proc/kcore");
654
655 // disable /proc/kallsyms
656 disable_file(BLACKLIST_FILE, "/proc/kallsyms"); 511 disable_file(BLACKLIST_FILE, "/proc/kallsyms");
512 disable_file(BLACKLIST_FILE, "/proc/mem");
513 disable_file(BLACKLIST_FILE, "/proc/kmem");
657 514
658 // disable /boot 515 // remove kernel symbol information
659 if (stat("/boot", &s) == 0) { 516 if (!arg_allow_debuggers) {
660 if (arg_debug) 517 disable_file(BLACKLIST_FILE, "/usr/src/linux");
661 printf("Disable /boot directory\n"); 518 disable_file(BLACKLIST_FILE, "/lib/modules");
519 disable_file(BLACKLIST_FILE, "/usr/lib/debug");
662 disable_file(BLACKLIST_FILE, "/boot"); 520 disable_file(BLACKLIST_FILE, "/boot");
663 } 521 }
664 522
665 // disable /selinux 523 // disable /selinux
666 if (stat("/selinux", &s) == 0) { 524 disable_file(BLACKLIST_FILE, "/selinux");
667 if (arg_debug)
668 printf("Disable /selinux directory\n");
669 disable_file(BLACKLIST_FILE, "/selinux");
670 }
671 525
672 // disable /dev/port 526 // disable /dev/port
673 if (stat("/dev/port", &s) == 0) { 527 disable_file(BLACKLIST_FILE, "/dev/port");
674 disable_file(BLACKLIST_FILE, "/dev/port");
675 }
676 528
677 if (getuid() != 0) { 529 if (getuid() != 0) {
678 // disable /dev/kmsg 530 // disable /dev/kmsg and /proc/kmsg
679 if (stat("/dev/kmsg", &s) == 0) { 531 disable_file(BLACKLIST_FILE, "/dev/kmsg");
680 disable_file(BLACKLIST_FILE, "/dev/kmsg"); 532 disable_file(BLACKLIST_FILE, "/proc/kmsg");
681 }
682
683 // disable /proc/kmsg
684 if (stat("/proc/kmsg", &s) == 0) {
685 disable_file(BLACKLIST_FILE, "/proc/kmsg");
686 }
687 } 533 }
688} 534}
689 535
690// disable firejail configuration in /etc/firejail and in ~/.config/firejail 536// disable firejail configuration in /etc/firejail and in ~/.config/firejail
691static void disable_firejail_config(void) { 537static void disable_config(void) {
692 struct stat s; 538 struct stat s;
693 if (stat("/etc/firejail", &s) == 0)
694 disable_file(BLACKLIST_FILE, "/etc/firejail");
695 539
696 char *fname; 540 char *fname;
697 if (asprintf(&fname, "%s/.config/firejail", cfg.homedir) == -1) 541 if (asprintf(&fname, "%s/.config/firejail", cfg.homedir) == -1)
698 errExit("asprintf"); 542 errExit("asprintf");
699 if (stat(fname, &s) == 0) 543 if (stat(fname, &s) == 0)
700 disable_file(BLACKLIST_FILE, fname); 544 disable_file(BLACKLIST_FILE, fname);
701
702 if (stat("/usr/local/etc/firejail", &s) == 0)
703 disable_file(BLACKLIST_FILE, "/usr/local/etc/firejail");
704
705 if (strcmp(PREFIX, "/usr/local")) {
706 if (asprintf(&fname, "%s/etc/firejail", PREFIX) == -1)
707 errExit("asprintf");
708 if (stat(fname, &s) == 0)
709 disable_file(BLACKLIST_FILE, fname);
710 }
711
712 free(fname); 545 free(fname);
713 546
714 // disable run time information 547 // disable run time information
@@ -725,8 +558,23 @@ static void disable_firejail_config(void) {
725 558
726// build a basic read-only filesystem 559// build a basic read-only filesystem
727void fs_basic_fs(void) { 560void fs_basic_fs(void) {
561 uid_t uid = getuid();
562
728 if (arg_debug) 563 if (arg_debug)
729 printf("Mounting read-only /bin, /sbin, /lib, /lib32, /lib64, /usr, /etc, /var\n"); 564 printf("Mounting read-only /bin, /sbin, /lib, /lib32, /lib64, /usr");
565 if (!arg_writable_etc) {
566 fs_rdonly("/etc");
567 if (uid)
568 fs_noexec("/etc");
569 if (arg_debug) printf(", /etc");
570 }
571 if (!arg_writable_var) {
572 fs_rdonly("/var");
573 if (uid)
574 fs_noexec("/var");
575 if (arg_debug) printf(", /var");
576 }
577 if (arg_debug) printf("\n");
730 fs_rdonly("/bin"); 578 fs_rdonly("/bin");
731 fs_rdonly("/sbin"); 579 fs_rdonly("/sbin");
732 fs_rdonly("/lib"); 580 fs_rdonly("/lib");
@@ -734,12 +582,10 @@ void fs_basic_fs(void) {
734 fs_rdonly("/lib32"); 582 fs_rdonly("/lib32");
735 fs_rdonly("/libx32"); 583 fs_rdonly("/libx32");
736 fs_rdonly("/usr"); 584 fs_rdonly("/usr");
737 fs_rdonly("/etc");
738 fs_rdonly("/var");
739 585
740 // update /var directory in order to support multiple sandboxes running on the same root directory 586 // update /var directory in order to support multiple sandboxes running on the same root directory
741 if (!arg_private_dev) 587// if (!arg_private_dev)
742 fs_dev_shm(); 588// fs_dev_shm();
743 fs_var_lock(); 589 fs_var_lock();
744 fs_var_tmp(); 590 fs_var_tmp();
745 fs_var_log(); 591 fs_var_log();
@@ -750,10 +596,51 @@ void fs_basic_fs(void) {
750 // don't leak user information 596 // don't leak user information
751 restrict_users(); 597 restrict_users();
752 598
753 disable_firejail_config(); 599 // when starting as root, firejail config is not disabled;
600 // this mode could be used to install and test new software by chaining
601 // firejail sandboxes (firejail --force)
602 if (uid)
603 disable_config();
754} 604}
755 605
756 606
607
608#ifdef HAVE_OVERLAYFS
609char *fs_check_overlay_dir(const char *subdirname, int allow_reuse) {
610 struct stat s;
611 char *dirname;
612
613 // create ~/.firejail directory
614 if (asprintf(&dirname, "%s/.firejail", cfg.homedir) == -1)
615 errExit("asprintf");
616 if (stat(dirname, &s) == -1) {
617 mkdir_attr(dirname, 0700, 0, 0);
618 }
619 else if (is_link(dirname)) {
620 fprintf(stderr, "Error: invalid ~/.firejail directory\n");
621 exit(1);
622 }
623 free(dirname);
624
625 // check overlay directory
626 if (asprintf(&dirname, "%s/.firejail/%s", cfg.homedir, subdirname) == -1)
627 errExit("asprintf");
628 if (is_link(dirname)) {
629 fprintf(stderr, "Error: overlay directory is a symbolic link\n");
630 exit(1);
631 }
632 if (allow_reuse == 0) {
633 if (stat(dirname, &s) == 0) {
634 fprintf(stderr, "Error: overlay directory already exists: %s\n", dirname);
635 exit(1);
636 }
637 }
638
639 return dirname;
640}
641
642
643
757// mount overlayfs on top of / directory 644// mount overlayfs on top of / directory
758// mounting an overlay and chrooting into it: 645// mounting an overlay and chrooting into it:
759// 646//
@@ -806,48 +693,53 @@ void fs_overlayfs(void) {
806 if (major == 3 && minor < 18) 693 if (major == 3 && minor < 18)
807 oldkernel = 1; 694 oldkernel = 1;
808 695
809 // build overlay directories
810 fs_build_mnt_dir();
811
812 char *oroot; 696 char *oroot;
813 if(asprintf(&oroot, "%s/oroot", RUN_MNT_DIR) == -1) 697 if(asprintf(&oroot, "%s/oroot", RUN_MNT_DIR) == -1)
814 errExit("asprintf"); 698 errExit("asprintf");
815 if (mkdir(oroot, 0755)) 699 mkdir_attr(oroot, 0755, 0, 0);
816 errExit("mkdir");
817 if (chown(oroot, 0, 0) < 0)
818 errExit("chown");
819 if (chmod(oroot, 0755) < 0)
820 errExit("chmod");
821 700
701 struct stat s;
822 char *basedir = RUN_MNT_DIR; 702 char *basedir = RUN_MNT_DIR;
823 if (arg_overlay_keep) { 703 if (arg_overlay_keep) {
824 // set base for working and diff directories 704 // set base for working and diff directories
825 basedir = cfg.overlay_dir; 705 basedir = cfg.overlay_dir;
826 if (mkdir(basedir, 0755) != 0) { 706
827 fprintf(stderr, "Error: cannot create overlay directory\n"); 707 // does the overlay exist?
828 exit(1); 708 if (stat(basedir, &s) == 0) {
709 if (arg_overlay_reuse == 0) {
710 fprintf(stderr, "Error: overlay directory exists, but reuse is not allowed\n");
711 exit(1);
712 }
713 }
714 else {
715 if (mkdir(basedir, 0755) != 0) {
716 fprintf(stderr, "Error: cannot create overlay directory\n");
717 exit(1);
718 }
829 } 719 }
830 } 720 }
831 721
832 char *odiff; 722 char *odiff;
833 if(asprintf(&odiff, "%s/odiff", basedir) == -1) 723 if(asprintf(&odiff, "%s/odiff", basedir) == -1)
834 errExit("asprintf"); 724 errExit("asprintf");
835 if (mkdir(odiff, 0755)) 725
836 errExit("mkdir"); 726 // no need to check arg_overlay_reuse
837 if (chown(odiff, 0, 0) < 0) 727 if (stat(odiff, &s) != 0) {
838 errExit("chown"); 728 mkdir_attr(odiff, 0755, 0, 0);
839 if (chmod(odiff, 0755) < 0) 729 }
840 errExit("chmod"); 730 else if (set_perms(odiff, 0, 0, 0755))
731 errExit("set_perms");
841 732
842 char *owork; 733 char *owork;
843 if(asprintf(&owork, "%s/owork", basedir) == -1) 734 if(asprintf(&owork, "%s/owork", basedir) == -1)
844 errExit("asprintf"); 735 errExit("asprintf");
845 if (mkdir(owork, 0755)) 736
846 errExit("mkdir"); 737 // no need to check arg_overlay_reuse
847 if (chown(owork, 0, 0) < 0) 738 if (stat(owork, &s) != 0) {
739 mkdir_attr(owork, 0755, 0, 0);
740 }
741 else if (set_perms(owork, 0, 0, 0755))
848 errExit("chown"); 742 errExit("chown");
849 if (chmod(owork, 0755) < 0)
850 errExit("chmod");
851 743
852 // mount overlayfs 744 // mount overlayfs
853 if (arg_debug) 745 if (arg_debug)
@@ -899,21 +791,23 @@ void fs_overlayfs(void) {
899 791
900 if(asprintf(&hdiff, "%s/hdiff", basedir) == -1) 792 if(asprintf(&hdiff, "%s/hdiff", basedir) == -1)
901 errExit("asprintf"); 793 errExit("asprintf");
902 if (mkdir(hdiff, S_IRWXU | S_IRWXG | S_IRWXO)) 794
903 errExit("mkdir"); 795 // no need to check arg_overlay_reuse
904 if (chown(hdiff, 0, 0) < 0) 796 if (stat(hdiff, &s) != 0) {
905 errExit("chown"); 797 mkdir_attr(hdiff, S_IRWXU | S_IRWXG | S_IRWXO, 0, 0);
906 if (chmod(hdiff, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) 798 }
907 errExit("chmod"); 799 else if (set_perms(hdiff, 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH))
800 errExit("set_perms");
908 801
909 if(asprintf(&hwork, "%s/hwork", basedir) == -1) 802 if(asprintf(&hwork, "%s/hwork", basedir) == -1)
910 errExit("asprintf"); 803 errExit("asprintf");
911 if (mkdir(hwork, S_IRWXU | S_IRWXG | S_IRWXO)) 804
912 errExit("mkdir"); 805 // no need to check arg_overlay_reuse
913 if (chown(hwork, 0, 0) < 0) 806 if (stat(hwork, &s) != 0) {
914 errExit("chown"); 807 mkdir_attr(hwork, S_IRWXU | S_IRWXG | S_IRWXO, 0, 0);
915 if (chmod(hwork, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) 808 }
916 errExit("chmod"); 809 else if (set_perms(hwork, 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH))
810 errExit("set_perms");
917 811
918 // no homedir in overlay so now mount another overlay for /home 812 // no homedir in overlay so now mount another overlay for /home
919 if (asprintf(&option, "lowerdir=/home,upperdir=%s,workdir=%s", hdiff, hwork) == -1) 813 if (asprintf(&option, "lowerdir=/home,upperdir=%s,workdir=%s", hdiff, hwork) == -1)
@@ -950,13 +844,30 @@ void fs_overlayfs(void) {
950 errExit("mounting /run"); 844 errExit("mounting /run");
951 fs_logger("whitelist /run"); 845 fs_logger("whitelist /run");
952 846
847 // mount-bind /tmp/.X11-unix directory
848 if (stat("/tmp/.X11-unix", &s) == 0) {
849 if (arg_debug)
850 printf("Mounting /tmp/.X11-unix\n");
851 char *x11;
852 if (asprintf(&x11, "%s/tmp/.X11-unix", oroot) == -1)
853 errExit("asprintf");
854 if (mount("/tmp/.X11-unix", x11, NULL, MS_BIND|MS_REC, NULL) < 0)
855 fprintf(stderr, "Warning: cannot mount /tmp/.X11-unix in overlay\n");
856 else
857 fs_logger("whitelist /tmp/.X11-unix");
858 free(x11);
859 }
860
953 // chroot in the new filesystem 861 // chroot in the new filesystem
862#ifdef HAVE_GCOV
863 __gcov_flush();
864#endif
954 if (chroot(oroot) == -1) 865 if (chroot(oroot) == -1)
955 errExit("chroot"); 866 errExit("chroot");
956 867
957 // update /var directory in order to support multiple sandboxes running on the same root directory 868 // update /var directory in order to support multiple sandboxes running on the same root directory
958 if (!arg_private_dev) 869// if (!arg_private_dev)
959 fs_dev_shm(); 870// fs_dev_shm();
960 fs_var_lock(); 871 fs_var_lock();
961 fs_var_tmp(); 872 fs_var_tmp();
962 fs_var_log(); 873 fs_var_log();
@@ -967,20 +878,18 @@ void fs_overlayfs(void) {
967 // don't leak user information 878 // don't leak user information
968 restrict_users(); 879 restrict_users();
969 880
970 // when starting as root in overlay mode, firejail config is not disabled; 881 // when starting as root, firejail config is not disabled;
971 // this mode could be used to install and test new software by chaining 882 // this mode could be used to install and test new software by chaining
972 // firejail sandboxes (firejail --force) 883 // firejail sandboxes (firejail --force)
973 if (getuid() != 0) 884 if (getuid() != 0)
974 disable_firejail_config(); 885 disable_config();
975 else
976 fprintf(stderr, "Warning: masking /etc/firejail disabled when starting the sandbox as root using --overlay option\n");
977 886
978 // cleanup and exit 887 // cleanup and exit
979 free(option); 888 free(option);
980 free(oroot); 889 free(oroot);
981 free(odiff); 890 free(odiff);
982} 891}
983 892#endif
984 893
985 894
986#ifdef HAVE_CHROOT 895#ifdef HAVE_CHROOT
@@ -991,6 +900,16 @@ int fs_check_chroot_dir(const char *rootdir) {
991 struct stat s; 900 struct stat s;
992 char *name; 901 char *name;
993 902
903 // rootdir has to be owned by root
904 if (stat(rootdir, &s) != 0) {
905 fprintf(stderr, "Error: cannot find chroot directory\n");
906 return 1;
907 }
908 if (s.st_uid != 0) {
909 fprintf(stderr, "Error: chroot directory should be owned by root\n");
910 return 1;
911 }
912
994 // check /dev 913 // check /dev
995 if (asprintf(&name, "%s/dev", rootdir) == -1) 914 if (asprintf(&name, "%s/dev", rootdir) == -1)
996 errExit("asprintf"); 915 errExit("asprintf");
@@ -1018,7 +937,7 @@ int fs_check_chroot_dir(const char *rootdir) {
1018 } 937 }
1019 free(name); 938 free(name);
1020 939
1021 // check /proc 940 // check /tmp
1022 if (asprintf(&name, "%s/tmp", rootdir) == -1) 941 if (asprintf(&name, "%s/tmp", rootdir) == -1)
1023 errExit("asprintf"); 942 errExit("asprintf");
1024 if (stat(name, &s) == -1) { 943 if (stat(name, &s) == -1) {
@@ -1026,16 +945,29 @@ int fs_check_chroot_dir(const char *rootdir) {
1026 return 1; 945 return 1;
1027 } 946 }
1028 free(name); 947 free(name);
1029 948
1030 // check /bin/bash 949 // check /bin/bash
1031 if (asprintf(&name, "%s/bin/bash", rootdir) == -1) 950// if (asprintf(&name, "%s/bin/bash", rootdir) == -1)
1032 errExit("asprintf"); 951// errExit("asprintf");
1033 if (stat(name, &s) == -1) { 952// if (stat(name, &s) == -1) {
1034 fprintf(stderr, "Error: cannot find /bin/bash in chroot directory\n"); 953// fprintf(stderr, "Error: cannot find /bin/bash in chroot directory\n");
1035 return 1; 954// return 1;
955// }
956// free(name);
957
958 // check x11 socket directory
959 if (getenv("FIREJAIL_X11")) {
960 mask_x11_abstract_socket = 1;
961 char *name;
962 if (asprintf(&name, "%s/tmp/.X11-unix", rootdir) == -1)
963 errExit("asprintf");
964 if (stat(name, &s) == -1) {
965 fprintf(stderr, "Error: cannot find /tmp/.X11-unix in chroot directory\n");
966 return 1;
967 }
968 free(name);
1036 } 969 }
1037 free(name); 970
1038
1039 return 0; 971 return 0;
1040} 972}
1041 973
@@ -1043,77 +975,108 @@ int fs_check_chroot_dir(const char *rootdir) {
1043void fs_chroot(const char *rootdir) { 975void fs_chroot(const char *rootdir) {
1044 assert(rootdir); 976 assert(rootdir);
1045 977
1046 //*********************************** 978 if (checkcfg(CFG_CHROOT_DESKTOP)) {
1047 // mount-bind a /dev in rootdir 979 // mount-bind a /dev in rootdir
1048 //*********************************** 980 char *newdev;
1049 // mount /dev 981 if (asprintf(&newdev, "%s/dev", rootdir) == -1)
1050 char *newdev; 982 errExit("asprintf");
1051 if (asprintf(&newdev, "%s/dev", rootdir) == -1) 983 if (arg_debug)
1052 errExit("asprintf"); 984 printf("Mounting /dev on %s\n", newdev);
1053 if (arg_debug) 985 if (mount("/dev", newdev, NULL, MS_BIND|MS_REC, NULL) < 0)
1054 printf("Mounting /dev on %s\n", newdev); 986 errExit("mounting /dev");
1055 if (mount("/dev", newdev, NULL, MS_BIND|MS_REC, NULL) < 0) 987 free(newdev);
1056 errExit("mounting /dev"); 988
1057 989 // x11
1058 // some older distros don't have a /run directory 990 if (getenv("FIREJAIL_X11")) {
1059 // create one by default 991 mask_x11_abstract_socket = 1;
1060 // no exit on error, let the user deal with any problems 992 char *newx11;
1061 char *rundir; 993 if (asprintf(&newx11, "%s/tmp/.X11-unix", rootdir) == -1)
1062 if (asprintf(&rundir, "%s/run", rootdir) == -1) 994 errExit("asprintf");
1063 errExit("asprintf"); 995 if (arg_debug)
1064 if (!is_dir(rundir)) { 996 printf("Mounting /tmp/.X11-unix on %s\n", newx11);
1065 int rv = mkdir(rundir, 0755); 997 if (mount("/tmp/.X11-unix", newx11, NULL, MS_BIND|MS_REC, NULL) < 0)
1066 (void) rv; 998 errExit("mounting /tmp/.X11-unix");
1067 rv = chown(rundir, 0, 0); 999 free(newx11);
1068 (void) rv; 1000 }
1001
1002 // create /run/firejail directory in chroot
1003 char *rundir;
1004 if (asprintf(&rundir, "%s/run", rootdir) == -1)
1005 errExit("asprintf");
1006 create_empty_dir_as_root(rundir, 0755);
1007 free(rundir);
1008 if (asprintf(&rundir, "%s/run/firejail", rootdir) == -1)
1009 errExit("asprintf");
1010 create_empty_dir_as_root(rundir, 0755);
1011 free(rundir);
1012
1013 // create /run/firejail/mnt directory in chroot and mount a tmpfs
1014 if (asprintf(&rundir, "%s/run/firejail/mnt", rootdir) == -1)
1015 errExit("asprintf");
1016 create_empty_dir_as_root(rundir, 0755);
1017 if (mount("tmpfs", rundir, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
1018 errExit("mounting /run/firejail/mnt");
1019 fs_logger2("tmpfs", RUN_MNT_DIR);
1020 free(rundir);
1021
1022 // retrieve seccomp.protocol
1023 struct stat s;
1024 if (stat(RUN_SECCOMP_PROTOCOL, &s) == 0) {
1025 if (asprintf(&rundir, "%s%s", rootdir, RUN_SECCOMP_PROTOCOL) == -1)
1026 errExit("asprintf");
1027 copy_file(RUN_SECCOMP_PROTOCOL, rundir, getuid(), getgid(), 0644);
1028 free(rundir);
1029 }
1030
1031 // copy /etc/resolv.conf in chroot directory
1032 // if resolv.conf in chroot is a symbolic link, this will fail
1033 // no exit on error, let the user deal with the problem
1034 char *fname;
1035 if (asprintf(&fname, "%s/etc/resolv.conf", rootdir) == -1)
1036 errExit("asprintf");
1037 if (arg_debug)
1038 printf("Updating /etc/resolv.conf in %s\n", fname);
1039 if (is_link(fname)) {
1040 fprintf(stderr, "Error: invalid %s file\n", fname);
1041 exit(1);
1042 }
1043 if (copy_file("/etc/resolv.conf", fname, 0, 0, 0644) == -1)
1044 fprintf(stderr, "Warning: /etc/resolv.conf not initialized\n");
1069 } 1045 }
1070 1046
1071 // copy /etc/resolv.conf in chroot directory
1072 // if resolv.conf in chroot is a symbolic link, this will fail
1073 // no exit on error, let the user deal with the problem
1074 char *fname;
1075 if (asprintf(&fname, "%s/etc/resolv.conf", rootdir) == -1)
1076 errExit("asprintf");
1077 if (arg_debug)
1078 printf("Updating /etc/resolv.conf in %s\n", fname);
1079 if (is_link(fname)) {
1080 fprintf(stderr, "Error: invalid %s file\n", fname);
1081 exit(1);
1082 }
1083 if (copy_file("/etc/resolv.conf", fname) == -1)
1084 fprintf(stderr, "Warning: /etc/resolv.conf not initialized\n");
1085
1086 // chroot into the new directory 1047 // chroot into the new directory
1048#ifdef HAVE_GCOV
1049 __gcov_flush();
1050#endif
1087 if (arg_debug) 1051 if (arg_debug)
1088 printf("Chrooting into %s\n", rootdir); 1052 printf("Chrooting into %s\n", rootdir);
1089 if (chroot(rootdir) < 0) 1053 if (chroot(rootdir) < 0)
1090 errExit("chroot"); 1054 errExit("chroot");
1091 // mount a new tmpfs in /run/firejail/mnt - the old one was lost in chroot
1092 fs_build_remount_mnt_dir();
1093
1094 // update /var directory in order to support multiple sandboxes running on the same root directory
1095 if (!arg_private_dev)
1096 fs_dev_shm();
1097 fs_var_lock();
1098 fs_var_tmp();
1099 fs_var_log();
1100 fs_var_lib();
1101 fs_var_cache();
1102 fs_var_utmp();
1103 1055
1104 // don't leak user information 1056 // create all other /run/firejail files and directories
1105 restrict_users(); 1057 preproc_build_firejail_dir();
1106 1058
1107 disable_firejail_config(); 1059 if (checkcfg(CFG_CHROOT_DESKTOP)) {
1060 // update /var directory in order to support multiple sandboxes running on the same root directory
1061// if (!arg_private_dev)
1062// fs_dev_shm();
1063 fs_var_lock();
1064 fs_var_tmp();
1065 fs_var_log();
1066 fs_var_lib();
1067 fs_var_cache();
1068 fs_var_utmp();
1069
1070 // don't leak user information
1071 restrict_users();
1072
1073 // when starting as root, firejail config is not disabled;
1074 // this mode could be used to install and test new software by chaining
1075 // firejail sandboxes (firejail --force)
1076 if (getuid() != 0)
1077 disable_config();
1078 }
1108} 1079}
1109#endif 1080#endif
1110 1081
1111void fs_private_tmp(void) {
1112 // mount tmpfs on top of /run/firejail/mnt
1113 if (arg_debug)
1114 printf("Mounting tmpfs on /tmp directory\n");
1115 if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=1777,gid=0") < 0)
1116 errExit("mounting /tmp/firejail/mnt");
1117 fs_logger2("tmpfs", "/tmp");
1118}
1119 1082
diff --git a/src/firejail/fs_bin.c b/src/firejail/fs_bin.c
index c3d24aaac..6cc1bf3ab 100644
--- a/src/firejail/fs_bin.c
+++ b/src/firejail/fs_bin.c
@@ -28,6 +28,8 @@ static char *paths[] = {
28 "/usr/local/bin", 28 "/usr/local/bin",
29 "/usr/bin", 29 "/usr/bin",
30 "/bin", 30 "/bin",
31 "/usr/games",
32 "/usr/local/games",
31 "/usr/local/sbin", 33 "/usr/local/sbin",
32 "/usr/sbin", 34 "/usr/sbin",
33 "/sbin", 35 "/sbin",
@@ -44,12 +46,38 @@ static char *check_dir_or_file(const char *name) {
44 46
45 int i = 0; 47 int i = 0;
46 while (paths[i]) { 48 while (paths[i]) {
49 // private-bin-no-local can be disabled in /etc/firejail/firejail.config
50 if (checkcfg(CFG_PRIVATE_BIN_NO_LOCAL) && strstr(paths[i], "local/")) {
51 i++;
52 continue;
53 }
54
55 // check file
47 if (asprintf(&fname, "%s/%s", paths[i], name) == -1) 56 if (asprintf(&fname, "%s/%s", paths[i], name) == -1)
48 errExit("asprintf"); 57 errExit("asprintf");
49 if (arg_debug) 58 if (arg_debug)
50 printf("Checking %s/%s\n", paths[i], name); 59 printf("Checking %s/%s\n", paths[i], name);
51 if (stat(fname, &s) == 0 && !S_ISDIR(s.st_mode)) // do not allow directories 60 if (stat(fname, &s) == 0 && !S_ISDIR(s.st_mode)) { // do not allow directories
61 // check symlink to firejail executable in /usr/local/bin
62 if (strcmp(paths[i], "/usr/local/bin") == 0 && is_link(fname)) {
63 char *actual_path = realpath(fname, NULL);
64 if (actual_path) {
65 char *ptr = strstr(actual_path, "/firejail");
66 if (ptr && strlen(ptr) == strlen("/firejail")) {
67 if (arg_debug)
68 printf("firejail exec symlink detected\n");
69 free(actual_path);
70 free(fname);
71 fname = NULL;
72 i++;
73 continue;
74 }
75 free(actual_path);
76 }
77
78 }
52 break; // file found 79 break; // file found
80 }
53 81
54 free(fname); 82 free(fname);
55 fname = NULL; 83 fname = NULL;
@@ -57,7 +85,8 @@ static char *check_dir_or_file(const char *name) {
57 } 85 }
58 86
59 if (!fname) { 87 if (!fname) {
60// fprintf(stderr, "Warning: file %s not found\n", name); 88 if (arg_debug)
89 fprintf(stderr, "Warning: file %s not found\n", name);
61 return NULL; 90 return NULL;
62 } 91 }
63 92
@@ -108,16 +137,16 @@ void fs_check_bin_list(void) {
108 } 137 }
109 138
110 if (*newlist == '\0') { 139 if (*newlist == '\0') {
111 fprintf(stderr, "Warning: no --private-bin list executable found, option disabled\n"); 140// fprintf(stderr, "Warning: no --private-bin list executable found, option disabled\n");
112 cfg.bin_private_keep = NULL; 141// cfg.bin_private_keep = NULL;
113 arg_private_bin = 0; 142// arg_private_bin = 0;
114 free(newlist); 143 free(newlist);
115 } 144 }
116 else { 145 else {
117 ptr = strrchr(newlist, ','); 146 ptr = strrchr(newlist, ',');
118 assert(ptr); 147 assert(ptr);
119 *ptr = '\0'; 148 *ptr = '\0';
120 if (notfound) 149 if (notfound && !arg_quiet)
121 fprintf(stderr, "Warning: not all executables from --private-bin list were found. The current list is %s\n", newlist); 150 fprintf(stderr, "Warning: not all executables from --private-bin list were found. The current list is %s\n", newlist);
122 151
123 cfg.bin_private_keep = newlist; 152 cfg.bin_private_keep = newlist;
@@ -127,7 +156,6 @@ void fs_check_bin_list(void) {
127} 156}
128 157
129static void duplicate(char *fname) { 158static void duplicate(char *fname) {
130 char *cmd;
131 char *path = check_dir_or_file(fname); 159 char *path = check_dir_or_file(fname);
132 if (!path) 160 if (!path)
133 return; 161 return;
@@ -153,13 +181,24 @@ static void duplicate(char *fname) {
153 } 181 }
154 else { 182 else {
155 // copy the file 183 // copy the file
156 if (asprintf(&cmd, "%s -a %s %s/%s", RUN_CP_COMMAND, actual_path, RUN_BIN_DIR, fname) == -1)
157 errExit("asprintf");
158 if (arg_debug) 184 if (arg_debug)
159 printf("%s\n", cmd); 185 printf("running: %s -a %s %s/%s", RUN_CP_COMMAND, actual_path, RUN_BIN_DIR, fname);
160 if (system(cmd)) 186
161 errExit("system cp -a"); 187 pid_t child = fork();
162 free(cmd); 188 if (child < 0)
189 errExit("fork");
190 if (child == 0) {
191 char *f;
192 if (asprintf(&f, "%s/%s", RUN_BIN_DIR, fname) == -1)
193 errExit("asprintf");
194 clearenv();
195 execlp(RUN_CP_COMMAND, RUN_CP_COMMAND, "-a", actual_path, f, NULL);
196 perror("execlp");
197 _exit(1);
198 }
199 // wait for the child to finish
200 waitpid(child, NULL, 0);
201
163 } 202 }
164 free(actual_path); 203 free(actual_path);
165 } 204 }
@@ -172,29 +211,8 @@ void fs_private_bin_list(void) {
172 char *private_list = cfg.bin_private_keep; 211 char *private_list = cfg.bin_private_keep;
173 assert(private_list); 212 assert(private_list);
174 213
175 // check bin paths 214 // create /run/firejail/mnt/bin directory
176 int i = 0; 215 mkdir_attr(RUN_BIN_DIR, 0755, 0, 0);
177#if 0
178 while (paths[i]) {
179 struct stat s;
180 if (stat(paths[i], &s) == -1) {
181 fprintf(stderr, "Error: cannot find %s directory\n", paths[i]);
182 exit(1);
183 }
184 i++;
185 }
186#endif
187
188 // create /tmp/firejail/mnt/bin directory
189 fs_build_mnt_dir();
190 int rv = mkdir(RUN_BIN_DIR, 0755);
191 if (rv == -1)
192 errExit("mkdir");
193 if (chown(RUN_BIN_DIR, 0, 0) < 0)
194 errExit("chown");
195 if (chmod(RUN_BIN_DIR, 0755) < 0)
196 errExit("chmod");
197
198 216
199 // copy the list of files in the new etc directory 217 // copy the list of files in the new etc directory
200 // using a new child process without root privileges 218 // using a new child process without root privileges
@@ -225,13 +243,16 @@ void fs_private_bin_list(void) {
225 duplicate(ptr); 243 duplicate(ptr);
226 free(dlist); 244 free(dlist);
227 fs_logger_print(); 245 fs_logger_print();
228 exit(0); 246#ifdef HAVE_GCOV
247 __gcov_flush();
248#endif
249 _exit(0);
229 } 250 }
230 // wait for the child to finish 251 // wait for the child to finish
231 waitpid(child, NULL, 0); 252 waitpid(child, NULL, 0);
232 253
233 // mount-bind 254 // mount-bind
234 i = 0; 255 int i = 0;
235 while (paths[i]) { 256 while (paths[i]) {
236 struct stat s; 257 struct stat s;
237 if (stat(paths[i], &s) == 0) { 258 if (stat(paths[i], &s) == 0) {
diff --git a/src/firejail/fs_dev.c b/src/firejail/fs_dev.c
index 2fd450391..d710e98f2 100644
--- a/src/firejail/fs_dev.c
+++ b/src/firejail/fs_dev.c
@@ -30,17 +30,75 @@
30#endif 30#endif
31#include <sys/types.h> 31#include <sys/types.h>
32 32
33typedef struct {
34 const char *dev_fname;
35 const char *run_fname;
36 int sound;
37 int hw3d;
38} DevEntry;
39
40static DevEntry dev[] = {
41 {"/dev/snd", RUN_DEV_DIR "/snd", 1, 0}, // sound device
42 {"/dev/dri", RUN_DEV_DIR "/dri", 0, 1}, // 3d device
43 {"/dev/nvidia0", RUN_DEV_DIR "/nvidia0", 0, 1},
44 {"/dev/nvidia1", RUN_DEV_DIR "/nvidia1", 0, 1},
45 {"/dev/nvidia2", RUN_DEV_DIR "/nvidia2", 0, 1},
46 {"/dev/nvidia3", RUN_DEV_DIR "/nvidia3", 0, 1},
47 {"/dev/nvidia4", RUN_DEV_DIR "/nvidia4", 0, 1},
48 {"/dev/nvidia5", RUN_DEV_DIR "/nvidia5", 0, 1},
49 {"/dev/nvidia6", RUN_DEV_DIR "/nvidia6", 0, 1},
50 {"/dev/nvidia7", RUN_DEV_DIR "/nvidia7", 0, 1},
51 {"/dev/nvidia8", RUN_DEV_DIR "/nvidia8", 0, 1},
52 {"/dev/nvidia9", RUN_DEV_DIR "/nvidia9", 0, 1},
53 {"/dev/nvidiactl", RUN_DEV_DIR "/nvidiactl", 0, 1},
54 {"/dev/nvidia-modset", RUN_DEV_DIR "/nvidia-modset", 0, 1},
55 {"/dev/nvidia-uvm", RUN_DEV_DIR "/nvidia-uvm", 0, 1},
56 {NULL, NULL, 0, 0}
57};
58
59static void deventry_mount(void) {
60 int i = 0;
61 while (dev[i].dev_fname != NULL) {
62 struct stat s;
63 if (stat(dev[i].run_fname, &s) == 0) {
64 int dir = is_dir(dev[i].run_fname);
65 if (arg_debug)
66 printf("mounting %s %s\n", dev[i].run_fname, (dir)? "directory": "file");
67 if (dir) {
68 mkdir_attr(dev[i].dev_fname, 0755, 0, 0);
69 }
70 else {
71 struct stat s;
72 if (stat(dev[i].run_fname, &s) == -1) {
73 if (arg_debug)
74 printf("Warning: cannot stat %s file\n", dev[i].run_fname);
75 i++;
76 continue;
77 }
78 FILE *fp = fopen(dev[i].dev_fname, "w");
79 if (fp) {
80 fprintf(fp, "\n");
81 SET_PERMS_STREAM(fp, s.st_uid, s.st_gid, s.st_mode);
82 fclose(fp);
83 }
84 }
85
86 if (mount(dev[i].run_fname, dev[i].dev_fname, NULL, MS_BIND|MS_REC, NULL) < 0)
87 errExit("mounting dev file");
88 fs_logger2("whitelist", dev[i].dev_fname);
89 }
90
91 i++;
92 }
93}
94
33static void create_char_dev(const char *path, mode_t mode, int major, int minor) { 95static void create_char_dev(const char *path, mode_t mode, int major, int minor) {
34 dev_t dev = makedev(major, minor); 96 dev_t dev = makedev(major, minor);
35 int rv = mknod(path, S_IFCHR | mode, dev); 97 if (mknod(path, S_IFCHR | mode, dev) == -1)
36 if (rv == -1)
37 goto errexit; 98 goto errexit;
38
39
40 if (chmod(path, mode) < 0) 99 if (chmod(path, mode) < 0)
41 goto errexit; 100 goto errexit;
42 if (chown(path, 0, 0) < 0) 101 ASSERT_PERMS(path, 0, 0, mode);
43 goto errexit;
44 102
45 return; 103 return;
46 104
@@ -62,35 +120,19 @@ errexit:
62} 120}
63 121
64void fs_private_dev(void){ 122void fs_private_dev(void){
65 int rv;
66 // install a new /dev directory 123 // install a new /dev directory
67 if (arg_debug) 124 if (arg_debug)
68 printf("Mounting tmpfs on /dev\n"); 125 printf("Mounting tmpfs on /dev\n");
69 126
70 int have_dri = 0;
71 struct stat s;
72 if (stat("/dev/dri", &s) == 0)
73 have_dri = 1;
74
75 // create DRI_DIR 127 // create DRI_DIR
76 fs_build_mnt_dir(); 128 // keep a copy of dev directory
77 if (have_dri) { 129 mkdir_attr(RUN_DEV_DIR, 0755, 0, 0);
78 /* coverity[toctou] */ 130 if (mount("/dev", RUN_DEV_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
79 rv = mkdir(RUN_DRI_DIR, 0755); 131 errExit("mounting /dev/dri");
80 if (rv == -1) 132
81 errExit("mkdir"); 133 // create DEVLOG_FILE
82 if (chown(RUN_DRI_DIR, 0, 0) < 0)
83 errExit("chown");
84 if (chmod(RUN_DRI_DIR, 0755) < 0)
85 errExit("chmod");
86
87 // keep a copy of /dev/dri under DRI_DIR
88 if (mount("/dev/dri", RUN_DRI_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
89 errExit("mounting /dev/dri");
90 }
91
92 // restore /dev/log
93 int have_devlog = 0; 134 int have_devlog = 0;
135 struct stat s;
94 if (stat("/dev/log", &s) == 0) { 136 if (stat("/dev/log", &s) == 0) {
95 have_devlog = 1; 137 have_devlog = 1;
96 FILE *fp = fopen(RUN_DEVLOG_FILE, "w"); 138 FILE *fp = fopen(RUN_DEVLOG_FILE, "w");
@@ -108,6 +150,8 @@ void fs_private_dev(void){
108 if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 150 if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
109 errExit("mounting /dev"); 151 errExit("mounting /dev");
110 fs_logger("tmpfs /dev"); 152 fs_logger("tmpfs /dev");
153
154 deventry_mount();
111 155
112 // bring back /dev/log 156 // bring back /dev/log
113 if (have_devlog) { 157 if (have_devlog) {
@@ -120,32 +164,14 @@ void fs_private_dev(void){
120 fs_logger("clone /dev/log"); 164 fs_logger("clone /dev/log");
121 } 165 }
122 } 166 }
167 if (mount(RUN_RO_DIR, RUN_DEV_DIR, "none", MS_BIND, "mode=400,gid=0") < 0)
168 errExit("disable /dev/snd");
123 169
124 // bring back the /dev/dri directory
125 if (have_dri) {
126 /* coverity[toctou] */
127 rv = mkdir("/dev/dri", 0755);
128 if (rv == -1)
129 errExit("mkdir");
130 if (chown("/dev/dri", 0, 0) < 0)
131 errExit("chown");
132 if (chmod("/dev/dri",0755) < 0)
133 errExit("chmod");
134 if (mount(RUN_DRI_DIR, "/dev/dri", NULL, MS_BIND|MS_REC, NULL) < 0)
135 errExit("mounting /dev/dri");
136 fs_logger("whitelist /dev/dri");
137 }
138 170
139 // create /dev/shm 171 // create /dev/shm
140 if (arg_debug) 172 if (arg_debug)
141 printf("Create /dev/shm directory\n"); 173 printf("Create /dev/shm directory\n");
142 rv = mkdir("/dev/shm", 01777); 174 mkdir_attr("/dev/shm", 01777, 0, 0);
143 if (rv == -1)
144 errExit("mkdir");
145 if (chown("/dev/shm", 0, 0) < 0)
146 errExit("chown");
147 if (chmod("/dev/shm", 01777) < 0)
148 errExit("chmod");
149 fs_logger("mkdir /dev/shm"); 175 fs_logger("mkdir /dev/shm");
150 176
151 // create devices 177 // create devices
@@ -167,13 +193,7 @@ void fs_private_dev(void){
167#endif 193#endif
168 194
169 // pseudo-terminal 195 // pseudo-terminal
170 rv = mkdir("/dev/pts", 0755); 196 mkdir_attr("/dev/pts", 0755, 0, 0);
171 if (rv == -1)
172 errExit("mkdir");
173 if (chown("/dev/pts", 0, 0) < 0)
174 errExit("chown");
175 if (chmod("/dev/pts", 0755) < 0)
176 errExit("chmod");
177 fs_logger("mkdir /dev/pts"); 197 fs_logger("mkdir /dev/pts");
178 create_char_dev("/dev/pts/ptmx", 0666, 5, 2); //"mknod -m 666 /dev/pts/ptmx c 5 2"); 198 create_char_dev("/dev/pts/ptmx", 0666, 5, 2); //"mknod -m 666 /dev/pts/ptmx c 5 2");
179 fs_logger("mknod /dev/pts/ptmx"); 199 fs_logger("mknod /dev/pts/ptmx");
@@ -186,7 +206,7 @@ void fs_private_dev(void){
186 206
187 207
188 // mount /dev/pts 208 // mount /dev/pts
189 gid_t ttygid = get_tty_gid(); 209 gid_t ttygid = get_group_id("tty");
190 char *data; 210 char *data;
191 if (asprintf(&data, "newinstance,gid=%d,mode=620,ptmxmode=0666", (int) ttygid) == -1) 211 if (asprintf(&data, "newinstance,gid=%d,mode=620,ptmxmode=0666", (int) ttygid) == -1)
192 errExit("asprintf"); 212 errExit("asprintf");
@@ -205,6 +225,7 @@ void fs_private_dev(void){
205} 225}
206 226
207 227
228#if 0
208void fs_dev_shm(void) { 229void fs_dev_shm(void) {
209 uid_t uid = getuid(); // set a new shm only if we started as root 230 uid_t uid = getuid(); // set a new shm only if we started as root
210 if (uid) 231 if (uid)
@@ -222,12 +243,7 @@ void fs_dev_shm(void) {
222 if (lnk) { 243 if (lnk) {
223 if (!is_dir(lnk)) { 244 if (!is_dir(lnk)) {
224 // create directory 245 // create directory
225 if (mkdir(lnk, 01777)) 246 mkdir_attr(lnk, 01777, 0, 0);
226 errExit("mkdir");
227 if (chown(lnk, 0, 0))
228 errExit("chown");
229 if (chmod(lnk, 01777))
230 errExit("chmod");
231 } 247 }
232 if (arg_debug) 248 if (arg_debug)
233 printf("Mounting tmpfs on %s on behalf of /dev/shm\n", lnk); 249 printf("Mounting tmpfs on %s on behalf of /dev/shm\n", lnk);
@@ -243,3 +259,40 @@ void fs_dev_shm(void) {
243 259
244 } 260 }
245} 261}
262#endif
263
264static void disable_file_or_dir(const char *fname) {
265 if (arg_debug)
266 printf("disable %s\n", fname);
267 struct stat s;
268 if (stat(fname, &s) != -1) {
269 if (is_dir(fname)) {
270 if (mount(RUN_RO_DIR, fname, "none", MS_BIND, "mode=400,gid=0") < 0)
271 errExit("disable directory");
272 }
273 else {
274 if (mount(RUN_RO_FILE, fname, "none", MS_BIND, "mode=400,gid=0") < 0)
275 errExit("disable file");
276 }
277 }
278 fs_logger2("blacklist", fname);
279
280}
281
282void fs_dev_disable_sound(void) {
283 int i = 0;
284 while (dev[i].dev_fname != NULL) {
285 if (dev[i].sound)
286 disable_file_or_dir(dev[i].dev_fname);
287 i++;
288 }
289}
290
291void fs_dev_disable_3d(void) {
292 int i = 0;
293 while (dev[i].dev_fname != NULL) {
294 if (dev[i].hw3d)
295 disable_file_or_dir(dev[i].dev_fname);
296 i++;
297 }
298}
diff --git a/src/firejail/fs_etc.c b/src/firejail/fs_etc.c
index 1a44b1305..7e18840fd 100644
--- a/src/firejail/fs_etc.c
+++ b/src/firejail/fs_etc.c
@@ -28,7 +28,7 @@
28static int check_dir_or_file(const char *name) { 28static int check_dir_or_file(const char *name) {
29 assert(name); 29 assert(name);
30 invalid_filename(name); 30 invalid_filename(name);
31 31
32 struct stat s; 32 struct stat s;
33 char *fname; 33 char *fname;
34 if (asprintf(&fname, "/etc/%s", name) == -1) 34 if (asprintf(&fname, "/etc/%s", name) == -1)
@@ -40,7 +40,11 @@ static int check_dir_or_file(const char *name) {
40 printf("Warning: file %s not found.\n", fname); 40 printf("Warning: file %s not found.\n", fname);
41 return 0; 41 return 0;
42 } 42 }
43 43
44 // read access
45 if (access(fname, R_OK) == -1)
46 goto errexit;
47
44 // dir or regular file 48 // dir or regular file
45 if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode)) { 49 if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode)) {
46 free(fname); 50 free(fname);
@@ -52,6 +56,8 @@ static int check_dir_or_file(const char *name) {
52 return 1; 56 return 1;
53 } 57 }
54 58
59
60errexit:
55 fprintf(stderr, "Error: invalid file type, %s.\n", fname); 61 fprintf(stderr, "Error: invalid file type, %s.\n", fname);
56 exit(1); 62 exit(1);
57} 63}
@@ -88,18 +94,25 @@ void fs_check_etc_list(void) {
88} 94}
89 95
90static void duplicate(char *fname) { 96static void duplicate(char *fname) {
91 char *cmd; 97 // copy the file
92
93 // copy the file - this code assumes ETC_DIR is actually MNT_DIR/etc
94 if (asprintf(&cmd, "%s -a --parents /etc/%s %s", RUN_CP_COMMAND, fname, RUN_MNT_DIR) == -1)
95 errExit("asprintf");
96 if (arg_debug) 98 if (arg_debug)
97 printf("%s\n", cmd); 99 printf("running: %s -a --parents /etc/%s %s\n", RUN_CP_COMMAND, fname, RUN_MNT_DIR);
98 if (system(cmd)) 100
99 fprintf(stderr, "Warning (fs_etc): error copying file /etc/%s, skipping...\n", fname); 101 pid_t child = fork();
102 if (child < 0)
103 errExit("fork");
104 if (child == 0) {
105 char *f;
106 if (asprintf(&f, "/etc/%s", fname) == -1)
107 errExit("asprintf");
108 clearenv();
109 execlp(RUN_CP_COMMAND, RUN_CP_COMMAND, "-a", "--parents", f, RUN_MNT_DIR, NULL);
110 perror("execlp");
111 _exit(1);
112 }
113 // wait for the child to finish
114 waitpid(child, NULL, 0);
100 115
101 free(cmd);
102
103 char *name; 116 char *name;
104 if (asprintf(&name, "/etc/%s", fname) == -1) 117 if (asprintf(&name, "/etc/%s", fname) == -1)
105 errExit("asprintf"); 118 errExit("asprintf");
@@ -118,51 +131,51 @@ void fs_private_etc_list(void) {
118 exit(1); 131 exit(1);
119 } 132 }
120 133
121 // create /tmp/firejail/mnt/etc directory 134 // create /run/firejail/mnt/etc directory
122 fs_build_mnt_dir(); 135 mkdir_attr(RUN_ETC_DIR, 0755, 0, 0);
123 int rv = mkdir(RUN_ETC_DIR, 0755);
124 if (rv == -1)
125 errExit("mkdir");
126 if (chown(RUN_ETC_DIR, 0, 0) < 0)
127 errExit("chown");
128 if (chmod(RUN_ETC_DIR, 0755) < 0)
129 errExit("chmod");
130 fs_logger("tmpfs /etc"); 136 fs_logger("tmpfs /etc");
131 137
132 // copy the list of files in the new etc directory
133 // using a new child process without root privileges
134 fs_logger_print(); // save the current log 138 fs_logger_print(); // save the current log
135 pid_t child = fork();
136 if (child < 0)
137 errExit("fork");
138 if (child == 0) {
139 if (arg_debug)
140 printf("Copying files in the new etc directory:\n");
141 139
142 // elevate privileges - files in the new /etc directory belong to root
143 if (setreuid(0, 0) < 0)
144 errExit("setreuid");
145 if (setregid(0, 0) < 0)
146 errExit("setregid");
147
148 // copy the list of files in the new home directory
149 char *dlist = strdup(private_list);
150 if (!dlist)
151 errExit("strdup");
152
153 140
154 char *ptr = strtok(dlist, ","); 141 // copy the list of files in the new etc directory
155 duplicate(ptr); 142 // using a new child process with root privileges
143 if (*private_list != '\0') {
144 pid_t child = fork();
145 if (child < 0)
146 errExit("fork");
147 if (child == 0) {
148 if (arg_debug)
149 printf("Copying files in the new etc directory:\n");
156 150
157 while ((ptr = strtok(NULL, ",")) != NULL) 151 // elevate privileges - files in the new /etc directory belong to root
152 if (setreuid(0, 0) < 0)
153 errExit("setreuid");
154 if (setregid(0, 0) < 0)
155 errExit("setregid");
156
157 // copy the list of files in the new home directory
158 char *dlist = strdup(private_list);
159 if (!dlist)
160 errExit("strdup");
161
162
163 char *ptr = strtok(dlist, ",");
158 duplicate(ptr); 164 duplicate(ptr);
159 free(dlist); 165
160 fs_logger_print(); 166 while ((ptr = strtok(NULL, ",")) != NULL)
161 exit(0); 167 duplicate(ptr);
168 free(dlist);
169 fs_logger_print();
170#ifdef HAVE_GCOV
171 __gcov_flush();
172#endif
173 _exit(0);
174 }
175 // wait for the child to finish
176 waitpid(child, NULL, 0);
162 } 177 }
163 // wait for the child to finish 178
164 waitpid(child, NULL, 0);
165
166 if (arg_debug) 179 if (arg_debug)
167 printf("Mount-bind %s on top of /etc\n", RUN_ETC_DIR); 180 printf("Mount-bind %s on top of /etc\n", RUN_ETC_DIR);
168 if (mount(RUN_ETC_DIR, "/etc", NULL, MS_BIND|MS_REC, NULL) < 0) 181 if (mount(RUN_ETC_DIR, "/etc", NULL, MS_BIND|MS_REC, NULL) < 0)
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c
index d4a16da0a..242482d26 100644
--- a/src/firejail/fs_home.c
+++ b/src/firejail/fs_home.c
@@ -28,11 +28,13 @@
28#include <sys/wait.h> 28#include <sys/wait.h>
29#include <unistd.h> 29#include <unistd.h>
30#include <grp.h> 30#include <grp.h>
31#include <ftw.h>
31 32
32static void skel(const char *homedir, uid_t u, gid_t g) { 33static void skel(const char *homedir, uid_t u, gid_t g) {
33 char *fname; 34 char *fname;
35
34 // zsh 36 // zsh
35 if (arg_zsh) { 37 if (!arg_shell_none && (strcmp(cfg.shell,"/usr/bin/zsh") == 0 || strcmp(cfg.shell,"/bin/zsh") == 0)) {
36 // copy skel files 38 // copy skel files
37 if (asprintf(&fname, "%s/.zshrc", homedir) == -1) 39 if (asprintf(&fname, "%s/.zshrc", homedir) == -1)
38 errExit("asprintf"); 40 errExit("asprintf");
@@ -41,13 +43,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
41 if (stat(fname, &s) == 0) 43 if (stat(fname, &s) == 0)
42 return; 44 return;
43 if (stat("/etc/skel/.zshrc", &s) == 0) { 45 if (stat("/etc/skel/.zshrc", &s) == 0) {
44 if (is_link("/etc/skel/.zshrc")) { 46 if (copy_file("/etc/skel/.zshrc", fname, u, g, 0644) == 0) {
45 fprintf(stderr, "Error: invalid /etc/skel/.zshrc file\n");
46 exit(1);
47 }
48 if (copy_file("/etc/skel/.zshrc", fname) == 0) {
49 if (chown(fname, u, g) == -1)
50 errExit("chown");
51 fs_logger("clone /etc/skel/.zshrc"); 47 fs_logger("clone /etc/skel/.zshrc");
52 } 48 }
53 } 49 }
@@ -55,18 +51,15 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
55 FILE *fp = fopen(fname, "w"); 51 FILE *fp = fopen(fname, "w");
56 if (fp) { 52 if (fp) {
57 fprintf(fp, "\n"); 53 fprintf(fp, "\n");
54 SET_PERMS_STREAM(fp, u, g, S_IRUSR | S_IWUSR);
58 fclose(fp); 55 fclose(fp);
59 if (chown(fname, u, g) == -1)
60 errExit("chown");
61 if (chmod(fname, S_IRUSR | S_IWUSR) < 0)
62 errExit("chown");
63 fs_logger2("touch", fname); 56 fs_logger2("touch", fname);
64 } 57 }
65 } 58 }
66 free(fname); 59 free(fname);
67 } 60 }
68 // csh 61 // csh
69 else if (arg_csh) { 62 else if (!arg_shell_none && strcmp(cfg.shell,"/bin/csh") == 0) {
70 // copy skel files 63 // copy skel files
71 if (asprintf(&fname, "%s/.cshrc", homedir) == -1) 64 if (asprintf(&fname, "%s/.cshrc", homedir) == -1)
72 errExit("asprintf"); 65 errExit("asprintf");
@@ -75,13 +68,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
75 if (stat(fname, &s) == 0) 68 if (stat(fname, &s) == 0)
76 return; 69 return;
77 if (stat("/etc/skel/.cshrc", &s) == 0) { 70 if (stat("/etc/skel/.cshrc", &s) == 0) {
78 if (is_link("/etc/skel/.cshrc")) { 71 if (copy_file("/etc/skel/.cshrc", fname, u, g, 0644) == 0) {
79 fprintf(stderr, "Error: invalid /etc/skel/.cshrc file\n");
80 exit(1);
81 }
82 if (copy_file("/etc/skel/.cshrc", fname) == 0) {
83 if (chown(fname, u, g) == -1)
84 errExit("chown");
85 fs_logger("clone /etc/skel/.cshrc"); 72 fs_logger("clone /etc/skel/.cshrc");
86 } 73 }
87 } 74 }
@@ -90,11 +77,8 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
90 FILE *fp = fopen(fname, "w"); 77 FILE *fp = fopen(fname, "w");
91 if (fp) { 78 if (fp) {
92 fprintf(fp, "\n"); 79 fprintf(fp, "\n");
80 SET_PERMS_STREAM(fp, u, g, S_IRUSR | S_IWUSR);
93 fclose(fp); 81 fclose(fp);
94 if (chown(fname, u, g) == -1)
95 errExit("chown");
96 if (chmod(fname, S_IRUSR | S_IWUSR) < 0)
97 errExit("chown");
98 fs_logger2("touch", fname); 82 fs_logger2("touch", fname);
99 } 83 }
100 } 84 }
@@ -110,14 +94,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
110 if (stat(fname, &s) == 0) 94 if (stat(fname, &s) == 0)
111 return; 95 return;
112 if (stat("/etc/skel/.bashrc", &s) == 0) { 96 if (stat("/etc/skel/.bashrc", &s) == 0) {
113 if (is_link("/etc/skel/.bashrc")) { 97 if (copy_file("/etc/skel/.bashrc", fname, u, g, 0644) == 0) {
114 fprintf(stderr, "Error: invalid /etc/skel/.bashrc file\n");
115 exit(1);
116 }
117 if (copy_file("/etc/skel/.bashrc", fname) == 0) {
118 /* coverity[toctou] */
119 if (chown(fname, u, g) == -1)
120 errExit("chown");
121 fs_logger("clone /etc/skel/.bashrc"); 98 fs_logger("clone /etc/skel/.bashrc");
122 } 99 }
123 } 100 }
@@ -127,8 +104,6 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
127 104
128static int store_xauthority(void) { 105static int store_xauthority(void) {
129 // put a copy of .Xauthority in XAUTHORITY_FILE 106 // put a copy of .Xauthority in XAUTHORITY_FILE
130 fs_build_mnt_dir();
131
132 char *src; 107 char *src;
133 char *dest = RUN_XAUTHORITY_FILE; 108 char *dest = RUN_XAUTHORITY_FILE;
134 if (asprintf(&src, "%s/.Xauthority", cfg.homedir) == -1) 109 if (asprintf(&src, "%s/.Xauthority", cfg.homedir) == -1)
@@ -137,11 +112,11 @@ static int store_xauthority(void) {
137 struct stat s; 112 struct stat s;
138 if (stat(src, &s) == 0) { 113 if (stat(src, &s) == 0) {
139 if (is_link(src)) { 114 if (is_link(src)) {
140 fprintf(stderr, "Error: invalid .Xauthority file\n"); 115 fprintf(stderr, "Warning: invalid .Xauthority file\n");
141 exit(1); 116 return 0;
142 } 117 }
143 118
144 int rv = copy_file(src, dest); 119 int rv = copy_file(src, dest, -1, -1, 0600);
145 if (rv) { 120 if (rv) {
146 fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n"); 121 fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n");
147 return 0; 122 return 0;
@@ -153,9 +128,6 @@ static int store_xauthority(void) {
153} 128}
154 129
155static int store_asoundrc(void) { 130static int store_asoundrc(void) {
156 // put a copy of .Xauthority in XAUTHORITY_FILE
157 fs_build_mnt_dir();
158
159 char *src; 131 char *src;
160 char *dest = RUN_ASOUNDRC_FILE; 132 char *dest = RUN_ASOUNDRC_FILE;
161 if (asprintf(&src, "%s/.asoundrc", cfg.homedir) == -1) 133 if (asprintf(&src, "%s/.asoundrc", cfg.homedir) == -1)
@@ -177,7 +149,7 @@ static int store_asoundrc(void) {
177 free(rp); 149 free(rp);
178 } 150 }
179 151
180 int rv = copy_file(src, dest); 152 int rv = copy_file(src, dest, -1, -1, -0644);
181 if (rv) { 153 if (rv) {
182 fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n"); 154 fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n");
183 return 0; 155 return 0;
@@ -194,17 +166,12 @@ static void copy_xauthority(void) {
194 char *dest; 166 char *dest;
195 if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1) 167 if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1)
196 errExit("asprintf"); 168 errExit("asprintf");
197 int rv = copy_file(src, dest); 169 // copy, set permissions and ownership
170 int rv = copy_file(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR);
198 if (rv) 171 if (rv)
199 fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n"); 172 fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n");
200 else { 173 else {
201 fs_logger2("clone", dest); 174 fs_logger2("clone", dest);
202
203 // set permissions and ownership
204 if (chown(dest, getuid(), getgid()) < 0)
205 errExit("chown");
206 if (chmod(dest, S_IRUSR | S_IWUSR) < 0)
207 errExit("chmod");
208 } 175 }
209 176
210 // delete the temporary file 177 // delete the temporary file
@@ -217,17 +184,12 @@ static void copy_asoundrc(void) {
217 char *dest; 184 char *dest;
218 if (asprintf(&dest, "%s/.asoundrc", cfg.homedir) == -1) 185 if (asprintf(&dest, "%s/.asoundrc", cfg.homedir) == -1)
219 errExit("asprintf"); 186 errExit("asprintf");
220 int rv = copy_file(src, dest); 187 // copy, set permissions and ownership
188 int rv = copy_file(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR);
221 if (rv) 189 if (rv)
222 fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n"); 190 fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n");
223 else { 191 else {
224 fs_logger2("clone", dest); 192 fs_logger2("clone", dest);
225
226 // set permissions and ownership
227 if (chown(dest, getuid(), getgid()) < 0)
228 errExit("chown");
229 if (chmod(dest, S_IRUSR | S_IWUSR) < 0)
230 errExit("chmod");
231 } 193 }
232 194
233 // delete the temporary file 195 // delete the temporary file
@@ -260,7 +222,7 @@ void fs_private_homedir(void) {
260 // mount bind private_homedir on top of homedir 222 // mount bind private_homedir on top of homedir
261 if (arg_debug) 223 if (arg_debug)
262 printf("Mount-bind %s on top of %s\n", private_homedir, homedir); 224 printf("Mount-bind %s on top of %s\n", private_homedir, homedir);
263 if (mount(private_homedir, homedir, NULL, MS_BIND|MS_REC, NULL) < 0) 225 if (mount(private_homedir, homedir, NULL, MS_NOSUID | MS_NODEV | MS_BIND | MS_REC, NULL) < 0)
264 errExit("mount bind"); 226 errExit("mount bind");
265 fs_logger3("mount-bind", private_homedir, cfg.homedir); 227 fs_logger3("mount-bind", private_homedir, cfg.homedir);
266 fs_logger2("whitelist", cfg.homedir); 228 fs_logger2("whitelist", cfg.homedir);
@@ -274,7 +236,7 @@ void fs_private_homedir(void) {
274 // mask /root 236 // mask /root
275 if (arg_debug) 237 if (arg_debug)
276 printf("Mounting a new /root directory\n"); 238 printf("Mounting a new /root directory\n");
277 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=700,gid=0") < 0) 239 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME | MS_REC, "mode=700,gid=0") < 0)
278 errExit("mounting home directory"); 240 errExit("mounting home directory");
279 fs_logger("tmpfs /root"); 241 fs_logger("tmpfs /root");
280 } 242 }
@@ -282,7 +244,7 @@ void fs_private_homedir(void) {
282 // mask /home 244 // mask /home
283 if (arg_debug) 245 if (arg_debug)
284 printf("Mounting a new /home directory\n"); 246 printf("Mounting a new /home directory\n");
285 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 247 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
286 errExit("mounting home directory"); 248 errExit("mounting home directory");
287 fs_logger("tmpfs /home"); 249 fs_logger("tmpfs /home");
288 } 250 }
@@ -312,14 +274,14 @@ void fs_private(void) {
312 // mask /home 274 // mask /home
313 if (arg_debug) 275 if (arg_debug)
314 printf("Mounting a new /home directory\n"); 276 printf("Mounting a new /home directory\n");
315 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 277 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
316 errExit("mounting home directory"); 278 errExit("mounting home directory");
317 fs_logger("tmpfs /home"); 279 fs_logger("tmpfs /home");
318 280
319 // mask /root 281 // mask /root
320 if (arg_debug) 282 if (arg_debug)
321 printf("Mounting a new /root directory\n"); 283 printf("Mounting a new /root directory\n");
322 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=700,gid=0") < 0) 284 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_STRICTATIME | MS_REC, "mode=700,gid=0") < 0)
323 errExit("mounting root directory"); 285 errExit("mounting root directory");
324 fs_logger("tmpfs /root"); 286 fs_logger("tmpfs /root");
325 287
@@ -343,8 +305,8 @@ void fs_private(void) {
343 copy_xauthority(); 305 copy_xauthority();
344 if (aflag) 306 if (aflag)
345 copy_asoundrc(); 307 copy_asoundrc();
346}
347 308
309}
348 310
349// check new private home directory (--private= option) - exit if it fails 311// check new private home directory (--private= option) - exit if it fails
350void fs_check_private_dir(void) { 312void fs_check_private_dir(void) {
@@ -384,3 +346,318 @@ void fs_check_private_dir(void) {
384 } 346 }
385} 347}
386 348
349//***********************************************************************************
350// --private-home
351//***********************************************************************************
352#define PRIVATE_COPY_LIMIT (500 * 1024 *1024)
353static int size_limit_reached = 0;
354static unsigned file_cnt = 0;
355static unsigned size_cnt = 0;
356static char *check_dir_or_file(const char *name);
357
358int fs_copydir(const char *path, const struct stat *st, int ftype, struct FTW *sftw) {
359 (void) st;
360 (void) sftw;
361 if (size_limit_reached)
362 return 0;
363
364 struct stat s;
365 char *dest;
366 if (asprintf(&dest, "%s%s", RUN_HOME_DIR, path + strlen(cfg.homedir)) == -1)
367 errExit("asprintf");
368
369 // don't copy it if we already have the file
370 if (stat(dest, &s) == 0) {
371 free(dest);
372 return 0;
373 }
374
375 // extract mode and ownership
376 if (stat(path, &s) != 0) {
377 free(dest);
378 return 0;
379 }
380
381 // check uid
382 if (s.st_uid != firejail_uid || s.st_gid != firejail_gid) {
383 free(dest);
384 return 0;
385 }
386
387 if ((s.st_size + size_cnt) > PRIVATE_COPY_LIMIT) {
388 size_limit_reached = 1;
389 free(dest);
390 return 0;
391 }
392
393 file_cnt++;
394 size_cnt += s.st_size;
395
396 if(ftype == FTW_F)
397 copy_file(path, dest, firejail_uid, firejail_gid, s.st_mode);
398 else if (ftype == FTW_D) {
399 if (mkdir(dest, s.st_mode) == -1)
400 errExit("mkdir");
401 if (set_perms(dest, firejail_uid, firejail_gid, s.st_mode))
402 errExit("set_perms");
403#if 0
404struct stat s2;
405if (stat(dest, &s2) == 0) {
406 printf("%s\t", dest);
407 printf((S_ISDIR(s.st_mode)) ? "d" : "-");
408 printf((s.st_mode & S_IRUSR) ? "r" : "-");
409 printf((s.st_mode & S_IWUSR) ? "w" : "-");
410 printf((s.st_mode & S_IXUSR) ? "x" : "-");
411 printf((s.st_mode & S_IRGRP) ? "r" : "-");
412 printf((s.st_mode & S_IWGRP) ? "w" : "-");
413 printf((s.st_mode & S_IXGRP) ? "x" : "-");
414 printf((s.st_mode & S_IROTH) ? "r" : "-");
415 printf((s.st_mode & S_IWOTH) ? "w" : "-");
416 printf((s.st_mode & S_IXOTH) ? "x" : "-");
417 printf("\n");
418}
419#endif
420
421 fs_logger2("clone", path);
422 }
423
424 free(dest);
425 return(0);
426}
427
428static void duplicate(char *name) {
429 char *fname = check_dir_or_file(name);
430
431 if (arg_debug)
432 printf("Private home: duplicating %s\n", fname);
433 assert(strncmp(fname, cfg.homedir, strlen(cfg.homedir)) == 0);
434
435 struct stat s;
436 if (stat(fname, &s) == -1) {
437 free(fname);
438 return;
439 }
440
441 if(nftw(fname, fs_copydir, 1, FTW_PHYS) != 0) {
442 fprintf(stderr, "Error: unable to copy template dir\n");
443 exit(1);
444 }
445 fs_logger_print(); // save the current log
446
447 free(fname);
448}
449
450
451
452static char *check_dir_or_file(const char *name) {
453 assert(name);
454 struct stat s;
455
456 // basic checks
457 invalid_filename(name);
458
459 if (arg_debug)
460 printf("Private home: checking %s\n", name);
461
462 // expand home directory
463 char *fname = expand_home(name, cfg.homedir);
464 if (!fname) {
465 fprintf(stderr, "Error: file %s not found.\n", name);
466 exit(1);
467 }
468
469 // If it doesn't start with '/', it must be relative to homedir
470 if (fname[0] != '/') {
471 char* tmp;
472 if (asprintf(&tmp, "%s/%s", cfg.homedir, fname) == -1)
473 errExit("asprintf");
474 free(fname);
475 fname = tmp;
476 }
477
478 // check the file is in user home directory
479 char *rname = realpath(fname, NULL);
480 if (!rname) {
481 fprintf(stderr, "Error: invalid file %s\n", name);
482 exit(1);
483 }
484 if (strncmp(rname, cfg.homedir, strlen(cfg.homedir)) != 0) {
485 fprintf(stderr, "Error: file %s is not in user home directory\n", name);
486 exit(1);
487 }
488
489 // a full home directory is not allowed
490 if (strcmp(rname, cfg.homedir) == 0) {
491 fprintf(stderr, "Error: invalid directory %s\n", rname);
492 exit(1);
493 }
494
495 // only top files and directories in user home are allowed
496 char *ptr = rname + strlen(cfg.homedir);
497 if (*ptr == '\0') {
498 fprintf(stderr, "Error: invalid file %s\n", name);
499 exit(1);
500 }
501 ptr++;
502 ptr = strchr(ptr, '/');
503 if (ptr) {
504 if (*ptr != '\0') {
505 fprintf(stderr, "Error: only top files and directories in user home are allowed\n");
506 exit(1);
507 }
508 }
509
510 if (stat(fname, &s) == -1) {
511 fprintf(stderr, "Error: file %s not found.\n", fname);
512 exit(1);
513 }
514
515 // check uid
516 uid_t uid = getuid();
517 gid_t gid = getgid();
518 if (s.st_uid != uid || s.st_gid != gid) {
519 fprintf(stderr, "Error: only files or directories created by the current user are allowed.\n");
520 exit(1);
521 }
522
523 // dir or regular file
524 if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode)) {
525 free(fname);
526 return rname; // regular exit from the function
527 }
528
529 fprintf(stderr, "Error: invalid file type, %s.\n", fname);
530 exit(1);
531}
532
533
534// check directory list specified by user (--private-home option) - exit if it fails
535void fs_check_home_list(void) {
536 if (strstr(cfg.home_private_keep, "..")) {
537 fprintf(stderr, "Error: invalid private-home list\n");
538 exit(1);
539 }
540
541 char *dlist = strdup(cfg.home_private_keep);
542 if (!dlist)
543 errExit("strdup");
544
545 char *ptr = strtok(dlist, ",");
546 char *tmp = check_dir_or_file(ptr);
547 free(tmp);
548
549 while ((ptr = strtok(NULL, ",")) != NULL) {
550 tmp = check_dir_or_file(ptr);
551 free(tmp);
552 }
553
554 free(dlist);
555}
556
557
558
559// private mode (--private-home=list):
560// mount homedir on top of /home/user,
561// tmpfs on top of /root in nonroot mode,
562// tmpfs on top of /tmp in root mode,
563// set skel files,
564// restore .Xauthority
565void fs_private_home_list(void) {
566 char *homedir = cfg.homedir;
567 char *private_list = cfg.home_private_keep;
568 assert(homedir);
569 assert(private_list);
570
571 int xflag = store_xauthority();
572 int aflag = store_asoundrc();
573
574 uid_t u = firejail_uid;
575 gid_t g = firejail_gid;
576 struct stat s;
577 if (stat(homedir, &s) == -1) {
578 fprintf(stderr, "Error: cannot find user home directory\n");
579 exit(1);
580 }
581
582 // create /run/firejail/mnt/home directory
583 int rv = mkdir(RUN_HOME_DIR, 0755);
584 if (rv == -1)
585 errExit("mkdir");
586 if (set_perms(RUN_HOME_DIR, u, g, 0755))
587 errExit("set_perms");
588 ASSERT_PERMS(RUN_HOME_DIR, u, g, 0755);
589
590 fs_logger_print(); // save the current log
591
592 // copy the list of files in the new home directory
593 // using a new child process without root privileges
594 pid_t child = fork();
595 if (child < 0)
596 errExit("fork");
597 if (child == 0) {
598 if (arg_debug)
599 printf("Copying files in the new home:\n");
600
601 // drop privileges
602 if (setgroups(0, NULL) < 0)
603 errExit("setgroups");
604 if (setgid(getgid()) < 0)
605 errExit("setgid/getgid");
606 if (setuid(getuid()) < 0)
607 errExit("setuid/getuid");
608
609 // copy the list of files in the new home directory
610 char *dlist = strdup(cfg.home_private_keep);
611 if (!dlist)
612 errExit("strdup");
613
614 char *ptr = strtok(dlist, ",");
615 duplicate(ptr);
616 while ((ptr = strtok(NULL, ",")) != NULL)
617 duplicate(ptr);
618
619 if (!arg_quiet) {
620 if (size_limit_reached)
621 fprintf(stderr, "Warning: private-home copy limit of %u MB reached, not all the files were copied\n",
622 PRIVATE_COPY_LIMIT / (1024 *1024));
623 else
624 printf("Private home: %u files, total size %u bytes\n", file_cnt, size_cnt);
625 }
626
627 fs_logger_print(); // save the current log
628 free(dlist);
629#ifdef HAVE_GCOV
630 __gcov_flush();
631#endif
632 _exit(0);
633 }
634 // wait for the child to finish
635 waitpid(child, NULL, 0);
636
637 if (arg_debug)
638 printf("Mount-bind %s on top of %s\n", RUN_HOME_DIR, homedir);
639
640 if (mount(RUN_HOME_DIR, homedir, NULL, MS_BIND|MS_REC, NULL) < 0)
641 errExit("mount bind");
642
643 if (u != 0) {
644 // mask /root
645 if (arg_debug)
646 printf("Mounting a new /root directory\n");
647 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=700,gid=0") < 0)
648 errExit("mounting home directory");
649 }
650 else {
651 // mask /home
652 if (arg_debug)
653 printf("Mounting a new /home directory\n");
654 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
655 errExit("mounting home directory");
656 }
657
658 skel(homedir, u, g);
659 if (xflag)
660 copy_xauthority();
661 if (aflag)
662 copy_asoundrc();
663}
diff --git a/src/firejail/fs_hostname.c b/src/firejail/fs_hostname.c
index aa391c0cb..04197eb8f 100644
--- a/src/firejail/fs_hostname.c
+++ b/src/firejail/fs_hostname.c
@@ -27,7 +27,6 @@
27 27
28void fs_hostname(const char *hostname) { 28void fs_hostname(const char *hostname) {
29 struct stat s; 29 struct stat s;
30 fs_build_mnt_dir();
31 30
32 // create a new /etc/hostname 31 // create a new /etc/hostname
33 if (stat("/etc/hostname", &s) == 0) { 32 if (stat("/etc/hostname", &s) == 0) {
@@ -40,14 +39,10 @@ void fs_hostname(const char *hostname) {
40 exit(1); 39 exit(1);
41 } 40 }
42 fprintf(fp, "%s\n", hostname); 41 fprintf(fp, "%s\n", hostname);
43 fclose(fp);
44
45 // mode and owner 42 // mode and owner
46 if (chown(RUN_HOSTNAME_FILE, 0, 0) < 0) 43 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH);
47 errExit("chown"); 44 fclose(fp);
48 if (chmod(RUN_HOSTNAME_FILE, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0) 45
49 errExit("chmod");
50
51 // bind-mount the file on top of /etc/hostname 46 // bind-mount the file on top of /etc/hostname
52 if (mount(RUN_HOSTNAME_FILE, "/etc/hostname", NULL, MS_BIND|MS_REC, NULL) < 0) 47 if (mount(RUN_HOSTNAME_FILE, "/etc/hostname", NULL, MS_BIND|MS_REC, NULL) < 0)
53 errExit("mount bind /etc/hostname"); 48 errExit("mount bind /etc/hostname");
@@ -88,13 +83,9 @@ void fs_hostname(const char *hostname) {
88 fprintf(fp2, "%s\n", buf); 83 fprintf(fp2, "%s\n", buf);
89 } 84 }
90 fclose(fp1); 85 fclose(fp1);
91 fclose(fp2);
92
93 // mode and owner 86 // mode and owner
94 if (chown(RUN_HOSTS_FILE, 0, 0) < 0) 87 SET_PERMS_STREAM(fp2, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH);
95 errExit("chown"); 88 fclose(fp2);
96 if (chmod(RUN_HOSTS_FILE, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0)
97 errExit("chmod");
98 89
99 // bind-mount the file on top of /etc/hostname 90 // bind-mount the file on top of /etc/hostname
100 if (mount(RUN_HOSTS_FILE, "/etc/hosts", NULL, MS_BIND|MS_REC, NULL) < 0) 91 if (mount(RUN_HOSTS_FILE, "/etc/hosts", NULL, MS_BIND|MS_REC, NULL) < 0)
@@ -108,7 +99,6 @@ void fs_resolvconf(void) {
108 return; 99 return;
109 100
110 struct stat s; 101 struct stat s;
111 fs_build_mnt_dir();
112 102
113 // create a new /etc/hostname 103 // create a new /etc/hostname
114 if (stat("/etc/resolv.conf", &s) == 0) { 104 if (stat("/etc/resolv.conf", &s) == 0) {
@@ -126,13 +116,11 @@ void fs_resolvconf(void) {
126 fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns2)); 116 fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns2));
127 if (cfg.dns3) 117 if (cfg.dns3)
128 fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns3)); 118 fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns3));
129 fclose(fp); 119
130
131 // mode and owner 120 // mode and owner
132 if (chown(RUN_RESOLVCONF_FILE, 0, 0) < 0) 121 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH);
133 errExit("chown"); 122
134 if (chmod(RUN_RESOLVCONF_FILE, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0) 123 fclose(fp);
135 errExit("chmod");
136 124
137 // bind-mount the file on top of /etc/hostname 125 // bind-mount the file on top of /etc/hostname
138 if (mount(RUN_RESOLVCONF_FILE, "/etc/resolv.conf", NULL, MS_BIND|MS_REC, NULL) < 0) 126 if (mount(RUN_RESOLVCONF_FILE, "/etc/resolv.conf", NULL, MS_BIND|MS_REC, NULL) < 0)
diff --git a/src/firejail/fs_logger.c b/src/firejail/fs_logger.c
index 30b0fe438..052a41457 100644
--- a/src/firejail/fs_logger.c
+++ b/src/firejail/fs_logger.c
@@ -97,11 +97,7 @@ void fs_logger_print(void) {
97 perror("fopen"); 97 perror("fopen");
98 return; 98 return;
99 } 99 }
100 100 SET_PERMS_STREAM_NOERR(fp, getuid(), getgid(), 0644);
101 int rv = chown(RUN_FSLOGGER_FILE, getuid(), getgid());
102 (void) rv; // best effort!
103 rv = chmod(RUN_FSLOGGER_FILE, 0644);
104 (void) rv; // best effort!
105 101
106 FsMsg *ptr = head; 102 FsMsg *ptr = head;
107 while (ptr) { 103 while (ptr) {
@@ -121,22 +117,6 @@ void fs_logger_change_owner(void) {
121 errExit("chown"); 117 errExit("chown");
122} 118}
123 119
124void fs_logger_print_log_name(const char *name) {
125 EUID_ASSERT();
126
127 if (!name || strlen(name) == 0) {
128 fprintf(stderr, "Error: invalid sandbox name\n");
129 exit(1);
130 }
131 pid_t pid;
132 if (name2pid(name, &pid)) {
133 fprintf(stderr, "Error: cannot find sandbox %s\n", name);
134 exit(1);
135 }
136
137 fs_logger_print_log(pid);
138}
139
140void fs_logger_print_log(pid_t pid) { 120void fs_logger_print_log(pid_t pid) {
141 EUID_ASSERT(); 121 EUID_ASSERT();
142 122
diff --git a/src/firejail/fs_mkdir.c b/src/firejail/fs_mkdir.c
index 398c534bf..6bcb3f33e 100644
--- a/src/firejail/fs_mkdir.c
+++ b/src/firejail/fs_mkdir.c
@@ -22,8 +22,38 @@
22#include <sys/stat.h> 22#include <sys/stat.h>
23#include <unistd.h> 23#include <unistd.h>
24#include <grp.h> 24#include <grp.h>
25 #include <sys/wait.h> 25#include <sys/wait.h>
26 26#include <string.h>
27
28static void mkdir_recursive(char *path) {
29 char *subdir = NULL;
30 struct stat s;
31
32 if (chdir("/")) {
33 fprintf(stderr, "Error: can't chdir to /");
34 return;
35 }
36
37 subdir = strtok(path, "/");
38 while(subdir) {
39 if (stat(subdir, &s) == -1) {
40 if (mkdir(subdir, 0700) == -1) {
41 fprintf(stderr, "Warning: cannot create %s directory\n", subdir);
42 return;
43 }
44 } else if (!S_ISDIR(s.st_mode)) {
45 fprintf(stderr, "Warning: '%s' exists, but is no directory\n", subdir);
46 return;
47 }
48 if (chdir(subdir)) {
49 fprintf(stderr, "Error: can't chdir to %s", subdir);
50 return;
51 }
52
53 subdir = strtok(NULL, "/");
54 }
55}
56
27void fs_mkdir(const char *name) { 57void fs_mkdir(const char *name) {
28 EUID_ASSERT(); 58 EUID_ASSERT();
29 59
@@ -42,9 +72,71 @@ void fs_mkdir(const char *name) {
42 } 72 }
43 73
44 // create directory 74 // create directory
45 if (mkdir(expanded, 0700) == -1) 75 pid_t child = fork();
46 fprintf(stderr, "Warning: cannot create %s directory\n", expanded); 76 if (child < 0)
77 errExit("fork");
78 if (child == 0) {
79 // drop privileges
80 drop_privs(0);
81
82 // create directory
83 mkdir_recursive(expanded);
84#ifdef HAVE_GCOV
85 __gcov_flush();
86#endif
87 _exit(0);
88 }
89 // wait for the child to finish
90 waitpid(child, NULL, 0);
47 91
48doexit: 92doexit:
49 free(expanded); 93 free(expanded);
50} 94}
95
96void fs_mkfile(const char *name) {
97 EUID_ASSERT();
98
99 // check file name
100 invalid_filename(name);
101 char *expanded = expand_home(name, cfg.homedir);
102 if (strncmp(expanded, cfg.homedir, strlen(cfg.homedir)) != 0) {
103 fprintf(stderr, "Error: only files in user home are supported by mkfile\n");
104 exit(1);
105 }
106
107 struct stat s;
108 if (stat(expanded, &s) == 0) {
109 // file exists, do nothing
110 goto doexit;
111 }
112
113 // create file
114 pid_t child = fork();
115 if (child < 0)
116 errExit("fork");
117 if (child == 0) {
118 // drop privileges
119 drop_privs(0);
120
121 FILE *fp = fopen(expanded, "w");
122 if (!fp)
123 fprintf(stderr, "Warning: cannot create %s file\n", expanded);
124 else {
125 int fd = fileno(fp);
126 if (fd == -1)
127 errExit("fileno");
128 int rv = fchmod(fd, 0600);
129 (void) rv;
130 fclose(fp);
131 }
132#ifdef HAVE_GCOV
133 __gcov_flush();
134#endif
135 _exit(0);
136 }
137 // wait for the child to finish
138 waitpid(child, NULL, 0);
139
140doexit:
141 free(expanded);
142}
diff --git a/src/firejail/fs_trace.c b/src/firejail/fs_trace.c
index f6ca28227..719b55048 100644
--- a/src/firejail/fs_trace.c
+++ b/src/firejail/fs_trace.c
@@ -37,19 +37,13 @@ void fs_trace_preload(void) {
37 FILE *fp = fopen("/etc/ld.so.preload", "w"); 37 FILE *fp = fopen("/etc/ld.so.preload", "w");
38 if (!fp) 38 if (!fp)
39 errExit("fopen"); 39 errExit("fopen");
40 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH);
40 fclose(fp); 41 fclose(fp);
41 if (chown("/etc/ld.so.preload", 0, 0) < 0)
42 errExit("chown");
43 if (chmod("/etc/ld.so.preload", S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0)
44 errExit("chmod");
45 fs_logger("touch /etc/ld.so.preload"); 42 fs_logger("touch /etc/ld.so.preload");
46 } 43 }
47} 44}
48 45
49void fs_trace(void) { 46void fs_trace(void) {
50 // create /tmp/firejail/mnt directory
51 fs_build_mnt_dir();
52
53 // create the new ld.so.preload file and mount-bind it 47 // create the new ld.so.preload file and mount-bind it
54 if (arg_debug) 48 if (arg_debug)
55 printf("Create the new ld.so.preload file\n"); 49 printf("Create the new ld.so.preload file\n");
@@ -57,21 +51,20 @@ void fs_trace(void) {
57 FILE *fp = fopen(RUN_LDPRELOAD_FILE, "w"); 51 FILE *fp = fopen(RUN_LDPRELOAD_FILE, "w");
58 if (!fp) 52 if (!fp)
59 errExit("fopen"); 53 errExit("fopen");
60 if (arg_trace) 54 if (arg_trace) {
61 fprintf(fp, "%s/firejail/libtrace.so\n", LIBDIR); 55 fprintf(fp, "%s/firejail/libtrace.so\n", LIBDIR);
56 }
62 else if (arg_tracelog) { 57 else if (arg_tracelog) {
63 fprintf(fp, "%s/firejail/libtracelog.so\n", LIBDIR); 58 fprintf(fp, "%s/firejail/libtracelog.so\n", LIBDIR);
64 if (!arg_quiet) 59 if (!arg_quiet)
65 printf("Blacklist violations are logged to syslog\n"); 60 printf("Blacklist violations are logged to syslog\n");
66 } 61 }
67 else 62
68 assert(0); 63 if (mask_x11_abstract_socket)
69 64 fprintf(fp, "%s/firejail/libconnect.so\n", LIBDIR);
65
66 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH);
70 fclose(fp); 67 fclose(fp);
71 if (chown(RUN_LDPRELOAD_FILE, 0, 0) < 0)
72 errExit("chown");
73 if (chmod(RUN_LDPRELOAD_FILE, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0)
74 errExit("chmod");
75 68
76 // mount the new preload file 69 // mount the new preload file
77 if (arg_debug) 70 if (arg_debug)
@@ -81,5 +74,3 @@ void fs_trace(void) {
81 fs_logger("create /etc/ld.so.preload"); 74 fs_logger("create /etc/ld.so.preload");
82} 75}
83 76
84
85 \ No newline at end of file
diff --git a/src/firejail/fs_var.c b/src/firejail/fs_var.c
index f904fa5d9..ca50685ad 100644
--- a/src/firejail/fs_var.c
+++ b/src/firejail/fs_var.c
@@ -98,10 +98,7 @@ static void build_dirs(void) {
98 // create directories under /var/log 98 // create directories under /var/log
99 DirData *ptr = dirlist; 99 DirData *ptr = dirlist;
100 while (ptr) { 100 while (ptr) {
101 if (mkdir(ptr->name, ptr->st_mode)) 101 mkdir_attr(ptr->name, ptr->st_mode, ptr->st_uid, ptr->st_gid);
102 errExit("mkdir");
103 if (chown(ptr->name, ptr->st_uid, ptr->st_gid))
104 errExit("chown");
105 fs_logger2("mkdir", ptr->name); 102 fs_logger2("mkdir", ptr->name);
106 ptr = ptr->next; 103 ptr = ptr->next;
107 } 104 }
@@ -121,7 +118,7 @@ void fs_var_log(void) {
121 // mount a tmpfs on top of /var/log 118 // mount a tmpfs on top of /var/log
122 if (arg_debug) 119 if (arg_debug)
123 printf("Mounting tmpfs on /var/log\n"); 120 printf("Mounting tmpfs on /var/log\n");
124 if (mount("tmpfs", "/var/log", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 121 if (mount("tmpfs", "/var/log", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
125 errExit("mounting /var/log"); 122 errExit("mounting /var/log");
126 fs_logger("tmpfs /var/log"); 123 fs_logger("tmpfs /var/log");
127 124
@@ -131,22 +128,16 @@ void fs_var_log(void) {
131 // create an empty /var/log/wtmp file 128 // create an empty /var/log/wtmp file
132 /* coverity[toctou] */ 129 /* coverity[toctou] */
133 FILE *fp = fopen("/var/log/wtmp", "w"); 130 FILE *fp = fopen("/var/log/wtmp", "w");
131 SET_PERMS_STREAM(fp, 0, wtmp_group, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH);
134 if (fp) 132 if (fp)
135 fclose(fp); 133 fclose(fp);
136 if (chown("/var/log/wtmp", 0, wtmp_group) < 0)
137 errExit("chown");
138 if (chmod("/var/log/wtmp", S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH ) < 0)
139 errExit("chmod");
140 fs_logger("touch /var/log/wtmp"); 134 fs_logger("touch /var/log/wtmp");
141 135
142 // create an empty /var/log/btmp file 136 // create an empty /var/log/btmp file
143 fp = fopen("/var/log/btmp", "w"); 137 fp = fopen("/var/log/btmp", "w");
138 SET_PERMS_STREAM(fp, 0, wtmp_group, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP);
144 if (fp) 139 if (fp)
145 fclose(fp); 140 fclose(fp);
146 if (chown("/var/log/btmp", 0, wtmp_group) < 0)
147 errExit("chown");
148 if (chmod("/var/log/btmp", S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP) < 0)
149 errExit("chmod");
150 fs_logger("touch /var/log/btmp"); 141 fs_logger("touch /var/log/btmp");
151 } 142 }
152 else 143 else
@@ -160,7 +151,7 @@ void fs_var_lib(void) {
160 if (stat("/var/lib/dhcp", &s) == 0) { 151 if (stat("/var/lib/dhcp", &s) == 0) {
161 if (arg_debug) 152 if (arg_debug)
162 printf("Mounting tmpfs on /var/lib/dhcp\n"); 153 printf("Mounting tmpfs on /var/lib/dhcp\n");
163 if (mount("tmpfs", "/var/lib/dhcp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 154 if (mount("tmpfs", "/var/lib/dhcp", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
164 errExit("mounting /var/lib/dhcp"); 155 errExit("mounting /var/lib/dhcp");
165 fs_logger("tmpfs /var/lib/dhcp"); 156 fs_logger("tmpfs /var/lib/dhcp");
166 157
@@ -169,11 +160,8 @@ void fs_var_lib(void) {
169 160
170 if (fp) { 161 if (fp) {
171 fprintf(fp, "\n"); 162 fprintf(fp, "\n");
163 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
172 fclose(fp); 164 fclose(fp);
173 if (chown("/var/lib/dhcp/dhcpd.leases", 0, 0) == -1)
174 errExit("chown");
175 if (chmod("/var/lib/dhcp/dhcpd.leases", S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH))
176 errExit("chmod");
177 fs_logger("touch /var/lib/dhcp/dhcpd.leases"); 165 fs_logger("touch /var/lib/dhcp/dhcpd.leases");
178 } 166 }
179 } 167 }
@@ -182,7 +170,7 @@ void fs_var_lib(void) {
182 if (stat("/var/lib/nginx", &s) == 0) { 170 if (stat("/var/lib/nginx", &s) == 0) {
183 if (arg_debug) 171 if (arg_debug)
184 printf("Mounting tmpfs on /var/lib/nginx\n"); 172 printf("Mounting tmpfs on /var/lib/nginx\n");
185 if (mount("tmpfs", "/var/lib/nginx", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 173 if (mount("tmpfs", "/var/lib/nginx", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
186 errExit("mounting /var/lib/nginx"); 174 errExit("mounting /var/lib/nginx");
187 fs_logger("tmpfs /var/lib/nginx"); 175 fs_logger("tmpfs /var/lib/nginx");
188 } 176 }
@@ -191,7 +179,7 @@ void fs_var_lib(void) {
191 if (stat("/var/lib/snmp", &s) == 0) { 179 if (stat("/var/lib/snmp", &s) == 0) {
192 if (arg_debug) 180 if (arg_debug)
193 printf("Mounting tmpfs on /var/lib/snmp\n"); 181 printf("Mounting tmpfs on /var/lib/snmp\n");
194 if (mount("tmpfs", "/var/lib/snmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 182 if (mount("tmpfs", "/var/lib/snmp", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
195 errExit("mounting /var/lib/snmp"); 183 errExit("mounting /var/lib/snmp");
196 fs_logger("tmpfs /var/lib/snmp"); 184 fs_logger("tmpfs /var/lib/snmp");
197 } 185 }
@@ -200,7 +188,7 @@ void fs_var_lib(void) {
200 if (stat("/var/lib/sudo", &s) == 0) { 188 if (stat("/var/lib/sudo", &s) == 0) {
201 if (arg_debug) 189 if (arg_debug)
202 printf("Mounting tmpfs on /var/lib/sudo\n"); 190 printf("Mounting tmpfs on /var/lib/sudo\n");
203 if (mount("tmpfs", "/var/lib/sudo", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 191 if (mount("tmpfs", "/var/lib/sudo", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
204 errExit("mounting /var/lib/sudo"); 192 errExit("mounting /var/lib/sudo");
205 fs_logger("tmpfs /var/lib/sudo"); 193 fs_logger("tmpfs /var/lib/sudo");
206 } 194 }
@@ -212,7 +200,7 @@ void fs_var_cache(void) {
212 if (stat("/var/cache/apache2", &s) == 0) { 200 if (stat("/var/cache/apache2", &s) == 0) {
213 if (arg_debug) 201 if (arg_debug)
214 printf("Mounting tmpfs on /var/cache/apache2\n"); 202 printf("Mounting tmpfs on /var/cache/apache2\n");
215 if (mount("tmpfs", "/var/cache/apache2", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 203 if (mount("tmpfs", "/var/cache/apache2", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
216 errExit("mounting /var/cache/apache2"); 204 errExit("mounting /var/cache/apache2");
217 fs_logger("tmpfs /var/cache/apache2"); 205 fs_logger("tmpfs /var/cache/apache2");
218 } 206 }
@@ -220,7 +208,7 @@ void fs_var_cache(void) {
220 if (stat("/var/cache/lighttpd", &s) == 0) { 208 if (stat("/var/cache/lighttpd", &s) == 0) {
221 if (arg_debug) 209 if (arg_debug)
222 printf("Mounting tmpfs on /var/cache/lighttpd\n"); 210 printf("Mounting tmpfs on /var/cache/lighttpd\n");
223 if (mount("tmpfs", "/var/cache/lighttpd", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 211 if (mount("tmpfs", "/var/cache/lighttpd", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
224 errExit("mounting /var/cache/lighttpd"); 212 errExit("mounting /var/cache/lighttpd");
225 fs_logger("tmpfs /var/cache/lighttpd"); 213 fs_logger("tmpfs /var/cache/lighttpd");
226 214
@@ -232,18 +220,10 @@ void fs_var_cache(void) {
232 gid = p->pw_gid; 220 gid = p->pw_gid;
233 } 221 }
234 222
235 int rv = mkdir("/var/cache/lighttpd/compress", 0755); 223 mkdir_attr("/var/cache/lighttpd/compress", 0755, uid, gid);
236 if (rv == -1)
237 errExit("mkdir");
238 if (chown("/var/cache/lighttpd/compress", uid, gid) < 0)
239 errExit("chown");
240 fs_logger("mkdir /var/cache/lighttpd/compress"); 224 fs_logger("mkdir /var/cache/lighttpd/compress");
241 225
242 rv = mkdir("/var/cache/lighttpd/uploads", 0755); 226 mkdir_attr("/var/cache/lighttpd/uploads", 0755, uid, gid);
243 if (rv == -1)
244 errExit("mkdir");
245 if (chown("/var/cache/lighttpd/uploads", uid, gid) < 0)
246 errExit("chown");
247 fs_logger("/var/cache/lighttpd/uploads"); 227 fs_logger("/var/cache/lighttpd/uploads");
248 } 228 }
249} 229}
@@ -268,7 +248,7 @@ void fs_var_lock(void) {
268 if (is_dir("/var/lock")) { 248 if (is_dir("/var/lock")) {
269 if (arg_debug) 249 if (arg_debug)
270 printf("Mounting tmpfs on /var/lock\n"); 250 printf("Mounting tmpfs on /var/lock\n");
271 if (mount("tmpfs", "/var/lock", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=1777,gid=0") < 0) 251 if (mount("tmpfs", "/var/lock", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=1777,gid=0") < 0)
272 errExit("mounting /lock"); 252 errExit("mounting /lock");
273 fs_logger("tmpfs /var/lock"); 253 fs_logger("tmpfs /var/lock");
274 } 254 }
@@ -277,16 +257,11 @@ void fs_var_lock(void) {
277 if (lnk) { 257 if (lnk) {
278 if (!is_dir(lnk)) { 258 if (!is_dir(lnk)) {
279 // create directory 259 // create directory
280 if (mkdir(lnk, S_IRWXU|S_IRWXG|S_IRWXO)) 260 mkdir_attr(lnk, S_IRWXU|S_IRWXG|S_IRWXO, 0, 0);
281 errExit("mkdir");
282 if (chown(lnk, 0, 0))
283 errExit("chown");
284 if (chmod(lnk, S_IRWXU|S_IRWXG|S_IRWXO))
285 errExit("chmod");
286 } 261 }
287 if (arg_debug) 262 if (arg_debug)
288 printf("Mounting tmpfs on %s on behalf of /var/lock\n", lnk); 263 printf("Mounting tmpfs on %s on behalf of /var/lock\n", lnk);
289 if (mount("tmpfs", lnk, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=1777,gid=0") < 0) 264 if (mount("tmpfs", lnk, "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=1777,gid=0") < 0)
290 errExit("mounting /var/lock"); 265 errExit("mounting /var/lock");
291 free(lnk); 266 free(lnk);
292 fs_logger("tmpfs /var/lock"); 267 fs_logger("tmpfs /var/lock");
@@ -304,7 +279,7 @@ void fs_var_tmp(void) {
304 if (!is_link("/var/tmp")) { 279 if (!is_link("/var/tmp")) {
305 if (arg_debug) 280 if (arg_debug)
306 printf("Mounting tmpfs on /var/tmp\n"); 281 printf("Mounting tmpfs on /var/tmp\n");
307 if (mount("tmpfs", "/var/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=1777,gid=0") < 0) 282 if (mount("tmpfs", "/var/tmp", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=1777,gid=0") < 0)
308 errExit("mounting /var/tmp"); 283 errExit("mounting /var/tmp");
309 fs_logger("tmpfs /var/tmp"); 284 fs_logger("tmpfs /var/tmp");
310 } 285 }
@@ -327,9 +302,6 @@ void fs_var_utmp(void) {
327 return; 302 return;
328 } 303 }
329 304
330 // create /tmp/firejail/mnt directory
331 fs_build_mnt_dir();
332
333 // create a new utmp file 305 // create a new utmp file
334 if (arg_debug) 306 if (arg_debug)
335 printf("Create the new utmp file\n"); 307 printf("Create the new utmp file\n");
@@ -353,16 +325,13 @@ void fs_var_utmp(void) {
353 325
354 // save new utmp file 326 // save new utmp file
355 fwrite(&u_boot, sizeof(u_boot), 1, fp); 327 fwrite(&u_boot, sizeof(u_boot), 1, fp);
328 SET_PERMS_STREAM(fp, 0, utmp_group, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH);
356 fclose(fp); 329 fclose(fp);
357 if (chown(RUN_UTMP_FILE, 0, utmp_group) < 0)
358 errExit("chown");
359 if (chmod(RUN_UTMP_FILE, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH ) < 0)
360 errExit("chmod");
361 330
362 // mount the new utmp file 331 // mount the new utmp file
363 if (arg_debug) 332 if (arg_debug)
364 printf("Mount the new utmp file\n"); 333 printf("Mount the new utmp file\n");
365 if (mount(RUN_UTMP_FILE, UTMP_FILE, NULL, MS_BIND|MS_REC, NULL) < 0) 334 if (mount(RUN_UTMP_FILE, UTMP_FILE, NULL, MS_BIND|MS_NOSUID|MS_NOEXEC | MS_NODEV | MS_REC, NULL) < 0)
366 errExit("mount bind utmp"); 335 errExit("mount bind utmp");
367 fs_logger("create /var/run/utmp"); 336 fs_logger("create /var/run/utmp");
368} 337}
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c
index 617e61dcd..564dc8290 100644
--- a/src/firejail/fs_whitelist.c
+++ b/src/firejail/fs_whitelist.c
@@ -157,10 +157,8 @@ static int mkpath(const char* path, mode_t mode) {
157 } 157 }
158 } 158 }
159 else { 159 else {
160 if (chmod(file_path, mode) == -1) 160 if (set_perms(file_path, uid, gid, mode))
161 errExit("chmod"); 161 errExit("set_perms");
162 if (chown(file_path, uid, gid) == -1)
163 errExit("chown");
164 done = 1; 162 done = 1;
165 } 163 }
166 164
@@ -181,11 +179,15 @@ static void whitelist_path(ProfileEntry *entry) {
181 char *wfile = NULL; 179 char *wfile = NULL;
182 180
183 if (entry->home_dir) { 181 if (entry->home_dir) {
184 fname = path + strlen(cfg.homedir); 182 if (strncmp(path, cfg.homedir, strlen(cfg.homedir)) == 0) {
185 if (*fname == '\0') { 183 fname = path + strlen(cfg.homedir);
186 fprintf(stderr, "Error: file %s is not in user home directory, exiting...\n", path); 184 if (*fname == '\0') {
187 exit(1); 185 fprintf(stderr, "Error: file %s is not in user home directory, exiting...\n", path);
186 exit(1);
187 }
188 } 188 }
189 else
190 fname = path;
189 191
190 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_HOME_USER_DIR, fname) == -1) 192 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_HOME_USER_DIR, fname) == -1)
191 errExit("asprintf"); 193 errExit("asprintf");
@@ -210,6 +212,16 @@ static void whitelist_path(ProfileEntry *entry) {
210 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_MEDIA_DIR, fname) == -1) 212 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_MEDIA_DIR, fname) == -1)
211 errExit("asprintf"); 213 errExit("asprintf");
212 } 214 }
215 else if (entry->mnt_dir) {
216 fname = path + 4; // strlen("/mnt")
217 if (*fname == '\0') {
218 fprintf(stderr, "Error: file %s is not in /mnt directory, exiting...\n", path);
219 exit(1);
220 }
221
222 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_MNT_DIR, fname) == -1)
223 errExit("asprintf");
224 }
213 else if (entry->var_dir) { 225 else if (entry->var_dir) {
214 fname = path + 4; // strlen("/var") 226 fname = path + 4; // strlen("/var")
215 if (*fname == '\0') { 227 if (*fname == '\0') {
@@ -240,7 +252,16 @@ static void whitelist_path(ProfileEntry *entry) {
240 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_OPT_DIR, fname) == -1) 252 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_OPT_DIR, fname) == -1)
241 errExit("asprintf"); 253 errExit("asprintf");
242 } 254 }
255 else if (entry->srv_dir) {
256 fname = path + 4; // strlen("/srv")
257 if (*fname == '\0') {
258 fprintf(stderr, "Error: file %s is not in /srv directory, exiting...\n", path);
259 exit(1);
260 }
243 261
262 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_SRV_DIR, fname) == -1)
263 errExit("asprintf");
264 }
244 // check if the file exists 265 // check if the file exists
245 struct stat s; 266 struct stat s;
246 if (wfile && stat(wfile, &s) == 0) { 267 if (wfile && stat(wfile, &s) == 0) {
@@ -248,9 +269,6 @@ static void whitelist_path(ProfileEntry *entry) {
248 printf("Whitelisting %s\n", path); 269 printf("Whitelisting %s\n", path);
249 } 270 }
250 else { 271 else {
251 if (arg_debug || arg_debug_whitelists) {
252 fprintf(stderr, "Warning (whitelisting): %s is an invalid file, skipping...\n", path);
253 }
254 return; 272 return;
255 } 273 }
256 274
@@ -267,21 +285,21 @@ static void whitelist_path(ProfileEntry *entry) {
267 285
268 // process regular file 286 // process regular file
269 else { 287 else {
270 // create an empty file 288 if (access(path, R_OK)) {
271 FILE *fp = fopen(path, "w"); 289 // create an empty file
272 if (!fp) { 290 FILE *fp = fopen(path, "w");
273 fprintf(stderr, "Error: cannot create empty file in home directory\n"); 291 if (!fp) {
274 exit(1); 292 fprintf(stderr, "Error: cannot create empty file in home directory\n");
293 exit(1);
294 }
295 // set file properties
296 SET_PERMS_STREAM(fp, s.st_uid, s.st_gid, s.st_mode);
297 fclose(fp);
275 } 298 }
276 fclose(fp); 299 else
300 return; // the file is already present
277 } 301 }
278 302
279 // set file properties
280 if (chown(path, s.st_uid, s.st_gid) < 0)
281 errExit("chown");
282 if (chmod(path, s.st_mode) < 0)
283 errExit("chmod");
284
285 // mount 303 // mount
286 if (mount(wfile, path, NULL, MS_BIND|MS_REC, NULL) < 0) 304 if (mount(wfile, path, NULL, MS_BIND|MS_REC, NULL) < 0)
287 errExit("mount bind"); 305 errExit("mount bind");
@@ -302,10 +320,11 @@ void fs_whitelist(void) {
302 int home_dir = 0; // /home/user directory flag 320 int home_dir = 0; // /home/user directory flag
303 int tmp_dir = 0; // /tmp directory flag 321 int tmp_dir = 0; // /tmp directory flag
304 int media_dir = 0; // /media directory flag 322 int media_dir = 0; // /media directory flag
323 int mnt_dir = 0; // /mnt directory flag
305 int var_dir = 0; // /var directory flag 324 int var_dir = 0; // /var directory flag
306 int dev_dir = 0; // /dev directory flag 325 int dev_dir = 0; // /dev directory flag
307 int opt_dir = 0; // /opt directory flag 326 int opt_dir = 0; // /opt directory flag
308 327 int srv_dir = 0; // /srv directory flag
309 // verify whitelist files, extract symbolic links, etc. 328 // verify whitelist files, extract symbolic links, etc.
310 while (entry) { 329 while (entry) {
311 // handle only whitelist commands 330 // handle only whitelist commands
@@ -367,13 +386,17 @@ void fs_whitelist(void) {
367 tmp_dir = 1; 386 tmp_dir = 1;
368 else if (strncmp(new_name, "/media/", 7) == 0) 387 else if (strncmp(new_name, "/media/", 7) == 0)
369 media_dir = 1; 388 media_dir = 1;
389 else if (strncmp(new_name, "/mnt/", 5) == 0)
390 mnt_dir = 1;
370 else if (strncmp(new_name, "/var/", 5) == 0) 391 else if (strncmp(new_name, "/var/", 5) == 0)
371 var_dir = 1; 392 var_dir = 1;
372 else if (strncmp(new_name, "/dev/", 5) == 0) 393 else if (strncmp(new_name, "/dev/", 5) == 0)
373 dev_dir = 1; 394 dev_dir = 1;
374 else if (strncmp(new_name, "/opt/", 5) == 0) 395 else if (strncmp(new_name, "/opt/", 5) == 0)
375 opt_dir = 1; 396 opt_dir = 1;
376 397 else if (strncmp(new_name, "/srv/", 5) == 0)
398 opt_dir = 1;
399
377 continue; 400 continue;
378 } 401 }
379 402
@@ -390,12 +413,16 @@ void fs_whitelist(void) {
390 413
391 entry->home_dir = 1; 414 entry->home_dir = 1;
392 home_dir = 1; 415 home_dir = 1;
416 if (arg_debug || arg_debug_whitelists)
417 fprintf(stderr, "Debug %d: fname #%s#, cfg.homedir #%s#\n",
418 __LINE__, fname, cfg.homedir);
419
393 // both path and absolute path are under /home 420 // both path and absolute path are under /home
394 if (strncmp(fname, cfg.homedir, strlen(cfg.homedir)) != 0) { 421 if (strncmp(fname, cfg.homedir, strlen(cfg.homedir)) != 0) {
395 if (arg_debug) 422 // check if the file is owned by the user
396 fprintf(stderr, "Debug %d: fname #%s#, cfg.homedir #%s#\n", 423 struct stat s;
397 __LINE__, fname, cfg.homedir); 424 if (stat(fname, &s) == 0 && s.st_uid != getuid())
398 goto errexit; 425 goto errexit;
399 } 426 }
400 } 427 }
401 else if (strncmp(new_name, "/tmp/", 5) == 0) { 428 else if (strncmp(new_name, "/tmp/", 5) == 0) {
@@ -418,6 +445,16 @@ void fs_whitelist(void) {
418 goto errexit; 445 goto errexit;
419 } 446 }
420 } 447 }
448 else if (strncmp(new_name, "/mnt/", 5) == 0) {
449 entry->mnt_dir = 1;
450 mnt_dir = 1;
451 // both path and absolute path are under /mnt
452 if (strncmp(fname, "/mnt/", 5) != 0) {
453 if (arg_debug)
454 fprintf(stderr, "Debug %d: fname #%s#\n", __LINE__, fname);
455 goto errexit;
456 }
457 }
421 else if (strncmp(new_name, "/var/", 5) == 0) { 458 else if (strncmp(new_name, "/var/", 5) == 0) {
422 entry->var_dir = 1; 459 entry->var_dir = 1;
423 var_dir = 1; 460 var_dir = 1;
@@ -453,6 +490,16 @@ void fs_whitelist(void) {
453 goto errexit; 490 goto errexit;
454 } 491 }
455 } 492 }
493 else if (strncmp(new_name, "/srv/", 5) == 0) {
494 entry->srv_dir = 1;
495 srv_dir = 1;
496 // both path and absolute path are under /srv
497 if (strncmp(fname, "/srv/", 5) != 0) {
498 if (arg_debug)
499 fprintf(stderr, "Debug %d: fname #%s#\n", __LINE__, fname);
500 goto errexit;
501 }
502 }
456 else { 503 else {
457 if (arg_debug) 504 if (arg_debug)
458 fprintf(stderr, "Debug %d: \n", __LINE__); 505 fprintf(stderr, "Debug %d: \n", __LINE__);
@@ -480,21 +527,10 @@ void fs_whitelist(void) {
480 entry = entry->next; 527 entry = entry->next;
481 } 528 }
482 529
483 // create mount points
484 fs_build_mnt_dir();
485
486
487 // /home/user 530 // /home/user
488 if (home_dir) { 531 if (home_dir) {
489 // keep a copy of real home dir in RUN_WHITELIST_HOME_USER_DIR 532 // keep a copy of real home dir in RUN_WHITELIST_HOME_USER_DIR
490 int rv = mkdir(RUN_WHITELIST_HOME_USER_DIR, 0755); 533 mkdir_attr(RUN_WHITELIST_HOME_USER_DIR, 0755, getuid(), getgid());
491 if (rv == -1)
492 errExit("mkdir");
493 if (chown(RUN_WHITELIST_HOME_USER_DIR, getuid(), getgid()) < 0)
494 errExit("chown");
495 if (chmod(RUN_WHITELIST_HOME_USER_DIR, 0755) < 0)
496 errExit("chmod");
497
498 if (mount(cfg.homedir, RUN_WHITELIST_HOME_USER_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) 534 if (mount(cfg.homedir, RUN_WHITELIST_HOME_USER_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
499 errExit("mount bind"); 535 errExit("mount bind");
500 536
@@ -504,15 +540,8 @@ void fs_whitelist(void) {
504 540
505 // /tmp mountpoint 541 // /tmp mountpoint
506 if (tmp_dir) { 542 if (tmp_dir) {
507 // keep a copy of real /tmp directory in WHITELIST_TMP_DIR 543 // keep a copy of real /tmp directory in
508 int rv = mkdir(RUN_WHITELIST_TMP_DIR, 1777); 544 mkdir_attr(RUN_WHITELIST_TMP_DIR, 1777, 0, 0);
509 if (rv == -1)
510 errExit("mkdir");
511 if (chown(RUN_WHITELIST_TMP_DIR, 0, 0) < 0)
512 errExit("chown");
513 if (chmod(RUN_WHITELIST_TMP_DIR, 1777) < 0)
514 errExit("chmod");
515
516 if (mount("/tmp", RUN_WHITELIST_TMP_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) 545 if (mount("/tmp", RUN_WHITELIST_TMP_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
517 errExit("mount bind"); 546 errExit("mount bind");
518 547
@@ -526,37 +555,51 @@ void fs_whitelist(void) {
526 555
527 // /media mountpoint 556 // /media mountpoint
528 if (media_dir) { 557 if (media_dir) {
529 // keep a copy of real /media directory in RUN_WHITELIST_MEDIA_DIR 558 // some distros don't have a /media directory
530 int rv = mkdir(RUN_WHITELIST_MEDIA_DIR, 0755); 559 struct stat s;
531 if (rv == -1) 560 if (stat("/media", &s) == 0) {
532 errExit("mkdir"); 561 // keep a copy of real /media directory in RUN_WHITELIST_MEDIA_DIR
533 if (chown(RUN_WHITELIST_MEDIA_DIR, 0, 0) < 0) 562 mkdir_attr(RUN_WHITELIST_MEDIA_DIR, 0755, 0, 0);
534 errExit("chown"); 563 if (mount("/media", RUN_WHITELIST_MEDIA_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
535 if (chmod(RUN_WHITELIST_MEDIA_DIR, 0755) < 0) 564 errExit("mount bind");
536 errExit("chmod");
537 565
538 if (mount("/media", RUN_WHITELIST_MEDIA_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) 566 // mount tmpfs on /media
539 errExit("mount bind"); 567 if (arg_debug || arg_debug_whitelists)
540 568 printf("Mounting tmpfs on /media directory\n");
541 // mount tmpfs on /media 569 if (mount("tmpfs", "/media", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
542 if (arg_debug || arg_debug_whitelists) 570 errExit("mounting tmpfs on /media");
543 printf("Mounting tmpfs on /media directory\n"); 571 fs_logger("tmpfs /media");
544 if (mount("tmpfs", "/media", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 572 }
545 errExit("mounting tmpfs on /media"); 573 else
546 fs_logger("tmpfs /media"); 574 media_dir = 0;
575 }
576
577 // /mnt mountpoint
578 if (mnt_dir) {
579 // check if /mnt directory exists
580 struct stat s;
581 if (stat("/mnt", &s) == 0) {
582 // keep a copy of real /mnt directory in RUN_WHITELIST_MNT_DIR
583 mkdir_attr(RUN_WHITELIST_MNT_DIR, 0755, 0, 0);
584 if (mount("/mnt", RUN_WHITELIST_MNT_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
585 errExit("mount bind");
586
587 // mount tmpfs on /mnt
588 if (arg_debug || arg_debug_whitelists)
589 printf("Mounting tmpfs on /mnt directory\n");
590 if (mount("tmpfs", "/mnt", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
591 errExit("mounting tmpfs on /mnt");
592 fs_logger("tmpfs /mnt");
593 }
594 else
595 mnt_dir = 0;
547 } 596 }
548 597
598
549 // /var mountpoint 599 // /var mountpoint
550 if (var_dir) { 600 if (var_dir) {
551 // keep a copy of real /var directory in RUN_WHITELIST_VAR_DIR 601 // keep a copy of real /var directory in RUN_WHITELIST_VAR_DIR
552 int rv = mkdir(RUN_WHITELIST_VAR_DIR, 0755); 602 mkdir_attr(RUN_WHITELIST_VAR_DIR, 0755, 0, 0);
553 if (rv == -1)
554 errExit("mkdir");
555 if (chown(RUN_WHITELIST_VAR_DIR, 0, 0) < 0)
556 errExit("chown");
557 if (chmod(RUN_WHITELIST_VAR_DIR, 0755) < 0)
558 errExit("chmod");
559
560 if (mount("/var", RUN_WHITELIST_VAR_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) 603 if (mount("/var", RUN_WHITELIST_VAR_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
561 errExit("mount bind"); 604 errExit("mount bind");
562 605
@@ -571,14 +614,7 @@ void fs_whitelist(void) {
571 // /dev mountpoint 614 // /dev mountpoint
572 if (dev_dir) { 615 if (dev_dir) {
573 // keep a copy of real /dev directory in RUN_WHITELIST_DEV_DIR 616 // keep a copy of real /dev directory in RUN_WHITELIST_DEV_DIR
574 int rv = mkdir(RUN_WHITELIST_DEV_DIR, 0755); 617 mkdir_attr(RUN_WHITELIST_DEV_DIR, 0755, 0, 0);
575 if (rv == -1)
576 errExit("mkdir");
577 if (chown(RUN_WHITELIST_DEV_DIR, 0, 0) < 0)
578 errExit("chown");
579 if (chmod(RUN_WHITELIST_DEV_DIR, 0755) < 0)
580 errExit("chmod");
581
582 if (mount("/dev", RUN_WHITELIST_DEV_DIR, NULL, MS_BIND|MS_REC, "mode=755,gid=0") < 0) 618 if (mount("/dev", RUN_WHITELIST_DEV_DIR, NULL, MS_BIND|MS_REC, "mode=755,gid=0") < 0)
583 errExit("mount bind"); 619 errExit("mount bind");
584 620
@@ -593,14 +629,7 @@ void fs_whitelist(void) {
593 // /opt mountpoint 629 // /opt mountpoint
594 if (opt_dir) { 630 if (opt_dir) {
595 // keep a copy of real /opt directory in RUN_WHITELIST_OPT_DIR 631 // keep a copy of real /opt directory in RUN_WHITELIST_OPT_DIR
596 int rv = mkdir(RUN_WHITELIST_OPT_DIR, 0755); 632 mkdir_attr(RUN_WHITELIST_OPT_DIR, 0755, 0, 0);
597 if (rv == -1)
598 errExit("mkdir");
599 if (chown(RUN_WHITELIST_OPT_DIR, 0, 0) < 0)
600 errExit("chown");
601 if (chmod(RUN_WHITELIST_OPT_DIR, 0755) < 0)
602 errExit("chmod");
603
604 if (mount("/opt", RUN_WHITELIST_OPT_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) 633 if (mount("/opt", RUN_WHITELIST_OPT_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
605 errExit("mount bind"); 634 errExit("mount bind");
606 635
@@ -612,6 +641,29 @@ void fs_whitelist(void) {
612 fs_logger("tmpfs /opt"); 641 fs_logger("tmpfs /opt");
613 } 642 }
614 643
644 // /srv mountpoint
645 if (srv_dir) {
646 // check if /srv directory exists
647 struct stat s;
648 if (stat("/srv", &s) == 0) {
649 // keep a copy of real /srv directory in RUN_WHITELIST_SRV_DIR
650 mkdir_attr(RUN_WHITELIST_SRV_DIR, 0755, 0, 0);
651 if (mount("/srv", RUN_WHITELIST_SRV_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
652 errExit("mount bind");
653
654 // mount tmpfs on /srv
655 if (arg_debug || arg_debug_whitelists)
656 printf("Mounting tmpfs on /srv directory\n");
657 if (mount("tmpfs", "/srv", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
658 errExit("mounting tmpfs on /srv");
659 fs_logger("tmpfs /srv");
660 }
661 else
662 srv_dir = 0;
663 }
664
665
666
615 // go through profile rules again, and interpret whitelist commands 667 // go through profile rules again, and interpret whitelist commands
616 entry = cfg.profile; 668 entry = cfg.profile;
617 while (entry) { 669 while (entry) {
@@ -696,6 +748,20 @@ void fs_whitelist(void) {
696 fs_logger2("tmpfs", RUN_WHITELIST_MEDIA_DIR); 748 fs_logger2("tmpfs", RUN_WHITELIST_MEDIA_DIR);
697 } 749 }
698 750
751 // mask the real /mnt directory, currently mounted on RUN_WHITELIST_MNT_DIR
752 if (mnt_dir) {
753 if (mount("tmpfs", RUN_WHITELIST_MNT_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
754 errExit("mount tmpfs");
755 fs_logger2("tmpfs", RUN_WHITELIST_MNT_DIR);
756 }
757
758 // mask the real /srv directory, currently mounted on RUN_WHITELIST_SRV_DIR
759 if (srv_dir) {
760 if (mount("tmpfs", RUN_WHITELIST_SRV_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
761 errExit("mount tmpfs");
762 fs_logger2("tmpfs", RUN_WHITELIST_SRV_DIR);
763 }
764
699 if (new_name) 765 if (new_name)
700 free(new_name); 766 free(new_name);
701 767
diff --git a/src/firejail/join.c b/src/firejail/join.c
index 98e140ce4..628002d35 100644
--- a/src/firejail/join.c
+++ b/src/firejail/join.c
@@ -23,12 +23,19 @@
23#include <fcntl.h> 23#include <fcntl.h>
24#include <unistd.h> 24#include <unistd.h>
25#include <sys/prctl.h> 25#include <sys/prctl.h>
26#include <errno.h>
26 27
27static int apply_caps = 0; 28static int apply_caps = 0;
28static uint64_t caps = 0; 29static uint64_t caps = 0;
29static int apply_seccomp = 0; 30static int apply_seccomp = 0;
30#define BUFLEN 4096 31#define BUFLEN 4096
31 32
33static void signal_handler(int sig){
34 flush_stdin();
35
36 exit(sig);
37}
38
32static void extract_command(int argc, char **argv, int index) { 39static void extract_command(int argc, char **argv, int index) {
33 EUID_ASSERT(); 40 EUID_ASSERT();
34 if (index >= argc) 41 if (index >= argc)
@@ -48,22 +55,9 @@ static void extract_command(int argc, char **argv, int index) {
48 exit(1); 55 exit(1);
49 } 56 }
50 57
51
52 int len = 0;
53 int i;
54 // calculate command length
55 for (i = index; i < argc; i++) {
56 len += strlen(argv[i]) + 1;
57 }
58 assert(len > 0);
59
60 // build command 58 // build command
61 cfg.command_line = malloc(len + 1); 59 build_cmdline(&cfg.command_line, &cfg.window_title, argc, argv, index);
62 *cfg.command_line = '\0'; 60
63 for (i = index; i < argc; i++) {
64 strcat(cfg.command_line, argv[i]);
65 strcat(cfg.command_line, " ");
66 }
67 if (arg_debug) 61 if (arg_debug)
68 printf("Extracted command #%s#\n", cfg.command_line); 62 printf("Extracted command #%s#\n", cfg.command_line);
69} 63}
@@ -134,7 +128,7 @@ static void extract_caps_seccomp(pid_t pid) {
134 break; 128 break;
135 } 129 }
136 else if (strncmp(buf, "CapBnd:", 7) == 0) { 130 else if (strncmp(buf, "CapBnd:", 7) == 0) {
137 char *ptr = buf + 8; 131 char *ptr = buf + 7;
138 unsigned long long val; 132 unsigned long long val;
139 sscanf(ptr, "%llx", &val); 133 sscanf(ptr, "%llx", &val);
140 apply_caps = 1; 134 apply_caps = 1;
@@ -179,26 +173,12 @@ static void extract_user_namespace(pid_t pid) {
179 free(uidmap); 173 free(uidmap);
180} 174}
181 175
182void join_name(const char *name, int argc, char **argv, int index) {
183 EUID_ASSERT();
184 if (!name || strlen(name) == 0) {
185 fprintf(stderr, "Error: invalid sandbox name\n");
186 exit(1);
187 }
188
189 pid_t pid;
190 if (name2pid(name, &pid)) {
191 fprintf(stderr, "Error: cannot find sandbox %s\n", name);
192 exit(1);
193 }
194 join(pid, argc, argv, index);
195}
196
197void join(pid_t pid, int argc, char **argv, int index) { 176void join(pid_t pid, int argc, char **argv, int index) {
198 EUID_ASSERT(); 177 EUID_ASSERT();
199 char *homedir = cfg.homedir; 178 char *homedir = cfg.homedir;
200 179
201 extract_command(argc, argv, index); 180 extract_command(argc, argv, index);
181 signal (SIGTERM, signal_handler);
202 182
203 // if the pid is that of a firejail process, use the pid of the first child process 183 // if the pid is that of a firejail process, use the pid of the first child process
204 EUID_ROOT(); 184 EUID_ROOT();
@@ -249,15 +229,11 @@ void join(pid_t pid, int argc, char **argv, int index) {
249 exit(1); 229 exit(1);
250 } 230 }
251 else { 231 else {
252 if (join_namespace(pid, "ipc")) 232 if (join_namespace(pid, "ipc") ||
253 exit(1); 233 join_namespace(pid, "net") ||
254 if (join_namespace(pid, "net")) 234 join_namespace(pid, "pid") ||
255 exit(1); 235 join_namespace(pid, "uts") ||
256 if (join_namespace(pid, "pid")) 236 join_namespace(pid, "mnt"))
257 exit(1);
258 if (join_namespace(pid, "uts"))
259 exit(1);
260 if (join_namespace(pid, "mnt"))
261 exit(1); 237 exit(1);
262 } 238 }
263 239
@@ -297,19 +273,18 @@ void join(pid_t pid, int argc, char **argv, int index) {
297 if (apply_caps == 1) // not available for uid 0 273 if (apply_caps == 1) // not available for uid 0
298 caps_set(caps); 274 caps_set(caps);
299#ifdef HAVE_SECCOMP 275#ifdef HAVE_SECCOMP
300 // set protocol filter 276 // read cfg.protocol from file
301 if (getuid() != 0) 277 if (getuid() != 0)
302 protocol_filter_load(RUN_PROTOCOL_CFG); 278 protocol_filter_load(RUN_PROTOCOL_CFG);
303 if (cfg.protocol) { // not available for uid 0 279 if (cfg.protocol) { // not available for uid 0
304 protocol_filter(); 280 seccomp_load(RUN_SECCOMP_PROTOCOL); // install filter
305 } 281 }
306 282
307 // set seccomp filter 283 // set seccomp filter
308 if (apply_seccomp == 1) // not available for uid 0 284 if (apply_seccomp == 1) // not available for uid 0
309 seccomp_set(); 285 seccomp_load(RUN_SECCOMP_CFG);
310
311#endif 286#endif
312 287
313 // fix qt 4.8 288 // fix qt 4.8
314 if (setenv("QT_X11_NO_MITSHM", "1", 1) < 0) 289 if (setenv("QT_X11_NO_MITSHM", "1", 1) < 0)
315 errExit("setenv"); 290 errExit("setenv");
@@ -322,76 +297,84 @@ void join(pid_t pid, int argc, char **argv, int index) {
322 printf("Joining user namespace\n"); 297 printf("Joining user namespace\n");
323 if (join_namespace(1, "user")) 298 if (join_namespace(1, "user"))
324 exit(1); 299 exit(1);
300
301 // user namespace resets capabilities
302 // set caps filter
303 if (apply_caps == 1) // not available for uid 0
304 caps_set(caps);
325 } 305 }
326 else 306 else
327 drop_privs(arg_nogroups); // nogroups not available for uid 0 307 drop_privs(arg_nogroups); // nogroups not available for uid 0
328 308
309
329 // set prompt color to green 310 // set prompt color to green
330 //export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] ' 311 char *prompt = getenv("FIREJAIL_PROMPT");
331 if (setenv("PROMPT_COMMAND", "export PS1=\"\\[\\e[1;32m\\][\\u@\\h \\W]\\$\\[\\e[0m\\] \"", 1) < 0) 312 if (prompt && strcmp(prompt, "yes") == 0) {
332 errExit("setenv"); 313 //export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] '
314 if (setenv("PROMPT_COMMAND", "export PS1=\"\\[\\e[1;32m\\][\\u@\\h \\W]\\$\\[\\e[0m\\] \"", 1) < 0)
315 errExit("setenv");
316 }
317
318 // set nice
319 if (arg_nice) {
320 errno = 0;
321 int rv = nice(cfg.nice);
322 (void) rv;
323 if (errno) {
324 fprintf(stderr, "Warning: cannot set nice value\n");
325 errno = 0;
326 }
327 }
333 328
334 // run cmdline trough /bin/bash 329 // run cmdline trough shell
335 if (cfg.command_line == NULL) { 330 if (cfg.command_line == NULL) {
331 // if the sandbox was started with --shell=none, it is possible we don't have a shell
332 // inside the sandbox
333 if (cfg.shell == NULL) {
334 cfg.shell = guess_shell();
335 if (!cfg.shell) {
336 fprintf(stderr, "Error: no POSIX shell found, please use --shell command line option\n");
337 exit(1);
338 }
339 }
340
336 struct stat s; 341 struct stat s;
342 if (stat(cfg.shell, &s) == -1) {
343 fprintf(stderr, "Error: %s shell not found inside the sandbox\n", cfg.shell);
344 exit(1);
345 }
337 346
338 // replace the process with a shell 347 cfg.command_line = cfg.shell;
339 if (stat("/bin/bash", &s) == 0) 348 cfg.window_title = cfg.shell;
340 execlp("/bin/bash", "/bin/bash", NULL);
341 else if (stat("/usr/bin/zsh", &s) == 0)
342 execlp("/usr/bin/zsh", "/usr/bin/zsh", NULL);
343 else if (stat("/bin/csh", &s) == 0)
344 execlp("/bin/csh", "/bin/csh", NULL);
345 else if (stat("/bin/sh", &s) == 0)
346 execlp("/bin/sh", "/bin/sh", NULL);
347
348 // no shell found, print an error and exit
349 fprintf(stderr, "Error: no POSIX shell found\n");
350 sleep(5);
351 exit(1);
352 } 349 }
353 else {
354 // run the command supplied by the user
355 int cwd = 0;
356 if (cfg.cwd) {
357 if (chdir(cfg.cwd) == 0)
358 cwd = 1;
359 }
360
361 if (!cwd) {
362 if (chdir("/") < 0)
363 errExit("chdir");
364 if (cfg.homedir) {
365 struct stat s;
366 if (stat(cfg.homedir, &s) == 0) {
367 if (chdir(cfg.homedir) < 0)
368 errExit("chdir");
369 }
370 }
371 }
372 350
373 char *arg[5]; 351 int cwd = 0;
374 arg[0] = "/bin/bash"; 352 if (cfg.cwd) {
375 arg[1] = "-c"; 353 if (chdir(cfg.cwd) == 0)
376 if (arg_debug) 354 cwd = 1;
377 printf("Starting %s\n", cfg.command_line); 355 }
378 if (!arg_doubledash) { 356
379 arg[2] = cfg.command_line; 357 if (!cwd) {
380 arg[3] = NULL; 358 if (chdir("/") < 0)
381 } 359 errExit("chdir");
382 else { 360 if (cfg.homedir) {
383 arg[2] = "--"; 361 struct stat s;
384 arg[3] = cfg.command_line; 362 if (stat(cfg.homedir, &s) == 0) {
385 arg[4] = NULL; 363 /* coverity[toctou] */
364 if (chdir(cfg.homedir) < 0)
365 errExit("chdir");
366 }
386 } 367 }
387 execvp("/bin/bash", arg);
388 } 368 }
389 369
370 start_application();
371
390 // it will never get here!!! 372 // it will never get here!!!
391 } 373 }
392 374
393 // wait for the child to finish 375 // wait for the child to finish
394 waitpid(child, NULL, 0); 376 waitpid(child, NULL, 0);
377 flush_stdin();
395 exit(0); 378 exit(0);
396} 379}
397 380
diff --git a/src/firejail/list.c b/src/firejail/list.c
deleted file mode 100644
index cd53264b6..000000000
--- a/src/firejail/list.c
+++ /dev/null
@@ -1,81 +0,0 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "firejail.h"
21#include <sys/types.h>
22#include <sys/stat.h>
23
24static void grsec_elevate_privileges(void) {
25 struct stat s;
26 if (stat("/proc/sys/kernel/grsecurity", &s) == 0) {
27 EUID_ROOT();
28
29 // elevate privileges
30 if (setreuid(0, 0))
31 errExit("setreuid");
32 if (setregid(0, 0))
33 errExit("setregid");
34 }
35}
36
37void top(void) {
38 EUID_ASSERT();
39
40 char *arg[4];
41 arg[0] = "bash";
42 arg[1] = "-c";
43 arg[2] = "firemon --top";
44 arg[3] = NULL;
45 execvp("/bin/bash", arg);
46}
47
48void netstats(void) {
49 EUID_ASSERT();
50 grsec_elevate_privileges();
51
52 char *arg[4];
53 arg[0] = "bash";
54 arg[1] = "-c";
55 arg[2] = "firemon --netstats";
56 arg[3] = NULL;
57 execvp("/bin/bash", arg);
58}
59
60void list(void) {
61 EUID_ASSERT();
62
63 char *arg[4];
64 arg[0] = "bash";
65 arg[1] = "-c";
66 arg[2] = "firemon --list";
67 arg[3] = NULL;
68 execvp("/bin/bash", arg);
69}
70
71void tree(void) {
72 EUID_ASSERT();
73
74 char *arg[4];
75 arg[0] = "bash";
76 arg[1] = "-c";
77 arg[2] = "firemon --tree";
78 arg[3] = NULL;
79 execvp("/bin/bash", arg);
80}
81
diff --git a/src/firejail/ls.c b/src/firejail/ls.c
index 444b5b69e..86c3a6079 100644
--- a/src/firejail/ls.c
+++ b/src/firejail/ls.c
@@ -185,23 +185,26 @@ static void print_directory(const char *path) {
185 free(namelist); 185 free(namelist);
186} 186}
187 187
188void sandboxfs_name(int op, const char *name, const char *path) { 188char *expand_path(const char *path) {
189 EUID_ASSERT(); 189 char *fname = NULL;
190 190 if (*path == '/') {
191 if (!name || strlen(name) == 0) { 191 fname = strdup(path);
192 fprintf(stderr, "Error: invalid sandbox name\n"); 192 if (!fname)
193 exit(1); 193 errExit("strdup");
194 } 194 }
195 pid_t pid; 195 else if (*path == '~') {
196 if (name2pid(name, &pid)) { 196 if (asprintf(&fname, "%s%s", cfg.homedir, path + 1) == -1)
197 fprintf(stderr, "Error: cannot find sandbox %s\n", name); 197 errExit("asprintf");
198 exit(1);
199 } 198 }
200 199 else {
201 sandboxfs(op, pid, path); 200 // assume the file is in current working directory
201 if (asprintf(&fname, "%s/%s", cfg.cwd, path) == -1)
202 errExit("asprintf");
203 }
204 return fname;
202} 205}
203 206
204void sandboxfs(int op, pid_t pid, const char *path) { 207void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) {
205 EUID_ASSERT(); 208 EUID_ASSERT();
206 209
207 // if the pid is that of a firejail process, use the pid of the first child process 210 // if the pid is that of a firejail process, use the pid of the first child process
@@ -228,22 +231,17 @@ void sandboxfs(int op, pid_t pid, const char *path) {
228 } 231 }
229 } 232 }
230 233
231 // full path or file in current directory? 234 // expand paths
232 char *fname; 235 char *fname1 = expand_path(path1);;
233 if (*path == '/') { 236 char *fname2 = NULL;
234 fname = strdup(path); 237 if (path2 != NULL) {
235 if (!fname) 238 fname2 = expand_path(path2);
236 errExit("strdup");
237 }
238 else if (*path == '~') {
239 if (asprintf(&fname, "%s%s", cfg.homedir, path + 1) == -1)
240 errExit("asprintf");
241 } 239 }
242 else { 240 if (arg_debug) {
243 fprintf(stderr, "Error: Cannot access %s\n", path); 241 printf("file1 %s\n", fname1);
244 exit(1); 242 printf("file2 %s\n", fname2);
245 } 243 }
246 244
247 // sandbox root directory 245 // sandbox root directory
248 char *rootdir; 246 char *rootdir;
249 if (asprintf(&rootdir, "/proc/%d/root", pid) == -1) 247 if (asprintf(&rootdir, "/proc/%d/root", pid) == -1)
@@ -257,22 +255,24 @@ void sandboxfs(int op, pid_t pid, const char *path) {
257 if (chdir("/") < 0) 255 if (chdir("/") < 0)
258 errExit("chdir"); 256 errExit("chdir");
259 257
260 // access chek is performed with the real UID 258 // drop privileges
261 if (access(fname, R_OK) == -1) { 259 drop_privs(0);
262 fprintf(stderr, "Error: Cannot access %s\n", fname); 260
261 if (access(fname1, R_OK) == -1) {
262 fprintf(stderr, "Error: Cannot access %s\n", fname1);
263 exit(1); 263 exit(1);
264 } 264 }
265 265
266 // list directory contents 266 // list directory contents
267 struct stat s; 267 struct stat s;
268 if (stat(fname, &s) == -1) { 268 if (stat(fname1, &s) == -1) {
269 fprintf(stderr, "Error: Cannot access %s\n", fname); 269 fprintf(stderr, "Error: Cannot access %s\n", fname1);
270 exit(1); 270 exit(1);
271 } 271 }
272 if (S_ISDIR(s.st_mode)) { 272 if (S_ISDIR(s.st_mode)) {
273 char *rp = realpath(fname, NULL); 273 char *rp = realpath(fname1, NULL);
274 if (!rp) { 274 if (!rp) {
275 fprintf(stderr, "Error: Cannot access %s\n", fname); 275 fprintf(stderr, "Error: Cannot access %s\n", fname1);
276 exit(1); 276 exit(1);
277 } 277 }
278 if (arg_debug) 278 if (arg_debug)
@@ -287,9 +287,9 @@ void sandboxfs(int op, pid_t pid, const char *path) {
287 free(dir); 287 free(dir);
288 } 288 }
289 else { 289 else {
290 char *rp = realpath(fname, NULL); 290 char *rp = realpath(fname1, NULL);
291 if (!rp) { 291 if (!rp) {
292 fprintf(stderr, "Error: Cannot access %s\n", fname); 292 fprintf(stderr, "Error: Cannot access %s\n", fname1);
293 exit(1); 293 exit(1);
294 } 294 }
295 if (arg_debug) 295 if (arg_debug)
@@ -308,19 +308,24 @@ void sandboxfs(int op, pid_t pid, const char *path) {
308 308
309 // get file from sandbox and store it in the current directory 309 // get file from sandbox and store it in the current directory
310 else if (op == SANDBOX_FS_GET) { 310 else if (op == SANDBOX_FS_GET) {
311 // check source file (sandbox) 311 char *src_fname =fname1;
312 char *src_fname; 312 char *dest_fname = strrchr(fname1, '/');
313 if (asprintf(&src_fname, "%s%s", rootdir, fname) == -1) 313 if (!dest_fname || *(++dest_fname) == '\0') {
314 errExit("asprintf"); 314 fprintf(stderr, "Error: invalid file name %s\n", fname1);
315 EUID_ROOT();
316 struct stat s;
317 if (stat(src_fname, &s) == -1) {
318 fprintf(stderr, "Error: Cannot access %s\n", fname);
319 exit(1); 315 exit(1);
320 } 316 }
321 317
322 318 EUID_ROOT();
323 // try to open the source file - we need to chroot 319 if (arg_debug)
320 printf("copy %s to %s\n", src_fname, dest_fname);
321
322 // create a user-owned temporary file in /run/firejail directory
323 char tmp_fname[] = "/run/firejail/tmpget-XXXXXX";
324 int fd = mkstemp(tmp_fname);
325 SET_PERMS_FD(fd, getuid(), getgid(), 0600);
326 close(fd);
327
328 // copy the source file into the temporary file - we need to chroot
324 pid_t child = fork(); 329 pid_t child = fork();
325 if (child < 0) 330 if (child < 0)
326 errExit("fork"); 331 errExit("fork");
@@ -334,55 +339,135 @@ void sandboxfs(int op, pid_t pid, const char *path) {
334 // drop privileges 339 // drop privileges
335 drop_privs(0); 340 drop_privs(0);
336 341
337 // try to read the file 342 // copy the file
338 if (access(fname, R_OK) == -1) { 343 if (copy_file(src_fname, tmp_fname, getuid(), getgid(), 0600))
339 fprintf(stderr, "Error: Cannot read %s\n", fname); 344 _exit(1);
340 exit(1); 345#ifdef HAVE_GCOV
341 } 346 __gcov_flush();
342 exit(0); 347#endif
348 _exit(0);
343 } 349 }
344 350
345 // wait for the child to finish 351 // wait for the child to finish
346 int status = 0; 352 int status = 0;
347 waitpid(child, &status, 0); 353 waitpid(child, &status, 0);
348 if (WIFEXITED(status) && WEXITSTATUS(status) == 0); 354 if (WIFEXITED(status) && WEXITSTATUS(status) == 0);
349 else 355 else {
356 unlink(tmp_fname);
350 exit(1); 357 exit(1);
351 EUID_USER(); 358 }
352 359
353 // check destination file (host) 360 // copy the temporary file into the destionation file
354 char *dest_fname = strrchr(fname, '/'); 361 child = fork();
355 if (!dest_fname || *(++dest_fname) == '\0') { 362 if (child < 0)
356 fprintf(stderr, "Error: invalid file name %s\n", fname); 363 errExit("fork");
364 if (child == 0) {
365 // drop privileges
366 drop_privs(0);
367
368 // copy the file
369 if (copy_file(tmp_fname, dest_fname, getuid(), getgid(), 0600))
370 _exit(1);
371#ifdef HAVE_GCOV
372 __gcov_flush();
373#endif
374 _exit(0);
375 }
376
377 // wait for the child to finish
378 status = 0;
379 waitpid(child, &status, 0);
380 if (WIFEXITED(status) && WEXITSTATUS(status) == 0);
381 else {
382 unlink(tmp_fname);
357 exit(1); 383 exit(1);
358 } 384 }
359 385
360 if (access(dest_fname, F_OK) == -1) { 386 // remove the temporary file
361 // try to create the file 387 unlink(tmp_fname);
362 FILE *fp = fopen(dest_fname, "w"); 388 EUID_USER();
363 if (!fp) { 389 }
364 fprintf(stderr, "Error: cannot create %s\n", dest_fname); 390 // get file from host and store it in the sandbox
365 exit(1); 391 else if (op == SANDBOX_FS_PUT && path2) {
366 } 392 char *src_fname =fname1;
367 fclose(fp); 393 char *dest_fname = fname2;
394
395 EUID_ROOT();
396 if (arg_debug)
397 printf("copy %s to %s\n", src_fname, dest_fname);
398
399 // create a user-owned temporary file in /run/firejail directory
400 char tmp_fname[] = "/run/firejail/tmpget-XXXXXX";
401 int fd = mkstemp(tmp_fname);
402 SET_PERMS_FD(fd, getuid(), getgid(), 0600);
403 close(fd);
404
405 // copy the source file into the temporary file - we need to chroot
406 pid_t child = fork();
407 if (child < 0)
408 errExit("fork");
409 if (child == 0) {
410 // drop privileges
411 drop_privs(0);
412
413 // copy the file
414 if (copy_file(src_fname, tmp_fname, getuid(), getgid(), 0600))
415 _exit(1);
416#ifdef HAVE_GCOV
417 __gcov_flush();
418#endif
419 _exit(0);
368 } 420 }
421
422 // wait for the child to finish
423 int status = 0;
424 waitpid(child, &status, 0);
425 if (WIFEXITED(status) && WEXITSTATUS(status) == 0);
369 else { 426 else {
370 if (access(dest_fname, W_OK) == -1) { 427 unlink(tmp_fname);
371 fprintf(stderr, "Error: cannot write %s\n", dest_fname); 428 exit(1);
372 exit(1);
373 }
374 } 429 }
375 // copy file 430
376 EUID_ROOT(); 431 // copy the temporary file into the destionation file
377 copy_file(src_fname, dest_fname); 432 child = fork();
378 if (chown(dest_fname, getuid(), getgid()) == -1) 433 if (child < 0)
379 errExit("chown"); 434 errExit("fork");
380 if (chmod(dest_fname, 0644) == -1) 435 if (child == 0) {
381 errExit("chmod"); 436 // chroot
437 if (chroot(rootdir) < 0)
438 errExit("chroot");
439 if (chdir("/") < 0)
440 errExit("chdir");
441
442 // drop privileges
443 drop_privs(0);
444
445 // copy the file
446 if (copy_file(tmp_fname, dest_fname, getuid(), getgid(), 0600))
447 _exit(1);
448#ifdef HAVE_GCOV
449 __gcov_flush();
450#endif
451 _exit(0);
452 }
453
454 // wait for the child to finish
455 status = 0;
456 waitpid(child, &status, 0);
457 if (WIFEXITED(status) && WEXITSTATUS(status) == 0);
458 else {
459 unlink(tmp_fname);
460 exit(1);
461 }
462
463 // remove the temporary file
464 unlink(tmp_fname);
382 EUID_USER(); 465 EUID_USER();
383 } 466 }
384 467
385 free(fname); 468 if (fname2)
469 free(fname2);
470 free(fname1);
386 free(rootdir); 471 free(rootdir);
387 472
388 exit(0); 473 exit(0);
diff --git a/src/firejail/main.c b/src/firejail/main.c
index bdf960b96..ec0c31285 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -46,21 +46,22 @@ printf("time %s:%d %u\n", __FILE__, __LINE__, (uint32_t) systick);
46#endif 46#endif
47 47
48uid_t firejail_uid = 0; 48uid_t firejail_uid = 0;
49gid_t firejail_gid = 0;
49 50
50#define STACK_SIZE (1024 * 1024) 51#define STACK_SIZE (1024 * 1024)
51static char child_stack[STACK_SIZE]; // space for child's stack 52static char child_stack[STACK_SIZE]; // space for child's stack
52Config cfg; // configuration 53Config cfg; // configuration
53int arg_private = 0; // mount private /home and /tmp directoryu 54int arg_private = 0; // mount private /home and /tmp directoryu
55int arg_private_template = 0; // mount private /home using a template
54int arg_debug = 0; // print debug messages 56int arg_debug = 0; // print debug messages
55int arg_debug_check_filename; // print debug messages for filename checking 57int arg_debug_check_filename = 0; // print debug messages for filename checking
56int arg_debug_blacklists; // print debug messages for blacklists 58int arg_debug_blacklists = 0; // print debug messages for blacklists
57int arg_debug_whitelists; // print debug messages for whitelists 59int arg_debug_whitelists = 0; // print debug messages for whitelists
58int arg_nonetwork = 0; // --net=none 60int arg_nonetwork = 0; // --net=none
59int arg_command = 0; // -c 61int arg_command = 0; // -c
60int arg_overlay = 0; // overlay option 62int arg_overlay = 0; // overlay option
61int arg_overlay_keep = 0; // place overlay diff directory in ~/.firejail 63int arg_overlay_keep = 0; // place overlay diff in a known directory
62int arg_zsh = 0; // use zsh as default shell 64int arg_overlay_reuse = 0; // allow the reuse of overlays
63int arg_csh = 0; // use csh as default shell
64 65
65int arg_seccomp = 0; // enable default seccomp filter 66int arg_seccomp = 0; // enable default seccomp filter
66 67
@@ -77,6 +78,7 @@ int arg_rlimit_nproc = 0; // rlimit nproc
77int arg_rlimit_fsize = 0; // rlimit fsize 78int arg_rlimit_fsize = 0; // rlimit fsize
78int arg_rlimit_sigpending = 0; // rlimit fsize 79int arg_rlimit_sigpending = 0; // rlimit fsize
79int arg_nogroups = 0; // disable supplementary groups 80int arg_nogroups = 0; // disable supplementary groups
81int arg_nonewprivs = 0; // set the NO_NEW_PRIVS prctl
80int arg_noroot = 0; // create a new user namespace and disable root user 82int arg_noroot = 0; // create a new user namespace and disable root user
81int arg_netfilter; // enable netfilter 83int arg_netfilter; // enable netfilter
82int arg_netfilter6; // enable netfilter6 84int arg_netfilter6; // enable netfilter6
@@ -91,11 +93,25 @@ int arg_private_tmp = 0; // private tmp directory
91int arg_scan = 0; // arp-scan all interfaces 93int arg_scan = 0; // arp-scan all interfaces
92int arg_whitelist = 0; // whitelist commad 94int arg_whitelist = 0; // whitelist commad
93int arg_nosound = 0; // disable sound 95int arg_nosound = 0; // disable sound
96int arg_no3d; // disable 3d hardware acceleration
94int arg_quiet = 0; // no output for scripting 97int arg_quiet = 0; // no output for scripting
95int arg_join_network = 0; // join only the network namespace 98int arg_join_network = 0; // join only the network namespace
96int arg_join_filesystem = 0; // join only the mount namespace 99int arg_join_filesystem = 0; // join only the mount namespace
97int arg_nice = 0; // nice value configured 100int arg_nice = 0; // nice value configured
98int arg_ipc = 0; // enable ipc namespace 101int arg_ipc = 0; // enable ipc namespace
102int arg_writable_etc = 0; // writable etc
103int arg_writable_var = 0; // writable var
104int arg_appimage = 0; // appimage
105int arg_audit = 0; // audit
106char *arg_audit_prog = NULL; // audit
107int arg_apparmor = 0; // apparmor
108int arg_allow_debuggers = 0; // allow debuggers
109int arg_x11_block = 0; // block X11
110int arg_x11_xorg = 0; // use X11 security extention
111int arg_allusers = 0; // all user home directories visible
112
113int login_shell = 0;
114
99 115
100int parent_to_child_fds[2]; 116int parent_to_child_fds[2];
101int child_to_parent_fds[2]; 117int child_to_parent_fds[2];
@@ -126,7 +142,8 @@ static void myexit(int rv) {
126 // delete sandbox files in shared memory 142 // delete sandbox files in shared memory
127 EUID_ROOT(); 143 EUID_ROOT();
128 clear_run_files(sandbox_pid); 144 clear_run_files(sandbox_pid);
129 145 appimage_clear();
146 flush_stdin();
130 exit(rv); 147 exit(rv);
131} 148}
132 149
@@ -141,20 +158,37 @@ static void my_handler(int s){
141 myexit(1); 158 myexit(1);
142} 159}
143 160
144// return 1 if error, 0 if a valid pid was found 161static pid_t extract_pid(const char *name) {
145static inline int read_pid(char *str, pid_t *pid) { 162 EUID_ASSERT();
163 if (!name || strlen(name) == 0) {
164 fprintf(stderr, "Error: invalid sandbox name\n");
165 exit(1);
166 }
167
168 pid_t pid;
169 EUID_ROOT();
170 if (name2pid(name, &pid)) {
171 fprintf(stderr, "Error: cannot find sandbox %s\n", name);
172 exit(1);
173 }
174 EUID_USER();
175 return pid;
176}
177
178
179static pid_t read_pid(const char *str) {
146 char *endptr; 180 char *endptr;
147 errno = 0; 181 errno = 0;
148 long int pidtmp = strtol(str, &endptr, 10); 182 long int pidtmp = strtol(str, &endptr, 10);
149 if ((errno == ERANGE && (pidtmp == LONG_MAX || pidtmp == LONG_MIN)) 183 if ((errno == ERANGE && (pidtmp == LONG_MAX || pidtmp == LONG_MIN))
150 || (errno != 0 && pidtmp == 0)) { 184 || (errno != 0 && pidtmp == 0)) {
151 return 1; 185 return extract_pid(str);
152 } 186 }
153 if (endptr == str) { 187 // endptr points to '\0' char in str if the entire string is valid
154 return 1; 188 if (endptr == NULL || endptr[0]!='\0') {
189 return extract_pid(str);
155 } 190 }
156 *pid = (pid_t)pidtmp; 191 return (pid_t)pidtmp;
157 return 0;
158} 192}
159 193
160// init configuration 194// init configuration
@@ -228,12 +262,14 @@ void check_user_namespace(void) {
228 stat("/proc/self/gid_map", &s3) == 0) 262 stat("/proc/self/gid_map", &s3) == 0)
229 arg_noroot = 1; 263 arg_noroot = 1;
230 else { 264 else {
231 fprintf(stderr, "Warning: user namespaces not available in the current kernel.\n"); 265 if (!arg_quiet || arg_debug)
266 fprintf(stderr, "Warning: user namespaces not available in the current kernel.\n");
232 arg_noroot = 0; 267 arg_noroot = 0;
233 } 268 }
234} 269}
235#endif 270#endif
236 271
272
237// exit commands 273// exit commands
238static void run_cmd_and_exit(int i, int argc, char **argv) { 274static void run_cmd_and_exit(int i, int argc, char **argv) {
239 EUID_ASSERT(); 275 EUID_ASSERT();
@@ -248,32 +284,36 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
248 } 284 }
249 else if (strcmp(argv[i], "--version") == 0) { 285 else if (strcmp(argv[i], "--version") == 0) {
250 printf("firejail version %s\n", VERSION); 286 printf("firejail version %s\n", VERSION);
251#ifndef HAVE_NETWORK 287 printf("\n");
252 printf("Networking support is disabled.\n"); 288 print_compiletime_support();
253#endif 289 printf("\n");
254#ifdef HAVE_NETWORK_RESTRICTED 290 exit(0);
255 printf("Networking support is allowed only to root user.\n"); 291 }
256#endif 292#ifdef HAVE_OVERLAYFS
257#ifndef HAVE_USERNS 293 else if (strcmp(argv[i], "--overlay-clean") == 0) {
258 printf("User namespace support is disabled.\n"); 294 if (checkcfg(CFG_OVERLAYFS)) {
259#endif 295 char *path;
260#ifndef HAVE_SECCOMP 296 if (asprintf(&path, "%s/.firejail", cfg.homedir) == -1)
261 printf("Seccomp-bpf support is disabled.\n"); 297 errExit("asprintf");
262#endif 298 EUID_ROOT();
263#ifndef HAVE_BIND 299 if (setreuid(0, 0) < 0)
264 printf("Bind support is disabled.\n"); 300 errExit("setreuid");
265#endif 301 if (setregid(0, 0) < 0)
266#ifndef HAVE_CHROOT 302 errExit("setregid");
267 printf("Chroot support is disabled.\n"); 303 errno = 0;
268#endif 304 int rv = remove_directory(path);
269#ifndef HAVE_X11 305 if (rv) {
270 printf("X11 support is disabled.\n"); 306 fprintf(stderr, "Error: cannot removed overlays stored in ~/.firejail directory, errno %d\n", errno);
271#endif 307 exit(1);
272#ifndef HAVE_FILE_TRANSFER 308 }
273 printf("File transfer support is disabled.\n"); 309 }
274#endif 310 else {
311 fprintf(stderr, "Error: overlayfs feature is disabled in Firejail configuration file\n");
312 exit(1);
313 }
275 exit(0); 314 exit(0);
276 } 315 }
316#endif
277#ifdef HAVE_X11 317#ifdef HAVE_X11
278 else if (strcmp(argv[i], "--x11") == 0) { 318 else if (strcmp(argv[i], "--x11") == 0) {
279 if (checkcfg(CFG_X11)) { 319 if (checkcfg(CFG_X11)) {
@@ -361,11 +401,8 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
361 } 401 }
362 402
363 // extract pid or sandbox name 403 // extract pid or sandbox name
364 pid_t pid; 404 pid_t pid = read_pid(argv[i] + 12);
365 if (read_pid(argv[i] + 12, &pid) == 0) 405 bandwidth_pid(pid, cmd, dev, down, up);
366 bandwidth_pid(pid, cmd, dev, down, up);
367 else
368 bandwidth_name(argv[i] + 12, cmd, dev, down, up);
369 } 406 }
370 else { 407 else {
371 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n"); 408 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n");
@@ -380,8 +417,8 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
380#ifdef HAVE_SECCOMP 417#ifdef HAVE_SECCOMP
381 else if (strcmp(argv[i], "--debug-syscalls") == 0) { 418 else if (strcmp(argv[i], "--debug-syscalls") == 0) {
382 if (checkcfg(CFG_SECCOMP)) { 419 if (checkcfg(CFG_SECCOMP)) {
383 syscall_print(); 420 int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FSECCOMP, "debug-syscalls");
384 exit(0); 421 exit(rv);
385 } 422 }
386 else { 423 else {
387 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); 424 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
@@ -390,7 +427,8 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
390 } 427 }
391 else if (strcmp(argv[i], "--debug-errnos") == 0) { 428 else if (strcmp(argv[i], "--debug-errnos") == 0) {
392 if (checkcfg(CFG_SECCOMP)) { 429 if (checkcfg(CFG_SECCOMP)) {
393 errno_print(); 430 int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FSECCOMP, "debug-errnos");
431 exit(rv);
394 } 432 }
395 else { 433 else {
396 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); 434 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
@@ -401,11 +439,8 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
401 else if (strncmp(argv[i], "--seccomp.print=", 16) == 0) { 439 else if (strncmp(argv[i], "--seccomp.print=", 16) == 0) {
402 if (checkcfg(CFG_SECCOMP)) { 440 if (checkcfg(CFG_SECCOMP)) {
403 // print seccomp filter for a sandbox specified by pid or by name 441 // print seccomp filter for a sandbox specified by pid or by name
404 pid_t pid; 442 pid_t pid = read_pid(argv[i] + 16);
405 if (read_pid(argv[i] + 16, &pid) == 0) 443 seccomp_print_filter(pid);
406 seccomp_print_filter(pid);
407 else
408 seccomp_print_filter_name(argv[i] + 16);
409 } 444 }
410 else { 445 else {
411 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); 446 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
@@ -414,17 +449,14 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
414 exit(0); 449 exit(0);
415 } 450 }
416 else if (strcmp(argv[i], "--debug-protocols") == 0) { 451 else if (strcmp(argv[i], "--debug-protocols") == 0) {
417 protocol_list(); 452 int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FSECCOMP, "debug-protocols");
418 exit(0); 453 exit(rv);
419 } 454 }
420 else if (strncmp(argv[i], "--protocol.print=", 17) == 0) { 455 else if (strncmp(argv[i], "--protocol.print=", 17) == 0) {
421 if (checkcfg(CFG_SECCOMP)) { 456 if (checkcfg(CFG_SECCOMP)) {
422 // print seccomp filter for a sandbox specified by pid or by name 457 // print seccomp filter for a sandbox specified by pid or by name
423 pid_t pid; 458 pid_t pid = read_pid(argv[i] + 17);
424 if (read_pid(argv[i] + 17, &pid) == 0) 459 protocol_print_filter(pid);
425 protocol_print_filter(pid);
426 else
427 protocol_print_filter_name(argv[i] + 17);
428 } 460 }
429 else { 461 else {
430 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); 462 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
@@ -435,38 +467,26 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
435#endif 467#endif
436 else if (strncmp(argv[i], "--cpu.print=", 12) == 0) { 468 else if (strncmp(argv[i], "--cpu.print=", 12) == 0) {
437 // join sandbox by pid or by name 469 // join sandbox by pid or by name
438 pid_t pid; 470 pid_t pid = read_pid(argv[i] + 12);
439 if (read_pid(argv[i] + 12, &pid) == 0) 471 cpu_print_filter(pid);
440 cpu_print_filter(pid);
441 else
442 cpu_print_filter_name(argv[i] + 12);
443 exit(0); 472 exit(0);
444 } 473 }
445 else if (strncmp(argv[i], "--caps.print=", 13) == 0) { 474 else if (strncmp(argv[i], "--caps.print=", 13) == 0) {
446 // join sandbox by pid or by name 475 // join sandbox by pid or by name
447 pid_t pid; 476 pid_t pid = read_pid(argv[i] + 13);
448 if (read_pid(argv[i] + 13, &pid) == 0) 477 caps_print_filter(pid);
449 caps_print_filter(pid);
450 else
451 caps_print_filter_name(argv[i] + 13);
452 exit(0); 478 exit(0);
453 } 479 }
454 else if (strncmp(argv[i], "--fs.print=", 11) == 0) { 480 else if (strncmp(argv[i], "--fs.print=", 11) == 0) {
455 // join sandbox by pid or by name 481 // join sandbox by pid or by name
456 pid_t pid; 482 pid_t pid = read_pid(argv[i] + 11);
457 if (read_pid(argv[i] + 11, &pid) == 0) 483 fs_logger_print_log(pid);
458 fs_logger_print_log(pid);
459 else
460 fs_logger_print_log_name(argv[i] + 11);
461 exit(0); 484 exit(0);
462 } 485 }
463 else if (strncmp(argv[i], "--dns.print=", 12) == 0) { 486 else if (strncmp(argv[i], "--dns.print=", 12) == 0) {
464 // join sandbox by pid or by name 487 // join sandbox by pid or by name
465 pid_t pid; 488 pid_t pid = read_pid(argv[i] + 12);
466 if (read_pid(argv[i] + 12, &pid) == 0) 489 net_dns_print(pid);
467 net_dns_print(pid);
468 else
469 net_dns_print_name(argv[i] + 12);
470 exit(0); 490 exit(0);
471 } 491 }
472 else if (strcmp(argv[i], "--debug-caps") == 0) { 492 else if (strcmp(argv[i], "--debug-caps") == 0) {
@@ -474,27 +494,44 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
474 exit(0); 494 exit(0);
475 } 495 }
476 else if (strcmp(argv[i], "--list") == 0) { 496 else if (strcmp(argv[i], "--list") == 0) {
477 list(); 497 if (pid_hidepid())
498 sbox_run(SBOX_ROOT| SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FIREMON, "--list");
499 else
500 sbox_run(SBOX_USER| SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FIREMON, "--list");
478 exit(0); 501 exit(0);
479 } 502 }
480 else if (strcmp(argv[i], "--tree") == 0) { 503 else if (strcmp(argv[i], "--tree") == 0) {
481 tree(); 504 if (pid_hidepid())
505 sbox_run(SBOX_ROOT | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FIREMON, "--tree");
506 else
507 sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FIREMON, "--tree");
482 exit(0); 508 exit(0);
483 } 509 }
484 else if (strcmp(argv[i], "--top") == 0) { 510 else if (strcmp(argv[i], "--top") == 0) {
485 top(); 511 if (pid_hidepid())
512 sbox_run(SBOX_ROOT | SBOX_CAPS_NONE | SBOX_SECCOMP | SBOX_ALLOW_STDIN,
513 2, PATH_FIREMON, "--top");
514 else
515 sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP | SBOX_ALLOW_STDIN,
516 2, PATH_FIREMON, "--top");
486 exit(0); 517 exit(0);
487 } 518 }
488#ifdef HAVE_NETWORK 519#ifdef HAVE_NETWORK
489 else if (strcmp(argv[i], "--netstats") == 0) { 520 else if (strcmp(argv[i], "--netstats") == 0) {
490 if (checkcfg(CFG_NETWORK)) { 521 if (checkcfg(CFG_NETWORK)) {
491 netstats(); 522 struct stat s;
523 if (stat("/proc/sys/kernel/grsecurity", &s) == 0 || pid_hidepid())
524 sbox_run(SBOX_ROOT | SBOX_CAPS_NONE | SBOX_SECCOMP | SBOX_ALLOW_STDIN,
525 2, PATH_FIREMON, "--netstats");
526 else
527 sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP | SBOX_ALLOW_STDIN,
528 2, PATH_FIREMON, "--netstats");
529 exit(0);
492 } 530 }
493 else { 531 else {
494 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n"); 532 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n");
495 exit(1); 533 exit(1);
496 } 534 }
497 exit(0);
498 } 535 }
499#endif 536#endif
500#ifdef HAVE_FILE_TRANSFER 537#ifdef HAVE_FILE_TRANSFER
@@ -515,11 +552,40 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
515 } 552 }
516 553
517 // get file 554 // get file
518 pid_t pid; 555 pid_t pid = read_pid(argv[i] + 6);
519 if (read_pid(argv[i] + 6, &pid) == 0) 556 sandboxfs(SANDBOX_FS_GET, pid, path, NULL);
520 sandboxfs(SANDBOX_FS_GET, pid, path); 557 exit(0);
521 else 558 }
522 sandboxfs_name(SANDBOX_FS_GET, argv[i] + 6, path); 559 else {
560 fprintf(stderr, "Error: --get feature is disabled in Firejail configuration file\n");
561 exit(1);
562 }
563 }
564 else if (strncmp(argv[i], "--put=", 6) == 0) {
565 if (checkcfg(CFG_FILE_TRANSFER)) {
566 logargs(argc, argv);
567
568 // verify path
569 if ((i + 3) != argc) {
570 fprintf(stderr, "Error: invalid --put option, 2 paths expected\n");
571 exit(1);
572 }
573 char *path1 = argv[i + 1];
574 invalid_filename(path1);
575 if (strstr(path1, "..")) {
576 fprintf(stderr, "Error: invalid file name %s\n", path1);
577 exit(1);
578 }
579 char *path2 = argv[i + 2];
580 invalid_filename(path2);
581 if (strstr(path2, "..")) {
582 fprintf(stderr, "Error: invalid file name %s\n", path2);
583 exit(1);
584 }
585
586 // get file
587 pid_t pid = read_pid(argv[i] + 6);
588 sandboxfs(SANDBOX_FS_PUT, pid, path1, path2);
523 exit(0); 589 exit(0);
524 } 590 }
525 else { 591 else {
@@ -544,11 +610,8 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
544 } 610 }
545 611
546 // list directory contents 612 // list directory contents
547 pid_t pid; 613 pid_t pid = read_pid(argv[i] + 5);
548 if (read_pid(argv[i] + 5, &pid) == 0) 614 sandboxfs(SANDBOX_FS_LS, pid, path, NULL);
549 sandboxfs(SANDBOX_FS_LS, pid, path);
550 else
551 sandboxfs_name(SANDBOX_FS_LS, argv[i] + 5, path);
552 exit(0); 615 exit(0);
553 } 616 }
554 else { 617 else {
@@ -559,14 +622,49 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
559#endif 622#endif
560 else if (strncmp(argv[i], "--join=", 7) == 0) { 623 else if (strncmp(argv[i], "--join=", 7) == 0) {
561 logargs(argc, argv); 624 logargs(argc, argv);
562 625
626 if (arg_shell_none) {
627 if (argc <= (i+1)) {
628 fprintf(stderr, "Error: --shell=none set, but no command specified\n");
629 exit(1);
630 }
631 cfg.original_program_index = i + 1;
632 }
633
634 if (!cfg.shell && !arg_shell_none)
635 cfg.shell = guess_shell();
636
563 // join sandbox by pid or by name 637 // join sandbox by pid or by name
638 pid_t pid = read_pid(argv[i] + 7);
639 join(pid, argc, argv, i + 1);
640 exit(0);
641
642 }
643 else if (strncmp(argv[i], "--join-or-start=", 16) == 0) {
644 // NOTE: this is first part of option handler,
645 // sandbox name is set in other part
646 logargs(argc, argv);
647
648 if (arg_shell_none) {
649 if (argc <= (i+1)) {
650 fprintf(stderr, "Error: --shell=none set, but no command specified\n");
651 exit(1);
652 }
653 cfg.original_program_index = i + 1;
654 }
655
656#if 0 // todo: redo it
657 // try to join by name only
564 pid_t pid; 658 pid_t pid;
565 if (read_pid(argv[i] + 7, &pid) == 0) 659 if (!name2pid(argv[i] + 16, &pid)) {
660 if (!cfg.shell && !arg_shell_none)
661 cfg.shell = guess_shell();
662
566 join(pid, argc, argv, i + 1); 663 join(pid, argc, argv, i + 1);
567 else 664 exit(0);
568 join_name(argv[i] + 7, argc, argv, i + 1); 665 }
569 exit(0); 666#endif
667 // if there no such sandbox continue argument processing
570 } 668 }
571#ifdef HAVE_NETWORK 669#ifdef HAVE_NETWORK
572 else if (strncmp(argv[i], "--join-network=", 15) == 0) { 670 else if (strncmp(argv[i], "--join-network=", 15) == 0) {
@@ -578,12 +676,12 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
578 exit(1); 676 exit(1);
579 } 677 }
580 678
679 if (!cfg.shell && !arg_shell_none)
680 cfg.shell = guess_shell();
681
581 // join sandbox by pid or by name 682 // join sandbox by pid or by name
582 pid_t pid; 683 pid_t pid = read_pid(argv[i] + 15);
583 if (read_pid(argv[i] + 15, &pid) == 0) 684 join(pid, argc, argv, i + 1);
584 join(pid, argc, argv, i + 1);
585 else
586 join_name(argv[i] + 15, argc, argv, i + 1);
587 } 685 }
588 else { 686 else {
589 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n"); 687 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n");
@@ -601,23 +699,20 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
601 exit(1); 699 exit(1);
602 } 700 }
603 701
702 if (!cfg.shell && !arg_shell_none)
703 cfg.shell = guess_shell();
704
604 // join sandbox by pid or by name 705 // join sandbox by pid or by name
605 pid_t pid; 706 pid_t pid = read_pid(argv[i] + 18);
606 if (read_pid(argv[i] + 18, &pid) == 0) 707 join(pid, argc, argv, i + 1);
607 join(pid, argc, argv, i + 1);
608 else
609 join_name(argv[i] + 18, argc, argv, i + 1);
610 exit(0); 708 exit(0);
611 } 709 }
612 else if (strncmp(argv[i], "--shutdown=", 11) == 0) { 710 else if (strncmp(argv[i], "--shutdown=", 11) == 0) {
613 logargs(argc, argv); 711 logargs(argc, argv);
614 712
615 // shutdown sandbox by pid or by name 713 // shutdown sandbox by pid or by name
616 pid_t pid; 714 pid_t pid = read_pid(argv[i] + 11);
617 if (read_pid(argv[i] + 11, &pid) == 0) 715 shut(pid);
618 shut(pid);
619 else
620 shut_name(argv[i] + 11);
621 exit(0); 716 exit(0);
622 } 717 }
623 718
@@ -635,14 +730,10 @@ static void set_name_file(pid_t pid) {
635 exit(1); 730 exit(1);
636 } 731 }
637 fprintf(fp, "%s\n", cfg.name); 732 fprintf(fp, "%s\n", cfg.name);
638 fclose(fp); 733
639
640 // mode and ownership 734 // mode and ownership
641 if (chown(fname, 0, 0) == -1) 735 SET_PERMS_STREAM(fp, 0, 0, 0644);
642 errExit("chown"); 736 fclose(fp);
643 if (chmod(fname, 0644) == -1)
644 errExit("chmod");
645
646} 737}
647 738
648static void delete_name_file(pid_t pid) { 739static void delete_name_file(pid_t pid) {
@@ -651,6 +742,7 @@ static void delete_name_file(pid_t pid) {
651 errExit("asprintf"); 742 errExit("asprintf");
652 int rv = unlink(fname); 743 int rv = unlink(fname);
653 (void) rv; 744 (void) rv;
745 free(fname);
654} 746}
655 747
656static void set_x11_file(pid_t pid, int display) { 748static void set_x11_file(pid_t pid, int display) {
@@ -665,14 +757,10 @@ static void set_x11_file(pid_t pid, int display) {
665 exit(1); 757 exit(1);
666 } 758 }
667 fprintf(fp, "%d\n", display); 759 fprintf(fp, "%d\n", display);
668 fclose(fp); 760
669
670 // mode and ownership 761 // mode and ownership
671 if (chown(fname, 0, 0) == -1) 762 SET_PERMS_STREAM(fp, 0, 0, 0644);
672 errExit("chown"); 763 fclose(fp);
673 if (chmod(fname, 0644) == -1)
674 errExit("chmod");
675
676} 764}
677 765
678static void delete_x11_file(pid_t pid) { 766static void delete_x11_file(pid_t pid) {
@@ -681,6 +769,62 @@ static void delete_x11_file(pid_t pid) {
681 errExit("asprintf"); 769 errExit("asprintf");
682 int rv = unlink(fname); 770 int rv = unlink(fname);
683 (void) rv; 771 (void) rv;
772 free(fname);
773}
774
775static void detect_quiet(int argc, char **argv) {
776 int i;
777
778 // detect --quiet
779 for (i = 1; i < argc; i++) {
780 if (strcmp(argv[i], "--quiet") == 0) {
781 arg_quiet = 1;
782 break;
783 }
784
785 // detect end of firejail params
786 if (strcmp(argv[i], "--") == 0)
787 break;
788 if (strncmp(argv[i], "--", 2) != 0)
789 break;
790 }
791}
792
793static void detect_allow_debuggers(int argc, char **argv) {
794 int i;
795
796 // detect --allow-debuggers
797 for (i = 1; i < argc; i++) {
798 if (strcmp(argv[i], "--allow-debuggers") == 0) {
799 arg_allow_debuggers = 1;
800 break;
801 }
802
803 // detect end of firejail params
804 if (strcmp(argv[i], "--") == 0)
805 break;
806 if (strncmp(argv[i], "--", 2) != 0)
807 break;
808 }
809}
810
811char *guess_shell(void) {
812 char *shell = NULL;
813 // shells in order of preference
814 char *shells[] = {"/bin/bash", "/bin/csh", "/usr/bin/zsh", "/bin/sh", "/bin/ash", NULL };
815
816 int i = 0;
817 while (shells[i] != NULL) {
818 struct stat s;
819 // access call checks as real UID/GID, not as effective UID/GID
820 if (stat(shells[i], &s) == 0 && access(shells[i], R_OK) == 0) {
821 shell = shells[i];
822 break;
823 }
824 i++;
825 }
826
827 return shell;
684} 828}
685 829
686//******************************************* 830//*******************************************
@@ -694,81 +838,106 @@ int main(int argc, char **argv) {
694 int option_force = 0; 838 int option_force = 0;
695 int custom_profile = 0; // custom profile loaded 839 int custom_profile = 0; // custom profile loaded
696 char *custom_profile_dir = NULL; // custom profile directory 840 char *custom_profile_dir = NULL; // custom profile directory
697 int arg_noprofile = 0; // use generic.profile if none other found/specified 841 int arg_noprofile = 0; // use default.profile if none other found/specified
698#ifdef HAVE_SECCOMP 842
699 int highest_errno = errno_highest_nr(); 843 // build /run/firejail directory structure
700#endif 844 preproc_build_firejail_dir();
845
846 detect_quiet(argc, argv);
847 detect_allow_debuggers(argc, argv);
701 848
702 // drop permissions by default and rise them when required 849 // drop permissions by default and rise them when required
703 EUID_INIT(); 850 EUID_INIT();
704 EUID_USER(); 851 EUID_USER();
705 852
853
706 // check argv[0] symlink wrapper if this is not a login shell 854 // check argv[0] symlink wrapper if this is not a login shell
707 if (*argv[0] != '-') 855 if (*argv[0] != '-')
708 run_symlink(argc, argv); 856 run_symlink(argc, argv);
709 857
710 // check if we already have a sandbox running 858 // check if we already have a sandbox running
859 // If LXC is detected, start firejail sandbox
860 // otherwise try to detect a PID namespace by looking under /proc for specific kernel processes and:
861 // - if --force flag is set, start firejail sandbox
862 // -- if --force flag is not set, start the application in a /bin/bash shell
863 if (check_namespace_virt() == 0) {
864 EUID_ROOT();
865 int rv = check_kernel_procs();
866 EUID_USER();
867 if (rv == 0) {
868 // if --force option is passed to the program, disregard the existing sandbox
869 int found = 0;
870 for (i = 1; i < argc; i++) {
871 if (strcmp(argv[i], "--force") == 0 ||
872 strcmp(argv[i], "--list") == 0 ||
873 strcmp(argv[i], "--netstats") == 0 ||
874 strcmp(argv[i], "--tree") == 0 ||
875 strcmp(argv[i], "--top") == 0 ||
876 strncmp(argv[i], "--ls=", 5) == 0 ||
877 strncmp(argv[i], "--get=", 6) == 0 ||
878 strcmp(argv[i], "--debug-caps") == 0 ||
879 strcmp(argv[i], "--debug-errnos") == 0 ||
880 strcmp(argv[i], "--debug-syscalls") == 0 ||
881 strcmp(argv[i], "--debug-protocols") == 0 ||
882 strcmp(argv[i], "--help") == 0 ||
883 strcmp(argv[i], "--version") == 0 ||
884 strcmp(argv[i], "--overlay-clean") == 0 ||
885 strncmp(argv[i], "--dns.print=", 12) == 0 ||
886 strncmp(argv[i], "--bandwidth=", 12) == 0 ||
887 strncmp(argv[i], "--caps.print=", 13) == 0 ||
888 strncmp(argv[i], "--cpu.print=", 12) == 0 ||
889 //********************************************************************************
890 // todo: fix the following problems
891 strncmp(argv[i], "--join=", 7) == 0 ||
892 //[netblue@debian Downloads]$ firejail --join=896
893 //Switching to pid 897, the first child process inside the sandbox
894 //Error: seccomp file not found
895 //********************************************************************************
896
897 strncmp(argv[i], "--join-filesystem=", 18) == 0 ||
898 strncmp(argv[i], "--join-network=", 15) == 0 ||
899 strncmp(argv[i], "--fs.print=", 11) == 0 ||
900 strncmp(argv[i], "--protocol.print=", 17) == 0 ||
901 strncmp(argv[i], "--seccomp.print", 15) == 0 ||
902 strncmp(argv[i], "--shutdown=", 11) == 0) {
903 found = 1;
904 break;
905 }
906
907 // detect end of firejail params
908 if (strcmp(argv[i], "--") == 0)
909 break;
910 if (strncmp(argv[i], "--", 2) != 0)
911 break;
912 }
913
914 if (found == 0) {
915 // start the program directly without sandboxing
916 run_no_sandbox(argc, argv);
917 // it will never get here!
918 assert(0);
919 }
920 else
921 option_force = 1;
922 }
923 }
924
925 // check root/suid
711 EUID_ROOT(); 926 EUID_ROOT();
712 int rv = check_kernel_procs(); 927 if (geteuid()) {
713 EUID_USER(); 928 // detect --version
714 if (rv == 0) {
715 // if --force option is passed to the program, disregard the existing sandbox
716 int found = 0;
717 for (i = 1; i < argc; i++) { 929 for (i = 1; i < argc; i++) {
718 if (strcmp(argv[i], "--force") == 0 || 930 if (strcmp(argv[i], "--version") == 0) {
719 strcmp(argv[i], "--list") == 0 || 931 printf("firejail version %s\n", VERSION);
720 strcmp(argv[i], "--netstats") == 0 || 932 exit(0);
721 strcmp(argv[i], "--tree") == 0 ||
722 strcmp(argv[i], "--top") == 0 ||
723 strncmp(argv[i], "--ls=", 5) == 0 ||
724 strncmp(argv[i], "--get=", 6) == 0 ||
725 strcmp(argv[i], "--debug-caps") == 0 ||
726 strcmp(argv[i], "--debug-errnos") == 0 ||
727 strcmp(argv[i], "--debug-syscalls") == 0 ||
728 strcmp(argv[i], "--debug-protocols") == 0 ||
729 strcmp(argv[i], "--help") == 0 ||
730 strcmp(argv[i], "--version") == 0 ||
731 strncmp(argv[i], "--dns.print=", 12) == 0 ||
732 strncmp(argv[i], "--bandwidth=", 12) == 0 ||
733 strncmp(argv[i], "--caps.print=", 13) == 0 ||
734 strncmp(argv[i], "--cpu.print=", 12) == 0 ||
735//********************************************************************************
736// todo: fix the following problems
737 strncmp(argv[i], "--join=", 7) == 0 ||
738//[netblue@debian Downloads]$ firejail --join=896
739//Switching to pid 897, the first child process inside the sandbox
740//Error: seccomp file not found
741//********************************************************************************
742
743 strncmp(argv[i], "--join-filesystem=", 18) == 0 ||
744 strncmp(argv[i], "--join-network=", 15) == 0 ||
745 strncmp(argv[i], "--fs.print=", 11) == 0 ||
746 strncmp(argv[i], "--protocol.print=", 17) == 0 ||
747 strncmp(argv[i], "--seccomp.print", 15) == 0 ||
748 strncmp(argv[i], "--shutdown=", 11) == 0) {
749 found = 1;
750 break;
751 } 933 }
934
935 // detect end of firejail params
752 if (strcmp(argv[i], "--") == 0) 936 if (strcmp(argv[i], "--") == 0)
753 break; 937 break;
754 if (strncmp(argv[i], "--", 2) != 0) 938 if (strncmp(argv[i], "--", 2) != 0)
755 break; 939 break;
756 } 940 }
757
758 if (found == 0) {
759 // start the program directly without sandboxing
760 run_no_sandbox(argc, argv);
761 // it will never get here!
762 assert(0);
763 }
764 else
765 option_force = 1;
766 }
767
768 // check root/suid
769 EUID_ROOT();
770 if (geteuid()) {
771 fprintf(stderr, "Error: the sandbox is not setuid root\n");
772 exit(1); 941 exit(1);
773 } 942 }
774 EUID_USER(); 943 EUID_USER();
@@ -776,10 +945,8 @@ int main(int argc, char **argv) {
776 // initialize globals 945 // initialize globals
777 init_cfg(argc, argv); 946 init_cfg(argc, argv);
778 947
779
780 // check firejail directories 948 // check firejail directories
781 EUID_ROOT(); 949 EUID_ROOT();
782 fs_build_firejail_dir();
783 bandwidth_del_run_file(sandbox_pid); 950 bandwidth_del_run_file(sandbox_pid);
784 network_del_run_file(sandbox_pid); 951 network_del_run_file(sandbox_pid);
785 delete_name_file(sandbox_pid); 952 delete_name_file(sandbox_pid);
@@ -798,15 +965,68 @@ int main(int argc, char **argv) {
798 if (strcmp(comm, "sshd") == 0) { 965 if (strcmp(comm, "sshd") == 0) {
799 arg_quiet = 1; 966 arg_quiet = 1;
800 parent_sshd = 1; 967 parent_sshd = 1;
968
969#ifdef DEBUG_RESTRICTED_SHELL
970 {EUID_ROOT();
971 FILE *fp = fopen("/firelog", "w");
972 if (fp) {
973 int i;
974 fprintf(fp, "argc %d: ", argc);
975 for (i = 0; i < argc; i++)
976 fprintf(fp, "#%s# ", argv[i]);
977 fprintf(fp, "\n");
978 fclose(fp);
979 }
980 EUID_USER();}
981#endif
982 // run sftp and scp directly without any sandboxing
983 // regular login has argv[0] == "-firejail"
984 if (*argv[0] != '-') {
985 if (strcmp(argv[1], "-c") == 0 && argc > 2) {
986 if (strcmp(argv[2], "/usr/lib/openssh/sftp-server") == 0 ||
987 strncmp(argv[2], "scp ", 4) == 0) {
988#ifdef DEBUG_RESTRICTED_SHELL
989 {EUID_ROOT();
990 FILE *fp = fopen("/firelog", "a");
991 if (fp) {
992 fprintf(fp, "run without a sandbox\n");
993 fclose(fp);
994 }
995 EUID_USER();}
996#endif
997
998 drop_privs(1);
999 int rv = system(argv[2]);
1000 exit(rv);
1001 }
1002 }
1003 }
801 } 1004 }
802 free(comm); 1005 free(comm);
803 } 1006 }
804 } 1007 }
805 1008
806 // is this a login shell, or a command passed by sshd insert command line options from /etc/firejail/login.users 1009 // is this a login shell, or a command passed by sshd, insert command line options from /etc/firejail/login.users
807 if (*argv[0] == '-' || parent_sshd) { 1010 if (*argv[0] == '-' || parent_sshd) {
1011 if (argc == 1)
1012 login_shell = 1;
808 fullargc = restricted_shell(cfg.username); 1013 fullargc = restricted_shell(cfg.username);
809 if (fullargc) { 1014 if (fullargc) {
1015
1016#ifdef DEBUG_RESTRICTED_SHELL
1017 {EUID_ROOT();
1018 FILE *fp = fopen("/firelog", "a");
1019 if (fp) {
1020 fprintf(fp, "fullargc %d: ", fullargc);
1021 int i;
1022 for (i = 0; i < fullargc; i++)
1023 fprintf(fp, "#%s# ", fullargv[i]);
1024 fprintf(fp, "\n");
1025 fclose(fp);
1026 }
1027 EUID_USER();}
1028#endif
1029
810 int j; 1030 int j;
811 for (i = 1, j = fullargc; i < argc && j < MAX_ARGS; i++, j++, fullargc++) 1031 for (i = 1, j = fullargc; i < argc && j < MAX_ARGS; i++, j++, fullargc++)
812 fullargv[j] = argv[i]; 1032 fullargv[j] = argv[i];
@@ -814,12 +1034,37 @@ int main(int argc, char **argv) {
814 // replace argc/argv with fullargc/fullargv 1034 // replace argc/argv with fullargc/fullargv
815 argv = fullargv; 1035 argv = fullargv;
816 argc = j; 1036 argc = j;
1037
1038#ifdef DEBUG_RESTRICTED_SHELL
1039 {EUID_ROOT();
1040 FILE *fp = fopen("/firelog", "a");
1041 if (fp) {
1042 fprintf(fp, "argc %d: ", argc);
1043 int i;
1044 for (i = 0; i < argc; i++)
1045 fprintf(fp, "#%s# ", argv[i]);
1046 fprintf(fp, "\n");
1047 fclose(fp);
1048 }
1049 EUID_USER();}
1050#endif
817 } 1051 }
818 } 1052 }
819 else { 1053 else {
820 // check --output option and execute it; 1054 // check --output option and execute it;
821 check_output(argc, argv); // the function will not return if --output option was found 1055 check_output(argc, argv); // the function will not return if --output option was found
822 check_user(argc, argv); // the function will not return if --user option was found 1056 }
1057
1058
1059 // check for force-nonewprivs in /etc/firejail/firejail.config file
1060 if (checkcfg(CFG_FORCE_NONEWPRIVS))
1061 arg_nonewprivs = 1;
1062
1063 if (arg_allow_debuggers) {
1064 char *cmd = strdup("noblacklist ${PATH}/strace");
1065 if (!cmd)
1066 errExit("strdup");
1067 profile_add(cmd);
823 } 1068 }
824 1069
825 // parse arguments 1070 // parse arguments
@@ -845,14 +1090,30 @@ int main(int argc, char **argv) {
845 } 1090 }
846 else if (strcmp(argv[i], "--force") == 0) 1091 else if (strcmp(argv[i], "--force") == 0)
847 ; 1092 ;
1093 else if (strcmp(argv[i], "--allow-debuggers") == 0) {
1094 // already handled
1095 }
848 1096
849 //************************************* 1097 //*************************************
850 // filtering 1098 // filtering
851 //************************************* 1099 //*************************************
1100#ifdef HAVE_APPARMOR
1101 else if (strcmp(argv[i], "--apparmor") == 0)
1102 arg_apparmor = 1;
1103#endif
852#ifdef HAVE_SECCOMP 1104#ifdef HAVE_SECCOMP
853 else if (strncmp(argv[i], "--protocol=", 11) == 0) { 1105 else if (strncmp(argv[i], "--protocol=", 11) == 0) {
854 if (checkcfg(CFG_SECCOMP)) { 1106 if (checkcfg(CFG_SECCOMP)) {
855 protocol_store(argv[i] + 11); 1107 if (cfg.protocol) {
1108 if (!arg_quiet)
1109 fprintf(stderr, "Warning: a protocol list is present, the new list \"%s\" will not be installed\n", argv[i] + 11);
1110 }
1111 else {
1112 // store list
1113 cfg.protocol = strdup(argv[i] + 11);
1114 if (!cfg.protocol)
1115 errExit("strdup");
1116 }
856 } 1117 }
857 else { 1118 else {
858 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); 1119 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
@@ -879,9 +1140,7 @@ int main(int argc, char **argv) {
879 exit(1); 1140 exit(1);
880 } 1141 }
881 arg_seccomp = 1; 1142 arg_seccomp = 1;
882 cfg.seccomp_list = strdup(argv[i] + 10); 1143 cfg.seccomp_list = seccomp_check_list(argv[i] + 10);
883 if (!cfg.seccomp_list)
884 errExit("strdup");
885 } 1144 }
886 else { 1145 else {
887 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); 1146 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
@@ -895,9 +1154,7 @@ int main(int argc, char **argv) {
895 exit(1); 1154 exit(1);
896 } 1155 }
897 arg_seccomp = 1; 1156 arg_seccomp = 1;
898 cfg.seccomp_list_drop = strdup(argv[i] + 15); 1157 cfg.seccomp_list_drop = seccomp_check_list(argv[i] + 15);
899 if (!cfg.seccomp_list_drop)
900 errExit("strdup");
901 } 1158 }
902 else { 1159 else {
903 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); 1160 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
@@ -911,43 +1168,7 @@ int main(int argc, char **argv) {
911 exit(1); 1168 exit(1);
912 } 1169 }
913 arg_seccomp = 1; 1170 arg_seccomp = 1;
914 cfg.seccomp_list_keep = strdup(argv[i] + 15); 1171 cfg.seccomp_list_keep = seccomp_check_list(argv[i] + 15);
915 if (!cfg.seccomp_list_keep)
916 errExit("strdup");
917 }
918 else {
919 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
920 exit(1);
921 }
922 }
923 else if (strncmp(argv[i], "--seccomp.e", 11) == 0 && strchr(argv[i], '=')) {
924 if (checkcfg(CFG_SECCOMP)) {
925 if (arg_seccomp && !cfg.seccomp_list_errno) {
926 fprintf(stderr, "Error: seccomp already enabled\n");
927 exit(1);
928 }
929 char *eq = strchr(argv[i], '=');
930 char *errnoname = strndup(argv[i] + 10, eq - (argv[i] + 10));
931 int nr = errno_find_name(errnoname);
932 if (nr == -1) {
933 fprintf(stderr, "Error: unknown errno %s\n", errnoname);
934 free(errnoname);
935 exit(1);
936 }
937
938 if (!cfg.seccomp_list_errno)
939 cfg.seccomp_list_errno = calloc(highest_errno+1, sizeof(cfg.seccomp_list_errno[0]));
940
941 if (cfg.seccomp_list_errno[nr]) {
942 fprintf(stderr, "Error: errno %s already configured\n", errnoname);
943 free(errnoname);
944 exit(1);
945 }
946 arg_seccomp = 1;
947 cfg.seccomp_list_errno[nr] = strdup(eq+1);
948 if (!cfg.seccomp_list_errno[nr])
949 errExit("strdup");
950 free(errnoname);
951 } 1172 }
952 else { 1173 else {
953 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); 1174 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
@@ -1021,6 +1242,8 @@ int main(int argc, char **argv) {
1021 read_cpu_list(argv[i] + 6); 1242 read_cpu_list(argv[i] + 6);
1022 else if (strncmp(argv[i], "--nice=", 7) == 0) { 1243 else if (strncmp(argv[i], "--nice=", 7) == 0) {
1023 cfg.nice = atoi(argv[i] + 7); 1244 cfg.nice = atoi(argv[i] + 7);
1245 if (getuid() != 0 &&cfg.nice < 0)
1246 cfg.nice = 0;
1024 arg_nice = 1; 1247 arg_nice = 1;
1025 } 1248 }
1026 else if (strncmp(argv[i], "--cgroup=", 9) == 0) { 1249 else if (strncmp(argv[i], "--cgroup=", 9) == 0) {
@@ -1039,6 +1262,8 @@ int main(int argc, char **argv) {
1039 //************************************* 1262 //*************************************
1040 // filesystem 1263 // filesystem
1041 //************************************* 1264 //*************************************
1265 else if (strcmp(argv[i], "--allusers") == 0)
1266 arg_allusers = 1;
1042#ifdef HAVE_BIND 1267#ifdef HAVE_BIND
1043 else if (strncmp(argv[i], "--bind=", 7) == 0) { 1268 else if (strncmp(argv[i], "--bind=", 7) == 0) {
1044 if (checkcfg(CFG_BIND)) { 1269 if (checkcfg(CFG_BIND)) {
@@ -1079,98 +1304,155 @@ int main(int argc, char **argv) {
1079 profile_check_line(line, 0, NULL); // will exit if something wrong 1304 profile_check_line(line, 0, NULL); // will exit if something wrong
1080 profile_add(line); 1305 profile_add(line);
1081 } 1306 }
1307
1308#ifdef HAVE_WHITELIST
1082 else if (strncmp(argv[i], "--whitelist=", 12) == 0) { 1309 else if (strncmp(argv[i], "--whitelist=", 12) == 0) {
1310 if (checkcfg(CFG_WHITELIST)) {
1311 char *line;
1312 if (asprintf(&line, "whitelist %s", argv[i] + 12) == -1)
1313 errExit("asprintf");
1314
1315 profile_check_line(line, 0, NULL); // will exit if something wrong
1316 profile_add(line);
1317 }
1318 else {
1319 fprintf(stderr, "Error: whitelist feature is disabled in Firejail configuration file\n");
1320 exit(1);
1321 }
1322 }
1323#endif
1324
1325 else if (strncmp(argv[i], "--read-only=", 12) == 0) {
1083 char *line; 1326 char *line;
1084 if (asprintf(&line, "whitelist %s", argv[i] + 12) == -1) 1327 if (asprintf(&line, "read-only %s", argv[i] + 12) == -1)
1085 errExit("asprintf"); 1328 errExit("asprintf");
1086 1329
1087 profile_check_line(line, 0, NULL); // will exit if something wrong 1330 profile_check_line(line, 0, NULL); // will exit if something wrong
1088 profile_add(line); 1331 profile_add(line);
1089 } 1332 }
1090 else if (strncmp(argv[i], "--read-only=", 12) == 0) { 1333 else if (strncmp(argv[i], "--noexec=", 9) == 0) {
1091 char *line; 1334 char *line;
1092 if (asprintf(&line, "read-only %s", argv[i] + 12) == -1) 1335 if (asprintf(&line, "noexec %s", argv[i] + 9) == -1)
1093 errExit("asprintf"); 1336 errExit("asprintf");
1094 1337
1095 profile_check_line(line, 0, NULL); // will exit if something wrong 1338 profile_check_line(line, 0, NULL); // will exit if something wrong
1096 profile_add(line); 1339 profile_add(line);
1097 } 1340 }
1098 else if (strcmp(argv[i], "--overlay") == 0) { 1341 else if (strncmp(argv[i], "--read-write=", 13) == 0) {
1099 if (cfg.chrootdir) { 1342 char *line;
1100 fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); 1343 if (asprintf(&line, "read-write %s", argv[i] + 13) == -1)
1101 exit(1);
1102 }
1103 struct stat s;
1104 if (stat("/proc/sys/kernel/grsecurity", &s) == 0) {
1105 fprintf(stderr, "Error: --overlay option is not available on Grsecurity systems\n");
1106 exit(1);
1107 }
1108 arg_overlay = 1;
1109 arg_overlay_keep = 1;
1110
1111 // create ~/.firejail directory
1112 char *dirname;
1113 if (asprintf(&dirname, "%s/.firejail", cfg.homedir) == -1)
1114 errExit("asprintf"); 1344 errExit("asprintf");
1115 if (stat(dirname, &s) == -1) { 1345
1116 /* coverity[toctou] */ 1346 profile_check_line(line, 0, NULL); // will exit if something wrong
1117 if (mkdir(dirname, 0700)) 1347 profile_add(line);
1118 errExit("mkdir"); 1348 }
1119 if (chown(dirname, getuid(), getgid()) < 0) 1349#ifdef HAVE_OVERLAYFS
1120 errExit("chown"); 1350 else if (strcmp(argv[i], "--overlay") == 0) {
1121 if (chmod(dirname, 0700) < 0) 1351 if (checkcfg(CFG_OVERLAYFS)) {
1122 errExit("chmod"); 1352 if (cfg.chrootdir) {
1353 fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n");
1354 exit(1);
1355 }
1356 struct stat s;
1357 if (stat("/proc/sys/kernel/grsecurity", &s) == 0) {
1358 fprintf(stderr, "Error: --overlay option is not available on Grsecurity systems\n");
1359 exit(1);
1360 }
1361 arg_overlay = 1;
1362 arg_overlay_keep = 1;
1363
1364 char *subdirname;
1365 if (asprintf(&subdirname, "%d", getpid()) == -1)
1366 errExit("asprintf");
1367 cfg.overlay_dir = fs_check_overlay_dir(subdirname, arg_overlay_reuse);
1368
1369 free(subdirname);
1123 } 1370 }
1124 else if (is_link(dirname)) { 1371 else {
1125 fprintf(stderr, "Error: invalid ~/.firejail directory\n"); 1372 fprintf(stderr, "Error: overlayfs feature is disabled in Firejail configuration file\n");
1126 exit(1); 1373 exit(1);
1127 } 1374 }
1128 1375 }
1129 free(dirname); 1376 else if (strncmp(argv[i], "--overlay-named=", 16) == 0) {
1130 1377 if (checkcfg(CFG_OVERLAYFS)) {
1131 // check overlay directory 1378 if (cfg.chrootdir) {
1132 if (asprintf(&dirname, "%s/.firejail/%d", cfg.homedir, getpid()) == -1) 1379 fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n");
1133 errExit("asprintf"); 1380 exit(1);
1134 if (stat(dirname, &s) == 0) { 1381 }
1135 fprintf(stderr, "Error: overlay directory already exists: %s\n", dirname); 1382 struct stat s;
1383 if (stat("/proc/sys/kernel/grsecurity", &s) == 0) {
1384 fprintf(stderr, "Error: --overlay option is not available on Grsecurity systems\n");
1385 exit(1);
1386 }
1387 arg_overlay = 1;
1388 arg_overlay_keep = 1;
1389 arg_overlay_reuse = 1;
1390
1391 char *subdirname = argv[i] + 16;
1392 if (subdirname == '\0') {
1393 fprintf(stderr, "Error: invalid overlay option\n");
1394 exit(1);
1395 }
1396
1397 // check name
1398 invalid_filename(subdirname);
1399 if (strstr(subdirname, "..") || strstr(subdirname, "/")) {
1400 fprintf(stderr, "Error: invalid overlay name\n");
1401 exit(1);
1402 }
1403 cfg.overlay_dir = fs_check_overlay_dir(subdirname, arg_overlay_reuse);
1404 }
1405 else {
1406 fprintf(stderr, "Error: overlayfs feature is disabled in Firejail configuration file\n");
1136 exit(1); 1407 exit(1);
1137 } 1408 }
1138 cfg.overlay_dir = dirname; 1409
1139 } 1410 }
1140 else if (strcmp(argv[i], "--overlay-tmpfs") == 0) { 1411 else if (strcmp(argv[i], "--overlay-tmpfs") == 0) {
1141 if (cfg.chrootdir) { 1412 if (checkcfg(CFG_OVERLAYFS)) {
1142 fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); 1413 if (cfg.chrootdir) {
1143 exit(1); 1414 fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n");
1415 exit(1);
1416 }
1417 struct stat s;
1418 if (stat("/proc/sys/kernel/grsecurity", &s) == 0) {
1419 fprintf(stderr, "Error: --overlay option is not available on Grsecurity systems\n");
1420 exit(1);
1421 }
1422 arg_overlay = 1;
1144 } 1423 }
1145 struct stat s; 1424 else {
1146 if (stat("/proc/sys/kernel/grsecurity", &s) == 0) { 1425 fprintf(stderr, "Error: overlayfs feature is disabled in Firejail configuration file\n");
1147 fprintf(stderr, "Error: --overlay option is not available on Grsecurity systems\n"); 1426 exit(1);
1148 exit(1);
1149 } 1427 }
1150 arg_overlay = 1;
1151 } 1428 }
1429#endif
1152 else if (strncmp(argv[i], "--profile=", 10) == 0) { 1430 else if (strncmp(argv[i], "--profile=", 10) == 0) {
1153 if (arg_noprofile) { 1431 if (arg_noprofile) {
1154 fprintf(stderr, "Error: --noprofile and --profile options are mutually exclusive\n"); 1432 fprintf(stderr, "Error: --noprofile and --profile options are mutually exclusive\n");
1155 exit(1); 1433 exit(1);
1156 } 1434 }
1157 invalid_filename(argv[i] + 10); 1435
1436 char *ppath = expand_home(argv[i] + 10, cfg.homedir);
1437 if (!ppath)
1438 errExit("strdup");
1439 invalid_filename(ppath);
1158 1440
1159 // multiple profile files are allowed! 1441 // multiple profile files are allowed!
1160 char *ptr = argv[i] + 10; 1442 if (is_dir(ppath) || is_link(ppath) || strstr(ppath, "..")) {
1161 if (is_dir(ptr) || is_link(ptr) || strstr(ptr, "..")) {
1162 fprintf(stderr, "Error: invalid profile file\n"); 1443 fprintf(stderr, "Error: invalid profile file\n");
1163 exit(1); 1444 exit(1);
1164 } 1445 }
1165 1446
1166 // access call checks as real UID/GID, not as effective UID/GID 1447 // access call checks as real UID/GID, not as effective UID/GID
1167 if (access(argv[i] + 10, R_OK)) { 1448 if (access(ppath, R_OK)) {
1168 fprintf(stderr, "Error: cannot access profile file\n"); 1449 fprintf(stderr, "Error: cannot access profile file\n");
1169 return 1; 1450 return 1;
1170 } 1451 }
1171 1452
1172 profile_read(argv[i] + 10); 1453 profile_read(ppath);
1173 custom_profile = 1; 1454 custom_profile = 1;
1455 free(ppath);
1174 } 1456 }
1175 else if (strncmp(argv[i], "--profile-path=", 15) == 0) { 1457 else if (strncmp(argv[i], "--profile-path=", 15) == 0) {
1176 if (arg_noprofile) { 1458 if (arg_noprofile) {
@@ -1255,6 +1537,14 @@ int main(int argc, char **argv) {
1255 return 1; 1537 return 1;
1256 } 1538 }
1257 1539
1540 // don't allow "--chroot=/"
1541 char *rpath = realpath(cfg.chrootdir, NULL);
1542 if (rpath == NULL || strcmp(rpath, "/") == 0) {
1543 fprintf(stderr, "Error: invalid chroot directory\n");
1544 exit(1);
1545 }
1546 free(rpath);
1547
1258 // check chroot directory structure 1548 // check chroot directory structure
1259 if (fs_check_chroot_dir(cfg.chrootdir)) { 1549 if (fs_check_chroot_dir(cfg.chrootdir)) {
1260 fprintf(stderr, "Error: invalid chroot\n"); 1550 fprintf(stderr, "Error: invalid chroot\n");
@@ -1265,12 +1555,27 @@ int main(int argc, char **argv) {
1265 fprintf(stderr, "Error: --chroot feature is disabled in Firejail configuration file\n"); 1555 fprintf(stderr, "Error: --chroot feature is disabled in Firejail configuration file\n");
1266 exit(1); 1556 exit(1);
1267 } 1557 }
1268
1269 } 1558 }
1270#endif 1559#endif
1271 else if (strcmp(argv[i], "--private") == 0) 1560 else if (strcmp(argv[i], "--writable-etc") == 0) {
1561 if (cfg.etc_private_keep) {
1562 fprintf(stderr, "Error: --private-etc and --writable-etc are mutually exclusive\n");
1563 exit(1);
1564 }
1565 arg_writable_etc = 1;
1566 }
1567 else if (strcmp(argv[i], "--writable-var") == 0) {
1568 arg_writable_var = 1;
1569 }
1570 else if (strcmp(argv[i], "--private") == 0) {
1272 arg_private = 1; 1571 arg_private = 1;
1572 }
1273 else if (strncmp(argv[i], "--private=", 10) == 0) { 1573 else if (strncmp(argv[i], "--private=", 10) == 0) {
1574 if (cfg.home_private_keep) {
1575 fprintf(stderr, "Error: a private list of files was already defined with --private-home option.\n");
1576 exit(1);
1577 }
1578
1274 // extract private home dirname 1579 // extract private home dirname
1275 cfg.home_private = argv[i] + 10; 1580 cfg.home_private = argv[i] + 10;
1276 if (*cfg.home_private == '\0') { 1581 if (*cfg.home_private == '\0') {
@@ -1278,12 +1583,42 @@ int main(int argc, char **argv) {
1278 exit(1); 1583 exit(1);
1279 } 1584 }
1280 fs_check_private_dir(); 1585 fs_check_private_dir();
1586
1587 // downgrade to --private if the directory is the user home directory
1588 if (strcmp(cfg.home_private, cfg.homedir) == 0) {
1589 free(cfg.home_private);
1590 cfg.home_private = NULL;
1591 }
1281 arg_private = 1; 1592 arg_private = 1;
1282 } 1593 }
1594#ifdef HAVE_PRIVATE_HOME
1595 else if (strncmp(argv[i], "--private-home=", 15) == 0) {
1596 if (checkcfg(CFG_PRIVATE_HOME)) {
1597 if (cfg.home_private) {
1598 fprintf(stderr, "Error: a private home directory was already defined with --private option.\n");
1599 exit(1);
1600 }
1601
1602 // extract private home dirname
1603 cfg.home_private_keep = argv[i] + 15;
1604 fs_check_home_list();
1605 arg_private = 1;
1606 }
1607 else {
1608 fprintf(stderr, "Error: --private-home feature is disabled in Firejail configuration file\n");
1609 exit(1);
1610 }
1611 }
1612#endif
1283 else if (strcmp(argv[i], "--private-dev") == 0) { 1613 else if (strcmp(argv[i], "--private-dev") == 0) {
1284 arg_private_dev = 1; 1614 arg_private_dev = 1;
1285 } 1615 }
1286 else if (strncmp(argv[i], "--private-etc=", 14) == 0) { 1616 else if (strncmp(argv[i], "--private-etc=", 14) == 0) {
1617 if (arg_writable_etc) {
1618 fprintf(stderr, "Error: --private-etc and --writable-etc are mutually exclusive\n");
1619 exit(1);
1620 }
1621
1287 // extract private etc list 1622 // extract private etc list
1288 cfg.etc_private_keep = argv[i] + 14; 1623 cfg.etc_private_keep = argv[i] + 14;
1289 if (*cfg.etc_private_keep == '\0') { 1624 if (*cfg.etc_private_keep == '\0') {
@@ -1291,12 +1626,7 @@ int main(int argc, char **argv) {
1291 exit(1); 1626 exit(1);
1292 } 1627 }
1293 fs_check_etc_list(); 1628 fs_check_etc_list();
1294 if (*cfg.etc_private_keep != '\0') 1629 arg_private_etc = 1;
1295 arg_private_etc = 1;
1296 else {
1297 arg_private_etc = 0;
1298 fprintf(stderr, "Warning: private-etc disabled, no file found\n");
1299 }
1300 } 1630 }
1301 else if (strncmp(argv[i], "--private-bin=", 14) == 0) { 1631 else if (strncmp(argv[i], "--private-bin=", 14) == 0) {
1302 // extract private bin list 1632 // extract private bin list
@@ -1341,11 +1671,18 @@ int main(int argc, char **argv) {
1341 } 1671 }
1342 } 1672 }
1343#endif 1673#endif
1674 else if (strcmp(argv[i], "--nonewprivs") == 0) {
1675 arg_nonewprivs = 1;
1676 }
1344 else if (strncmp(argv[i], "--env=", 6) == 0) 1677 else if (strncmp(argv[i], "--env=", 6) == 0)
1345 env_store(argv[i] + 6); 1678 env_store(argv[i] + 6, SETENV);
1346 else if (strncmp(argv[i], "--nosound", 9) == 0) { 1679 else if (strncmp(argv[i], "--rmenv=", 8) == 0)
1680 env_store(argv[i] + 8, RMENV);
1681 else if (strcmp(argv[i], "--nosound") == 0) {
1347 arg_nosound = 1; 1682 arg_nosound = 1;
1348 arg_private_dev = 1; 1683 }
1684 else if (strcmp(argv[i], "--no3d") == 0) {
1685 arg_no3d = 1;
1349 } 1686 }
1350 1687
1351 //************************************* 1688 //*************************************
@@ -1401,7 +1738,8 @@ int main(int argc, char **argv) {
1401 errExit("strdup"); 1738 errExit("strdup");
1402 1739
1403 if (net_get_if_addr(intf->dev, &intf->ip, &intf->mask, intf->mac, &intf->mtu)) { 1740 if (net_get_if_addr(intf->dev, &intf->ip, &intf->mask, intf->mac, &intf->mtu)) {
1404 fprintf(stderr, "Warning: interface %s is not configured\n", intf->dev); 1741 if (!arg_quiet || arg_debug)
1742 fprintf(stderr, "Warning: interface %s is not configured\n", intf->dev);
1405 } 1743 }
1406 intf->configured = 1; 1744 intf->configured = 1;
1407 } 1745 }
@@ -1464,6 +1802,27 @@ int main(int argc, char **argv) {
1464 } 1802 }
1465 } 1803 }
1466 1804
1805 else if (strncmp(argv[i], "--veth-name=", 12) == 0) {
1806 if (checkcfg(CFG_NETWORK)) {
1807 Bridge *br = last_bridge_configured();
1808 if (br == NULL) {
1809 fprintf(stderr, "Error: no network device configured\n");
1810 exit(1);
1811 }
1812 br->veth_name = strdup(argv[i] + 12);
1813 if (br->veth_name == NULL)
1814 errExit("strdup");
1815 if (*br->veth_name == '\0') {
1816 fprintf(stderr, "Error: no veth-name configured\n");
1817 exit(1);
1818 }
1819 }
1820 else {
1821 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n");
1822 exit(1);
1823 }
1824 }
1825
1467 else if (strcmp(argv[i], "--scan") == 0) { 1826 else if (strcmp(argv[i], "--scan") == 0) {
1468 if (checkcfg(CFG_NETWORK)) { 1827 if (checkcfg(CFG_NETWORK)) {
1469 arg_scan = 1; 1828 arg_scan = 1;
@@ -1522,17 +1881,17 @@ int main(int argc, char **argv) {
1522 Bridge *br = last_bridge_configured(); 1881 Bridge *br = last_bridge_configured();
1523 if (br == NULL) { 1882 if (br == NULL) {
1524 fprintf(stderr, "Error: no network device configured\n"); 1883 fprintf(stderr, "Error: no network device configured\n");
1525 return 1; 1884 exit(1);
1526 } 1885 }
1527 if (mac_not_zero(br->macsandbox)) { 1886 if (mac_not_zero(br->macsandbox)) {
1528 fprintf(stderr, "Error: cannot configure the MAC address twice for the same interface\n"); 1887 fprintf(stderr, "Error: cannot configure the MAC address twice for the same interface\n");
1529 return 1; 1888 exit(1);
1530 } 1889 }
1531 1890
1532 // read the address 1891 // read the address
1533 if (atomac(argv[i] + 6, br->macsandbox)) { 1892 if (atomac(argv[i] + 6, br->macsandbox)) {
1534 fprintf(stderr, "Error: invalid MAC address\n"); 1893 fprintf(stderr, "Error: invalid MAC address\n");
1535 return 1; 1894 exit(1);
1536 } 1895 }
1537 } 1896 }
1538 else { 1897 else {
@@ -1546,12 +1905,12 @@ int main(int argc, char **argv) {
1546 Bridge *br = last_bridge_configured(); 1905 Bridge *br = last_bridge_configured();
1547 if (br == NULL) { 1906 if (br == NULL) {
1548 fprintf(stderr, "Error: no network device configured\n"); 1907 fprintf(stderr, "Error: no network device configured\n");
1549 return 1; 1908 exit(1);
1550 } 1909 }
1551 1910
1552 if (sscanf(argv[i] + 6, "%d", &br->mtu) != 1 || br->mtu < 576 || br->mtu > 9198) { 1911 if (sscanf(argv[i] + 6, "%d", &br->mtu) != 1 || br->mtu < 576 || br->mtu > 9198) {
1553 fprintf(stderr, "Error: invalid mtu value\n"); 1912 fprintf(stderr, "Error: invalid mtu value\n");
1554 return 1; 1913 exit(1);
1555 } 1914 }
1556 } 1915 }
1557 else { 1916 else {
@@ -1565,11 +1924,11 @@ int main(int argc, char **argv) {
1565 Bridge *br = last_bridge_configured(); 1924 Bridge *br = last_bridge_configured();
1566 if (br == NULL) { 1925 if (br == NULL) {
1567 fprintf(stderr, "Error: no network device configured\n"); 1926 fprintf(stderr, "Error: no network device configured\n");
1568 return 1; 1927 exit(1);
1569 } 1928 }
1570 if (br->arg_ip_none || br->ipsandbox) { 1929 if (br->arg_ip_none || br->ipsandbox) {
1571 fprintf(stderr, "Error: cannot configure the IP address twice for the same interface\n"); 1930 fprintf(stderr, "Error: cannot configure the IP address twice for the same interface\n");
1572 return 1; 1931 exit(1);
1573 } 1932 }
1574 1933
1575 // configure this IP address for the last bridge defined 1934 // configure this IP address for the last bridge defined
@@ -1578,7 +1937,7 @@ int main(int argc, char **argv) {
1578 else { 1937 else {
1579 if (atoip(argv[i] + 5, &br->ipsandbox)) { 1938 if (atoip(argv[i] + 5, &br->ipsandbox)) {
1580 fprintf(stderr, "Error: invalid IP address\n"); 1939 fprintf(stderr, "Error: invalid IP address\n");
1581 return 1; 1940 exit(1);
1582 } 1941 }
1583 } 1942 }
1584 } 1943 }
@@ -1593,11 +1952,11 @@ int main(int argc, char **argv) {
1593 Bridge *br = last_bridge_configured(); 1952 Bridge *br = last_bridge_configured();
1594 if (br == NULL) { 1953 if (br == NULL) {
1595 fprintf(stderr, "Error: no network device configured\n"); 1954 fprintf(stderr, "Error: no network device configured\n");
1596 return 1; 1955 exit(1);
1597 } 1956 }
1598 if (br->arg_ip_none || br->ip6sandbox) { 1957 if (br->arg_ip_none || br->ip6sandbox) {
1599 fprintf(stderr, "Error: cannot configure the IP address twice for the same interface\n"); 1958 fprintf(stderr, "Error: cannot configure the IP address twice for the same interface\n");
1600 return 1; 1959 exit(1);
1601 } 1960 }
1602 1961
1603 // configure this IP address for the last bridge defined 1962 // configure this IP address for the last bridge defined
@@ -1605,7 +1964,7 @@ int main(int argc, char **argv) {
1605 br->ip6sandbox = argv[i] + 6; 1964 br->ip6sandbox = argv[i] + 6;
1606// if (atoip(argv[i] + 5, &br->ipsandbox)) { 1965// if (atoip(argv[i] + 5, &br->ipsandbox)) {
1607// fprintf(stderr, "Error: invalid IP address\n"); 1966// fprintf(stderr, "Error: invalid IP address\n");
1608// return 1; 1967// exit(1);
1609// } 1968// }
1610 } 1969 }
1611 else { 1970 else {
@@ -1619,7 +1978,7 @@ int main(int argc, char **argv) {
1619 if (checkcfg(CFG_NETWORK)) { 1978 if (checkcfg(CFG_NETWORK)) {
1620 if (atoip(argv[i] + 12, &cfg.defaultgw)) { 1979 if (atoip(argv[i] + 12, &cfg.defaultgw)) {
1621 fprintf(stderr, "Error: invalid IP address\n"); 1980 fprintf(stderr, "Error: invalid IP address\n");
1622 return 1; 1981 exit(1);
1623 } 1982 }
1624 } 1983 }
1625 else { 1984 else {
@@ -1649,6 +2008,18 @@ int main(int argc, char **argv) {
1649 2008
1650#ifdef HAVE_NETWORK 2009#ifdef HAVE_NETWORK
1651 else if (strcmp(argv[i], "--netfilter") == 0) { 2010 else if (strcmp(argv[i], "--netfilter") == 0) {
2011#ifdef HAVE_NETWORK_RESTRICTED
2012 // compile time restricted networking
2013 if (getuid() != 0) {
2014 fprintf(stderr, "Error: --netfilter is only allowed for root\n");
2015 exit(1);
2016 }
2017#endif
2018 // run time restricted networking
2019 if (checkcfg(CFG_RESTRICTED_NETWORK) && getuid() != 0) {
2020 fprintf(stderr, "Error: --netfilter is only allowed for root\n");
2021 exit(1);
2022 }
1652 if (checkcfg(CFG_NETWORK)) { 2023 if (checkcfg(CFG_NETWORK)) {
1653 arg_netfilter = 1; 2024 arg_netfilter = 1;
1654 } 2025 }
@@ -1659,6 +2030,18 @@ int main(int argc, char **argv) {
1659 } 2030 }
1660 2031
1661 else if (strncmp(argv[i], "--netfilter=", 12) == 0) { 2032 else if (strncmp(argv[i], "--netfilter=", 12) == 0) {
2033#ifdef HAVE_NETWORK_RESTRICTED
2034 // compile time restricted networking
2035 if (getuid() != 0) {
2036 fprintf(stderr, "Error: --netfilter is only allowed for root\n");
2037 exit(1);
2038 }
2039#endif
2040 // run time restricted networking
2041 if (checkcfg(CFG_RESTRICTED_NETWORK) && getuid() != 0) {
2042 fprintf(stderr, "Error: --netfilter is only allowed for root\n");
2043 exit(1);
2044 }
1662 if (checkcfg(CFG_NETWORK)) { 2045 if (checkcfg(CFG_NETWORK)) {
1663 arg_netfilter = 1; 2046 arg_netfilter = 1;
1664 arg_netfilter_file = argv[i] + 12; 2047 arg_netfilter_file = argv[i] + 12;
@@ -1685,32 +2068,49 @@ int main(int argc, char **argv) {
1685 //************************************* 2068 //*************************************
1686 // command 2069 // command
1687 //************************************* 2070 //*************************************
2071 else if (strcmp(argv[i], "--audit") == 0) {
2072 if (asprintf(&arg_audit_prog, "%s/firejail/faudit", LIBDIR) == -1)
2073 errExit("asprintf");
2074 arg_audit = 1;
2075 }
2076 else if (strncmp(argv[i], "--audit=", 8) == 0) {
2077 if (strlen(argv[i] + 8) == 0) {
2078 fprintf(stderr, "Error: invalid audit program\n");
2079 exit(1);
2080 }
2081 arg_audit_prog = strdup(argv[i] + 8);
2082 if (!arg_audit_prog)
2083 errExit("strdup");
2084 arg_audit = 1;
2085 }
2086 else if (strcmp(argv[i], "--appimage") == 0)
2087 arg_appimage = 1;
1688 else if (strcmp(argv[i], "--csh") == 0) { 2088 else if (strcmp(argv[i], "--csh") == 0) {
1689 if (arg_shell_none) { 2089 if (arg_shell_none) {
1690 2090
1691 fprintf(stderr, "Error: --shell=none was already specified.\n"); 2091 fprintf(stderr, "Error: --shell=none was already specified.\n");
1692 return 1; 2092 return 1;
1693 } 2093 }
1694 if (arg_zsh || cfg.shell ) { 2094 if (cfg.shell) {
1695 fprintf(stderr, "Error: only one default user shell can be specified\n"); 2095 fprintf(stderr, "Error: only one default user shell can be specified\n");
1696 return 1; 2096 return 1;
1697 } 2097 }
1698 arg_csh = 1; 2098 cfg.shell = "/bin/csh";
1699 } 2099 }
1700 else if (strcmp(argv[i], "--zsh") == 0) { 2100 else if (strcmp(argv[i], "--zsh") == 0) {
1701 if (arg_shell_none) { 2101 if (arg_shell_none) {
1702 fprintf(stderr, "Error: --shell=none was already specified.\n"); 2102 fprintf(stderr, "Error: --shell=none was already specified.\n");
1703 return 1; 2103 return 1;
1704 } 2104 }
1705 if (arg_csh || cfg.shell ) { 2105 if (cfg.shell) {
1706 fprintf(stderr, "Error: only one default user shell can be specified\n"); 2106 fprintf(stderr, "Error: only one default user shell can be specified\n");
1707 return 1; 2107 return 1;
1708 } 2108 }
1709 arg_zsh = 1; 2109 cfg.shell = "/bin/zsh";
1710 } 2110 }
1711 else if (strcmp(argv[i], "--shell=none") == 0) { 2111 else if (strcmp(argv[i], "--shell=none") == 0) {
1712 arg_shell_none = 1; 2112 arg_shell_none = 1;
1713 if (arg_csh || arg_zsh || cfg.shell) { 2113 if (cfg.shell) {
1714 fprintf(stderr, "Error: a shell was already specified\n"); 2114 fprintf(stderr, "Error: a shell was already specified\n");
1715 return 1; 2115 return 1;
1716 } 2116 }
@@ -1722,7 +2122,7 @@ int main(int argc, char **argv) {
1722 } 2122 }
1723 invalid_filename(argv[i] + 8); 2123 invalid_filename(argv[i] + 8);
1724 2124
1725 if (arg_csh || arg_zsh || cfg.shell) { 2125 if (cfg.shell) {
1726 fprintf(stderr, "Error: only one user shell can be specified\n"); 2126 fprintf(stderr, "Error: only one user shell can be specified\n");
1727 return 1; 2127 return 1;
1728 } 2128 }
@@ -1732,9 +2132,18 @@ int main(int argc, char **argv) {
1732 fprintf(stderr, "Error: invalid shell\n"); 2132 fprintf(stderr, "Error: invalid shell\n");
1733 exit(1); 2133 exit(1);
1734 } 2134 }
1735 2135
1736 // access call checks as real UID/GID, not as effective UID/GID 2136 // access call checks as real UID/GID, not as effective UID/GID
1737 if (access(cfg.shell, R_OK)) { 2137 if(cfg.chrootdir) {
2138 char *shellpath;
2139 if (asprintf(&shellpath, "%s%s", cfg.chrootdir, cfg.shell) == -1)
2140 errExit("asprintf");
2141 if (access(shellpath, R_OK)) {
2142 fprintf(stderr, "Error: cannot access shell file in chroot\n");
2143 exit(1);
2144 }
2145 free(shellpath);
2146 } else if (access(cfg.shell, R_OK)) {
1738 fprintf(stderr, "Error: cannot access shell file\n"); 2147 fprintf(stderr, "Error: cannot access shell file\n");
1739 exit(1); 2148 exit(1);
1740 } 2149 }
@@ -1746,6 +2155,32 @@ int main(int argc, char **argv) {
1746 return 1; 2155 return 1;
1747 } 2156 }
1748 } 2157 }
2158
2159 // unlike all other x11 features, this is available always
2160 else if (strcmp(argv[i], "--x11=none") == 0) {
2161 arg_x11_block = 1;
2162 }
2163#ifdef HAVE_X11
2164 else if (strcmp(argv[i], "--x11=xorg") == 0) {
2165 if (checkcfg(CFG_X11))
2166 arg_x11_xorg = 1;
2167 else {
2168 fprintf(stderr, "Error: --x11 feature is disabled in Firejail configuration file\n");
2169 exit(1);
2170 }
2171 }
2172#endif
2173 else if (strncmp(argv[i], "--join-or-start=", 16) == 0) {
2174 // NOTE: this is second part of option handler,
2175 // atempt to find and join sandbox is done in other one
2176
2177 // set sandbox name and start normally
2178 cfg.name = argv[i] + 16;
2179 if (strlen(cfg.name) == 0) {
2180 fprintf(stderr, "Error: please provide a name for sandbox\n");
2181 return 1;
2182 }
2183 }
1749 else if (strcmp(argv[i], "--") == 0) { 2184 else if (strcmp(argv[i], "--") == 0) {
1750 // double dash - positional params to follow 2185 // double dash - positional params to follow
1751 arg_doubledash = 1; 2186 arg_doubledash = 1;
@@ -1766,15 +2201,33 @@ int main(int argc, char **argv) {
1766 } 2201 }
1767 2202
1768 // we have a program name coming 2203 // we have a program name coming
1769 extract_command_name(i, argv); 2204 if (arg_appimage) {
2205 cfg.command_name = strdup(argv[i]);
2206 if (!cfg.command_name)
2207 errExit("strdup");
2208 }
2209 else
2210 extract_command_name(i, argv);
1770 prog_index = i; 2211 prog_index = i;
1771 break; 2212 break;
1772 } 2213 }
1773 } 2214 }
2215
2216 // prog_index could still be -1 if no program was specified
2217 if (prog_index == -1 && arg_shell_none) {
2218 fprintf(stderr, "shell=none configured, but no program specified\n");
2219 exit(1);
2220 }
1774 2221
1775 // check trace configuration 2222 // check trace configuration
1776 if (arg_trace && arg_tracelog) 2223 if (arg_trace && arg_tracelog) {
1777 fprintf(stderr, "Warning: --trace and --tracelog are mutually exclusive; --tracelog disabled\n"); 2224 if (!arg_quiet || arg_debug)
2225 fprintf(stderr, "Warning: --trace and --tracelog are mutually exclusive; --tracelog disabled\n");
2226 }
2227
2228 // disable x11 abstract socket
2229 if (getenv("FIREJAIL_X11"))
2230 mask_x11_abstract_socket = 1;
1778 2231
1779 // check user namespace (--noroot) options 2232 // check user namespace (--noroot) options
1780 if (arg_noroot) { 2233 if (arg_noroot) {
@@ -1798,66 +2251,41 @@ int main(int argc, char **argv) {
1798 free(msg); 2251 free(msg);
1799 } 2252 }
1800 2253
1801 // build the sandbox command 2254 // guess shell if unspecified
1802 if (prog_index == -1 && arg_zsh) { 2255 if (!arg_shell_none && !cfg.shell) {
1803 cfg.command_line = "/usr/bin/zsh"; 2256 cfg.shell = guess_shell();
1804 cfg.window_title = "/usr/bin/zsh"; 2257 if (!cfg.shell) {
1805 cfg.command_name = "zsh"; 2258 fprintf(stderr, "Error: unable to guess your shell, please set explicitly by using --shell option.\n");
1806 } 2259 exit(1);
1807 else if (prog_index == -1 && arg_csh) { 2260 }
1808 cfg.command_line = "/bin/csh"; 2261 if (arg_debug)
1809 cfg.window_title = "/bin/csh"; 2262 printf("Autoselecting %s as shell\n", cfg.shell);
1810 cfg.command_name = "csh";
1811 } 2263 }
1812 else if (prog_index == -1 && cfg.shell) { 2264
2265 // build the sandbox command
2266 if (prog_index == -1 && cfg.shell) {
1813 cfg.command_line = cfg.shell; 2267 cfg.command_line = cfg.shell;
1814 cfg.window_title = cfg.shell; 2268 cfg.window_title = cfg.shell;
1815 cfg.command_name = cfg.shell; 2269 cfg.command_name = cfg.shell;
1816 } 2270 }
1817 else if (prog_index == -1) { 2271 else if (arg_appimage) {
1818 cfg.command_line = "/bin/bash"; 2272 if (arg_debug)
1819 cfg.window_title = "/bin/bash"; 2273 printf("Configuring appimage environment\n");
1820 cfg.command_name = "bash"; 2274 appimage_set(cfg.command_name);
2275 cfg.window_title = "appimage";
1821 } 2276 }
1822 else { 2277 else {
1823 // calculate the length of the command 2278 build_cmdline(&cfg.command_line, &cfg.window_title, argc, argv, prog_index);
1824 int i;
1825 int len = 0;
1826 int argcnt = argc - prog_index;
1827 for (i = 0; i < argcnt; i++)
1828 len += strlen(argv[i + prog_index]) + 3; // + ' ' + 2 '"'
1829
1830 // build the string
1831 cfg.command_line = malloc(len + 1); // + '\0'
1832 if (!cfg.command_line)
1833 errExit("malloc");
1834 cfg.window_title = malloc(len + 1); // + '\0'
1835 if (!cfg.window_title)
1836 errExit("malloc");
1837
1838 char *ptr1 = cfg.command_line;
1839 char *ptr2 = cfg.window_title;
1840 for (i = 0; i < argcnt; i++) {
1841 // detect bash commands
1842 if (strstr(argv[i + prog_index], "&&") || strstr(argv[i + prog_index], "||")) {
1843 sprintf(ptr1, "%s ", argv[i + prog_index]);
1844 }
1845 else if (arg_command){
1846 sprintf(ptr1, "%s ", argv[i + prog_index]);
1847 }
1848 else {
1849 sprintf(ptr1, "\"%s\" ", argv[i + prog_index]);
1850 }
1851 sprintf(ptr2, "%s ", argv[i + prog_index]);
1852
1853 ptr1 += strlen(ptr1);
1854 ptr2 += strlen(ptr2);
1855 }
1856 } 2279 }
2280/* else {
2281 fprintf(stderr, "Error: command must be specified when --shell=none used.\n");
2282 exit(1);
2283 }*/
1857 2284
1858 assert(cfg.command_name); 2285 assert(cfg.command_name);
1859 if (arg_debug) 2286 if (arg_debug)
1860 printf("Command name #%s#\n", cfg.command_name); 2287 printf("Command name #%s#\n", cfg.command_name);
2288
1861 2289
1862 // load the profile 2290 // load the profile
1863 if (!arg_noprofile) { 2291 if (!arg_noprofile) {
@@ -1881,14 +2309,16 @@ int main(int argc, char **argv) {
1881 } 2309 }
1882 } 2310 }
1883 2311
1884 // use generic.profile as the default 2312 // use default.profile as the default
1885 if (!custom_profile && !arg_noprofile) { 2313 if (!custom_profile && !arg_noprofile) {
1886 if (cfg.chrootdir) 2314 if (cfg.chrootdir) {
1887 fprintf(stderr, "Warning: default profile disabled by --chroot option\n"); 2315 if (!arg_quiet || arg_debug)
1888 else if (arg_overlay) 2316 fprintf(stderr, "Warning: default profile disabled by --chroot option\n");
1889 fprintf(stderr, "Warning: default profile disabled by --overlay option\n"); 2317 }
1890// else if (cfg.home_private_keep) 2318 else if (arg_overlay) {
1891// fprintf(stderr, "Warning: default profile disabled by --private-home option\n"); 2319 if (!arg_quiet || arg_debug)
2320 fprintf(stderr, "Warning: default profile disabled by --overlay option\n");
2321 }
1892 else { 2322 else {
1893 // try to load a default profile 2323 // try to load a default profile
1894 char *profile_name = DEFAULT_USER_PROFILE; 2324 char *profile_name = DEFAULT_USER_PROFILE;
@@ -1911,12 +2341,20 @@ int main(int argc, char **argv) {
1911 else 2341 else
1912 custom_profile = profile_find(profile_name, SYSCONFDIR); 2342 custom_profile = profile_find(profile_name, SYSCONFDIR);
1913 } 2343 }
2344 if (!custom_profile) {
2345 fprintf(stderr, "Error: no default.profile installed\n");
2346 exit(1);
2347 }
1914 2348
1915 if (custom_profile && !arg_quiet) 2349 if (custom_profile && !arg_quiet)
1916 printf("\n** Note: you can use --noprofile to disable %s.profile **\n\n", profile_name); 2350 printf("\n** Note: you can use --noprofile to disable %s.profile **\n\n", profile_name);
1917 } 2351 }
1918 } 2352 }
1919 2353
2354 // block X11 sockets
2355 if (arg_x11_block)
2356 x11_block();
2357
1920 // check network configuration options - it will exit if anything went wrong 2358 // check network configuration options - it will exit if anything went wrong
1921 net_check_cfg(); 2359 net_check_cfg();
1922 2360
@@ -1947,11 +2385,13 @@ int main(int argc, char **argv) {
1947 errExit("pipe"); 2385 errExit("pipe");
1948 2386
1949 if (arg_noroot && arg_overlay) { 2387 if (arg_noroot && arg_overlay) {
1950 fprintf(stderr, "Warning: --overlay and --noroot are mutually exclusive, noroot disabled\n"); 2388 if (!arg_quiet || arg_debug)
2389 fprintf(stderr, "Warning: --overlay and --noroot are mutually exclusive, noroot disabled\n");
1951 arg_noroot = 0; 2390 arg_noroot = 0;
1952 } 2391 }
1953 else if (arg_noroot && cfg.chrootdir) { 2392 else if (arg_noroot && cfg.chrootdir) {
1954 fprintf(stderr, "Warning: --chroot and --noroot are mutually exclusive, noroot disabled\n"); 2393 if (!arg_quiet || arg_debug)
2394 fprintf(stderr, "Warning: --chroot and --noroot are mutually exclusive, noroot disabled\n");
1955 arg_noroot = 0; 2395 arg_noroot = 0;
1956 } 2396 }
1957 2397
@@ -2012,7 +2452,10 @@ int main(int argc, char **argv) {
2012 network_main(child); 2452 network_main(child);
2013 if (arg_debug) 2453 if (arg_debug)
2014 printf("Host network configured\n"); 2454 printf("Host network configured\n");
2015 exit(0); 2455#ifdef HAVE_GCOV
2456 __gcov_flush();
2457#endif
2458 _exit(0);
2016 } 2459 }
2017 2460
2018 // wait for the child to finish 2461 // wait for the child to finish
@@ -2061,16 +2504,30 @@ int main(int argc, char **argv) {
2061 ptr += strlen(ptr); 2504 ptr += strlen(ptr);
2062 2505
2063 // add tty group 2506 // add tty group
2064 gid_t ttygid = get_tty_gid(); 2507 gid_t g = get_group_id("tty");
2065 if (ttygid) { 2508 if (g) {
2066 sprintf(ptr, "%d %d 1\n", ttygid, ttygid); 2509 sprintf(ptr, "%d %d 1\n", g, g);
2067 ptr += strlen(ptr); 2510 ptr += strlen(ptr);
2068 } 2511 }
2069 2512
2070 // add audio group 2513 // add audio group
2071 gid_t audiogid = get_audio_gid(); 2514 g = get_group_id("audio");
2072 if (ttygid) { 2515 if (g) {
2073 sprintf(ptr, "%d %d 1\n", audiogid, audiogid); 2516 sprintf(ptr, "%d %d 1\n", g, g);
2517 ptr += strlen(ptr);
2518 }
2519
2520 // add video group
2521 g = get_group_id("video");
2522 if (g) {
2523 sprintf(ptr, "%d %d 1\n", g, g);
2524 ptr += strlen(ptr);
2525 }
2526
2527 // add games group
2528 g = get_group_id("games");
2529 if (g) {
2530 sprintf(ptr, "%d %d 1\n", g, g);
2074 } 2531 }
2075 2532
2076 EUID_ROOT(); 2533 EUID_ROOT();
@@ -2084,8 +2541,10 @@ int main(int argc, char **argv) {
2084 close(parent_to_child_fds[1]); 2541 close(parent_to_child_fds[1]);
2085 2542
2086 EUID_ROOT(); 2543 EUID_ROOT();
2087 if (lockfd != -1) 2544 if (lockfd != -1) {
2088 flock(lockfd, LOCK_UN); 2545 flock(lockfd, LOCK_UN);
2546 close(lockfd);
2547 }
2089 2548
2090 // create name file under /run/firejail 2549 // create name file under /run/firejail
2091 2550
@@ -2101,13 +2560,6 @@ int main(int argc, char **argv) {
2101 waitpid(child, &status, 0); 2560 waitpid(child, &status, 0);
2102 2561
2103 // free globals 2562 // free globals
2104#ifdef HAVE_SECCOMP
2105 if (cfg.seccomp_list_errno) {
2106 for (i = 0; i < highest_errno; i++)
2107 free(cfg.seccomp_list_errno[i]);
2108 free(cfg.seccomp_list_errno);
2109 }
2110#endif
2111 if (cfg.profile) { 2563 if (cfg.profile) {
2112 ProfileEntry *prf = cfg.profile; 2564 ProfileEntry *prf = cfg.profile;
2113 while (prf != NULL) { 2565 while (prf != NULL) {
diff --git a/src/firejail/netfilter.c b/src/firejail/netfilter.c
index 71abfb53d..1df4b7a0f 100644
--- a/src/firejail/netfilter.c
+++ b/src/firejail/netfilter.c
@@ -66,6 +66,8 @@ void netfilter(const char *fname) {
66 66
67 // custom filter 67 // custom filter
68 int allocated = 0; 68 int allocated = 0;
69 if (netfilter_default)
70 fname = netfilter_default;
69 if (fname) { 71 if (fname) {
70 // buffer the filter 72 // buffer the filter
71 struct stat s; 73 struct stat s;
@@ -141,9 +143,10 @@ void netfilter(const char *fname) {
141 dup2(fd,STDIN_FILENO); 143 dup2(fd,STDIN_FILENO);
142 144
143 // wipe out environment variables 145 // wipe out environment variables
144 environ = NULL; 146 clearenv();
145 execl(iptables_restore, iptables_restore, NULL); 147 execl(iptables_restore, iptables_restore, NULL);
146 // it will never get here!!! 148 perror("execl");
149 _exit(1);
147 } 150 }
148 // wait for the child to finish 151 // wait for the child to finish
149 waitpid(child, NULL, 0); 152 waitpid(child, NULL, 0);
@@ -160,8 +163,10 @@ void netfilter(const char *fname) {
160 if (setregid(0, 0)) 163 if (setregid(0, 0))
161 errExit("setregid"); 164 errExit("setregid");
162 environ = NULL; 165 environ = NULL;
166 assert(getenv("LD_PRELOAD") == NULL);
163 execl(iptables, iptables, "-vL", NULL); 167 execl(iptables, iptables, "-vL", NULL);
164 // it will never get here!!! 168 perror("execl");
169 _exit(1);
165 } 170 }
166 // wait for the child to finish 171 // wait for the child to finish
167 waitpid(child, NULL, 0); 172 waitpid(child, NULL, 0);
@@ -252,9 +257,10 @@ void netfilter6(const char *fname) {
252 dup2(fd,STDIN_FILENO); 257 dup2(fd,STDIN_FILENO);
253 258
254 // wipe out environment variables 259 // wipe out environment variables
255 environ = NULL; 260 clearenv();
256 execl(ip6tables_restore, ip6tables_restore, NULL); 261 execl(ip6tables_restore, ip6tables_restore, NULL);
257 // it will never get here!!! 262 perror("execl");
263 _exit(1);
258 } 264 }
259 // wait for the child to finish 265 // wait for the child to finish
260 waitpid(child, NULL, 0); 266 waitpid(child, NULL, 0);
@@ -265,9 +271,10 @@ void netfilter6(const char *fname) {
265 if (child < 0) 271 if (child < 0)
266 errExit("fork"); 272 errExit("fork");
267 if (child == 0) { 273 if (child == 0) {
268 environ = NULL; 274 clearenv();
269 execl(ip6tables, ip6tables, "-vL", NULL); 275 execl(ip6tables, ip6tables, "-vL", NULL);
270 // it will never get here!!! 276 perror("execl");
277 _exit(1);
271 } 278 }
272 // wait for the child to finish 279 // wait for the child to finish
273 waitpid(child, NULL, 0); 280 waitpid(child, NULL, 0);
diff --git a/src/firejail/network.c b/src/firejail/network.c
index aac48e521..6d09d770f 100644
--- a/src/firejail/network.c
+++ b/src/firejail/network.c
@@ -28,70 +28,6 @@
28#include <net/route.h> 28#include <net/route.h>
29#include <linux/if_bridge.h> 29#include <linux/if_bridge.h>
30 30
31// scan interfaces in current namespace and print IP address/mask for each interface
32void net_ifprint(void) {
33 uint32_t ip;
34 uint32_t mask;
35 struct ifaddrs *ifaddr, *ifa;
36
37 if (getifaddrs(&ifaddr) == -1)
38 errExit("getifaddrs");
39
40 printf("%-17.17s%-19.19s%-17.17s%-17.17s%-6.6s\n",
41 "Interface", "MAC", "IP", "Mask", "Status");
42 // walk through the linked list
43 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
44 if (ifa->ifa_addr == NULL)
45 continue;
46
47 if (ifa->ifa_addr->sa_family == AF_INET) {
48 struct sockaddr_in *si = (struct sockaddr_in *) ifa->ifa_netmask;
49 mask = ntohl(si->sin_addr.s_addr);
50 si = (struct sockaddr_in *) ifa->ifa_addr;
51 ip = ntohl(si->sin_addr.s_addr);
52
53 // interface status
54 char *status;
55 if (ifa->ifa_flags & IFF_RUNNING && ifa->ifa_flags & IFF_UP)
56 status = "UP";
57 else
58 status = "DOWN";
59
60 // ip address and mask
61 char ipstr[30];
62 sprintf(ipstr, "%d.%d.%d.%d", PRINT_IP(ip));
63 char maskstr[30];
64 sprintf(maskstr, "%d.%d.%d.%d", PRINT_IP(mask));
65
66 // mac address
67 unsigned char mac[6];
68 net_get_mac(ifa->ifa_name, mac);
69 char macstr[30];
70 if (strcmp(ifa->ifa_name, "lo") == 0)
71 macstr[0] = '\0';
72 else
73 sprintf(macstr, "%02x:%02x:%02x:%02x:%02x:%02x", PRINT_MAC(mac));
74
75 // print
76 printf("%-17.17s%-19.19s%-17.17s%-17.17s%-6.6s\n",
77 ifa->ifa_name, macstr, ipstr, maskstr, status);
78
79 // network scanning
80 if (!arg_scan) // scanning disabled
81 continue;
82 if (strcmp(ifa->ifa_name, "lo") == 0) // no loopbabck scanning
83 continue;
84 if (mask2bits(mask) < 16) // not scanning large networks
85 continue;
86 if (!ip) // if not configured
87 continue;
88 // only if the interface is up and running
89 if (ifa->ifa_flags & IFF_RUNNING && ifa->ifa_flags & IFF_UP)
90 arp_scan(ifa->ifa_name, ip, mask);
91 }
92 }
93 freeifaddrs(ifaddr);
94}
95 31
96int net_get_mtu(const char *ifname) { 32int net_get_mtu(const char *ifname) {
97 int mtu = 0; 33 int mtu = 0;
@@ -190,95 +126,11 @@ void net_if_up(const char *ifname) {
190 fprintf(stderr, "Error: invalid network device name %s\n", ifname); 126 fprintf(stderr, "Error: invalid network device name %s\n", ifname);
191 exit(1); 127 exit(1);
192 } 128 }
193 129 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 3,
194 int sock = socket(AF_INET,SOCK_DGRAM,0); 130 PATH_FNET, "ifup", ifname);
195 if (sock < 0) 131}
196 errExit("socket");
197
198 // get the existing interface flags
199 struct ifreq ifr;
200 memset(&ifr, 0, sizeof(ifr));
201 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
202 ifr.ifr_addr.sa_family = AF_INET;
203
204 // read the existing flags
205 if (ioctl(sock, SIOCGIFFLAGS, &ifr ) < 0) {
206 close(sock);
207 errExit("ioctl");
208 }
209 132
210 ifr.ifr_flags |= IFF_UP;
211 133
212 // set the new flags
213 if (ioctl( sock, SIOCSIFFLAGS, &ifr ) < 0) {
214 close(sock);
215 errExit("ioctl");
216 }
217
218 // checking
219 // read the existing flags
220 if (ioctl(sock, SIOCGIFFLAGS, &ifr ) < 0) {
221 close(sock);
222 errExit("ioctl");
223 }
224
225 // wait not more than 500ms for the interface to come up
226 int cnt = 0;
227 while (cnt < 50) {
228 usleep(10000); // sleep 10ms
229
230 // read the existing flags
231 if (ioctl(sock, SIOCGIFFLAGS, &ifr ) < 0) {
232 close(sock);
233 errExit("ioctl");
234 }
235 if (ifr.ifr_flags & IFF_RUNNING)
236 break;
237 cnt++;
238 }
239
240 close(sock);
241}
242
243// bring interface up
244void net_if_down(const char *ifname) {
245 if (strlen(ifname) > IFNAMSIZ) {
246 fprintf(stderr, "Error: invalid network device name %s\n", ifname);
247 exit(1);
248 }
249
250 int sock = socket(AF_INET,SOCK_DGRAM,0);
251 if (sock < 0)
252 errExit("socket");
253
254 // get the existing interface flags
255 struct ifreq ifr;
256 memset(&ifr, 0, sizeof(ifr));
257 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
258 ifr.ifr_addr.sa_family = AF_INET;
259
260 // read the existing flags
261 if (ioctl(sock, SIOCGIFFLAGS, &ifr ) < 0) {
262 close(sock);
263 errExit("ioctl");
264 }
265
266 ifr.ifr_flags &= ~IFF_UP;
267
268 // set the new flags
269 if (ioctl( sock, SIOCSIFFLAGS, &ifr ) < 0) {
270 close(sock);
271 errExit("ioctl");
272 }
273
274 close(sock);
275}
276
277struct ifreq6 {
278 struct in6_addr ifr6_addr;
279 uint32_t ifr6_prefixlen;
280 unsigned int ifr6_ifindex;
281};
282// configure interface ipv6 address 134// configure interface ipv6 address
283// ex: firejail --net=eth0 --ip6=2001:0db8:0:f101::1/64 135// ex: firejail --net=eth0 --ip6=2001:0db8:0:f101::1/64
284void net_if_ip6(const char *ifname, const char *addr6) { 136void net_if_ip6(const char *ifname, const char *addr6) {
@@ -287,107 +139,11 @@ void net_if_ip6(const char *ifname, const char *addr6) {
287 exit(1); 139 exit(1);
288 } 140 }
289 141
290 // extract prefix 142 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 5,
291 unsigned long prefix; 143 PATH_FNET, "config", "ipv6", ifname, addr6);
292 char *ptr;
293 if ((ptr = strchr(addr6, '/'))) {
294 prefix = atol(ptr + 1);
295 if (prefix > 128) {
296 fprintf(stderr, "Error: invalid prefix for IPv6 address %s\n", addr6);
297 exit(1);
298 }
299 *ptr = '\0'; // mark the end of the address
300 }
301 else
302 prefix = 128;
303
304 // extract address
305 struct sockaddr_in6 sin6;
306 memset(&sin6, 0, sizeof(sin6));
307 sin6.sin6_family = AF_INET6;
308 int rv = inet_pton(AF_INET6, addr6, sin6.sin6_addr.s6_addr);
309 if (rv <= 0) {
310 fprintf(stderr, "Error: invalid IPv6 address %s\n", addr6);
311 exit(1);
312 }
313
314 // open socket
315 int sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
316 if (sock < 0) {
317 fprintf(stderr, "Error: IPv6 is not supported on this system\n");
318 exit(1);
319 }
320
321 // find interface index
322 struct ifreq ifr;
323 memset(&ifr, 0, sizeof(ifr));
324 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
325 ifr.ifr_addr.sa_family = AF_INET;
326 if (ioctl(sock, SIOGIFINDEX, &ifr) < 0) {
327 perror("ioctl SIOGIFINDEX");
328 exit(1);
329 }
330
331 // configure address
332 struct ifreq6 ifr6;
333 memset(&ifr6, 0, sizeof(ifr6));
334 ifr6.ifr6_prefixlen = prefix;
335 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
336 memcpy((char *) &ifr6.ifr6_addr, (char *) &sin6.sin6_addr, sizeof(struct in6_addr));
337 if (ioctl(sock, SIOCSIFADDR, &ifr6) < 0) {
338 perror("ioctl SIOCSIFADDR");
339 exit(1);
340 }
341
342 close(sock);
343}
344
345// configure interface ipv4 address
346void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask, int mtu) {
347 if (strlen(ifname) > IFNAMSIZ) {
348 fprintf(stderr, "Error: invalid network device name %s\n", ifname);
349 exit(1);
350 }
351 if (arg_debug)
352 printf("configure interface %s\n", ifname);
353
354 int sock = socket(AF_INET,SOCK_DGRAM,0);
355 if (sock < 0)
356 errExit("socket");
357
358 struct ifreq ifr;
359 memset(&ifr, 0, sizeof(ifr));
360 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
361 ifr.ifr_addr.sa_family = AF_INET;
362
363 ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr = htonl(ip);
364 if (ioctl( sock, SIOCSIFADDR, &ifr ) < 0) {
365 close(sock);
366 errExit("ioctl");
367 }
368
369 if (ip != 0) {
370 ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr = htonl(mask);
371 if (ioctl( sock, SIOCSIFNETMASK, &ifr ) < 0) {
372 close(sock);
373 errExit("ioctl");
374 }
375 }
376
377 // configure mtu
378 if (mtu > 0) {
379 ifr.ifr_mtu = mtu;
380 if (ioctl( sock, SIOCSIFMTU, &ifr ) < 0) {
381 close(sock);
382 errExit("ioctl");
383 }
384 }
385 144
386 close(sock);
387 usleep(10000); // sleep 10ms
388} 145}
389 146
390
391// add an IP route, return -1 if error, 0 if the route was added 147// add an IP route, return -1 if error, 0 if the route was added
392int net_add_route(uint32_t ip, uint32_t mask, uint32_t gw) { 148int net_add_route(uint32_t ip, uint32_t mask, uint32_t gw) {
393 int sock; 149 int sock;
@@ -425,52 +181,6 @@ int net_add_route(uint32_t ip, uint32_t mask, uint32_t gw) {
425} 181}
426 182
427 183
428// add a veth device to a bridge
429void net_bridge_add_interface(const char *bridge, const char *dev) {
430 if (strlen(bridge) > IFNAMSIZ) {
431 fprintf(stderr, "Error: invalid network device name %s\n", bridge);
432 exit(1);
433 }
434
435 // somehow adding the interface to the bridge resets MTU on bridge device!!!
436 // workaround: restore MTU on the bridge device
437 // todo: put a real fix in
438 int mtu1 = net_get_mtu(bridge);
439
440 struct ifreq ifr;
441 int err;
442 int ifindex = if_nametoindex(dev);
443
444 if (ifindex <= 0)
445 errExit("if_nametoindex");
446
447 int sock;
448 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
449 errExit("socket");
450
451 memset(&ifr, 0, sizeof(ifr));
452 strncpy(ifr.ifr_name, bridge, IFNAMSIZ);
453#ifdef SIOCBRADDIF
454 ifr.ifr_ifindex = ifindex;
455 err = ioctl(sock, SIOCBRADDIF, &ifr);
456 if (err < 0)
457#endif
458 {
459 unsigned long args[4] = { BRCTL_ADD_IF, ifindex, 0, 0 };
460
461 ifr.ifr_data = (char *) args;
462 err = ioctl(sock, SIOCDEVPRIVATE, &ifr);
463 }
464 (void) err;
465 close(sock);
466
467 int mtu2 = net_get_mtu(bridge);
468 if (mtu1 != mtu2) {
469 if (arg_debug)
470 printf("Restoring MTU for %s\n", bridge);
471 net_set_mtu(bridge, mtu1);
472 }
473}
474 184
475#define BUFSIZE 1024 185#define BUFSIZE 1024
476uint32_t network_get_defaultgw(void) { 186uint32_t network_get_defaultgw(void) {
@@ -504,20 +214,15 @@ uint32_t network_get_defaultgw(void) {
504} 214}
505 215
506int net_config_mac(const char *ifname, const unsigned char mac[6]) { 216int net_config_mac(const char *ifname, const unsigned char mac[6]) {
507 struct ifreq ifr; 217 char *macstr;
508 int sock; 218 if (asprintf(&macstr, "%02x:%02x:%02x:%02x:%02x:%02x",
509 219 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]) == -1)
510 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) 220 errExit("asprintf");
511 errExit("socket");
512 221
513 memset(&ifr, 0, sizeof(ifr)); 222 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 5,
514 strncpy(ifr.ifr_name, ifname, IFNAMSIZ); 223 PATH_FNET, "config", "mac", ifname, macstr);
515 ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
516 memcpy(ifr.ifr_hwaddr.sa_data, mac, 6);
517 224
518 if (ioctl(sock, SIOCSIFHWADDR, &ifr) == -1) 225 free(macstr);
519 errExit("ioctl");
520 close(sock);
521 return 0; 226 return 0;
522} 227}
523 228
@@ -540,3 +245,27 @@ int net_get_mac(const char *ifname, unsigned char mac[6]) {
540 close(sock); 245 close(sock);
541 return 0; 246 return 0;
542} 247}
248
249void net_config_interface(const char *dev, uint32_t ip, uint32_t mask, int mtu) {
250 assert(dev);
251
252 char *ipstr;
253 if (asprintf(&ipstr, "%llu", (long long unsigned) ip) == -1)
254 errExit("asprintf");
255
256 char *maskstr;
257 if (asprintf(&maskstr, "%llu", (long long unsigned) mask) == -1)
258 errExit("asprintf");
259
260 char *mtustr;
261 if (asprintf(&mtustr, "%d", mtu) == -1)
262 errExit("asprintf");
263
264 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 7,
265 PATH_FNET, "config", "interface", dev, ipstr, maskstr, mtustr);
266
267 free(ipstr);
268 free(maskstr);
269 free(mtustr);
270}
271
diff --git a/src/firejail/network.txt b/src/firejail/network.txt
index 673d5b941..f6df0f485 100644
--- a/src/firejail/network.txt
+++ b/src/firejail/network.txt
@@ -13,7 +13,7 @@ net_configure_bridge(br, device) {
13} 13}
14 14
15net_configure_sandbox_ip(br) { 15net_configure_sandbox_ip(br) {
16 if br->ip_snadbox 16 if br->ip_sandbox
17 check br->ipsandbox inside the bridge network 17 check br->ipsandbox inside the bridge network
18 arp_check(br->ipsandbox) // send an arp req to check if anybody else is using this address 18 arp_check(br->ipsandbox) // send an arp req to check if anybody else is using this address
19 else 19 else
diff --git a/src/firejail/network_main.c b/src/firejail/network_main.c
index e6d5cd5d7..9fbc09d2b 100644
--- a/src/firejail/network_main.c
+++ b/src/firejail/network_main.c
@@ -23,6 +23,7 @@
23#include <sys/stat.h> 23#include <sys/stat.h>
24#include <unistd.h> 24#include <unistd.h>
25#include <net/if.h> 25#include <net/if.h>
26#include <stdarg.h>
26 27
27// configure bridge structure 28// configure bridge structure
28// - extract ip address and mask from the bridge interface 29// - extract ip address and mask from the bridge interface
@@ -56,9 +57,12 @@ void net_configure_bridge(Bridge *br, char *dev_name) {
56 } 57 }
57 } 58 }
58 59
60 // allow unconfigured interfaces
59 if (net_get_if_addr(br->dev, &br->ip, &br->mask, br->mac, &br->mtu)) { 61 if (net_get_if_addr(br->dev, &br->ip, &br->mask, br->mac, &br->mtu)) {
60 fprintf(stderr, "Error: interface %s is not configured\n", br->dev); 62 fprintf(stderr, "Warning: the network interface %s is not configured\n", br->dev);
61 exit(1); 63 br->configured = 1;
64 br->arg_ip_none = 1;
65 return;
62 } 66 }
63 if (arg_debug) { 67 if (arg_debug) {
64 if (br->macvlan == 0) 68 if (br->macvlan == 0)
@@ -117,15 +121,18 @@ void net_configure_veth_pair(Bridge *br, const char *ifname, pid_t child) {
117 121
118 // create a veth pair 122 // create a veth pair
119 char *dev; 123 char *dev;
120 if (asprintf(&dev, "veth%u%s", getpid(), ifname) < 0) 124 if (br->veth_name == NULL) {
125 if (asprintf(&dev, "veth%u%s", getpid(), ifname) < 0)
126 errExit("asprintf");
127 }
128 else
129 dev = br->veth_name;
130
131 char *cstr;
132 if (asprintf(&cstr, "%d", child) == -1)
121 errExit("asprintf"); 133 errExit("asprintf");
122 net_create_veth(dev, ifname, child); 134 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 7, PATH_FNET, "create", "veth", dev, ifname, br->dev, cstr);
123 135 free(cstr);
124 // add interface to the bridge
125 net_bridge_add_interface(br->dev, dev);
126
127 // bring up the interface
128 net_if_up(dev);
129 136
130 char *msg; 137 char *msg;
131 if (asprintf(&msg, "%d.%d.%d.%d address assigned to sandbox", PRINT_IP(br->ipsandbox)) == -1) 138 if (asprintf(&msg, "%d.%d.%d.%d address assigned to sandbox", PRINT_IP(br->ipsandbox)) == -1)
@@ -224,23 +231,6 @@ void net_check_cfg(void) {
224 } 231 }
225} 232}
226 233
227
228
229void net_dns_print_name(const char *name) {
230 EUID_ASSERT();
231 if (!name || strlen(name) == 0) {
232 fprintf(stderr, "Error: invalid sandbox name\n");
233 exit(1);
234 }
235 pid_t pid;
236 if (name2pid(name, &pid)) {
237 fprintf(stderr, "Error: cannot find sandbox %s\n", name);
238 exit(1);
239 }
240
241 net_dns_print(pid);
242}
243
244#define MAXBUF 4096 234#define MAXBUF 4096
245void net_dns_print(pid_t pid) { 235void net_dns_print(pid_t pid) {
246 EUID_ASSERT(); 236 EUID_ASSERT();
@@ -282,47 +272,53 @@ void net_dns_print(pid_t pid) {
282} 272}
283 273
284void network_main(pid_t child) { 274void network_main(pid_t child) {
275 char *cstr;
276 if (asprintf(&cstr, "%d", child) == -1)
277 errExit("asprintf");
278
285 // create veth pair or macvlan device 279 // create veth pair or macvlan device
286 if (cfg.bridge0.configured) { 280 if (cfg.bridge0.configured) {
287 if (cfg.bridge0.macvlan == 0) { 281 if (cfg.bridge0.macvlan == 0) {
288 net_configure_veth_pair(&cfg.bridge0, "eth0", child); 282 net_configure_veth_pair(&cfg.bridge0, "eth0", child);
289 } 283 }
290 else 284 else
291 net_create_macvlan(cfg.bridge0.devsandbox, cfg.bridge0.dev, child); 285 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 6, PATH_FNET, "create", "macvlan", cfg.bridge0.devsandbox, cfg.bridge0.dev, cstr);
292 } 286 }
293 287
294 if (cfg.bridge1.configured) { 288 if (cfg.bridge1.configured) {
295 if (cfg.bridge1.macvlan == 0) 289 if (cfg.bridge1.macvlan == 0)
296 net_configure_veth_pair(&cfg.bridge1, "eth1", child); 290 net_configure_veth_pair(&cfg.bridge1, "eth1", child);
297 else 291 else
298 net_create_macvlan(cfg.bridge1.devsandbox, cfg.bridge1.dev, child); 292 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 6, PATH_FNET, "create", "macvlan", cfg.bridge1.devsandbox, cfg.bridge1.dev, cstr);
299 } 293 }
300 294
301 if (cfg.bridge2.configured) { 295 if (cfg.bridge2.configured) {
302 if (cfg.bridge2.macvlan == 0) 296 if (cfg.bridge2.macvlan == 0)
303 net_configure_veth_pair(&cfg.bridge2, "eth2", child); 297 net_configure_veth_pair(&cfg.bridge2, "eth2", child);
304 else 298 else
305 net_create_macvlan(cfg.bridge2.devsandbox, cfg.bridge2.dev, child); 299 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 6, PATH_FNET, "create", "macvlan", cfg.bridge2.devsandbox, cfg.bridge2.dev, cstr);
306 } 300 }
307 301
308 if (cfg.bridge3.configured) { 302 if (cfg.bridge3.configured) {
309 if (cfg.bridge3.macvlan == 0) 303 if (cfg.bridge3.macvlan == 0)
310 net_configure_veth_pair(&cfg.bridge3, "eth3", child); 304 net_configure_veth_pair(&cfg.bridge3, "eth3", child);
311 else 305 else
312 net_create_macvlan(cfg.bridge3.devsandbox, cfg.bridge3.dev, child); 306 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 6, PATH_FNET, "create", "macvlan", cfg.bridge3.devsandbox, cfg.bridge3.dev, cstr);
313 } 307 }
314 308
315 // move interfaces in sandbox 309 // move interfaces in sandbox
316 if (cfg.interface0.configured) { 310 if (cfg.interface0.configured) {
317 net_move_interface(cfg.interface0.dev, child); 311 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 4, PATH_FNET, "moveif", cfg.interface0.dev, cstr);
318 } 312 }
319 if (cfg.interface1.configured) { 313 if (cfg.interface1.configured) {
320 net_move_interface(cfg.interface1.dev, child); 314 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 4, PATH_FNET, "moveif", cfg.interface1.dev, cstr);
321 } 315 }
322 if (cfg.interface2.configured) { 316 if (cfg.interface2.configured) {
323 net_move_interface(cfg.interface2.dev, child); 317 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 4, PATH_FNET, "moveif", cfg.interface3.dev, cstr);
324 } 318 }
325 if (cfg.interface3.configured) { 319 if (cfg.interface3.configured) {
326 net_move_interface(cfg.interface3.dev, child); 320 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 4, PATH_FNET, "moveif", cfg.interface3.dev, cstr);
327 } 321 }
322
323 free(cstr);
328} 324}
diff --git a/src/firejail/no_sandbox.c b/src/firejail/no_sandbox.c
index a9242f035..aae490c34 100644
--- a/src/firejail/no_sandbox.c
+++ b/src/firejail/no_sandbox.c
@@ -23,6 +23,65 @@
23#include <unistd.h> 23#include <unistd.h>
24#include <grp.h> 24#include <grp.h>
25 25
26#define MAX_BUF 4096
27
28int is_container(const char *str) {
29 assert(str);
30 if (strcmp(str, "lxc") == 0 ||
31 strcmp(str, "docker") == 0 ||
32 strcmp(str, "lxc-libvirt") == 0 ||
33 strcmp(str, "systemd-nspawn") == 0 ||
34 strcmp(str, "rkt") == 0)
35 return 1;
36 return 0;
37}
38
39// returns 1 if we are running under LXC
40int check_namespace_virt(void) {
41 EUID_ASSERT();
42
43 // check container environment variable
44 char *str = getenv("container");
45 if (str && is_container(str))
46 return 1;
47
48 // check PID 1 container environment variable
49 EUID_ROOT();
50 FILE *fp = fopen("/proc/1/environ", "r");
51 if (fp) {
52 int c = 0;
53 while (c != EOF) {
54 // read one line
55 char buf[MAX_BUF];
56 int i = 0;
57 while ((c = fgetc(fp)) != EOF) {
58 if (c == 0)
59 break;
60 buf[i] = (char) c;
61 if (++i == (MAX_BUF - 1))
62 break;
63 }
64 buf[i] = '\0';
65
66 // check env var name
67 if (strncmp(buf, "container=", 10) == 0) {
68 // found it
69 if (is_container(buf + 10)) {
70 fclose(fp);
71 EUID_USER();
72 return 1;
73 }
74 }
75// printf("i %d c %d, buf #%s#\n", i, c, buf);
76 }
77
78 fclose(fp);
79 }
80
81 EUID_USER();
82 return 0;
83}
84
26// check process space for kernel processes 85// check process space for kernel processes
27// return 1 if found, 0 if not found 86// return 1 if found, 0 if not found
28int check_kernel_procs(void) { 87int check_kernel_procs(void) {
@@ -103,44 +162,130 @@ int check_kernel_procs(void) {
103void run_no_sandbox(int argc, char **argv) { 162void run_no_sandbox(int argc, char **argv) {
104 EUID_ASSERT(); 163 EUID_ASSERT();
105 164
106 // build command 165 // process limited subset of options
107 char *command = NULL; 166 int i;
108 int allocated = 0; 167 for (i = 0; i < argc; i++) {
109 if (argc == 1) 168 if (strcmp(argv[i], "--csh") == 0) {
110 command = "/bin/bash"; 169 if (arg_shell_none) {
111 else { 170 fprintf(stderr, "Error: --shell=none was already specified.\n");
112 // calculate length 171 exit(1);
113 int len = 0; 172 }
114 int i; 173 if (cfg.shell) {
115 for (i = 1; i < argc; i++) { 174 fprintf(stderr, "Error: only one default user shell can be specified\n");
116 if (*argv[i] == '-') 175 exit(1);
117 continue; 176 }
177 cfg.shell = "/bin/csh";
178 }
179 else if (strcmp(argv[i], "--zsh") == 0) {
180 if (arg_shell_none) {
181 fprintf(stderr, "Error: --shell=none was already specified.\n");
182 exit(1);
183 }
184 if (cfg.shell) {
185 fprintf(stderr, "Error: only one default user shell can be specified\n");
186 exit(1);
187 }
188 cfg.shell = "/bin/zsh";
189 }
190 else if (strcmp(argv[i], "--shell=none") == 0) {
191 arg_shell_none = 1;
192 if (cfg.shell) {
193 fprintf(stderr, "Error: a shell was already specified\n");
194 exit(1);
195 }
196 }
197 else if (strncmp(argv[i], "--shell=", 8) == 0) {
198 if (arg_shell_none) {
199 fprintf(stderr, "Error: --shell=none was already specified.\n");
200 exit(1);
201 }
202 invalid_filename(argv[i] + 8);
203
204 if (cfg.shell) {
205 fprintf(stderr, "Error: only one user shell can be specified\n");
206 exit(1);
207 }
208 cfg.shell = argv[i] + 8;
209
210 if (is_dir(cfg.shell) || strstr(cfg.shell, "..")) {
211 fprintf(stderr, "Error: invalid shell\n");
212 exit(1);
213 }
214
215 // access call checks as real UID/GID, not as effective UID/GID
216 if(cfg.chrootdir) {
217 char *shellpath;
218 if (asprintf(&shellpath, "%s%s", cfg.chrootdir, cfg.shell) == -1)
219 errExit("asprintf");
220 if (access(shellpath, R_OK)) {
221 fprintf(stderr, "Error: cannot access shell file in chroot\n");
222 exit(1);
223 }
224 free(shellpath);
225 } else if (access(cfg.shell, R_OK)) {
226 fprintf(stderr, "Error: cannot access shell file\n");
227 exit(1);
228 }
229 }
230 }
231
232 // use $SHELL to get shell used in sandbox
233 if (!arg_shell_none && !cfg.shell) {
234 char *shell = getenv("SHELL");
235 if (access(shell, R_OK) == 0)
236 cfg.shell = shell;
237 }
238 // guess shell otherwise
239 if (!arg_shell_none && !cfg.shell) {
240 cfg.shell = guess_shell();
241 if (arg_debug)
242 printf("Autoselecting %s as shell\n", cfg.shell);
243 }
244 if (!arg_shell_none && !cfg.shell) {
245 fprintf(stderr, "Error: unable to guess your shell, please set explicitly by using --shell option.\n");
246 exit(1);
247 }
248
249 int prog_index = 0;
250 // find first non option arg:
251 // - first argument not starting wiht --,
252 // - whatever follows after -c (example: firejail -c ls)
253 for (i = 1; i < argc; i++) {
254 if (strcmp(argv[i], "-c") == 0) {
255 prog_index = i + 1;
256 if (prog_index == argc) {
257 fprintf(stderr, "Error: option -c requires an argument\n");
258 exit(1);
259 }
118 break; 260 break;
119 } 261 }
120 int start_index = i; 262 // check first argument not starting with --
121 for (i = start_index; i < argc; i++) 263 if (strncmp(argv[i],"--",2) != 0) {
122 len += strlen(argv[i]) + 1; 264 prog_index = i;
123 265 break;
124 // allocate
125 command = malloc(len + 1);
126 if (!command)
127 errExit("malloc");
128 memset(command, 0, len + 1);
129 allocated = 1;
130
131 // copy
132 for (i = start_index; i < argc; i++) {
133 strcat(command, argv[i]);
134 strcat(command, " ");
135 } 266 }
136 } 267 }
137 268
138 // start the program in /bin/sh 269 if (!arg_shell_none) {
139 fprintf(stderr, "Warning: an existing sandbox was detected. " 270 if (prog_index == 0) {
140 "%s will run without any additional sandboxing features in a /bin/sh shell\n", command); 271 cfg.command_line = cfg.shell;
141 int rv = system(command); 272 cfg.window_title = cfg.shell;
142 (void) rv; 273 } else {
143 if (allocated) 274 build_cmdline(&cfg.command_line, &cfg.window_title, argc, argv, prog_index);
144 free(command); 275 }
145 exit(1); 276 }
277
278 cfg.original_argv = argv;
279 cfg.original_program_index = prog_index;
280
281 char *command;
282 if (prog_index == 0)
283 command = cfg.shell;
284 else
285 command = argv[prog_index];
286 if (!arg_quiet)
287 fprintf(stderr, "Warning: an existing sandbox was detected. "
288 "%s will run without any additional sandboxing features\n", command);
289
290 start_application();
146} 291}
diff --git a/src/firejail/output.c b/src/firejail/output.c
index 269ac25ea..91fe7f164 100644
--- a/src/firejail/output.c
+++ b/src/firejail/output.c
@@ -27,7 +27,6 @@ void check_output(int argc, char **argv) {
27 27
28 int i; 28 int i;
29 char *outfile = NULL; 29 char *outfile = NULL;
30// drop_privs(0);
31 30
32 int found = 0; 31 int found = 0;
33 for (i = 1; i < argc; i++) { 32 for (i = 1; i < argc; i++) {
@@ -91,6 +90,7 @@ void check_output(int argc, char **argv) {
91 sprintf(ptr, "2>&1 | %s/firejail/ftee %s", LIBDIR, outfile); 90 sprintf(ptr, "2>&1 | %s/firejail/ftee %s", LIBDIR, outfile);
92 91
93 // run command 92 // run command
93 drop_privs(0);
94 char *a[4]; 94 char *a[4];
95 a[0] = "/bin/bash"; 95 a[0] = "/bin/bash";
96 a[1] = "-c"; 96 a[1] = "-c";
diff --git a/src/firejail/preproc.c b/src/firejail/preproc.c
new file mode 100644
index 000000000..ea4e6743f
--- /dev/null
+++ b/src/firejail/preproc.c
@@ -0,0 +1,125 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "firejail.h"
21#include <sys/mount.h>
22#include <sys/stat.h>
23
24static int tmpfs_mounted = 0;
25
26// build /run/firejail directory
27void preproc_build_firejail_dir(void) {
28 struct stat s;
29
30 // CentOS 6 doesn't have /run directory
31 if (stat(RUN_FIREJAIL_BASEDIR, &s)) {
32 create_empty_dir_as_root(RUN_FIREJAIL_BASEDIR, 0755);
33 }
34
35 if (stat(RUN_FIREJAIL_DIR, &s)) {
36 create_empty_dir_as_root(RUN_FIREJAIL_DIR, 0755);
37 }
38
39 if (stat(RUN_FIREJAIL_NETWORK_DIR, &s)) {
40 create_empty_dir_as_root(RUN_FIREJAIL_NETWORK_DIR, 0755);
41 }
42
43 if (stat(RUN_FIREJAIL_BANDWIDTH_DIR, &s)) {
44 create_empty_dir_as_root(RUN_FIREJAIL_BANDWIDTH_DIR, 0755);
45 }
46
47 if (stat(RUN_FIREJAIL_NAME_DIR, &s)) {
48 create_empty_dir_as_root(RUN_FIREJAIL_NAME_DIR, 0755);
49 }
50
51 if (stat(RUN_FIREJAIL_X11_DIR, &s)) {
52 create_empty_dir_as_root(RUN_FIREJAIL_X11_DIR, 0755);
53 }
54
55 if (stat(RUN_FIREJAIL_APPIMAGE_DIR, &s)) {
56 create_empty_dir_as_root(RUN_FIREJAIL_APPIMAGE_DIR, 0755);
57 }
58
59 if (stat(RUN_MNT_DIR, &s)) {
60 create_empty_dir_as_root(RUN_MNT_DIR, 0755);
61 }
62
63 create_empty_file_as_root(RUN_RO_FILE, S_IRUSR);
64 create_empty_dir_as_root(RUN_RO_DIR, S_IRUSR);
65}
66
67// build /run/firejail/mnt directory
68void preproc_mount_mnt_dir(void) {
69 // mount tmpfs on top of /run/firejail/mnt
70 if (!tmpfs_mounted) {
71 if (arg_debug)
72 printf("Mounting tmpfs on %s directory\n", RUN_MNT_DIR);
73 if (mount("tmpfs", RUN_MNT_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
74 errExit("mounting /run/firejail/mnt");
75 tmpfs_mounted = 1;
76 fs_logger2("tmpfs", RUN_MNT_DIR);
77
78 // create all seccomp files
79 // as root, create RUN_SECCOMP_I386 file
80 create_empty_file_as_root(RUN_SECCOMP_I386, 0644);
81 if (set_perms(RUN_SECCOMP_I386, getuid(), getgid(), 0644))
82 errExit("set_perms");
83
84 // as root, create RUN_SECCOMP_AMD64 file
85 create_empty_file_as_root(RUN_SECCOMP_AMD64, 0644);
86 if (set_perms(RUN_SECCOMP_AMD64, getuid(), getgid(), 0644))
87 errExit("set_perms");
88
89 // as root, create RUN_SECCOMP file
90 create_empty_file_as_root(RUN_SECCOMP_CFG, 0644);
91 if (set_perms(RUN_SECCOMP_CFG, getuid(), getgid(), 0644))
92 errExit("set_perms");
93
94 // as root, create RUN_SECCOMP_PROTOCOL file
95 create_empty_file_as_root(RUN_SECCOMP_PROTOCOL, 0644);
96 if (set_perms(RUN_SECCOMP_PROTOCOL, getuid(), getgid(), 0644))
97 errExit("set_perms");
98 }
99}
100
101// grab a copy of cp command
102void preproc_build_cp_command(void) {
103 struct stat s;
104 preproc_mount_mnt_dir();
105 if (stat(RUN_CP_COMMAND, &s)) {
106 char* fname = realpath("/bin/cp", NULL);
107 if (fname == NULL || stat(fname, &s) || is_link(fname)) {
108 fprintf(stderr, "Error: invalid /bin/cp\n");
109 exit(1);
110 }
111 int rv = copy_file(fname, RUN_CP_COMMAND, 0, 0, 0755);
112 if (rv) {
113 fprintf(stderr, "Error: cannot access /bin/cp\n");
114 exit(1);
115 }
116 ASSERT_PERMS(RUN_CP_COMMAND, 0, 0, 0755);
117
118 free(fname);
119 }
120}
121
122// delete the temporary cp command
123void preproc_delete_cp_command(void) {
124 unlink(RUN_CP_COMMAND);
125}
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 6ded0ca2f..0fd45d1ef 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -105,7 +105,12 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
105 // mkdir 105 // mkdir
106 if (strncmp(ptr, "mkdir ", 6) == 0) { 106 if (strncmp(ptr, "mkdir ", 6) == 0) {
107 fs_mkdir(ptr + 6); 107 fs_mkdir(ptr + 6);
108 return 0; 108 return 1; // process mkdir again while applying blacklists
109 }
110 // mkfile
111 if (strncmp(ptr, "mkfile ", 7) == 0) {
112 fs_mkfile(ptr + 7);
113 return 1; // process mkfile again while applying blacklists
109 } 114 }
110 // sandbox name 115 // sandbox name
111 else if (strncmp(ptr, "name ", 5) == 0) { 116 else if (strncmp(ptr, "name ", 5) == 0) {
@@ -131,6 +136,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
131 136
132 return 0; 137 return 0;
133 } 138 }
139 else if (strcmp(ptr, "nonewprivs") == 0) {
140 arg_nonewprivs = 1;
141 return 0;
142 }
134 else if (strcmp(ptr, "seccomp") == 0) { 143 else if (strcmp(ptr, "seccomp") == 0) {
135#ifdef HAVE_SECCOMP 144#ifdef HAVE_SECCOMP
136 if (checkcfg(CFG_SECCOMP)) 145 if (checkcfg(CFG_SECCOMP))
@@ -160,6 +169,22 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
160 arg_private = 1; 169 arg_private = 1;
161 return 0; 170 return 0;
162 } 171 }
172 if (strncmp(ptr, "private-home ", 13) == 0) {
173#ifdef HAVE_PRIVATE_HOME
174 if (checkcfg(CFG_PRIVATE_HOME)) {
175 cfg.home_private_keep = ptr + 13;
176 fs_check_home_list();
177 arg_private = 1;
178 }
179 else
180 fprintf(stderr, "Warning: private-home is disabled in Firejail configuration file\n");
181#endif
182 return 0;
183 }
184 else if (strcmp(ptr, "allusers") == 0) {
185 arg_allusers = 1;
186 return 0;
187 }
163 else if (strcmp(ptr, "private-dev") == 0) { 188 else if (strcmp(ptr, "private-dev") == 0) {
164 arg_private_dev = 1; 189 arg_private_dev = 1;
165 return 0; 190 return 0;
@@ -174,7 +199,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
174 } 199 }
175 else if (strcmp(ptr, "nosound") == 0) { 200 else if (strcmp(ptr, "nosound") == 0) {
176 arg_nosound = 1; 201 arg_nosound = 1;
177 arg_private_dev = 1; 202 return 0;
203 }
204 else if (strcmp(ptr, "no3d") == 0) {
205 arg_no3d = 1;
178 return 0; 206 return 0;
179 } 207 }
180 else if (strcmp(ptr, "netfilter") == 0) { 208 else if (strcmp(ptr, "netfilter") == 0) {
@@ -274,6 +302,29 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
274 return 0; 302 return 0;
275 } 303 }
276 304
305 else if (strncmp(ptr, "veth-name ", 10) == 0) {
306#ifdef HAVE_NETWORK
307 if (checkcfg(CFG_NETWORK)) {
308 Bridge *br = last_bridge_configured();
309 if (br == NULL) {
310 fprintf(stderr, "Error: no network device configured\n");
311 exit(1);
312 }
313
314 br->veth_name = strdup(ptr + 10);
315 if (br->veth_name == NULL)
316 errExit("strdup");
317 if (*br->veth_name == '\0') {
318 fprintf(stderr, "Error: no veth-name configured\n");
319 exit(1);
320 }
321 }
322 else
323 fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n");
324#endif
325 return 0;
326 }
327
277 else if (strncmp(ptr, "iprange ", 8) == 0) { 328 else if (strncmp(ptr, "iprange ", 8) == 0) {
278#ifdef HAVE_NETWORK 329#ifdef HAVE_NETWORK
279 if (checkcfg(CFG_NETWORK)) { 330 if (checkcfg(CFG_NETWORK)) {
@@ -319,11 +370,145 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
319 return 0; 370 return 0;
320 } 371 }
321 372
322 373
374 else if (strncmp(ptr, "mac ", 4) == 0) {
375#ifdef HAVE_NETWORK
376 if (checkcfg(CFG_NETWORK)) {
377 Bridge *br = last_bridge_configured();
378 if (br == NULL) {
379 fprintf(stderr, "Error: no network device configured\n");
380 exit(1);
381 }
382
383 if (mac_not_zero(br->macsandbox)) {
384 fprintf(stderr, "Error: cannot configure the MAC address twice for the same interface\n");
385 exit(1);
386 }
387
388 // read the address
389 if (atomac(ptr + 4, br->macsandbox)) {
390 fprintf(stderr, "Error: invalid MAC address\n");
391 exit(1);
392 }
393 }
394 else
395 fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n");
396#endif
397 return 0;
398 }
399
400 else if (strncmp(ptr, "mtu ", 4) == 0) {
401#ifdef HAVE_NETWORK
402 if (checkcfg(CFG_NETWORK)) {
403 Bridge *br = last_bridge_configured();
404 if (br == NULL) {
405 fprintf(stderr, "Error: no network device configured\n");
406 exit(1);
407 }
408
409 if (sscanf(ptr + 4, "%d", &br->mtu) != 1 || br->mtu < 576 || br->mtu > 9198) {
410 fprintf(stderr, "Error: invalid mtu value\n");
411 exit(1);
412 }
413 }
414 else
415 fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n");
416#endif
417 return 0;
418 }
419
420 else if (strncmp(ptr, "ip ", 3) == 0) {
421#ifdef HAVE_NETWORK
422 if (checkcfg(CFG_NETWORK)) {
423 Bridge *br = last_bridge_configured();
424 if (br == NULL) {
425 fprintf(stderr, "Error: no network device configured\n");
426 exit(1);
427 }
428 if (br->arg_ip_none || br->ipsandbox) {
429 fprintf(stderr, "Error: cannot configure the IP address twice for the same interface\n");
430 exit(1);
431 }
432
433 // configure this IP address for the last bridge defined
434 if (strcmp(ptr + 3, "none") == 0)
435 br->arg_ip_none = 1;
436 else {
437 if (atoip(ptr + 3, &br->ipsandbox)) {
438 fprintf(stderr, "Error: invalid IP address\n");
439 exit(1);
440 }
441 }
442 }
443 else
444 fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n");
445#endif
446 return 0;
447 }
448
449 else if (strncmp(ptr, "ip6 ", 4) == 0) {
450#ifdef HAVE_NETWORK
451 if (checkcfg(CFG_NETWORK)) {
452 Bridge *br = last_bridge_configured();
453 if (br == NULL) {
454 fprintf(stderr, "Error: no network device configured\n");
455 exit(1);
456 }
457 if (br->arg_ip_none || br->ip6sandbox) {
458 fprintf(stderr, "Error: cannot configure the IP address twice for the same interface\n");
459 exit(1);
460 }
461
462 // configure this IP address for the last bridge defined
463 // todo: verify ipv6 syntax
464 br->ip6sandbox = ptr + 4;
465// if (atoip(argv[i] + 5, &br->ipsandbox)) {
466// fprintf(stderr, "Error: invalid IP address\n");
467// exit(1);
468// }
469
470 }
471 else
472 fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n");
473#endif
474 return 0;
475 }
476
477 else if (strncmp(ptr, "defaultgw ", 10) == 0) {
478#ifdef HAVE_NETWORK
479 if (checkcfg(CFG_NETWORK)) {
480 if (atoip(ptr + 10, &cfg.defaultgw)) {
481 fprintf(stderr, "Error: invalid IP address\n");
482 exit(1);
483 }
484 }
485 else
486 fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n");
487#endif
488 return 0;
489 }
490
491 if (strcmp(ptr, "apparmor") == 0) {
492#ifdef HAVE_APPARMOR
493 arg_apparmor = 1;
494#endif
495 return 0;
496 }
497
323 if (strncmp(ptr, "protocol ", 9) == 0) { 498 if (strncmp(ptr, "protocol ", 9) == 0) {
324#ifdef HAVE_SECCOMP 499#ifdef HAVE_SECCOMP
325 if (checkcfg(CFG_SECCOMP)) 500 if (checkcfg(CFG_SECCOMP)) {
326 protocol_store(ptr + 9); 501 if (cfg.protocol) {
502 if (!arg_quiet)
503 fprintf(stderr, "Warning: a protocol list is present, the new list \"%s\" will not be installed\n", ptr + 9);
504 return 0;
505 }
506
507 // store list
508 cfg.protocol = strdup(ptr + 9);
509 if (!cfg.protocol)
510 errExit("strdup");
511 }
327 else 512 else
328 fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); 513 fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n");
329#endif 514#endif
@@ -331,7 +516,11 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
331 } 516 }
332 517
333 if (strncmp(ptr, "env ", 4) == 0) { 518 if (strncmp(ptr, "env ", 4) == 0) {
334 env_store(ptr + 4); 519 env_store(ptr + 4, SETENV);
520 return 0;
521 }
522 if (strncmp(ptr, "rmenv ", 6) == 0) {
523 env_store(ptr + 6, RMENV);
335 return 0; 524 return 0;
336 } 525 }
337 526
@@ -340,9 +529,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
340#ifdef HAVE_SECCOMP 529#ifdef HAVE_SECCOMP
341 if (checkcfg(CFG_SECCOMP)) { 530 if (checkcfg(CFG_SECCOMP)) {
342 arg_seccomp = 1; 531 arg_seccomp = 1;
343 cfg.seccomp_list = strdup(ptr + 8); 532 cfg.seccomp_list = seccomp_check_list(ptr + 8);
344 if (!cfg.seccomp_list)
345 errExit("strdup");
346 } 533 }
347 else 534 else
348 fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); 535 fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n");
@@ -356,9 +543,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
356#ifdef HAVE_SECCOMP 543#ifdef HAVE_SECCOMP
357 if (checkcfg(CFG_SECCOMP)) { 544 if (checkcfg(CFG_SECCOMP)) {
358 arg_seccomp = 1; 545 arg_seccomp = 1;
359 cfg.seccomp_list_drop = strdup(ptr + 13); 546 cfg.seccomp_list_drop = seccomp_check_list(ptr + 13);
360 if (!cfg.seccomp_list_drop)
361 errExit("strdup");
362 } 547 }
363 else 548 else
364 fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); 549 fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n");
@@ -371,9 +556,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
371#ifdef HAVE_SECCOMP 556#ifdef HAVE_SECCOMP
372 if (checkcfg(CFG_SECCOMP)) { 557 if (checkcfg(CFG_SECCOMP)) {
373 arg_seccomp = 1; 558 arg_seccomp = 1;
374 cfg.seccomp_list_keep= strdup(ptr + 13); 559 cfg.seccomp_list_keep= seccomp_check_list(ptr + 13);
375 if (!cfg.seccomp_list_keep)
376 errExit("strdup");
377 } 560 }
378 else 561 else
379 fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); 562 fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n");
@@ -387,7 +570,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
387 arg_caps_list = strdup(ptr + 10); 570 arg_caps_list = strdup(ptr + 10);
388 if (!arg_caps_list) 571 if (!arg_caps_list)
389 errExit("strdup"); 572 errExit("strdup");
390 // verify seccomp list and exit if problems 573 // verify caps list and exit if problems
391 if (caps_check_list(arg_caps_list, NULL)) 574 if (caps_check_list(arg_caps_list, NULL))
392 exit(1); 575 exit(1);
393 return 0; 576 return 0;
@@ -399,7 +582,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
399 arg_caps_list = strdup(ptr + 10); 582 arg_caps_list = strdup(ptr + 10);
400 if (!arg_caps_list) 583 if (!arg_caps_list)
401 errExit("strdup"); 584 errExit("strdup");
402 // verify seccomp list and exit if problems 585 // verify caps list and exit if problems
403 if (caps_check_list(arg_caps_list, NULL)) 586 if (caps_check_list(arg_caps_list, NULL))
404 exit(1); 587 exit(1);
405 return 0; 588 return 0;
@@ -441,6 +624,8 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
441 // nice value 624 // nice value
442 if (strncmp(ptr, "nice ", 4) == 0) { 625 if (strncmp(ptr, "nice ", 4) == 0) {
443 cfg.nice = atoi(ptr + 5); 626 cfg.nice = atoi(ptr + 5);
627 if (getuid() != 0 &&cfg.nice < 0)
628 cfg.nice = 0;
444 arg_nice = 1; 629 arg_nice = 1;
445 return 0; 630 return 0;
446 } 631 }
@@ -451,6 +636,22 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
451 return 0; 636 return 0;
452 } 637 }
453 638
639 // writable-etc
640 if (strcmp(ptr, "writable-etc") == 0) {
641 if (cfg.etc_private_keep) {
642 fprintf(stderr, "Error: private-etc and writable-etc are mutually exclusive\n");
643 exit(1);
644 }
645 arg_writable_etc = 1;
646 return 0;
647 }
648
649 // writable-var
650 if (strcmp(ptr, "writable-var") == 0) {
651 arg_writable_var = 1;
652 return 0;
653 }
654
454 // private directory 655 // private directory
455 if (strncmp(ptr, "private ", 8) == 0) { 656 if (strncmp(ptr, "private ", 8) == 0) {
456 cfg.home_private = ptr + 8; 657 cfg.home_private = ptr + 8;
@@ -459,16 +660,85 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
459 return 0; 660 return 0;
460 } 661 }
461 662
663 if (strcmp(ptr, "x11 none") == 0) {
664 arg_x11_block = 1;
665 return 0;
666 }
667
668 if (strcmp(ptr, "x11 xephyr") == 0) {
669#ifdef HAVE_X11
670 if (checkcfg(CFG_X11)) {
671 char *x11env = getenv("FIREJAIL_X11");
672 if (x11env && strcmp(x11env, "yes") == 0) {
673 mask_x11_abstract_socket = 1;
674 return 0;
675 }
676 else {
677 // start x11
678 x11_start_xephyr(cfg.original_argc, cfg.original_argv);
679 exit(0);
680 }
681 }
682#endif
683 return 0;
684 }
685
686 if (strcmp(ptr, "x11 xorg") == 0) {
687#ifdef HAVE_X11
688 if (checkcfg(CFG_X11))
689 arg_x11_xorg = 1;
690 else {
691 fprintf(stderr, "Error: --x11 feature is disabled in Firejail configuration file\n");
692 return 0;
693 }
694#endif
695 return 0;
696 }
697 if (strcmp(ptr, "x11 xpra") == 0) {
698#ifdef HAVE_X11
699 if (checkcfg(CFG_X11)) {
700 char *x11env = getenv("FIREJAIL_X11");
701 if (x11env && strcmp(x11env, "yes") == 0) {
702 mask_x11_abstract_socket = 1;
703 return 0;
704 }
705 else {
706 // start x11
707 x11_start_xpra(cfg.original_argc, cfg.original_argv);
708 exit(0);
709 }
710 }
711#endif
712 return 0;
713 }
714
715 if (strcmp(ptr, "x11") == 0) {
716#ifdef HAVE_X11
717 if (checkcfg(CFG_X11)) {
718 char *x11env = getenv("FIREJAIL_X11");
719 if (x11env && strcmp(x11env, "yes") == 0) {
720 mask_x11_abstract_socket = 1;
721 return 0;
722 }
723 else {
724 // start x11
725 x11_start(cfg.original_argc, cfg.original_argv);
726 exit(0);
727 }
728 }
729#endif
730 return 0;
731 }
732
462 // private /etc list of files and directories 733 // private /etc list of files and directories
463 if (strncmp(ptr, "private-etc ", 12) == 0) { 734 if (strncmp(ptr, "private-etc ", 12) == 0) {
735 if (arg_writable_etc) {
736 fprintf(stderr, "Error: --private-etc and --writable-etc are mutually exclusive\n");
737 exit(1);
738 }
464 cfg.etc_private_keep = ptr + 12; 739 cfg.etc_private_keep = ptr + 12;
465 fs_check_etc_list(); 740 fs_check_etc_list();
466 if (*cfg.etc_private_keep != '\0') 741 arg_private_etc = 1;
467 arg_private_etc = 1;
468 else {
469 arg_private_etc = 0;
470 fprintf(stderr, "Warning: private-etc disabled, no file found\n");
471 }
472 742
473 return 0; 743 return 0;
474 } 744 }
@@ -569,6 +839,30 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
569 return 0; 839 return 0;
570 } 840 }
571 841
842 if (strncmp(ptr, "join-or-start ", 14) == 0) {
843 // try to join by name only
844 pid_t pid;
845 if (!name2pid(ptr + 14, &pid)) {
846 if (!cfg.shell && !arg_shell_none)
847 cfg.shell = guess_shell();
848
849 // find first non-option arg
850 int i;
851 for (i = 1; i < cfg.original_argc && strncmp(cfg.original_argv[i], "--", 2) != 0; i++);
852
853 join(pid, cfg.original_argc,cfg.original_argv, i + 1);
854 exit(0);
855 }
856
857 // set sandbox name and start normally
858 cfg.name = ptr + 14;
859 if (strlen(cfg.name) == 0) {
860 fprintf(stderr, "Error: invalid sandbox name\n");
861 exit(1);
862 }
863 return 0;
864 }
865
572 // rest of filesystem 866 // rest of filesystem
573 if (strncmp(ptr, "blacklist ", 10) == 0) 867 if (strncmp(ptr, "blacklist ", 10) == 0)
574 ptr += 10; 868 ptr += 10;
@@ -577,11 +871,23 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
577 else if (strncmp(ptr, "noblacklist ", 12) == 0) 871 else if (strncmp(ptr, "noblacklist ", 12) == 0)
578 ptr += 12; 872 ptr += 12;
579 else if (strncmp(ptr, "whitelist ", 10) == 0) { 873 else if (strncmp(ptr, "whitelist ", 10) == 0) {
580 arg_whitelist = 1; 874#ifdef HAVE_WHITELIST
581 ptr += 10; 875 if (checkcfg(CFG_WHITELIST)) {
876 arg_whitelist = 1;
877 ptr += 10;
878 }
879 else
880 return 0;
881#else
882 return 0;
883#endif
582 } 884 }
583 else if (strncmp(ptr, "read-only ", 10) == 0) 885 else if (strncmp(ptr, "read-only ", 10) == 0)
584 ptr += 10; 886 ptr += 10;
887 else if (strncmp(ptr, "read-write ", 11) == 0)
888 ptr += 11;
889 else if (strncmp(ptr, "noexec ", 7) == 0)
890 ptr += 7;
585 else if (strncmp(ptr, "tmpfs ", 6) == 0) { 891 else if (strncmp(ptr, "tmpfs ", 6) == 0) {
586 if (getuid() != 0) { 892 if (getuid() != 0) {
587 fprintf(stderr, "Error: tmpfs available only when running the sandbox as root\n"); 893 fprintf(stderr, "Error: tmpfs available only when running the sandbox as root\n");
@@ -651,6 +957,16 @@ void profile_read(const char *fname) {
651 exit(1); 957 exit(1);
652 } 958 }
653 959
960 // allow debuggers
961 if (arg_allow_debuggers) {
962 char *tmp = strrchr(fname, '/');
963 if (tmp && *(tmp + 1) != '\0') {
964 tmp++;
965 if (strcmp(tmp, "disable-devel.inc") == 0)
966 return;
967 }
968 }
969
654 // open profile file: 970 // open profile file:
655 FILE *fp = fopen(fname, "r"); 971 FILE *fp = fopen(fname, "r");
656 if (fp == NULL) { 972 if (fp == NULL) {
@@ -658,8 +974,7 @@ void profile_read(const char *fname) {
658 exit(1); 974 exit(1);
659 } 975 }
660 976
661 if (!arg_quiet) 977 int msg_printed = 0;
662 fprintf(stderr, "Reading profile %s\n", fname);
663 978
664 // read the file line by line 979 // read the file line by line
665 char buf[MAX_READ + 1]; 980 char buf[MAX_READ + 1];
@@ -677,6 +992,17 @@ void profile_read(const char *fname) {
677 continue; 992 continue;
678 } 993 }
679 994
995 // process quiet
996 if (strcmp(ptr, "quiet") == 0) {
997 arg_quiet = 1;
998 continue;
999 }
1000 if (!msg_printed) {
1001 if (!arg_quiet)
1002 fprintf(stderr, "Reading profile %s\n", fname);
1003 msg_printed = 1;
1004 }
1005
680 // process include 1006 // process include
681 if (strncmp(ptr, "include ", 8) == 0) { 1007 if (strncmp(ptr, "include ", 8) == 0) {
682 include_level++; 1008 include_level++;
diff --git a/src/firejail/protocol.c b/src/firejail/protocol.c
index 7e5ab7dfb..2a09ed010 100644
--- a/src/firejail/protocol.c
+++ b/src/firejail/protocol.c
@@ -18,269 +18,18 @@
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/ 19*/
20 20
21/*
22 struct sock_filter filter[] = {
23 VALIDATE_ARCHITECTURE,
24 EXAMINE_SYSCALL,
25 ONLY(SYS_socket),
26 EXAMINE_ARGUMENT(0), // allow only AF_INET and AF_INET6, drop everything else
27 WHITELIST(AF_INET),
28 WHITELIST(AF_INET6),
29 WHITELIST(AF_PACKET),
30 RETURN_ERRNO(ENOTSUP)
31 };
32 struct sock_fprog prog = {
33 .len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
34 .filter = filter,
35 };
36
37
38 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
39 perror("prctl(NO_NEW_PRIVS)");
40 return 1;
41 }
42 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
43 perror("prctl");
44 return 1;
45 }
46*/
47
48#ifdef HAVE_SECCOMP 21#ifdef HAVE_SECCOMP
49#include "firejail.h" 22#include "firejail.h"
50#include "seccomp.h" 23#include "../include/seccomp.h"
51#include <sys/types.h>
52#include <sys/socket.h>
53
54static char *protocol[] = {
55 "unix",
56 "inet",
57 "inet6",
58 "netlink",
59 "packet",
60 NULL
61};
62
63static struct sock_filter protocol_filter_command[] = {
64 WHITELIST(AF_UNIX),
65 WHITELIST(AF_INET),
66 WHITELIST(AF_INET6),
67 WHITELIST(AF_NETLINK),
68 WHITELIST(AF_PACKET)
69};
70// Note: protocol[] and protocol_filter_command are synchronized
71
72// command length
73struct sock_filter whitelist[] = {
74 WHITELIST(AF_UNIX)
75};
76unsigned whitelist_len = sizeof(whitelist) / sizeof(struct sock_filter);
77
78
79
80static int is_protocol(const char *p) {
81 int i = 0;
82 while (protocol[i] != NULL) {
83 if (strcmp(protocol[i], p) == 0)
84 return 1;
85 i++;
86 }
87
88 return 0;
89}
90
91static struct sock_filter *find_protocol_domain(const char *p) {
92 int i = 0;
93 while (protocol[i] != NULL) {
94 if (strcmp(protocol[i], p) == 0)
95 return &protocol_filter_command[i * whitelist_len];
96 i++;
97 }
98
99 return NULL;
100}
101
102// --debug-protocols
103void protocol_list(void) {
104 EUID_ASSERT();
105
106#ifndef SYS_socket
107 fprintf(stderr, "Warning: --protocol not supported on this platform\n");
108 return;
109#endif
110
111 int i = 0;
112 while (protocol[i] != NULL) {
113 printf("%s, ", protocol[i]);
114 i++;
115 }
116 printf("\n");
117}
118
119
120// check protocol list and store it in cfg structure
121void protocol_store(const char *prlist) {
122 EUID_ASSERT();
123 assert(prlist);
124
125 if (cfg.protocol && !arg_quiet) {
126 fprintf(stderr, "Warning: a protocol list is present, the new list \"%s\" will not be installed\n", prlist);
127 return;
128 }
129
130 // temporary list
131 char *tmplist = strdup(prlist);
132 if (!tmplist)
133 errExit("strdup");
134
135 // check list
136 char *token = strtok(tmplist, ",");
137 if (!token)
138 goto errout;
139
140 while (token) {
141 if (!is_protocol(token))
142 goto errout;
143 token = strtok(NULL, ",");
144 }
145 free(tmplist);
146
147 // store list
148 cfg.protocol = strdup(prlist);
149 if (!cfg.protocol)
150 errExit("strdup");
151 return;
152
153errout:
154 fprintf(stderr, "Error: invalid protocol list\n");
155 exit(1);
156}
157
158// install protocol filter
159void protocol_filter(void) {
160 assert(cfg.protocol);
161 if (arg_debug)
162 printf("Set protocol filter: %s\n", cfg.protocol);
163
164#ifndef SYS_socket
165 (void) find_protocol_domain;
166 fprintf(stderr, "Warning: --protocol not supported on this platform\n");
167 return;
168#else
169 // build the filter
170 struct sock_filter filter[32]; // big enough
171 memset(&filter[0], 0, sizeof(filter));
172 uint8_t *ptr = (uint8_t *) &filter[0];
173
174 // header
175 struct sock_filter filter_start[] = {
176 VALIDATE_ARCHITECTURE,
177 EXAMINE_SYSCALL,
178 ONLY(SYS_socket),
179 EXAMINE_ARGUMENT(0)
180 };
181 memcpy(ptr, &filter_start[0], sizeof(filter_start));
182 ptr += sizeof(filter_start);
183
184#if 0
185printf("entries %u\n", (unsigned) (sizeof(filter_start) / sizeof(struct sock_filter)));
186{
187 unsigned j;
188 unsigned char *ptr2 = (unsigned char *) &filter[0];
189 for (j = 0; j < sizeof(filter); j++, ptr2++) {
190 if ((j % (sizeof(struct sock_filter))) == 0)
191 printf("\n%u: ", 1 + (unsigned) (j / (sizeof(struct sock_filter))));
192 printf("%02x, ", (*ptr2) & 0xff);
193 }
194 printf("\n");
195}
196printf("whitelist_len %u, struct sock_filter len %u\n", whitelist_len, (unsigned) sizeof(struct sock_filter));
197#endif
198
199
200 // parse list and add commands
201 char *tmplist = strdup(cfg.protocol);
202 if (!tmplist)
203 errExit("strdup");
204 char *token = strtok(tmplist, ",");
205 if (!token)
206 errExit("strtok");
207
208 while (token) {
209 struct sock_filter *domain = find_protocol_domain(token);
210 assert(domain);
211 memcpy(ptr, domain, whitelist_len * sizeof(struct sock_filter));
212 ptr += whitelist_len * sizeof(struct sock_filter);
213 token = strtok(NULL, ",");
214
215#if 0
216printf("entries %u\n", (unsigned) ((uint64_t) ptr - (uint64_t) (filter)) / (unsigned) sizeof(struct sock_filter));
217{
218 unsigned j;
219 unsigned char *ptr2 = (unsigned char *) &filter[0];
220 for (j = 0; j < sizeof(filter); j++, ptr2++) {
221 if ((j % (sizeof(struct sock_filter))) == 0)
222 printf("\n%u: ", 1 + (unsigned) (j / (sizeof(struct sock_filter))));
223 printf("%02x, ", (*ptr2) & 0xff);
224 }
225 printf("\n");
226}
227#endif
228
229
230 }
231 free(tmplist);
232
233 // add end of filter
234 struct sock_filter filter_end[] = {
235 RETURN_ERRNO(ENOTSUP)
236 };
237 memcpy(ptr, &filter_end[0], sizeof(filter_end));
238 ptr += sizeof(filter_end);
239
240#if 0
241printf("entries %u\n", (unsigned) ((uint64_t) ptr - (uint64_t) (filter)) / (unsigned) sizeof(struct sock_filter));
242{
243 unsigned j;
244 unsigned char *ptr2 = (unsigned char *) &filter[0];
245 for (j = 0; j < sizeof(filter); j++, ptr2++) {
246 if ((j % (sizeof(struct sock_filter))) == 0)
247 printf("\n%u: ", 1 + (unsigned) (j / (sizeof(struct sock_filter))));
248 printf("%02x, ", (*ptr2) & 0xff);
249 }
250 printf("\n");
251}
252#endif
253
254 // install filter
255 unsigned short entries = (unsigned short) ((uintptr_t) ptr - (uintptr_t) (filter)) / (unsigned) sizeof(struct sock_filter);
256 struct sock_fprog prog = {
257 .len = entries,
258 .filter = filter,
259 };
260
261 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
262 fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n");
263 return;
264 }
265#endif // SYS_socket
266}
267 24
268void protocol_filter_save(void) { 25void protocol_filter_save(void) {
269 // save protocol filter configuration in PROTOCOL_CFG 26 // save protocol filter configuration in PROTOCOL_CFG
270 fs_build_mnt_dir();
271
272 FILE *fp = fopen(RUN_PROTOCOL_CFG, "w"); 27 FILE *fp = fopen(RUN_PROTOCOL_CFG, "w");
273 if (!fp) 28 if (!fp)
274 errExit("fopen"); 29 errExit("fopen");
275 fprintf(fp, "%s\n", cfg.protocol); 30 fprintf(fp, "%s\n", cfg.protocol);
31 SET_PERMS_STREAM(fp, 0, 0, 0600);
276 fclose(fp); 32 fclose(fp);
277
278 if (chmod(RUN_PROTOCOL_CFG, 0600) < 0)
279 errExit("chmod");
280
281 if (chown(RUN_PROTOCOL_CFG, 0, 0) < 0)
282 errExit("chown");
283
284} 33}
285 34
286void protocol_filter_load(const char *fname) { 35void protocol_filter_load(const char *fname) {
@@ -310,29 +59,6 @@ void protocol_filter_load(const char *fname) {
310 59
311 60
312// --protocol.print 61// --protocol.print
313void protocol_print_filter_name(const char *name) {
314 EUID_ASSERT();
315
316 (void) name;
317#ifdef SYS_socket
318 if (!name || strlen(name) == 0) {
319 fprintf(stderr, "Error: invalid sandbox name\n");
320 exit(1);
321 }
322 pid_t pid;
323 if (name2pid(name, &pid)) {
324 fprintf(stderr, "Error: cannot find sandbox %s\n", name);
325 exit(1);
326 }
327
328 protocol_print_filter(pid);
329#else
330 fprintf(stderr, "Warning: --protocol not supported on this platform\n");
331 return;
332#endif
333}
334
335// --protocol.print
336void protocol_print_filter(pid_t pid) { 62void protocol_print_filter(pid_t pid) {
337 EUID_ASSERT(); 63 EUID_ASSERT();
338 64
diff --git a/src/firejail/pulseaudio.c b/src/firejail/pulseaudio.c
index 1eb5e59e1..6ec590eaa 100644
--- a/src/firejail/pulseaudio.c
+++ b/src/firejail/pulseaudio.c
@@ -53,16 +53,32 @@ doexit:
53 53
54// disable pulseaudio socket 54// disable pulseaudio socket
55void pulseaudio_disable(void) { 55void pulseaudio_disable(void) {
56 if (arg_debug)
57 printf("disable pulseaudio\n");
56 // blacklist user config directory 58 // blacklist user config directory
57 disable_file(cfg.homedir, ".config/pulse"); 59 disable_file(cfg.homedir, ".config/pulse");
58 60
61
62 // blacklist pulseaudio socket in XDG_RUNTIME_DIR
63 char *name = getenv("XDG_RUNTIME_DIR");
64 if (name)
65 disable_file(name, "pulse/native");
66
67 // try the default location anyway
68 char *path;
69 if (asprintf(&path, "/run/user/%d", getuid()) == -1)
70 errExit("asprintf");
71 disable_file(path, "pulse/native");
72 free(path);
73
74
75
59 // blacklist any pulse* file in /tmp directory 76 // blacklist any pulse* file in /tmp directory
60 DIR *dir; 77 DIR *dir;
61 if (!(dir = opendir("/tmp"))) { 78 if (!(dir = opendir("/tmp"))) {
62 // sleep 2 seconds and try again 79 // sleep 2 seconds and try again
63 sleep(2); 80 sleep(2);
64 if (!(dir = opendir("/tmp"))) { 81 if (!(dir = opendir("/tmp"))) {
65 fprintf(stderr, "Warning: cannot open /tmp directory. PulseAudio sockets are not disabled\n");
66 return; 82 return;
67 } 83 }
68 } 84 }
@@ -76,10 +92,6 @@ void pulseaudio_disable(void) {
76 92
77 closedir(dir); 93 closedir(dir);
78 94
79 // blacklist XDG_RUNTIME_DIR
80 char *name = getenv("XDG_RUNTIME_DIR");
81 if (name)
82 disable_file(name, "pulse/native");
83} 95}
84 96
85 97
@@ -92,33 +104,23 @@ void pulseaudio_init(void) {
92 return; 104 return;
93 105
94 // create the new user pulseaudio directory 106 // create the new user pulseaudio directory
95 fs_build_mnt_dir();
96 int rv = mkdir(RUN_PULSE_DIR, 0700); 107 int rv = mkdir(RUN_PULSE_DIR, 0700);
97 (void) rv; // in --chroot mode the directory can already be there 108 (void) rv; // in --chroot mode the directory can already be there
98 if (chown(RUN_PULSE_DIR, getuid(), getgid()) < 0) 109 if (set_perms(RUN_PULSE_DIR, getuid(), getgid(), 0700))
99 errExit("chown"); 110 errExit("set_perms");
100 if (chmod(RUN_PULSE_DIR, 0700) < 0)
101 errExit("chmod");
102 111
103 // create the new client.conf file 112 // create the new client.conf file
104 char *pulsecfg = NULL; 113 char *pulsecfg = NULL;
105 if (asprintf(&pulsecfg, "%s/client.conf", RUN_PULSE_DIR) == -1) 114 if (asprintf(&pulsecfg, "%s/client.conf", RUN_PULSE_DIR) == -1)
106 errExit("asprintf"); 115 errExit("asprintf");
107 if (is_link("/etc/pulse/client.conf")) { 116 if (copy_file("/etc/pulse/client.conf", pulsecfg, -1, -1, 0644))
108 fprintf(stderr, "Error: invalid /etc/pulse/client.conf file\n");
109 exit(1);
110 }
111 if (copy_file("/etc/pulse/client.conf", pulsecfg))
112 errExit("copy_file"); 117 errExit("copy_file");
113 FILE *fp = fopen(pulsecfg, "a+"); 118 FILE *fp = fopen(pulsecfg, "a+");
114 if (!fp) 119 if (!fp)
115 errExit("fopen"); 120 errExit("fopen");
116 fprintf(fp, "%s", "\nenable-shm = no\n"); 121 fprintf(fp, "%s", "\nenable-shm = no\n");
122 SET_PERMS_STREAM(fp, getuid(), getgid(), 0644);
117 fclose(fp); 123 fclose(fp);
118 if (chmod(pulsecfg, 0644) == -1)
119 errExit("chmod");
120 if (chown(pulsecfg, getuid(), getgid()) == -1)
121 errExit("chown");
122 124
123 // create ~/.config/pulse directory if not present 125 // create ~/.config/pulse directory if not present
124 char *dir1; 126 char *dir1;
@@ -127,10 +129,8 @@ void pulseaudio_init(void) {
127 if (stat(dir1, &s) == -1) { 129 if (stat(dir1, &s) == -1) {
128 int rv = mkdir(dir1, 0755); 130 int rv = mkdir(dir1, 0755);
129 if (rv == 0) { 131 if (rv == 0) {
130 rv = chown(dir1, getuid(), getgid()); 132 if (set_perms(dir1, getuid(), getgid(), 0755))
131 (void) rv; 133 {;} // do nothing
132 rv = chmod(dir1, 0755);
133 (void) rv;
134 } 134 }
135 } 135 }
136 free(dir1); 136 free(dir1);
@@ -139,10 +139,8 @@ void pulseaudio_init(void) {
139 if (stat(dir1, &s) == -1) { 139 if (stat(dir1, &s) == -1) {
140 int rv = mkdir(dir1, 0700); 140 int rv = mkdir(dir1, 0700);
141 if (rv == 0) { 141 if (rv == 0) {
142 rv = chown(dir1, getuid(), getgid()); 142 if (set_perms(dir1, getuid(), getgid(), 0700))
143 (void) rv; 143 {;} // do nothing
144 rv = chmod(dir1, 0700);
145 (void) rv;
146 } 144 }
147 } 145 }
148 free(dir1); 146 free(dir1);
diff --git a/src/firejail/restrict_users.c b/src/firejail/restrict_users.c
index 5a41c441b..393851148 100644
--- a/src/firejail/restrict_users.c
+++ b/src/firejail/restrict_users.c
@@ -26,6 +26,7 @@
26#include <dirent.h> 26#include <dirent.h>
27#include <fcntl.h> 27#include <fcntl.h>
28#include <errno.h> 28#include <errno.h>
29#include "../../uids.h"
29 30
30#define MAXBUF 1024 31#define MAXBUF 1024
31 32
@@ -72,7 +73,6 @@ static void sanitize_home(void) {
72 return; 73 return;
73 } 74 }
74 75
75 fs_build_mnt_dir();
76 if (mkdir(RUN_WHITELIST_HOME_DIR, 0755) == -1) 76 if (mkdir(RUN_WHITELIST_HOME_DIR, 0755) == -1)
77 errExit("mkdir"); 77 errExit("mkdir");
78 78
@@ -95,10 +95,8 @@ static void sanitize_home(void) {
95 fs_logger2("mkdir", cfg.homedir); 95 fs_logger2("mkdir", cfg.homedir);
96 96
97 // set mode and ownership 97 // set mode and ownership
98 if (chown(cfg.homedir, s.st_uid, s.st_gid) == -1) 98 if (set_perms(cfg.homedir, s.st_uid, s.st_gid, s.st_mode))
99 errExit("chown"); 99 errExit("set_perms");
100 if (chmod(cfg.homedir, s.st_mode) == -1)
101 errExit("chmod");
102 100
103 // mount user home directory 101 // mount user home directory
104 if (mount(RUN_WHITELIST_HOME_DIR, cfg.homedir, NULL, MS_BIND|MS_REC, NULL) < 0) 102 if (mount(RUN_WHITELIST_HOME_DIR, cfg.homedir, NULL, MS_BIND|MS_REC, NULL) < 0)
@@ -118,7 +116,7 @@ static void sanitize_passwd(void) {
118 if (stat("/etc/passwd", &s) == -1) 116 if (stat("/etc/passwd", &s) == -1)
119 return; 117 return;
120 if (arg_debug) 118 if (arg_debug)
121 printf("Sanitizing /etc/passwd\n"); 119 printf("Sanitizing /etc/passwd, UID_MIN %d\n", UID_MIN);
122 if (is_link("/etc/passwd")) { 120 if (is_link("/etc/passwd")) {
123 fprintf(stderr, "Error: invalid /etc/passwd\n"); 121 fprintf(stderr, "Error: invalid /etc/passwd\n");
124 exit(1); 122 exit(1);
@@ -126,7 +124,6 @@ static void sanitize_passwd(void) {
126 124
127 FILE *fpin = NULL; 125 FILE *fpin = NULL;
128 FILE *fpout = NULL; 126 FILE *fpout = NULL;
129 fs_build_mnt_dir();
130 127
131 // open files 128 // open files
132 /* coverity[toctou] */ 129 /* coverity[toctou] */
@@ -170,7 +167,7 @@ static void sanitize_passwd(void) {
170 int rv = sscanf(ptr, "%d:", &uid); 167 int rv = sscanf(ptr, "%d:", &uid);
171 if (rv == 0 || uid < 0) 168 if (rv == 0 || uid < 0)
172 goto errout; 169 goto errout;
173 if (uid < 1000) { // todo extract UID_MIN from /etc/login.def 170 if (uid < UID_MIN) {
174 fprintf(fpout, "%s", buf); 171 fprintf(fpout, "%s", buf);
175 continue; 172 continue;
176 } 173 }
@@ -186,12 +183,9 @@ static void sanitize_passwd(void) {
186 fprintf(fpout, "%s", buf); 183 fprintf(fpout, "%s", buf);
187 } 184 }
188 fclose(fpin); 185 fclose(fpin);
186 SET_PERMS_STREAM(fpout, 0, 0, 0644);
189 fclose(fpout); 187 fclose(fpout);
190 if (chown(RUN_PASSWD_FILE, 0, 0) == -1) 188
191 errExit("chown");
192 if (chmod(RUN_PASSWD_FILE, 0644) == -1)
193 errExit("chmod");
194
195 // mount-bind tne new password file 189 // mount-bind tne new password file
196 if (mount(RUN_PASSWD_FILE, "/etc/passwd", "none", MS_BIND, "mode=400,gid=0") < 0) 190 if (mount(RUN_PASSWD_FILE, "/etc/passwd", "none", MS_BIND, "mode=400,gid=0") < 0)
197 errExit("mount"); 191 errExit("mount");
@@ -255,7 +249,7 @@ static void sanitize_group(void) {
255 if (stat("/etc/group", &s) == -1) 249 if (stat("/etc/group", &s) == -1)
256 return; 250 return;
257 if (arg_debug) 251 if (arg_debug)
258 printf("Sanitizing /etc/group\n"); 252 printf("Sanitizing /etc/group, GID_MIN %d\n", GID_MIN);
259 if (is_link("/etc/group")) { 253 if (is_link("/etc/group")) {
260 fprintf(stderr, "Error: invalid /etc/group\n"); 254 fprintf(stderr, "Error: invalid /etc/group\n");
261 exit(1); 255 exit(1);
@@ -263,7 +257,6 @@ static void sanitize_group(void) {
263 257
264 FILE *fpin = NULL; 258 FILE *fpin = NULL;
265 FILE *fpout = NULL; 259 FILE *fpout = NULL;
266 fs_build_mnt_dir();
267 260
268 // open files 261 // open files
269 /* coverity[toctou] */ 262 /* coverity[toctou] */
@@ -306,7 +299,7 @@ static void sanitize_group(void) {
306 int rv = sscanf(ptr, "%d:", &gid); 299 int rv = sscanf(ptr, "%d:", &gid);
307 if (rv == 0 || gid < 0) 300 if (rv == 0 || gid < 0)
308 goto errout; 301 goto errout;
309 if (gid < 1000) { // todo extract GID_MIN from /etc/login.def 302 if (gid < GID_MIN) {
310 if (copy_line(fpout, buf, ptr)) 303 if (copy_line(fpout, buf, ptr))
311 goto errout; 304 goto errout;
312 continue; 305 continue;
@@ -318,12 +311,9 @@ static void sanitize_group(void) {
318 goto errout; 311 goto errout;
319 } 312 }
320 fclose(fpin); 313 fclose(fpin);
314 SET_PERMS_STREAM(fpout, 0, 0, 0644);
321 fclose(fpout); 315 fclose(fpout);
322 if (chown(RUN_GROUP_FILE, 0, 0) == -1) 316
323 errExit("chown");
324 if (chmod(RUN_GROUP_FILE, 0644) == -1)
325 errExit("chmod");
326
327 // mount-bind tne new group file 317 // mount-bind tne new group file
328 if (mount(RUN_GROUP_FILE, "/etc/group", "none", MS_BIND, "mode=400,gid=0") < 0) 318 if (mount(RUN_GROUP_FILE, "/etc/group", "none", MS_BIND, "mode=400,gid=0") < 0)
329 errExit("mount"); 319 errExit("mount");
@@ -340,6 +330,9 @@ errout:
340} 330}
341 331
342void restrict_users(void) { 332void restrict_users(void) {
333 if (arg_allusers)
334 return;
335
343 // only in user mode 336 // only in user mode
344 if (getuid()) { 337 if (getuid()) {
345 if (strncmp(cfg.homedir, "/home/", 6) == 0) { 338 if (strncmp(cfg.homedir, "/home/", 6) == 0) {
@@ -347,7 +340,7 @@ void restrict_users(void) {
347 sanitize_home(); 340 sanitize_home();
348 } 341 }
349 else { 342 else {
350 // user has the home diercotry outside /home 343 // user has the home directory outside /home
351 // mount tmpfs on top of /home in order to hide it 344 // mount tmpfs on top of /home in order to hide it
352 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 345 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
353 errExit("mount tmpfs"); 346 errExit("mount tmpfs");
diff --git a/src/firejail/restricted_shell.c b/src/firejail/restricted_shell.c
index ee6e94957..979bb1eed 100644
--- a/src/firejail/restricted_shell.c
+++ b/src/firejail/restricted_shell.c
@@ -18,6 +18,7 @@
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/ 19*/
20#include "firejail.h" 20#include "firejail.h"
21#include <fnmatch.h>
21 22
22#define MAX_READ 4096 // maximum line length 23#define MAX_READ 4096 // maximum line length
23char *restricted_user = NULL; 24char *restricted_user = NULL;
@@ -40,7 +41,7 @@ int restricted_shell(const char *user) {
40 char buf[MAX_READ]; 41 char buf[MAX_READ];
41 while (fgets(buf, MAX_READ, fp)) { 42 while (fgets(buf, MAX_READ, fp)) {
42 lineno++; 43 lineno++;
43 44
44 // remove empty spaces at the beginning of the line 45 // remove empty spaces at the beginning of the line
45 char *ptr = buf; 46 char *ptr = buf;
46 while (*ptr == ' ' || *ptr == '\t') { 47 while (*ptr == ' ' || *ptr == '\t') {
@@ -48,21 +49,26 @@ int restricted_shell(const char *user) {
48 } 49 }
49 if (*ptr == '\n' || *ptr == '#') 50 if (*ptr == '\n' || *ptr == '#')
50 continue; 51 continue;
52
53 //
54 // parse line
55 //
51 56
52 // parse line 57 // extract users
53 char *usr = ptr; 58 char *usr = ptr;
54 char *args = strchr(usr, ':'); 59 char *args = strchr(usr, ':');
55 if (args == NULL) { 60 if (args == NULL) {
56 fprintf(stderr, "Error: users.conf line %d\n", lineno); 61 fprintf(stderr, "Error: users.conf line %d\n", lineno);
57 exit(1); 62 exit(1);
58 } 63 }
64
59 *args = '\0'; 65 *args = '\0';
60 args++; 66 args++;
61 ptr = strchr(args, '\n'); 67 ptr = strchr(args, '\n');
62 if (ptr) 68 if (ptr)
63 *ptr = '\0'; 69 *ptr = '\0';
64 70
65 // if nothing follows, continue 71 // extract firejail command line arguments
66 char *ptr2 = args; 72 char *ptr2 = args;
67 int found = 0; 73 int found = 0;
68 while (*ptr2 != '\0') { 74 while (*ptr2 != '\0') {
@@ -70,29 +76,42 @@ int restricted_shell(const char *user) {
70 found = 1; 76 found = 1;
71 break; 77 break;
72 } 78 }
79 ptr2++;
73 } 80 }
81 // if nothing follows, continue
74 if (!found) 82 if (!found)
75 continue; 83 continue;
76 84
77 // process user 85 // user name globbing
78 if (strcmp(user, usr) == 0) { 86 if (fnmatch(usr, user, 0) == 0) {
79 restricted_user = strdup(user); 87 // process program arguments
80 // extract program arguments
81 88
82 fullargv[0] = "firejail"; 89 fullargv[0] = "firejail";
83 int i; 90 int i;
84 ptr = args; 91 ptr = args;
85 for (i = 1; i < MAX_ARGS; i++) { 92 for (i = 1; i < MAX_ARGS; i++) {
86 fullargv[i] = ptr; 93 // skip blanks
87 while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0') 94 while (*ptr == ' ' || *ptr == '\t')
88 ptr++; 95 ptr++;
96 fullargv[i] = ptr;
97#ifdef DEBUG_RESTRICTED_SHELL
98 {EUID_ROOT();
99 FILE *fp = fopen("/firelog", "a");
100 if (fp) {
101 fprintf(fp, "i %d ptr #%s#\n", i, fullargv[i]);
102 fclose(fp);
103 }
104 EUID_USER();}
105#endif
106
89 if (*ptr != '\0') { 107 if (*ptr != '\0') {
108 // go to the end of the word
109 while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0')
110 ptr++;
90 *ptr ='\0'; 111 *ptr ='\0';
91 fullargv[i] = strdup(fullargv[i]); 112 fullargv[i] = strdup(fullargv[i]);
92 if (fullargv[i] == NULL) { 113 if (fullargv[i] == NULL)
93 fprintf(stderr, "Error: cannot allocate memory\n"); 114 errExit("strdup");
94 exit(1);
95 }
96 ptr++; 115 ptr++;
97 while (*ptr == ' ' || *ptr == '\t') 116 while (*ptr == ' ' || *ptr == '\t')
98 ptr++; 117 ptr++;
@@ -108,7 +127,7 @@ int restricted_shell(const char *user) {
108 } 127 }
109 } 128 }
110 fclose(fp); 129 fclose(fp);
111 130
112 return 0; 131 return 0;
113} 132}
114 133
diff --git a/src/firejail/run_symlink.c b/src/firejail/run_symlink.c
index d57816e12..8aa2fe53f 100644
--- a/src/firejail/run_symlink.c
+++ b/src/firejail/run_symlink.c
@@ -91,14 +91,22 @@ void run_symlink(int argc, char **argv) {
91 91
92 printf("Redirecting symlink to %s\n", program); 92 printf("Redirecting symlink to %s\n", program);
93 93
94 // drop privileges
95 if (setgid(getgid()) < 0)
96 errExit("setgid/getgid");
97 if (setuid(getuid()) < 0)
98 errExit("setuid/getuid");
99
94 // run command 100 // run command
95 char *a[3 + argc]; 101 char *a[3 + argc];
96 a[0] = firejail; 102 a[0] = firejail;
97 a[1] = program; 103 a[1] = program;
98 int i; 104 int i;
99 for (i = 0; i < (argc - 1); i++) 105 for (i = 0; i < (argc - 1); i++) {
100 a[i + 2] = argv[i + 1]; 106 a[i + 2] = argv[i + 1];
107 }
101 a[i + 2] = NULL; 108 a[i + 2] = NULL;
109 assert(getenv("LD_PRELOAD") == NULL);
102 execvp(a[0], a); 110 execvp(a[0], a);
103 111
104 perror("execvp"); 112 perror("execvp");
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 3f3564295..109daf552 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -28,12 +28,23 @@
28#include <sys/types.h> 28#include <sys/types.h>
29#include <dirent.h> 29#include <dirent.h>
30#include <errno.h> 30#include <errno.h>
31#include <fcntl.h>
31 32
32#include <sched.h> 33#include <sched.h>
33#ifndef CLONE_NEWUSER 34#ifndef CLONE_NEWUSER
34#define CLONE_NEWUSER 0x10000000 35#define CLONE_NEWUSER 0x10000000
35#endif 36#endif
36 37
38#include <sys/prctl.h>
39#ifndef PR_SET_NO_NEW_PRIVS
40# define PR_SET_NO_NEW_PRIVS 38
41#endif
42
43#ifdef HAVE_APPARMOR
44#include <sys/apparmor.h>
45#endif
46
47
37static int monitored_pid = 0; 48static int monitored_pid = 0;
38static void sandbox_handler(int sig){ 49static void sandbox_handler(int sig){
39 if (!arg_quiet) { 50 if (!arg_quiet) {
@@ -70,8 +81,11 @@ static void sandbox_handler(int sig){
70 81
71 } 82 }
72 83
84
73 // broadcast a SIGKILL 85 // broadcast a SIGKILL
74 kill(-1, SIGKILL); 86 kill(-1, SIGKILL);
87 flush_stdin();
88
75 exit(sig); 89 exit(sig);
76} 90}
77 91
@@ -94,9 +108,8 @@ void save_nogroups(void) {
94 FILE *fp = fopen(RUN_GROUPS_CFG, "w"); 108 FILE *fp = fopen(RUN_GROUPS_CFG, "w");
95 if (fp) { 109 if (fp) {
96 fprintf(fp, "\n"); 110 fprintf(fp, "\n");
111 SET_PERMS_STREAM(fp, 0, 0, 0644); // assume mode 0644
97 fclose(fp); 112 fclose(fp);
98 if (chown(RUN_GROUPS_CFG, 0, 0) < 0)
99 errExit("chown");
100 } 113 }
101 else { 114 else {
102 fprintf(stderr, "Error: cannot save nogroups state\n"); 115 fprintf(stderr, "Error: cannot save nogroups state\n");
@@ -109,7 +122,7 @@ static void sandbox_if_up(Bridge *br) {
109 assert(br); 122 assert(br);
110 if (!br->configured) 123 if (!br->configured)
111 return; 124 return;
112 125
113 char *dev = br->devsandbox; 126 char *dev = br->devsandbox;
114 net_if_up(dev); 127 net_if_up(dev);
115 128
@@ -124,8 +137,7 @@ static void sandbox_if_up(Bridge *br) {
124 assert(br->ipsandbox); 137 assert(br->ipsandbox);
125 if (arg_debug) 138 if (arg_debug)
126 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(br->ipsandbox), dev); 139 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(br->ipsandbox), dev);
127 net_if_ip(dev, br->ipsandbox, br->mask, br->mtu); 140 net_config_interface(dev, br->ipsandbox, br->mask, br->mtu);
128 net_if_up(dev);
129 } 141 }
130 else if (br->arg_ip_none == 0 && br->macvlan == 1) { 142 else if (br->arg_ip_none == 0 && br->macvlan == 1) {
131 // reassign the macvlan address 143 // reassign the macvlan address
@@ -147,8 +159,7 @@ static void sandbox_if_up(Bridge *br) {
147 159
148 if (arg_debug) 160 if (arg_debug)
149 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(br->ipsandbox), dev); 161 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(br->ipsandbox), dev);
150 net_if_ip(dev, br->ipsandbox, br->mask, br->mtu); 162 net_config_interface(dev, br->ipsandbox, br->mask, br->mtu);
151 net_if_up(dev);
152 } 163 }
153 164
154 if (br->ip6sandbox) 165 if (br->ip6sandbox)
@@ -198,6 +209,12 @@ static int monitor_application(pid_t app_pid) {
198 if (arg_debug) 209 if (arg_debug)
199 printf("Sandbox monitor: waitpid %u retval %d status %d\n", monitored_pid, rv, status); 210 printf("Sandbox monitor: waitpid %u retval %d status %d\n", monitored_pid, rv, status);
200 211
212 // if /proc is not remounted, we cannot check /proc directory,
213 // for now we just get out of here
214 // todo: find another way of checking child processes!
215 if (!checkcfg(CFG_REMOUNT_PROC_SYS))
216 break;
217
201 DIR *dir; 218 DIR *dir;
202 if (!(dir = opendir("/proc"))) { 219 if (!(dir = opendir("/proc"))) {
203 // sleep 2 seconds and try again 220 // sleep 2 seconds and try again
@@ -237,40 +254,46 @@ static int monitor_application(pid_t app_pid) {
237 254
238 // return the latest exit status. 255 // return the latest exit status.
239 return status; 256 return status;
257}
240 258
241#if 0 259void start_audit(void) {
242// todo: find a way to shut down interfaces before closing the namespace 260 char *audit_prog;
243// the problem is we don't have enough privileges to shutdown interfaces in this moment 261 if (asprintf(&audit_prog, "%s/firejail/faudit", LIBDIR) == -1)
244 // shut down bridge/macvlan interfaces 262 errExit("asprintf");
245 if (any_bridge_configured()) { 263 assert(getenv("LD_PRELOAD") == NULL);
246 264 execl(audit_prog, audit_prog, NULL);
247 if (cfg.bridge0.configured) { 265 perror("execl");
248 printf("Shutting down %s\n", cfg.bridge0.devsandbox); 266 exit(1);
249 net_if_down( cfg.bridge0.devsandbox);
250 }
251 if (cfg.bridge1.configured) {
252 printf("Shutting down %s\n", cfg.bridge1.devsandbox);
253 net_if_down( cfg.bridge1.devsandbox);
254 }
255 if (cfg.bridge2.configured) {
256 printf("Shutting down %s\n", cfg.bridge2.devsandbox);
257 net_if_down( cfg.bridge2.devsandbox);
258 }
259 if (cfg.bridge3.configured) {
260 printf("Shutting down %s\n", cfg.bridge3.devsandbox);
261 net_if_down( cfg.bridge3.devsandbox);
262 }
263 usleep(20000); // 20 ms sleep
264 }
265#endif
266} 267}
267 268
269void start_application(void) {
270//if (setsid() == -1)
271//errExit("setsid");
268 272
269static void start_application(void) { 273 // set environment
274 env_defaults();
275 env_apply();
276 if (arg_debug) {
277 printf("starting application\n");
278 printf("LD_PRELOAD=%s\n", getenv("LD_PRELOAD"));
279 }
280
281 //****************************************
282 // audit
283 //****************************************
284 if (arg_audit) {
285 assert(arg_audit_prog);
286 struct stat s;
287 if (stat(arg_audit_prog, &s) != 0) {
288 fprintf(stderr, "Error: cannot find the audit program\n");
289 exit(1);
290 }
291 execl(arg_audit_prog, arg_audit_prog, NULL);
292 }
270 //**************************************** 293 //****************************************
271 // start the program without using a shell 294 // start the program without using a shell
272 //**************************************** 295 //****************************************
273 if (arg_shell_none) { 296 else if (arg_shell_none) {
274 if (arg_debug) { 297 if (arg_debug) {
275 int i; 298 int i;
276 for (i = cfg.original_program_index; i < cfg.original_argc; i++) { 299 for (i = cfg.original_program_index; i < cfg.original_argc; i++) {
@@ -289,35 +312,33 @@ static void start_application(void) {
289 printf("Child process initialized\n"); 312 printf("Child process initialized\n");
290 313
291 execvp(cfg.original_argv[cfg.original_program_index], &cfg.original_argv[cfg.original_program_index]); 314 execvp(cfg.original_argv[cfg.original_program_index], &cfg.original_argv[cfg.original_program_index]);
315 exit(1);
292 } 316 }
293 //**************************************** 317 //****************************************
294 // start the program using a shell 318 // start the program using a shell
295 //**************************************** 319 //****************************************
296 else { 320 else {
297 // choose the shell requested by the user, or use bash as default 321 assert(cfg.shell);
298 char *sh; 322 assert(cfg.command_line);
299 if (cfg.shell) 323
300 sh = cfg.shell;
301 else if (arg_zsh)
302 sh = "/usr/bin/zsh";
303 else if (arg_csh)
304 sh = "/bin/csh";
305 else
306 sh = "/bin/bash";
307
308 char *arg[5]; 324 char *arg[5];
309 int index = 0; 325 int index = 0;
310 arg[index++] = sh; 326 arg[index++] = cfg.shell;
311 arg[index++] = "-c"; 327 if (login_shell) {
312 assert(cfg.command_line); 328 arg[index++] = "-l";
313 if (arg_debug) 329 if (arg_debug)
314 printf("Starting %s\n", cfg.command_line); 330 printf("Starting %s login shell\n", cfg.shell);
315 if (arg_doubledash) 331 } else {
316 arg[index++] = "--"; 332 arg[index++] = "-c";
317 arg[index++] = cfg.command_line; 333 if (arg_debug)
334 printf("Running %s command through %s\n", cfg.command_line, cfg.shell);
335 if (arg_doubledash)
336 arg[index++] = "--";
337 arg[index++] = cfg.command_line;
338 }
318 arg[index] = NULL; 339 arg[index] = NULL;
319 assert(index < 5); 340 assert(index < 5);
320 341
321 if (arg_debug) { 342 if (arg_debug) {
322 char *msg; 343 char *msg;
323 if (asprintf(&msg, "sandbox %d, execvp into %s", sandbox_pid, cfg.command_line) == -1) 344 if (asprintf(&msg, "sandbox %d, execvp into %s", sandbox_pid, cfg.command_line) == -1)
@@ -325,7 +346,7 @@ static void start_application(void) {
325 logmsg(msg); 346 logmsg(msg);
326 free(msg); 347 free(msg);
327 } 348 }
328 349
329 if (arg_debug) { 350 if (arg_debug) {
330 int i; 351 int i;
331 for (i = 0; i < 5; i++) { 352 for (i = 0; i < 5; i++) {
@@ -334,17 +355,40 @@ static void start_application(void) {
334 printf("execvp argument %d: %s\n", i, arg[i]); 355 printf("execvp argument %d: %s\n", i, arg[i]);
335 } 356 }
336 } 357 }
337 358
338 if (!arg_command && !arg_quiet) 359 if (!arg_command && !arg_quiet)
339 printf("Child process initialized\n"); 360 printf("Child process initialized\n");
340 execvp(sh, arg); 361 execvp(arg[0], arg);
341 } 362 }
342 363
343 perror("execvp"); 364 perror("execvp");
344 exit(1); // it should never get here!!! 365 exit(1); // it should never get here!!!
345} 366}
346 367
347 368static void enforce_filters(void) {
369 // force default seccomp inside the chroot, no keep or drop list
370 // the list build on top of the default drop list is kept intact
371 arg_seccomp = 1;
372 if (cfg.seccomp_list_drop) {
373 free(cfg.seccomp_list_drop);
374 cfg.seccomp_list_drop = NULL;
375 }
376 if (cfg.seccomp_list_keep) {
377 free(cfg.seccomp_list_keep);
378 cfg.seccomp_list_keep = NULL;
379 }
380
381 // disable all capabilities
382 if (arg_caps_default_filter || arg_caps_list)
383 fprintf(stderr, "Warning: all capabilities disabled for a regular user in chroot\n");
384 arg_caps_drop_all = 1;
385
386 // drop all supplementary groups; /etc/group file inside chroot
387 // is controlled by a regular usr
388 arg_nogroups = 1;
389 if (!arg_quiet)
390 printf("Dropping all Linux capabilities and enforcing default seccomp filter\n");
391}
348 392
349int sandbox(void* sandbox_arg) { 393int sandbox(void* sandbox_arg) {
350 // Get rid of unused parameter warning 394 // Get rid of unused parameter warning
@@ -364,6 +408,7 @@ int sandbox(void* sandbox_arg) {
364 if (arg_debug && child_pid == 1) 408 if (arg_debug && child_pid == 1)
365 printf("PID namespace installed\n"); 409 printf("PID namespace installed\n");
366 410
411
367 //**************************** 412 //****************************
368 // set hostname 413 // set hostname
369 //**************************** 414 //****************************
@@ -379,7 +424,8 @@ int sandbox(void* sandbox_arg) {
379 if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) { 424 if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) {
380 chk_chroot(); 425 chk_chroot();
381 } 426 }
382 427 // ... and mount a tmpfs on top of /run/firejail/mnt directory
428 preproc_mount_mnt_dir();
383 429
384 //**************************** 430 //****************************
385 // log sandbox data 431 // log sandbox data
@@ -396,7 +442,7 @@ int sandbox(void* sandbox_arg) {
396 fs_logger("install mount namespace"); 442 fs_logger("install mount namespace");
397 443
398 //**************************** 444 //****************************
399 // netfilter etc. 445 // netfilter
400 //**************************** 446 //****************************
401 if (arg_netfilter && any_bridge_configured()) { // assuming by default the client filter 447 if (arg_netfilter && any_bridge_configured()) { // assuming by default the client filter
402 netfilter(arg_netfilter_file); 448 netfilter(arg_netfilter_file);
@@ -405,6 +451,101 @@ int sandbox(void* sandbox_arg) {
405 netfilter6(arg_netfilter6_file); 451 netfilter6(arg_netfilter6_file);
406 } 452 }
407 453
454 //****************************
455 // networking
456 //****************************
457 int gw_cfg_failed = 0; // default gw configuration flag
458 if (arg_nonetwork) {
459 net_if_up("lo");
460 if (arg_debug)
461 printf("Network namespace enabled, only loopback interface available\n");
462 }
463 else if (any_bridge_configured() || any_interface_configured()) {
464 // configure lo and eth0...eth3
465 net_if_up("lo");
466
467 if (mac_not_zero(cfg.bridge0.macsandbox))
468 net_config_mac(cfg.bridge0.devsandbox, cfg.bridge0.macsandbox);
469 sandbox_if_up(&cfg.bridge0);
470
471 if (mac_not_zero(cfg.bridge1.macsandbox))
472 net_config_mac(cfg.bridge1.devsandbox, cfg.bridge1.macsandbox);
473 sandbox_if_up(&cfg.bridge1);
474
475 if (mac_not_zero(cfg.bridge2.macsandbox))
476 net_config_mac(cfg.bridge2.devsandbox, cfg.bridge2.macsandbox);
477 sandbox_if_up(&cfg.bridge2);
478
479 if (mac_not_zero(cfg.bridge3.macsandbox))
480 net_config_mac(cfg.bridge3.devsandbox, cfg.bridge3.macsandbox);
481 sandbox_if_up(&cfg.bridge3);
482
483
484 // moving an interface in a namespace using --interface will reset the interface configuration;
485 // we need to put the configuration back
486 if (cfg.interface0.configured && cfg.interface0.ip) {
487 if (arg_debug)
488 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface0.ip), cfg.interface0.dev);
489 net_config_interface(cfg.interface0.dev, cfg.interface0.ip, cfg.interface0.mask, cfg.interface0.mtu);
490 }
491 if (cfg.interface1.configured && cfg.interface1.ip) {
492 if (arg_debug)
493 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface1.ip), cfg.interface1.dev);
494 net_config_interface(cfg.interface1.dev, cfg.interface1.ip, cfg.interface1.mask, cfg.interface1.mtu);
495 }
496 if (cfg.interface2.configured && cfg.interface2.ip) {
497 if (arg_debug)
498 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface2.ip), cfg.interface2.dev);
499 net_config_interface(cfg.interface2.dev, cfg.interface2.ip, cfg.interface2.mask, cfg.interface2.mtu);
500 }
501 if (cfg.interface3.configured && cfg.interface3.ip) {
502 if (arg_debug)
503 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface3.ip), cfg.interface3.dev);
504 net_config_interface(cfg.interface3.dev, cfg.interface3.ip, cfg.interface3.mask, cfg.interface3.mtu);
505 }
506
507 // add a default route
508 if (cfg.defaultgw) {
509 // set the default route
510 if (net_add_route(0, 0, cfg.defaultgw)) {
511 fprintf(stderr, "Warning: cannot configure default route\n");
512 gw_cfg_failed = 1;
513 }
514 }
515
516 if (arg_debug)
517 printf("Network namespace enabled\n");
518 }
519
520
521 // print network configuration
522 if (!arg_quiet) {
523 if (any_bridge_configured() || any_interface_configured() || cfg.defaultgw || cfg.dns1) {
524 printf("\n");
525 if (any_bridge_configured() || any_interface_configured()) {
526// net_ifprint();
527 if (arg_scan)
528 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 3, PATH_FNET, "printif", "scan");
529 else
530 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 2, PATH_FNET, "printif", "scan");
531
532 }
533 if (cfg.defaultgw != 0) {
534 if (gw_cfg_failed)
535 printf("Default gateway configuration failed\n");
536 else
537 printf("Default gateway %d.%d.%d.%d\n", PRINT_IP(cfg.defaultgw));
538 }
539 if (cfg.dns1 != 0)
540 printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns1));
541 if (cfg.dns2 != 0)
542 printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns2));
543 if (cfg.dns3 != 0)
544 printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns3));
545 printf("\n");
546 }
547 }
548
408 // load IBUS env variables 549 // load IBUS env variables
409 if (arg_nonetwork || any_bridge_configured() || any_interface_configured()) { 550 if (arg_nonetwork || any_bridge_configured() || any_interface_configured()) {
410 // do nothing - there are problems with ibus version 1.5.11 551 // do nothing - there are problems with ibus version 1.5.11
@@ -412,11 +553,29 @@ int sandbox(void* sandbox_arg) {
412 else 553 else
413 env_ibus_load(); 554 env_ibus_load();
414 555
415 // grab a copy of cp command 556 //****************************
416 fs_build_cp_command(); 557 // fs pre-processing:
417 558 // - copy some commands under /run
559 // - build seccomp filters
560 // - create an empty /etc/ld.so.preload
561 //****************************
562 preproc_build_cp_command();
563
564#ifdef HAVE_SECCOMP
565 if (cfg.protocol) {
566 if (arg_debug)
567 printf("Build protocol filter: %s\n", cfg.protocol);
568
569 // build the seccomp filter as a regular user
570 int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 5,
571 PATH_FSECCOMP, "protocol", "build", cfg.protocol, RUN_SECCOMP_PROTOCOL);
572 if (rv)
573 exit(rv);
574 }
575#endif
576
418 // trace pre-install 577 // trace pre-install
419 if (arg_trace || arg_tracelog) 578 if (arg_trace || arg_tracelog || mask_x11_abstract_socket)
420 fs_trace_preload(); 579 fs_trace_preload();
421 580
422 //**************************** 581 //****************************
@@ -425,39 +584,23 @@ int sandbox(void* sandbox_arg) {
425#ifdef HAVE_SECCOMP 584#ifdef HAVE_SECCOMP
426 int enforce_seccomp = 0; 585 int enforce_seccomp = 0;
427#endif 586#endif
587 if (arg_appimage) {
588 enforce_filters();
589#ifdef HAVE_SECCOMP
590 enforce_seccomp = 1;
591#endif
592 }
593
428#ifdef HAVE_CHROOT 594#ifdef HAVE_CHROOT
429 if (cfg.chrootdir) { 595 if (cfg.chrootdir) {
430 fs_chroot(cfg.chrootdir); 596 fs_chroot(cfg.chrootdir);
431 // redo cp command
432 fs_build_cp_command();
433 597
434 // force caps and seccomp if not started as root 598 // force caps and seccomp if not started as root
435 if (getuid() != 0) { 599 if (getuid() != 0) {
436 // force default seccomp inside the chroot, no keep or drop list 600 enforce_filters();
437 // the list build on top of the default drop list is kept intact
438 arg_seccomp = 1;
439#ifdef HAVE_SECCOMP 601#ifdef HAVE_SECCOMP
440 enforce_seccomp = 1; 602 enforce_seccomp = 1;
441#endif 603#endif
442 if (cfg.seccomp_list_drop) {
443 free(cfg.seccomp_list_drop);
444 cfg.seccomp_list_drop = NULL;
445 }
446 if (cfg.seccomp_list_keep) {
447 free(cfg.seccomp_list_keep);
448 cfg.seccomp_list_keep = NULL;
449 }
450
451 // disable all capabilities
452 if (arg_caps_default_filter || arg_caps_list)
453 fprintf(stderr, "Warning: all capabilities disabled for a regular user during chroot\n");
454 arg_caps_drop_all = 1;
455
456 // drop all supplementary groups; /etc/group file inside chroot
457 // is controlled by a regular usr
458 arg_nogroups = 1;
459 if (!arg_quiet)
460 printf("Dropping all Linux capabilities and enforcing default seccomp filter\n");
461 } 604 }
462 else 605 else
463 arg_seccomp = 1; 606 arg_seccomp = 1;
@@ -465,17 +608,28 @@ int sandbox(void* sandbox_arg) {
465 //**************************** 608 //****************************
466 // trace pre-install, this time inside chroot 609 // trace pre-install, this time inside chroot
467 //**************************** 610 //****************************
468 if (arg_trace || arg_tracelog) 611 if (arg_trace || arg_tracelog || mask_x11_abstract_socket)
469 fs_trace_preload(); 612 fs_trace_preload();
470 } 613 }
471 else 614 else
472#endif 615#endif
473 if (arg_overlay) 616#ifdef HAVE_OVERLAYFS
617 if (arg_overlay) {
474 fs_overlayfs(); 618 fs_overlayfs();
619 // force caps and seccomp if not started as root
620 if (getuid() != 0) {
621 enforce_filters();
622#ifdef HAVE_SECCOMP
623 enforce_seccomp = 1;
624#endif
625 }
626 else
627 arg_seccomp = 1;
628 }
475 else 629 else
630#endif
476 fs_basic_fs(); 631 fs_basic_fs();
477 632
478
479 //**************************** 633 //****************************
480 // set hostname in /etc/hostname 634 // set hostname in /etc/hostname
481 //**************************** 635 //****************************
@@ -487,145 +641,135 @@ int sandbox(void* sandbox_arg) {
487 // private mode 641 // private mode
488 //**************************** 642 //****************************
489 if (arg_private) { 643 if (arg_private) {
490 if (cfg.home_private) // --private= 644 if (cfg.home_private) { // --private=
491 fs_private_homedir(); 645 if (cfg.chrootdir)
646 fprintf(stderr, "Warning: private=directory feature is disabled in chroot\n");
647 else if (arg_overlay)
648 fprintf(stderr, "Warning: private=directory feature is disabled in overlay\n");
649 else
650 fs_private_homedir();
651 }
652 else if (cfg.home_private_keep) { // --private-home=
653 if (cfg.chrootdir)
654 fprintf(stderr, "Warning: private-home= feature is disabled in chroot\n");
655 else if (arg_overlay)
656 fprintf(stderr, "Warning: private-home= feature is disabled in overlay\n");
657 else
658 fs_private_home_list();
659 }
492 else // --private 660 else // --private
493 fs_private(); 661 fs_private();
494 } 662 }
495 663
496 if (arg_private_dev) 664 if (arg_private_dev) {
497 fs_private_dev(); 665 if (cfg.chrootdir)
666 fprintf(stderr, "Warning: private-dev feature is disabled in chroot\n");
667 else if (arg_overlay)
668 fprintf(stderr, "Warning: private-dev feature is disabled in overlay\n");
669 else
670 fs_private_dev();
671 }
672
498 if (arg_private_etc) { 673 if (arg_private_etc) {
499 fs_private_etc_list(); 674 if (cfg.chrootdir)
500 // create /etc/ld.so.preload file again 675 fprintf(stderr, "Warning: private-etc feature is disabled in chroot\n");
501 if (arg_trace || arg_tracelog) 676 else if (arg_overlay)
502 fs_trace_preload(); 677 fprintf(stderr, "Warning: private-etc feature is disabled in overlay\n");
678 else {
679 fs_private_etc_list();
680 // create /etc/ld.so.preload file again
681 if (arg_trace || arg_tracelog || mask_x11_abstract_socket)
682 fs_trace_preload();
683 }
684 }
685
686 if (arg_private_bin) {
687 if (cfg.chrootdir)
688 fprintf(stderr, "Warning: private-bin feature is disabled in chroot\n");
689 else if (arg_overlay)
690 fprintf(stderr, "Warning: private-bin feature is disabled in overlay\n");
691 else {
692 // for --x11=xorg we need to add xauth command
693 if (arg_x11_xorg) {
694 EUID_USER();
695 char *tmp;
696 if (asprintf(&tmp, "%s,xauth", cfg.bin_private_keep) == -1)
697 errExit("asprintf");
698 cfg.bin_private_keep = tmp;
699 fs_check_bin_list();
700 EUID_ROOT();
701 }
702 fs_private_bin_list();
703 }
704 }
705
706 if (arg_private_tmp) {
707 if (cfg.chrootdir)
708 fprintf(stderr, "Warning: private-tmp feature is disabled in chroot\n");
709 else if (arg_overlay)
710 fprintf(stderr, "Warning: private-tmp feature is disabled in overlay\n");
711 else {
712 // private-tmp is implemented as a whitelist
713 EUID_USER();
714 profile_add("whitelist /tmp/.X11-unix");
715 EUID_ROOT();
716 }
503 } 717 }
504 if (arg_private_bin) 718
505 fs_private_bin_list(); 719 //****************************
506 if (arg_private_tmp) 720 // update /proc, /sys, /dev, /boot directorymy
507 fs_private_tmp(); 721 //****************************
722 if (checkcfg(CFG_REMOUNT_PROC_SYS))
723 fs_proc_sys_dev_boot();
508 724
509 //**************************** 725 //****************************
510 // apply the profile file 726 // apply the profile file
511 //**************************** 727 //****************************
512 if (cfg.profile) { 728 // apply all whitelist commands ...
513 // apply all whitelist commands ... 729 if (cfg.chrootdir)
730 fprintf(stderr, "Warning: whitelist feature is disabled in chroot\n");
731 else if (arg_overlay)
732 fprintf(stderr, "Warning: whitelist feature is disabled in overlay\n");
733 else
514 fs_whitelist(); 734 fs_whitelist();
515 735
516 // ... followed by blacklist commands 736 // ... followed by blacklist commands
517 fs_blacklist(); 737 fs_blacklist(); // mkdir and mkfile are processed all over again
518 }
519 738
520 //**************************** 739 //****************************
521 // install trace 740 // install trace
522 //**************************** 741 //****************************
523 if (arg_trace || arg_tracelog) 742 if (arg_trace || arg_tracelog || mask_x11_abstract_socket)
524 fs_trace(); 743 fs_trace();
525 744
526 //**************************** 745 //****************************
527 // update /proc, /dev, /boot directorymy 746 // nosound/no3d and fix for pulseaudio 7.0
528 //****************************
529 fs_proc_sys_dev_boot();
530
531 //****************************
532 // --nosound and fix for pulseaudio 7.0
533 //**************************** 747 //****************************
534 if (arg_nosound) 748 if (arg_nosound) {
749 // disable pulseaudio
535 pulseaudio_disable(); 750 pulseaudio_disable();
751
752 // disable /dev/snd
753 fs_dev_disable_sound();
754 }
536 else 755 else
537 pulseaudio_init(); 756 pulseaudio_init();
538 757
758 if (arg_no3d)
759 fs_dev_disable_3d();
760
539 //**************************** 761 //****************************
540 // networking 762 // set dns
541 //**************************** 763 //****************************
542 if (arg_nonetwork) {
543 net_if_up("lo");
544 if (arg_debug)
545 printf("Network namespace enabled, only loopback interface available\n");
546 }
547 else if (any_bridge_configured() || any_interface_configured()) {
548 // configure lo and eth0...eth3
549 net_if_up("lo");
550
551 if (mac_not_zero(cfg.bridge0.macsandbox))
552 net_config_mac(cfg.bridge0.devsandbox, cfg.bridge0.macsandbox);
553 sandbox_if_up(&cfg.bridge0);
554
555 if (mac_not_zero(cfg.bridge1.macsandbox))
556 net_config_mac(cfg.bridge1.devsandbox, cfg.bridge1.macsandbox);
557 sandbox_if_up(&cfg.bridge1);
558
559 if (mac_not_zero(cfg.bridge2.macsandbox))
560 net_config_mac(cfg.bridge2.devsandbox, cfg.bridge2.macsandbox);
561 sandbox_if_up(&cfg.bridge2);
562
563 if (mac_not_zero(cfg.bridge3.macsandbox))
564 net_config_mac(cfg.bridge3.devsandbox, cfg.bridge3.macsandbox);
565 sandbox_if_up(&cfg.bridge3);
566
567 // add a default route
568 if (cfg.defaultgw) {
569 // set the default route
570 if (net_add_route(0, 0, cfg.defaultgw))
571 fprintf(stderr, "Warning: cannot configure default route\n");
572 }
573
574 // enable interfaces
575 if (cfg.interface0.configured && cfg.interface0.ip) {
576 if (arg_debug)
577 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface0.ip), cfg.interface0.dev);
578 net_if_ip(cfg.interface0.dev, cfg.interface0.ip, cfg.interface0.mask, cfg.interface0.mtu);
579 net_if_up(cfg.interface0.dev);
580 }
581 if (cfg.interface1.configured && cfg.interface1.ip) {
582 if (arg_debug)
583 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface1.ip), cfg.interface1.dev);
584 net_if_ip(cfg.interface1.dev, cfg.interface1.ip, cfg.interface1.mask, cfg.interface1.mtu);
585 net_if_up(cfg.interface1.dev);
586 }
587 if (cfg.interface2.configured && cfg.interface2.ip) {
588 if (arg_debug)
589 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface2.ip), cfg.interface2.dev);
590 net_if_ip(cfg.interface2.dev, cfg.interface2.ip, cfg.interface2.mask, cfg.interface2.mtu);
591 net_if_up(cfg.interface2.dev);
592 }
593 if (cfg.interface3.configured && cfg.interface3.ip) {
594 if (arg_debug)
595 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface3.ip), cfg.interface3.dev);
596 net_if_ip(cfg.interface3.dev, cfg.interface3.ip, cfg.interface3.mask, cfg.interface3.mtu);
597 net_if_up(cfg.interface3.dev);
598 }
599
600 if (arg_debug)
601 printf("Network namespace enabled\n");
602 }
603
604 // if any dns server is configured, it is time to set it now
605 fs_resolvconf(); 764 fs_resolvconf();
765
766 //****************************
767 // fs post-processing
768 //****************************
769 preproc_delete_cp_command();
606 fs_logger_print(); 770 fs_logger_print();
607 fs_logger_change_owner(); 771 fs_logger_change_owner();
608 772
609 // print network configuration
610 if (!arg_quiet) {
611 if (any_bridge_configured() || any_interface_configured() || cfg.defaultgw || cfg.dns1) {
612 printf("\n");
613 if (any_bridge_configured() || any_interface_configured())
614 net_ifprint();
615 if (cfg.defaultgw != 0)
616 printf("Default gateway %d.%d.%d.%d\n", PRINT_IP(cfg.defaultgw));
617 if (cfg.dns1 != 0)
618 printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns1));
619 if (cfg.dns2 != 0)
620 printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns2));
621 if (cfg.dns3 != 0)
622 printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns3));
623 printf("\n");
624 }
625 }
626
627 fs_delete_cp_command();
628
629 //**************************** 773 //****************************
630 // set application environment 774 // set application environment
631 //**************************** 775 //****************************
@@ -649,12 +793,6 @@ int sandbox(void* sandbox_arg) {
649 } 793 }
650 } 794 }
651 795
652 // set environment
653 env_defaults();
654
655 // set user-supplied environment variables
656 env_apply();
657
658 // set nice 796 // set nice
659 if (arg_nice) { 797 if (arg_nice) {
660 errno = 0; 798 errno = 0;
@@ -668,6 +806,8 @@ int sandbox(void* sandbox_arg) {
668 806
669 // clean /tmp/.X11-unix sockets 807 // clean /tmp/.X11-unix sockets
670 fs_x11(); 808 fs_x11();
809 if (arg_x11_xorg)
810 x11_xorg();
671 811
672 //**************************** 812 //****************************
673 // set security filters 813 // set security filters
@@ -679,35 +819,35 @@ int sandbox(void* sandbox_arg) {
679 // set rlimits 819 // set rlimits
680 set_rlimits(); 820 set_rlimits();
681 821
682 // set seccomp 822 // set cpu affinity
823 if (cfg.cpus) {
824 save_cpu(); // save cpu affinity mask to CPU_CFG file
825 set_cpu_affinity();
826 }
827
828 // save cgroup in CGROUP_CFG file
829 if (cfg.cgroup)
830 save_cgroup();
831
832 // set seccomp //todo: push it down after drop_privs and/or configuring noroot
683#ifdef HAVE_SECCOMP 833#ifdef HAVE_SECCOMP
684 // install protocol filter 834 // install protocol filter
685 if (cfg.protocol) { 835 if (cfg.protocol) {
686 protocol_filter(); // install filter 836 if (arg_debug)
687 protocol_filter_save(); // save filter in PROTOCOL_CFG 837 printf("Install protocol filter: %s\n", cfg.protocol);
838 seccomp_load(RUN_SECCOMP_PROTOCOL); // install filter
839 protocol_filter_save(); // save filter in RUN_PROTOCOL_CFG
688 } 840 }
689 841
690 // if a keep list is available, disregard the drop list 842 // if a keep list is available, disregard the drop list
691 if (arg_seccomp == 1) { 843 if (arg_seccomp == 1) {
692 if (cfg.seccomp_list_keep) 844 if (cfg.seccomp_list_keep)
693 seccomp_filter_keep(); 845 seccomp_filter_keep();
694 else if (cfg.seccomp_list_errno)
695 seccomp_filter_errno();
696 else 846 else
697 seccomp_filter_drop(enforce_seccomp); 847 seccomp_filter_drop(enforce_seccomp);
698 } 848 }
699#endif 849#endif
700 850
701 // set cpu affinity
702 if (cfg.cpus) {
703 save_cpu(); // save cpu affinity mask to CPU_CFG file
704 set_cpu_affinity();
705 }
706
707 // save cgroup in CGROUP_CFG file
708 if (cfg.cgroup)
709 save_cgroup();
710
711 //**************************************** 851 //****************************************
712 // drop privileges or create a new user namespace 852 // drop privileges or create a new user namespace
713 //**************************************** 853 //****************************************
@@ -715,7 +855,7 @@ int sandbox(void* sandbox_arg) {
715 if (arg_noroot) { 855 if (arg_noroot) {
716 int rv = unshare(CLONE_NEWUSER); 856 int rv = unshare(CLONE_NEWUSER);
717 if (rv == -1) { 857 if (rv == -1) {
718 fprintf(stderr, "Warning: cannot mount a new user namespace, going forward without it...\n"); 858 fprintf(stderr, "Warning: cannot create a new user namespace, going forward without it...\n");
719 drop_privs(arg_nogroups); 859 drop_privs(arg_nogroups);
720 arg_noroot = 0; 860 arg_noroot = 0;
721 } 861 }
@@ -739,6 +879,18 @@ int sandbox(void* sandbox_arg) {
739 printf("noroot user namespace installed\n"); 879 printf("noroot user namespace installed\n");
740 set_caps(); 880 set_caps();
741 } 881 }
882
883 //****************************************
884 // Set NO_NEW_PRIVS if desired
885 //****************************************
886 if (arg_nonewprivs) {
887 int no_new_privs = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
888
889 if(no_new_privs != 0)
890 fprintf(stderr, "Warning: NO_NEW_PRIVS disabled, it requires a Linux kernel version 3.5 or newer.\n");
891 else if (arg_debug)
892 printf("NO_NEW_PRIVS set\n");
893 }
742 894
743 //**************************************** 895 //****************************************
744 // fork the application and monitor it 896 // fork the application and monitor it
@@ -746,13 +898,27 @@ int sandbox(void* sandbox_arg) {
746 pid_t app_pid = fork(); 898 pid_t app_pid = fork();
747 if (app_pid == -1) 899 if (app_pid == -1)
748 errExit("fork"); 900 errExit("fork");
749 901
750 if (app_pid == 0) { 902 if (app_pid == 0) {
903#ifdef HAVE_APPARMOR
904 if (arg_apparmor) {
905 errno = 0;
906 if (aa_change_onexec("firejail-default")) {
907 fprintf(stderr, "Error: cannot confine the application using AppArmor.\n");
908 fprintf(stderr, "Maybe firejail-default AppArmor profile is not loaded into the kernel.\n");
909 fprintf(stderr, "As root, run \"aa-enforce firejail-default\" to load it.\n");
910 exit(1);
911 }
912 else if (arg_debug)
913 printf("AppArmor enabled\n");
914 }
915#endif
751 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died 916 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died
752 start_application(); // start app 917 start_application(); // start app
753 } 918 }
754 919
755 int status = monitor_application(app_pid); // monitor application 920 int status = monitor_application(app_pid); // monitor application
921 flush_stdin();
756 922
757 if (WIFEXITED(status)) { 923 if (WIFEXITED(status)) {
758 // if we had a proper exit, return that exit status 924 // if we had a proper exit, return that exit status
diff --git a/src/firejail/sbox.c b/src/firejail/sbox.c
new file mode 100644
index 000000000..430ffb86e
--- /dev/null
+++ b/src/firejail/sbox.c
@@ -0,0 +1,206 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "firejail.h"
21#include <sys/types.h>
22#include <sys/stat.h>
23#include <unistd.h>
24#include <net/if.h>
25#include <stdarg.h>
26 #include <sys/wait.h>
27#include "../include/seccomp.h"
28
29static struct sock_filter filter[] = {
30 VALIDATE_ARCHITECTURE,
31 EXAMINE_SYSCALL,
32
33#if defined(__x86_64__)
34#define X32_SYSCALL_BIT 0x40000000
35 // handle X32 ABI
36 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, X32_SYSCALL_BIT, 1, 0),
37 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 0, 1, 0),
38 RETURN_ERRNO(EPERM),
39#endif
40
41 // syscall list
42#ifdef SYS_mount
43 BLACKLIST(SYS_mount), // mount/unmount filesystems
44#endif
45#ifdef SYS_umount2
46 BLACKLIST(SYS_umount2),
47#endif
48#ifdef SYS_ptrace
49 BLACKLIST(SYS_ptrace), // trace processes
50#endif
51#ifdef SYS_kexec_file_load
52 BLACKLIST(SYS_kexec_file_load),
53#endif
54#ifdef SYS_kexec_load
55 BLACKLIST(SYS_kexec_load), // loading a different kernel
56#endif
57#ifdef SYS_name_to_handle_at
58 BLACKLIST(SYS_name_to_handle_at),
59#endif
60#ifdef SYS_open_by_handle_at
61 BLACKLIST(SYS_open_by_handle_at), // open by handle
62#endif
63#ifdef SYS_init_module
64 BLACKLIST(SYS_init_module), // kernel module handling
65#endif
66#ifdef SYS_finit_module // introduced in 2013
67 BLACKLIST(SYS_finit_module),
68#endif
69#ifdef SYS_create_module
70 BLACKLIST(SYS_create_module),
71#endif
72#ifdef SYS_delete_module
73 BLACKLIST(SYS_delete_module),
74#endif
75#ifdef SYS_iopl
76 BLACKLIST(SYS_iopl), // io permissions
77#endif
78#ifdef SYS_ioperm
79 BLACKLIST(SYS_ioperm),
80#endif
81#ifdef SYS_iopl
82 BLACKLIST(SYS_iopl), // io permissions
83#endif
84#ifdef SYS_ioprio_set
85 BLACKLIST(SYS_ioprio_set),
86#endif
87#ifdef SYS_ni_syscall // new io permissions call on arm devices
88 BLACKLIST(SYS_ni_syscall),
89#endif
90#ifdef SYS_swapon
91 BLACKLIST(SYS_swapon), // swap on/off
92#endif
93#ifdef SYS_swapoff
94 BLACKLIST(SYS_swapoff),
95#endif
96#ifdef SYS_syslog
97 BLACKLIST(SYS_syslog), // kernel printk control
98#endif
99 RETURN_ALLOW
100};
101
102static struct sock_fprog prog = {
103 .len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
104 .filter = filter,
105};
106
107typedef struct sbox_config {
108 char *name;
109 char *path;
110 unsigned filters;
111} SboxConfig;
112
113
114int sbox_run(unsigned filter, int num, ...) {
115 EUID_ROOT();
116
117 int i;
118 va_list valist;
119 va_start(valist, num);
120
121 // build argument list
122 char *arg[num + 1];
123 for (i = 0; i < num; i++)
124 arg[i] = va_arg(valist, char*);
125 arg[i] = NULL;
126 va_end(valist);
127
128 if (arg_debug) {
129 printf("sbox run: ");
130 for (i = 0; i <= num; i++)
131 printf("%s ", arg[i]);
132 printf("\n");
133 }
134
135 pid_t child = fork();
136 if (child < 0)
137 errExit("fork");
138 if (child == 0) {
139 // clean the new process
140 clearenv();
141 int max = 20; // getdtablesize() is overkill for a firejail process
142 for (i = 3; i < max; i++)
143 close(i); // close open files
144 if ((filter & SBOX_ALLOW_STDIN) == 0) {
145 int fd = open("/dev/null",O_RDWR, 0);
146 if (fd != -1) {
147 dup2 (fd, STDIN_FILENO);
148 if (fd > 2)
149 close (fd);
150 }
151 else // the user could run the sandbox without /dev/null
152 close(STDIN_FILENO);
153 }
154 umask(027);
155
156 // apply filters
157 if (filter & SBOX_CAPS_NONE) {
158 caps_drop_all();
159 }
160 else if (filter & SBOX_CAPS_NETWORK) {
161#ifndef HAVE_GCOV // the following filter will prevent GCOV from saving info in .gcda files
162 uint64_t set = ((uint64_t) 1) << CAP_NET_ADMIN;
163 set |= ((uint64_t) 1) << CAP_NET_RAW;
164 caps_set(set);
165#endif
166 }
167
168 if (filter & SBOX_SECCOMP) {
169 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
170 perror("prctl(NO_NEW_PRIVS)");
171 }
172 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
173 perror("prctl(PR_SET_SECCOMP)");
174 }
175 }
176
177 if (filter & SBOX_ROOT) {
178 // elevate privileges in order to get grsecurity working
179 if (setreuid(0, 0))
180 errExit("setreuid");
181 if (setregid(0, 0))
182 errExit("setregid");
183 }
184 else if (filter & SBOX_USER)
185 drop_privs(1);
186
187 clearenv();
188 if (arg[0]) // get rid of scan-build warning
189 execvp(arg[0], arg);
190 else
191 assert(0);
192 perror("execl");
193 _exit(1);
194 }
195
196 int status;
197 if (waitpid(child, &status, 0) == -1 ) {
198 errExit("waitpid");
199 }
200 if (WIFEXITED(status) && status != 0) {
201 fprintf(stderr, "Error: failed to run %s\n", arg[0]);
202 exit(1);
203 }
204
205 return status;
206}
diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c
index 7108b5a05..4a2221e98 100644
--- a/src/firejail/seccomp.c
+++ b/src/firejail/seccomp.c
@@ -20,798 +20,216 @@
20 20
21#ifdef HAVE_SECCOMP 21#ifdef HAVE_SECCOMP
22#include "firejail.h" 22#include "firejail.h"
23#include "seccomp.h" 23#include "../include/seccomp.h"
24
25#define SECSIZE 128 // initial filter size
26static struct sock_filter *sfilter = NULL;
27static int sfilter_alloc_size = 0;
28static int sfilter_index = 0;
29
30// debug filter
31void filter_debug(void) {
32 // start filter
33 struct sock_filter filter[] = {
34 VALIDATE_ARCHITECTURE,
35 EXAMINE_SYSCALL
36 };
37 24
38 // print sizes 25char *seccomp_check_list(const char *str) {
39 printf("SECCOMP Filter:\n"); 26 assert(str);
40 if (sfilter == NULL) { 27 if (strlen(str) == 0) {
41 printf("SECCOMP filter not allocated\n"); 28 fprintf(stderr, "Error: empty syscall lists are not allowed\n");
42 return; 29 exit(1);
43 } 30 }
44 if (sfilter_index < 4)
45 return;
46 31
47 // test the start of the filter 32 int len = strlen(str) + 1;
48 if (memcmp(sfilter, filter, sizeof(filter)) == 0) { 33 char *rv = malloc(len);
49 printf(" VALIDATE_ARCHITECTURE\n"); 34 if (!rv)
50 printf(" EXAMINE_SYSCAL\n"); 35 errExit("malloc");
51 } 36 memset(rv, 0, len);
52 37
53 // loop trough blacklists 38 const char *ptr1 = str;
54 int i = 4; 39 char *ptr2 = rv;
55 while (i < sfilter_index) { 40 while (*ptr1 != '\0') {
56 // minimal parsing! 41 if (isalnum(*ptr1) || *ptr1 == '_' || *ptr1 == ',' || *ptr1 == ':')
57 unsigned char *ptr = (unsigned char *) &sfilter[i]; 42 *ptr2++ = *ptr1++;
58 int *nr = (int *) (ptr + 4);
59 if (*ptr == 0x15 && *(ptr +14) == 0xff && *(ptr + 15) == 0x7f ) {
60 printf(" WHITELIST %d %s\n", *nr, syscall_find_nr(*nr));
61 i += 2;
62 }
63 else if (*ptr == 0x15 && *(ptr +14) == 0 && *(ptr + 15) == 0) {
64 printf(" BLACKLIST %d %s\n", *nr, syscall_find_nr(*nr));
65 i += 2;
66 }
67 else if (*ptr == 0x15 && *(ptr +14) == 0x5 && *(ptr + 15) == 0) {
68 int err = *(ptr + 13) << 8 | *(ptr + 12);
69 printf(" ERRNO %d %s %d %s\n", *nr, syscall_find_nr(*nr), err, errno_find_nr(err));
70 i += 2;
71 }
72 else if (*ptr == 0x06 && *(ptr +6) == 0 && *(ptr + 7) == 0 ) {
73 printf(" KILL_PROCESS\n");
74 i++;
75 }
76 else if (*ptr == 0x06 && *(ptr +6) == 0xff && *(ptr + 7) == 0x7f ) {
77 printf(" RETURN_ALLOW\n");
78 i++;
79 }
80 else { 43 else {
81 printf(" UNKNOWN ENTRY!!!\n"); 44 fprintf(stderr, "Error: invalid syscall list\n");
82 i++; 45 exit(1);
83 } 46 }
84 } 47 }
48
49 return rv;
85} 50}
86 51
87// initialize filter
88static void filter_init(void) {
89 if (sfilter) {
90 assert(0);
91 return;
92 }
93
94// if (arg_debug)
95// printf("Initialize seccomp filter\n");
96 // allocate a filter of SECSIZE
97 sfilter = malloc(sizeof(struct sock_filter) * SECSIZE);
98 if (!sfilter)
99 errExit("malloc");
100 memset(sfilter, 0, sizeof(struct sock_filter) * SECSIZE);
101 sfilter_alloc_size = SECSIZE;
102
103 // copy the start entries
104 struct sock_filter filter[] = {
105 VALIDATE_ARCHITECTURE,
106 EXAMINE_SYSCALL
107 };
108 sfilter_index = sizeof(filter) / sizeof(struct sock_filter);
109 memcpy(sfilter, filter, sizeof(filter));
110}
111
112static void filter_realloc(void) {
113 assert(sfilter);
114 assert(sfilter_alloc_size);
115 assert(sfilter_index);
116 if (arg_debug)
117 printf("Allocating more seccomp filter entries\n");
118
119 // allocate the new memory
120 struct sock_filter *old = sfilter;
121 sfilter = malloc(sizeof(struct sock_filter) * (sfilter_alloc_size + SECSIZE));
122 if (!sfilter)
123 errExit("malloc");
124 memset(sfilter, 0, sizeof(struct sock_filter) * (sfilter_alloc_size + SECSIZE));
125
126 // copy old filter
127 memcpy(sfilter, old, sizeof(struct sock_filter) * sfilter_alloc_size);
128 sfilter_alloc_size += SECSIZE;
129}
130
131static void filter_add_whitelist(int syscall, int arg) {
132 (void) arg;
133 assert(sfilter);
134 assert(sfilter_alloc_size);
135 assert(sfilter_index);
136// if (arg_debug)
137// printf("Whitelisting syscall %d %s\n", syscall, syscall_find_nr(syscall));
138
139 if ((sfilter_index + 2) > sfilter_alloc_size)
140 filter_realloc();
141
142 struct sock_filter filter[] = {
143 WHITELIST(syscall)
144 };
145#if 0
146{
147 int i;
148 unsigned char *ptr = (unsigned char *) &filter[0];
149 for (i = 0; i < sizeof(filter); i++, ptr++)
150 printf("%x, ", (*ptr) & 0xff);
151 printf("\n");
152}
153#endif
154 memcpy(&sfilter[sfilter_index], filter, sizeof(filter));
155 sfilter_index += sizeof(filter) / sizeof(struct sock_filter);
156}
157
158static void filter_add_blacklist(int syscall, int arg) {
159 (void) arg;
160 assert(sfilter);
161 assert(sfilter_alloc_size);
162 assert(sfilter_index);
163// if (arg_debug)
164// printf("Blacklisting syscall %d %s\n", syscall, syscall_find_nr(syscall));
165
166 if ((sfilter_index + 2) > sfilter_alloc_size)
167 filter_realloc();
168
169 struct sock_filter filter[] = {
170 BLACKLIST(syscall)
171 };
172#if 0
173{
174 int i;
175 unsigned char *ptr = (unsigned char *) &filter[0];
176 for (i = 0; i < sizeof(filter); i++, ptr++)
177 printf("%x, ", (*ptr) & 0xff);
178 printf("\n");
179}
180#endif
181 memcpy(&sfilter[sfilter_index], filter, sizeof(filter));
182 sfilter_index += sizeof(filter) / sizeof(struct sock_filter);
183}
184
185static void filter_add_errno(int syscall, int arg) {
186 assert(sfilter);
187 assert(sfilter_alloc_size);
188 assert(sfilter_index);
189// if (arg_debug)
190// printf("Errno syscall %d %d %s\n", syscall, arg, syscall_find_nr(syscall));
191
192 if ((sfilter_index + 2) > sfilter_alloc_size)
193 filter_realloc();
194
195 struct sock_filter filter[] = {
196 BLACKLIST_ERRNO(syscall, arg)
197 };
198#if 0
199{
200 int i;
201 unsigned char *ptr = (unsigned char *) &filter[0];
202 for (i = 0; i < sizeof(filter); i++, ptr++)
203 printf("%x, ", (*ptr) & 0xff);
204 printf("\n");
205}
206#endif
207 memcpy(&sfilter[sfilter_index], filter, sizeof(filter));
208 sfilter_index += sizeof(filter) / sizeof(struct sock_filter);
209}
210
211static void filter_end_blacklist(void) {
212 assert(sfilter);
213 assert(sfilter_alloc_size);
214 assert(sfilter_index);
215// if (arg_debug)
216// printf("Ending syscall filter\n");
217
218 if ((sfilter_index + 2) > sfilter_alloc_size)
219 filter_realloc();
220
221 struct sock_filter filter[] = {
222 RETURN_ALLOW
223 };
224#if 0
225{
226 int i;
227 unsigned char *ptr = (unsigned char *) &filter[0];
228 for (i = 0; i < sizeof(filter); i++, ptr++)
229 printf("%x, ", (*ptr) & 0xff);
230 printf("\n");
231}
232#endif
233 memcpy(&sfilter[sfilter_index], filter, sizeof(filter));
234 sfilter_index += sizeof(filter) / sizeof(struct sock_filter);
235}
236
237static void filter_end_whitelist(void) {
238 assert(sfilter);
239 assert(sfilter_alloc_size);
240 assert(sfilter_index);
241 if (arg_debug)
242 printf("Ending syscall filter\n");
243
244 if ((sfilter_index + 2) > sfilter_alloc_size)
245 filter_realloc();
246
247 struct sock_filter filter[] = {
248 KILL_PROCESS
249 };
250#if 0
251{
252 int i;
253 unsigned char *ptr = (unsigned char *) &filter[0];
254 for (i = 0; i < sizeof(filter); i++, ptr++)
255 printf("%x, ", (*ptr) & 0xff);
256 printf("\n");
257}
258#endif
259 memcpy(&sfilter[sfilter_index], filter, sizeof(filter));
260 sfilter_index += sizeof(filter) / sizeof(struct sock_filter);
261}
262
263
264// save seccomp filter in /run/firejail/mnt/seccomp
265static void write_seccomp_file(void) {
266 fs_build_mnt_dir();
267 assert(sfilter);
268 52
269 int fd = open(RUN_SECCOMP_CFG, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); 53int seccomp_load(const char *fname) {
270 if (fd == -1) 54 assert(fname);
271 errExit("open");
272
273 if (arg_debug)
274 printf("Save seccomp filter, size %u bytes\n", (unsigned) (sfilter_index * sizeof(struct sock_filter)));
275 errno = 0;
276 ssize_t sz = write(fd, sfilter, sfilter_index * sizeof(struct sock_filter));
277 if (sz != (ssize_t)(sfilter_index * sizeof(struct sock_filter))) {
278 fprintf(stderr, "Error: cannot save seccomp filter\n");
279 exit(1);
280 }
281 close(fd);
282 if (chown(RUN_SECCOMP_CFG, 0, 0) < 0)
283 errExit("chown");
284}
285
286// read seccomp filter from /run/firejail/mnt/seccomp
287static void read_seccomp_file(const char *fname) {
288 assert(sfilter == NULL && sfilter_index == 0);
289 55
290 // check file 56 // check file
291 struct stat s; 57 struct stat s;
292 if (stat(fname, &s) == -1) { 58 if (stat(fname, &s) == -1) {
293 fprintf(stderr, "Warning: seccomp file not found\n"); 59 fprintf(stderr, "Error: cannot read protocol filter file\n");
294 return;
295 }
296 ssize_t sz = s.st_size;
297 if (sz == 0 || (sz % sizeof(struct sock_filter)) != 0) {
298 fprintf(stderr, "Error: invalid seccomp file\n");
299 exit(1); 60 exit(1);
300 } 61 }
301 sfilter = malloc(sz); 62 int size = s.st_size;
302 if (!sfilter) 63 unsigned short entries = (unsigned short) size / (unsigned short) sizeof(struct sock_filter);
303 errExit("malloc"); 64//printf("size %d, entries %d\n", s.st_size, entries);
304 65
305 // read file 66 // read filter
306 /* coverity[toctou] */ 67 struct sock_filter filter[entries];
307 int fd = open(fname,O_RDONLY); 68 memset(&filter[0], 0, sizeof(filter));
308 if (fd == -1) 69 int src = open(fname, O_RDONLY);
309 errExit("open"); 70 int rd = 0;
310 errno = 0; 71 while (rd < size) {
311 ssize_t size = read(fd, sfilter, sz); 72 int rv = read(src, (unsigned char *) filter + rd, size - rd);
312 if (size != sz) { 73 if (rv == -1) {
313 fprintf(stderr, "Error: invalid seccomp file\n"); 74 fprintf(stderr, "Error: cannot read %s file\n", fname);
314 exit(1); 75 exit(1);
76 }
77 rd += rv;
315 } 78 }
316 sfilter_index = sz / sizeof(struct sock_filter); 79 close(src);
317 80
318 if (arg_debug) 81 // install filter
319 printf("Read seccomp filter, size %u bytes\n", (unsigned) (sfilter_index * sizeof(struct sock_filter))); 82 struct sock_fprog prog = {
83 .len = entries,
84 .filter = filter,
85 };
320 86
321 close(fd); 87 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
88 fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n");
89 return 1;
90 }
322 91
323 if (arg_debug) 92 return 0;
324 filter_debug();
325} 93}
326 94
95
96
97
327// i386 filter installed on amd64 architectures 98// i386 filter installed on amd64 architectures
328void seccomp_filter_32(void) { 99void seccomp_filter_32(void) {
329 // hardcoded syscall values 100 if (arg_debug)
330 struct sock_filter filter[] = { 101 printf("Build secondary 32-bit filter\n");
331 VALIDATE_ARCHITECTURE_32,
332 EXAMINE_SYSCALL,
333 BLACKLIST(21), // mount
334 BLACKLIST(52), // umount2
335 BLACKLIST(26), // ptrace
336 BLACKLIST(283), // kexec_load
337 BLACKLIST(342), // open_by_handle_at
338 BLACKLIST(128), // init_module
339 BLACKLIST(350), // finit_module
340 BLACKLIST(129), // delete_module
341 BLACKLIST(110), // iopl
342 BLACKLIST(101), // ioperm
343 BLACKLIST(87), // swapon
344 BLACKLIST(115), // swapoff
345 BLACKLIST(103), // syslog
346 BLACKLIST(347), // process_vm_readv
347 BLACKLIST(348), // process_vm_writev
348 BLACKLIST(135), // sysfs
349 BLACKLIST(149), // _sysctl
350 BLACKLIST(124), // adjtimex
351 BLACKLIST(343), // clock_adjtime
352 BLACKLIST(253), // lookup_dcookie
353 BLACKLIST(336), // perf_event_open
354 BLACKLIST(338), // fanotify_init
355 BLACKLIST(349), // kcmp
356 BLACKLIST(286), // add_key
357 BLACKLIST(287), // request_key
358 BLACKLIST(288), // keyctl
359 BLACKLIST(86), // uselib
360 BLACKLIST(51), // acct
361 BLACKLIST(123), // modify_ldt
362 BLACKLIST(217), // pivot_root
363 BLACKLIST(245), // io_setup
364 BLACKLIST(246), // io_destroy
365 BLACKLIST(247), // io_getevents
366 BLACKLIST(248), // io_submit
367 BLACKLIST(249), // io_cancel
368 BLACKLIST(257), // remap_file_pages
369 BLACKLIST(274), // mbind
370 BLACKLIST(275), // get_mempolicy
371 BLACKLIST(276), // set_mempolicy
372 BLACKLIST(294), // migrate_pages
373 BLACKLIST(317), // move_pages
374 BLACKLIST(316), // vmsplice
375 BLACKLIST(61), // chroot
376 BLACKLIST(88), // reboot
377 BLACKLIST(169), // nfsservctl
378 BLACKLIST(130), // get_kernel_syms
379 RETURN_ALLOW
380 };
381 102
382 struct sock_fprog prog = { 103 // build the seccomp filter as a regular user
383 .len = (unsigned short)(sizeof(filter) / sizeof(filter[0])), 104 int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 4,
384 .filter = filter, 105 PATH_FSECCOMP, "secondary", "32", RUN_SECCOMP_I386);
385 }; 106 if (rv)
107 exit(rv);
386 108
387 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { 109 if (seccomp_load(RUN_SECCOMP_I386) == 0) {
388 ; 110 if (arg_debug)
389 } 111 printf("Dual i386/amd64 seccomp filter configured\n");
390 else if (arg_debug) {
391 printf("Dual i386/amd64 seccomp filter configured\n");
392 } 112 }
393} 113}
394 114
395// amd64 filter installed on i386 architectures 115// amd64 filter installed on i386 architectures
396void seccomp_filter_64(void) { 116void seccomp_filter_64(void) {
397 // hardcoded syscall values 117 if (arg_debug)
398 struct sock_filter filter[] = { 118 printf("Build secondary 64-bit filter\n");
399 VALIDATE_ARCHITECTURE_64,
400 EXAMINE_SYSCALL,
401 BLACKLIST(165), // mount
402 BLACKLIST(166), // umount2
403 BLACKLIST(101), // ptrace
404 BLACKLIST(246), // kexec_load
405 BLACKLIST(304), // open_by_handle_at
406 BLACKLIST(175), // init_module
407 BLACKLIST(313), // finit_module
408 BLACKLIST(176), // delete_module
409 BLACKLIST(172), // iopl
410 BLACKLIST(173), // ioperm
411 BLACKLIST(167), // swapon
412 BLACKLIST(168), // swapoff
413 BLACKLIST(103), // syslog
414 BLACKLIST(310), // process_vm_readv
415 BLACKLIST(311), // process_vm_writev
416 BLACKLIST(139), // sysfs
417 BLACKLIST(156), // _sysctl
418 BLACKLIST(159), // adjtimex
419 BLACKLIST(305), // clock_adjtime
420 BLACKLIST(212), // lookup_dcookie
421 BLACKLIST(298), // perf_event_open
422 BLACKLIST(300), // fanotify_init
423 BLACKLIST(312), // kcmp
424 BLACKLIST(248), // add_key
425 BLACKLIST(249), // request_key
426 BLACKLIST(250), // keyctl
427 BLACKLIST(134), // uselib
428 BLACKLIST(163), // acct
429 BLACKLIST(154), // modify_ldt
430 BLACKLIST(155), // pivot_root
431 BLACKLIST(206), // io_setup
432 BLACKLIST(207), // io_destroy
433 BLACKLIST(208), // io_getevents
434 BLACKLIST(209), // io_submit
435 BLACKLIST(210), // io_cancel
436 BLACKLIST(216), // remap_file_pages
437 BLACKLIST(237), // mbind
438 BLACKLIST(239), // get_mempolicy
439 BLACKLIST(238), // set_mempolicy
440 BLACKLIST(256), // migrate_pages
441 BLACKLIST(279), // move_pages
442 BLACKLIST(278), // vmsplice
443 BLACKLIST(161), // chroot
444 BLACKLIST(184), // tuxcall
445 BLACKLIST(169), // reboot
446 BLACKLIST(180), // nfsservctl
447 BLACKLIST(177), // get_kernel_syms
448 RETURN_ALLOW
449 };
450 119
451 struct sock_fprog prog = { 120 // build the seccomp filter as a regular user
452 .len = (unsigned short)(sizeof(filter) / sizeof(filter[0])), 121 int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 4,
453 .filter = filter, 122 PATH_FSECCOMP, "secondary", "64", RUN_SECCOMP_AMD64);
454 }; 123 if (rv)
124 exit(rv);
455 125
456 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { 126 if (seccomp_load(RUN_SECCOMP_AMD64) == 0) {
457 ; 127 if (arg_debug)
458 } 128 printf("Dual i386/amd64 seccomp filter configured\n");
459 else if (arg_debug) {
460 printf("Dual i386/amd64 seccomp filter configured\n");
461 } 129 }
462} 130}
463 131
464 132
465// drop filter for seccomp option 133// drop filter for seccomp option
466int seccomp_filter_drop(int enforce_seccomp) { 134int seccomp_filter_drop(int enforce_seccomp) {
467 filter_init();
468
469 // default seccomp 135 // default seccomp
470 if (cfg.seccomp_list_drop == NULL) { 136 if (cfg.seccomp_list_drop == NULL && cfg.seccomp_list == NULL) {
471#if defined(__x86_64__) 137#if defined(__x86_64__)
472 seccomp_filter_32(); 138 seccomp_filter_32();
473#endif 139#endif
474#if defined(__i386__) 140#if defined(__i386__)
475 seccomp_filter_64(); 141 seccomp_filter_64();
476#endif 142#endif
143 if (arg_debug)
144 printf("Build default seccomp filter\n");
145 // build the seccomp filter as a regular user
146 int rv;
147 if (arg_allow_debuggers)
148 rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 4,
149 PATH_FSECCOMP, "default", RUN_SECCOMP_CFG, "allow-debuggers");
150 else
151 rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 3,
152 PATH_FSECCOMP, "default", RUN_SECCOMP_CFG);
153 if (rv)
154 exit(rv);
155 }
477 156
478#ifdef SYS_mount 157 // default seccomp filter with additional drop list
479 filter_add_blacklist(SYS_mount, 0); 158 else if (cfg.seccomp_list && cfg.seccomp_list_drop == NULL) {
480#endif 159#if defined(__x86_64__)
481#ifdef SYS_umount2 160 seccomp_filter_32();
482 filter_add_blacklist(SYS_umount2, 0);
483#endif
484#ifdef SYS_ptrace
485 filter_add_blacklist(SYS_ptrace, 0);
486#endif
487#ifdef SYS_kexec_load
488 filter_add_blacklist(SYS_kexec_load, 0);
489#endif
490#ifdef SYS_kexec_file_load
491 filter_add_blacklist(SYS_kexec_file_load, 0);
492#endif
493#ifdef SYS_open_by_handle_at
494 filter_add_blacklist(SYS_open_by_handle_at, 0);
495#endif
496#ifdef SYS_init_module
497 filter_add_blacklist(SYS_init_module, 0);
498#endif
499#ifdef SYS_finit_module // introduced in 2013
500 filter_add_blacklist(SYS_finit_module, 0);
501#endif
502#ifdef SYS_delete_module
503 filter_add_blacklist(SYS_delete_module, 0);
504#endif
505#ifdef SYS_iopl
506 filter_add_blacklist(SYS_iopl, 0);
507#endif
508#ifdef SYS_ioperm
509 filter_add_blacklist(SYS_ioperm, 0);
510#endif
511#ifdef SYS_ni_syscall // new io permissions call on arm devices
512 filter_add_blacklist(SYS_ni_syscall, 0);
513#endif
514#ifdef SYS_swapon
515 filter_add_blacklist(SYS_swapon, 0);
516#endif
517#ifdef SYS_swapoff
518 filter_add_blacklist(SYS_swapoff, 0);
519#endif
520#ifdef SYS_syslog
521 filter_add_blacklist(SYS_syslog, 0);
522#endif
523#ifdef SYS_process_vm_readv
524 filter_add_blacklist(SYS_process_vm_readv, 0);
525#endif 161#endif
526#ifdef SYS_process_vm_writev 162#if defined(__i386__)
527 filter_add_blacklist(SYS_process_vm_writev, 0); 163 seccomp_filter_64();
528#endif 164#endif
529 165 if (arg_debug)
530// mknod removed in 0.9.29 - it brakes Zotero extension 166 printf("Build default+drop seccomp filter\n");
531//#ifdef SYS_mknod
532// filter_add_blacklist(SYS_mknod, 0);
533//#endif
534 167
535 // new syscalls in 0.9,23 168 // build the seccomp filter as a regular user
536#ifdef SYS_sysfs 169 int rv;
537 filter_add_blacklist(SYS_sysfs, 0); 170 if (arg_allow_debuggers)
538#endif 171 rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 6,
539#ifdef SYS__sysctl 172 PATH_FSECCOMP, "default", "drop", RUN_SECCOMP_CFG, cfg.seccomp_list, "allow-debuggers");
540 filter_add_blacklist(SYS__sysctl, 0); 173 else
541#endif 174 rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 5,
542#ifdef SYS_adjtimex 175 PATH_FSECCOMP, "default", "drop", RUN_SECCOMP_CFG, cfg.seccomp_list);
543 filter_add_blacklist(SYS_adjtimex, 0); 176 if (rv)
544#endif 177 exit(rv);
545#ifdef SYS_clock_adjtime
546 filter_add_blacklist(SYS_clock_adjtime, 0);
547#endif
548#ifdef SYS_lookup_dcookie
549 filter_add_blacklist(SYS_lookup_dcookie, 0);
550#endif
551#ifdef SYS_perf_event_open
552 filter_add_blacklist(SYS_perf_event_open, 0);
553#endif
554#ifdef SYS_fanotify_init
555 filter_add_blacklist(SYS_fanotify_init, 0);
556#endif
557#ifdef SYS_kcmp
558 filter_add_blacklist(SYS_kcmp, 0);
559#endif
560
561// 0.9.32
562#ifdef SYS_add_key
563 filter_add_blacklist(SYS_add_key, 0);
564#endif
565#ifdef SYS_request_key
566 filter_add_blacklist(SYS_request_key, 0);
567#endif
568#ifdef SYS_keyctl
569 filter_add_blacklist(SYS_keyctl, 0);
570#endif
571#ifdef SYS_uselib
572 filter_add_blacklist(SYS_uselib, 0);
573#endif
574#ifdef SYS_acct
575 filter_add_blacklist(SYS_acct, 0);
576#endif
577#ifdef SYS_modify_ldt
578 filter_add_blacklist(SYS_modify_ldt, 0);
579#endif
580 //#ifdef SYS_unshare
581 // filter_add_blacklist(SYS_unshare, 0);
582 //#endif
583#ifdef SYS_pivot_root
584 filter_add_blacklist(SYS_pivot_root, 0);
585#endif
586 //#ifdef SYS_quotactl
587 // filter_add_blacklist(SYS_quotactl, 0);
588 //#endif
589#ifdef SYS_io_setup
590 filter_add_blacklist(SYS_io_setup, 0);
591#endif
592#ifdef SYS_io_destroy
593 filter_add_blacklist(SYS_io_destroy, 0);
594#endif
595#ifdef SYS_io_getevents
596 filter_add_blacklist(SYS_io_getevents, 0);
597#endif
598#ifdef SYS_io_submit
599 filter_add_blacklist(SYS_io_submit, 0);
600#endif
601#ifdef SYS_io_cancel
602 filter_add_blacklist(SYS_io_cancel, 0);
603#endif
604#ifdef SYS_remap_file_pages
605 filter_add_blacklist(SYS_remap_file_pages, 0);
606#endif
607#ifdef SYS_mbind
608 filter_add_blacklist(SYS_mbind, 0);
609#endif
610#ifdef SYS_get_mempolicy
611 filter_add_blacklist(SYS_get_mempolicy, 0);
612#endif
613#ifdef SYS_set_mempolicy
614 filter_add_blacklist(SYS_set_mempolicy, 0);
615#endif
616#ifdef SYS_migrate_pages
617 filter_add_blacklist(SYS_migrate_pages, 0);
618#endif
619#ifdef SYS_move_pages
620 filter_add_blacklist(SYS_move_pages, 0);
621#endif
622#ifdef SYS_vmsplice
623 filter_add_blacklist(SYS_vmsplice, 0);
624#endif
625#ifdef SYS_chroot
626 filter_add_blacklist(SYS_chroot, 0);
627#endif
628 //#ifdef SYS_set_robust_list
629 // filter_add_blacklist(SYS_set_robust_list, 0);
630 //#endif
631 //#ifdef SYS_get_robust_list
632 // filter_add_blacklist(SYS_get_robust_list, 0);
633 //#endif
634
635 // CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(clone), 1,
636 // SCMP_A0(SCMP_CMP_MASKED_EQ, CLONE_NEWUSER, CLONE_NEWUSER)));
637
638// 0.9.39
639#ifdef SYS_tuxcall
640 filter_add_blacklist(SYS_tuxcall, 0);
641#endif
642#ifdef SYS_reboot
643 filter_add_blacklist(SYS_reboot, 0);
644#endif
645#ifdef SYS_nfsservctl
646 filter_add_blacklist(SYS_nfsservctl, 0);
647#endif
648#ifdef SYS_get_kernel_syms
649 filter_add_blacklist(SYS_get_kernel_syms, 0);
650#endif
651 }
652
653 // default seccomp filter with additional drop list
654 if (cfg.seccomp_list && cfg.seccomp_list_drop == NULL) {
655 if (syscall_check_list(cfg.seccomp_list, filter_add_blacklist, 0)) {
656 fprintf(stderr, "Error: cannot load seccomp filter\n");
657 exit(1);
658 }
659 }
660 // drop list
661 else if (cfg.seccomp_list == NULL && cfg.seccomp_list_drop) {
662 if (syscall_check_list(cfg.seccomp_list_drop, filter_add_blacklist, 0)) {
663 fprintf(stderr, "Error: cannot load seccomp filter\n");
664 exit(1);
665 }
666 } 178 }
667 179
668 180 // drop list without defaults - secondary filters are not installed
669 filter_end_blacklist(); 181 else if (cfg.seccomp_list == NULL && cfg.seccomp_list_drop) {
670 if (arg_debug) 182 if (arg_debug)
671 filter_debug(); 183 printf("Build drop seccomp filter\n");
672 184
673 // save seccomp filter in /tmp/firejail/mnt/seccomp 185 // build the seccomp filter as a regular user
674 // in order to use it in --join operations 186 int rv;
675 write_seccomp_file(); 187 if (arg_allow_debuggers)
676 188 rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 5,
677 189 PATH_FSECCOMP, "drop", RUN_SECCOMP_CFG, cfg.seccomp_list_drop, "allow-debuggers");
678 struct sock_fprog prog = {
679 .len = sfilter_index,
680 .filter = sfilter,
681 };
682
683 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
684 if (enforce_seccomp) {
685 fprintf(stderr, "Error: a seccomp-enabled Linux kernel is required, exiting...\n");
686 exit(1);
687 }
688 else 190 else
689 fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); 191 rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 4,
192 PATH_FSECCOMP, "drop", RUN_SECCOMP_CFG, cfg.seccomp_list_drop);
690 193
691 return 1; 194 if (rv)
195 exit(rv);
692 } 196 }
693 197 else {
694 return 0; 198 assert(0);
695}
696
697// keep filter for seccomp option
698int seccomp_filter_keep(void) {
699 filter_init();
700
701 // these 4 syscalls are used by firejail after the seccomp filter is initialized
702 filter_add_whitelist(SYS_setuid, 0);
703 filter_add_whitelist(SYS_setgid, 0);
704 filter_add_whitelist(SYS_setgroups, 0);
705 filter_add_whitelist(SYS_dup, 0);
706
707 // apply keep list
708 if (cfg.seccomp_list_keep) {
709 if (syscall_check_list(cfg.seccomp_list_keep, filter_add_whitelist, 0)) {
710 fprintf(stderr, "Error: cannot load seccomp filter\n");
711 exit(1);
712 }
713 } 199 }
714 200
715 filter_end_whitelist(); 201 // load the filter
716 if (arg_debug) 202 if (seccomp_load(RUN_SECCOMP_CFG) == 0) {
717 filter_debug(); 203 if (arg_debug)
718 204 printf("seccomp filter configured\n");
719 // save seccomp filter in /tmp/firejail/mnt/seccomp
720 // in order to use it in --join operations
721 write_seccomp_file();
722
723
724 struct sock_fprog prog = {
725 .len = sfilter_index,
726 .filter = sfilter,
727 };
728
729 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
730 fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n");
731 return 1;
732 } 205 }
733 else if (arg_debug) { 206 else if (enforce_seccomp) {
734 printf("seccomp enabled\n"); 207 fprintf(stderr, "Error: a seccomp-enabled Linux kernel is required, exiting...\n");
208 exit(1);
735 } 209 }
736 210
737 return 0;
738}
739
740// errno filter for seccomp option
741int seccomp_filter_errno(void) {
742 int i;
743 int higest_errno = errno_highest_nr();
744 filter_init();
745
746 // apply errno list
747
748 for (i = 0; i < higest_errno; i++) {
749 if (cfg.seccomp_list_errno[i]) {
750 if (syscall_check_list(cfg.seccomp_list_errno[i], filter_add_errno, i)) {
751 fprintf(stderr, "Error: cannot load seccomp filter\n");
752 exit(1);
753 }
754 }
755 }
756
757 filter_end_blacklist();
758 if (arg_debug) 211 if (arg_debug)
759 filter_debug(); 212 sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 3,
760 213 PATH_FSECCOMP, "print", RUN_SECCOMP_CFG);
761 // save seccomp filter in /tmp/firejail/mnt/seccomp
762 // in order to use it in --join operations
763 write_seccomp_file();
764
765 struct sock_fprog prog = {
766 .len = sfilter_index,
767 .filter = sfilter,
768 };
769
770 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
771 fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n");
772 return 1;
773 }
774 else if (arg_debug) {
775 printf("seccomp enabled\n");
776 }
777 214
778 return 0; 215 return seccomp_load(RUN_SECCOMP_CFG);
779} 216}
780 217
781 218// keep filter for seccomp option
782 219int seccomp_filter_keep(void) {
783void seccomp_set(void) { 220 if (arg_debug)
784 // read seccomp filter from /tmp/firejail/mnt/seccomp 221 printf("Build drop seccomp filter\n");
785 read_seccomp_file(RUN_SECCOMP_CFG);
786
787 // apply filter
788 struct sock_fprog prog = {
789 .len = sfilter_index,
790 .filter = sfilter,
791 };
792 222
793 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { 223 // build the seccomp filter as a regular user
794 fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); 224 int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 4,
795 return; 225 PATH_FSECCOMP, "keep", RUN_SECCOMP_CFG, cfg.seccomp_list_keep);
796 } 226 if (rv)
797 else if (arg_debug) { 227 exit(rv);
798 printf("seccomp enabled\n"); 228 if (arg_debug)
799 } 229 printf("seccomp filter configured\n");
800}
801
802void seccomp_print_filter_name(const char *name) {
803 EUID_ASSERT();
804 if (!name || strlen(name) == 0) {
805 fprintf(stderr, "Error: invalid sandbox name\n");
806 exit(1);
807 }
808 pid_t pid;
809 if (name2pid(name, &pid)) {
810 fprintf(stderr, "Error: cannot find sandbox %s\n", name);
811 exit(1);
812 }
813 230
814 seccomp_print_filter(pid); 231
232 return seccomp_load(RUN_SECCOMP_CFG);
815} 233}
816 234
817void seccomp_print_filter(pid_t pid) { 235void seccomp_print_filter(pid_t pid) {
@@ -853,10 +271,11 @@ void seccomp_print_filter(pid_t pid) {
853 exit(1); 271 exit(1);
854 } 272 }
855 273
856 // read and print the filter 274 // read and print the filter - run this as root, the user doesn't have access
857 read_seccomp_file(fname); 275 int rv = sbox_run(SBOX_ROOT | SBOX_SECCOMP, 3,
858 drop_privs(1); 276 PATH_FSECCOMP, "print", fname);
859 filter_debug(); 277 if (rv)
278 exit(rv);
860 free(fname); 279 free(fname);
861 280
862 exit(0); 281 exit(0);
diff --git a/src/firejail/shutdown.c b/src/firejail/shutdown.c
index 8d8035bfb..c23e87321 100644
--- a/src/firejail/shutdown.c
+++ b/src/firejail/shutdown.c
@@ -23,22 +23,6 @@
23#include <fcntl.h> 23#include <fcntl.h>
24#include <sys/prctl.h> 24#include <sys/prctl.h>
25 25
26void shut_name(const char *name) {
27 EUID_ASSERT();
28 if (!name || strlen(name) == 0) {
29 fprintf(stderr, "Error: invalid sandbox name\n");
30 exit(1);
31 }
32
33 pid_t pid;
34 if (name2pid(name, &pid)) {
35 fprintf(stderr, "Error: cannot find sandbox %s\n", name);
36 exit(1);
37 }
38
39 shut(pid);
40}
41
42void shut(pid_t pid) { 26void shut(pid_t pid) {
43 EUID_ASSERT(); 27 EUID_ASSERT();
44 28
diff --git a/src/firejail/usage.c b/src/firejail/usage.c
index 539785f21..c8bed06e3 100644
--- a/src/firejail/usage.c
+++ b/src/firejail/usage.c
@@ -23,330 +23,190 @@ void usage(void) {
23 printf("firejail - version %s\n\n", VERSION); 23 printf("firejail - version %s\n\n", VERSION);
24 printf("Firejail is a SUID sandbox program that reduces the risk of security breaches by\n"); 24 printf("Firejail is a SUID sandbox program that reduces the risk of security breaches by\n");
25 printf("restricting the running environment of untrusted applications using Linux\n"); 25 printf("restricting the running environment of untrusted applications using Linux\n");
26 printf("namespaces. It includes a sandbox profile for Mozilla Firefox.\n\n"); 26 printf("namespaces.\n");
27 printf("\n"); 27 printf("\n");
28 printf("Usage: firejail [options] [program and arguments]\n\n"); 28 printf("Usage: firejail [options] [program and arguments]\n");
29 printf("\n"); 29 printf("\n");
30 printf("Without any options, the sandbox consists of a filesystem chroot build from the\n"); 30 printf("Options:\n");
31 printf("current system directories mounted read-only, and new PID and IPC\n"); 31 printf(" -- - signal the end of options and disables further option processing.\n");
32 printf("namespaces. If no program is specified as an argument, /bin/bash is started by\n"); 32 printf(" --allow-debuggers - allow tools such as strace and gdb inside the sandbox.\n");
33 printf("default in the sandbox.\n\n"); 33 printf(" --allusers - all user home directories are visible inside the sandbox.\n");
34 printf("\n"); 34 printf(" --apparmor - enable AppArmor confinement.\n");
35 printf("Options:\n\n"); 35 printf(" --appimage - sandbox an AppImage application.\n");
36 printf(" -- - signal the end of options and disables further option processing.\n\n"); 36 printf(" --audit[=test-program] - audit the sandbox.\n");
37#ifdef HAVE_NETWORK 37#ifdef HAVE_NETWORK
38 printf(" --bandwidth=name|pid - set bandwidth limits for the sandbox identified\n"); 38 printf(" --bandwidth=name|pid - set bandwidth limits\n");
39 printf("\tby name or PID, see Traffic Shaping section fo more details.\n\n");
40#endif 39#endif
41#ifdef HAVE_BIND 40#ifdef HAVE_BIND
42 printf(" --bind=dirname1,dirname2 - mount-bind dirname1 on top of dirname2.\n\n"); 41 printf(" --bind=dirname1,dirname2 - mount-bind dirname1 on top of dirname2.\n");
43 printf(" --bind=filename1,filename2 - mount-bind filename1 on top of filename2.\n\n"); 42 printf(" --bind=filename1,filename2 - mount-bind filename1 on top of filename2.\n");
44#endif 43#endif
45 printf(" --blacklist=dirname_or_filename - blacklist directory or file.\n\n"); 44 printf(" --blacklist=filename - blacklist directory or file.\n");
46 printf(" -c - execute command and exit.\n\n"); 45 printf(" -c - execute command and exit.\n");
47 printf(" --caps - enable default Linux capabilities filter.\n\n"); 46 printf(" --caps - enable default Linux capabilities filter.\n");
48 printf(" --caps.drop=all - drop all capabilities.\n\n"); 47 printf(" --caps.drop=all - drop all capabilities.\n");
49 printf(" --caps.drop=capability,capability - blacklist capabilities filter.\n\n"); 48 printf(" --caps.drop=capability,capability - blacklist capabilities filter.\n");
50 printf(" --caps.keep=capability,capability - whitelist capabilities filter.\n\n"); 49 printf(" --caps.keep=capability,capability - whitelist capabilities filter.\n");
51 printf(" --caps.print=name|pid - print the caps filter for the sandbox identified\n"); 50 printf(" --caps.print=name|pid - print the caps filter.\n");
52 printf("\tby name or PID.\n\n");
53 printf(" --cgroup=tasks-file - place the sandbox in the specified control group.\n"); 51 printf(" --cgroup=tasks-file - place the sandbox in the specified control group.\n");
54 printf("\ttasks-file is the full path of cgroup tasks file.\n\n");
55#ifdef HAVE_CHROOT 52#ifdef HAVE_CHROOT
56 printf(" --chroot=dirname - chroot into directory.\n\n"); 53 printf(" --chroot=dirname - chroot into directory.\n");
54#endif
55 printf(" --cpu=cpu-number,cpu-number - set cpu affinity.\n");
56 printf(" --cpu.print=name|pid - print the cpus in use.\n");
57 printf(" --csh - use /bin/csh as default shell.\n");
58 printf(" --debug - print sandbox debug messages.\n");
59 printf(" --debug-blacklists - debug blacklisting.\n");
60 printf(" --debug-caps - print all recognized capabilities.\n");
61 printf(" --debug-check-filename - debug filename checking.\n");
62 printf(" --debug-errnos - print all recognized error numbers.\n");
63 printf(" --debug-protocols - print all recognized protocols.\n");
64 printf(" --debug-syscalls - print all recognized system calls.\n");
65#ifdef HAVE_WHITELIST
66 printf(" --debug-whitelists - debug whitelisting.\n");
57#endif 67#endif
58 printf(" --cpu=cpu-number,cpu-number - set cpu affinity.\n\n");
59 printf(" --cpu.print=name|pid - print the cup in use by the sandbox identified\n");
60 printf("\tby name or PID.\n\n");
61 printf(" --csh - use /bin/csh as default shell.\n\n");
62
63 printf(" --debug - print sandbox debug messages.\n\n");
64 printf(" --debug-blacklists - debug blacklisting.\n\n");
65 printf(" --debug-caps - print all recognized capabilities in the current Firejail\n");
66 printf("\tsoftware build.\n\n");
67 printf(" --debug-check-filename - debug filename checking.\n\n");
68 printf(" --debug-errnos - print all recognized error numbers in the current Firejail\n");
69 printf("\tsoftware build.\n\n");
70 printf(" --debug-protocols - print all recognized protocols in the current Firejail\n");
71 printf("\tsoftware build.\n\n");
72 printf(" --debug-syscalls - print all recognized system calls in the current Firejail\n");
73 printf("\tsoftware build.\n\n");
74 printf(" --debug-whitelists - debug whitelisting.\n\n");
75
76
77
78#ifdef HAVE_NETWORK 68#ifdef HAVE_NETWORK
79 printf(" --defaultgw=address - use this address as default gateway in the new network\n"); 69 printf(" --defaultgw=address - configure default gateway.\n");
80 printf("\tnamespace.\n\n");
81#endif 70#endif
82 printf(" --dns=address - set a DNS server for the sandbox. Up to three DNS servers\n"); 71 printf(" --dns=address - set DNS server.\n");
83 printf("\tcan be defined.\n\n"); 72 printf(" --dns.print=name|pid - print DNS configuration.\n");
84 printf(" --dns.print=name|pid - print DNS configuration for the sandbox identified\n");
85 printf("\tby name or PID.\n\n");
86 73
87 printf(" --env=name=value - set environment variable in the new sandbox.\n\n"); 74 printf(" --env=name=value - set environment variable.\n");
88 printf(" --fs.print=name|pid - print the filesystem log for the sandbox identified\n"); 75 printf(" --fs.print=name|pid - print the filesystem log.\n");
89 printf("\tby name or PID.\n\n"); 76 printf(" --get=name|pid filename - get a file from sandbox container.\n");
90 printf(" --get=name|pid filename - get a file from sandbox container.\n\n"); 77 printf(" --help, -? - this help screen.\n");
91 printf(" --help, -? - this help screen.\n\n"); 78 printf(" --hostname=name - set sandbox hostname.\n");
92 printf(" --hostname=name - set sandbox hostname.\n\n"); 79 printf(" --ignore=command - ignore command in profile files.\n");
93 printf(" --ignore=command - ignore command in profile files.\n\n");
94#ifdef HAVE_NETWORK 80#ifdef HAVE_NETWORK
95 printf(" --interface=name - move interface in a new network namespace. Up to four\n"); 81 printf(" --interface=name - move interface in sandbox.\n");
96 printf("\t--interface options can be specified.\n\n"); 82 printf(" --ip=address - set interface IP address.\n");
97 printf(" --ip=address - set interface IP address.\n\n"); 83 printf(" --ip=none - no IP address and no default gateway are configured.\n");
98 printf(" --ip=none - no IP address and no default gateway address are configured\n"); 84 printf(" --ip6=address - set interface IPv6 address.\n");
99 printf("\tin the new network namespace. Use this option in case you intend to\n"); 85 printf(" --iprange=address,address - configure an IP address in this range.\n");
100 printf("\tstart an external DHCP client in the sandbox.\n\n");
101 printf(" --ip6=address - set interface IPv6 address.\n\n");
102 printf(" --iprange=address,address - configure an IP address in this range.\n\n");
103#endif 86#endif
104 printf(" --ipc-namespace - enable a new IPC namespace if the sandbox was started as\n"); 87 printf(" --ipc-namespace - enable a new IPC namespace.\n");
105 printf("\tregular user. IPC namespace is enabled by default only if the sandbox\n"); 88 printf(" --join=name|pid - join the sandbox.\n");
106 printf("\tis started as root.\n\n"); 89 printf(" --join-filesystem=name|pid - join the mount namespace.\n");
107 printf(" --join=name|pid - join the sandbox identified by name or PID.\n\n");
108 printf(" --join-filesystem=name|pid - join the mount namespace of the sandbox\n");
109 printf("\tidentified by name or PID.\n\n");
110#ifdef HAVE_NETWORK 90#ifdef HAVE_NETWORK
111 printf(" --join-network=name|pid - join the network namespace of the sandbox\n"); 91 printf(" --join-network=name|pid - join the network namespace.\n");
112 printf("\tidentified by name or PID.\n\n");
113#endif 92#endif
114 printf(" --list - list all sandboxes.\n\n"); 93 printf(" --list - list all sandboxes.\n");
115 printf(" --ls=name|pid dir_or_filename - list files in sandbox container.\n\n"); 94 printf(" --ls=name|pid dir_or_filename - list files in sandbox container.\n");
116#ifdef HAVE_NETWORK 95#ifdef HAVE_NETWORK
117 printf(" --mac=xx:xx:xx:xx:xx:xx - set interface MAC address.\n\n"); 96 printf(" --mac=xx:xx:xx:xx:xx:xx - set interface MAC address.\n");
118 printf(" --mtu=number - set interface MTU.\n\n"); 97 printf(" --mtu=number - set interface MTU.\n");
119#endif 98#endif
120 printf(" --name=name - set sandbox name.\n\n"); 99 printf(" --name=name - set sandbox name.\n");
121#ifdef HAVE_NETWORK 100#ifdef HAVE_NETWORK
122 printf(" --net=bridgename - enable network namespaces and connect to this bridge\n"); 101 printf(" --net=bridgename - enable network namespaces and connect to this bridge.\n");
123 printf("\tdevice. Up to four --net devices can be defined.\n\n");
124
125 printf(" --net=ethernet_interface - enable network namespaces and connect to this\n"); 102 printf(" --net=ethernet_interface - enable network namespaces and connect to this\n");
126 printf("\tEthernet interface using the standard Linux macvlan driver. Up to four\n"); 103 printf("\tEthernet interface.\n");
127 printf("\t--net devices can be defined.\n\n"); 104 printf(" --net=none - enable a new, unconnected network namespace.\n");
128 105 printf(" --netfilter[=filename] - enable the default client network filter.\n");
129 printf(" --net=none - enable a new, unconnected network namespace.\n\n"); 106 printf(" --netfilter6=filename - enable the IPv6 network filter.\n");
130 107 printf(" --netstats - monitor network statistics.\n");
131 printf(" --netfilter - enable the default client network filter in the new\n");
132 printf("\tnetwork namespace.\n\n");
133 printf(" --netfilter=filename - enable the network filter specified by\n");
134 printf("\tfilename in the new network namespace. The filter file format\n");
135 printf("\tis the format of iptables-save and iptable-restore commands.\n\n");
136 printf(" --netfilter6=filename - enable the IPv6 network filter specified by\n");
137 printf("\tfilename in the new network namespace. The filter file format\n");
138 printf("\tis the format of ip6tables-save and ip6table-restore commands.\n\n");
139
140 printf(" --netstats - monitor network statistics for sandboxes creating a new\n");
141 printf("\tnetwork namespace.\n\n");
142#endif 108#endif
143 printf(" --nice=value - set nice value\n\n"); 109 printf(" --nice=value - set nice value.\n");
144 printf(" --noblacklist=dirname_or_filename - disable blacklist for directory or\n"); 110 printf(" --no3d - disable 3D hardware acceleration.\n");
145 printf("\tfile.\n\n"); 111 printf(" --noblacklist=filename - disable blacklist for file or directory .\n");
146 printf(" --nogroups - disable supplementary groups. Without this option,\n"); 112 printf(" --noexec=filename - remount the file or directory noexec nosuid and nodev.\n");
147 printf("\tsupplementary groups are enabled for the user starting the sandbox.\n"); 113 printf(" --nogroups - disable supplementary groups.\n");
148 printf("\t For root, groups are always disabled.\n\n"); 114 printf(" --noprofile - do not use a security profile.\n");
149
150 printf(" --noprofile - do not use a profile. Profile priority is use the one\n");
151 printf("\tspecified on the command line, next try to find one that\n");
152 printf("\tmatches the command name, and lastly use %s.profile\n", DEFAULT_USER_PROFILE);
153 printf("\tif running as regular user or %s.profile if running as\n", DEFAULT_ROOT_PROFILE);
154 printf("\troot.\n\n");
155#ifdef HAVE_USERNS 115#ifdef HAVE_USERNS
156 printf(" --noroot - install a user namespace with a single user - the current\n"); 116 printf(" --noroot - install a user namespace with only the current user.\n");
157 printf("\tuser. root user does not exist in the new namespace. This option\n");
158 printf("\tis not supported for --chroot and --overlay configurations.\n\n");
159#endif 117#endif
160 printf(" --nosound - disable sound system.\n\n"); 118 printf(" --nonewprivs - sets the NO_NEW_PRIVS prctl.\n");
161 119 printf(" --output=logfile - stdout logging and log rotation.\n");
162 printf(" --output=logfile - stdout logging and log rotation. Copy stdout and stderr\n");
163 printf("\tto logfile, and keep the size of the file under 500KB using log\n");
164 printf("\trotation. Five files with prefixes .1 to .5 are used in\n");
165 printf("\trotation.\n\n");
166
167 printf(" --overlay - mount a filesystem overlay on top of the current filesystem.\n"); 120 printf(" --overlay - mount a filesystem overlay on top of the current filesystem.\n");
168 printf("\tThe upper filesystem layer is persistent, and stored in\n"); 121 printf(" --overlay-named=name - mount a filesystem overlay on top of the current\n");
169 printf("\t$HOME/.firejail directory. (OverlayFS support is required in\n"); 122 printf("\tfilesystem, and store it in name directory.\n");
170 printf("\tLinux kernel for this option to work). \n\n"); 123 printf(" --overlay-tmpfs - mount a temporary filesystem overlay on top of the current\n");
171 124 printf("\tfilesystem.\n");
172 printf(" --overlay-tmpfs - mount a filesystem overlay on top of the current\n"); 125 printf(" --overlay-clean - clean all overlays stored in $HOME/.firejail directory.\n");
173 printf("\tfilesystem. The upper layer is stored in a tmpfs filesystem,\n"); 126 printf(" --private - temporary home directory.\n");
174 printf("\tand it is discarded when the sandbox is closed. (OverlayFS\n"); 127 printf(" --private=directory - use directory as user home.\n");
175 printf("\tsupport is required in Linux kernel for this option to work).\n\n"); 128 printf(" --private-home=file,directory - build a new user home in a temporary\n");
176 129 printf("\tfilesystem, and copy the files and directories in the list in\n");
177 printf(" --private - mount new /root and /home/user directories in temporary\n"); 130 printf("\tthe new home.\n");
178 printf("\tfilesystems. All modifications are discarded when the sandbox is\n");
179 printf("\tclosed.\n\n");
180 printf(" --private=directory - use directory as user home.\n\n");
181
182 printf(" --private-bin=file,file - build a new /bin in a temporary filesystem,\n"); 131 printf(" --private-bin=file,file - build a new /bin in a temporary filesystem,\n");
183 printf("\tand copy the programs in the list.\n\n"); 132 printf("\tand copy the programs in the list.\n");
184
185 printf(" --private-dev - create a new /dev directory. Only dri, null, full, zero,\n"); 133 printf(" --private-dev - create a new /dev directory. Only dri, null, full, zero,\n");
186 printf("\ttty, pst, ptms, random, urandom, log and shm devices are available.\n\n"); 134 printf("\ttty, pst, ptms, random, snd, urandom, log and shm devices are available.\n");
187
188 printf(" --private-etc=file,directory - build a new /etc in a temporary\n"); 135 printf(" --private-etc=file,directory - build a new /etc in a temporary\n");
189 printf("\tfilesystem, and copy the files and directories in the list.\n"); 136 printf("\tfilesystem, and copy the files and directories in the list.\n");
190 printf("\tAll modifications are discarded when the sandbox is closed.\n\n"); 137 printf(" --private-tmp - mount a tmpfs on top of /tmp directory.\n");
191 138 printf(" --profile=filename - use a custom profile.\n");
192 printf(" --private-tmp - mount a tmpfs on top of /tmp directory\n\n"); 139 printf(" --profile-path=directory - use this directory to look for profile files.\n");
193
194 printf(" --profile=filename - use a custom profile.\n\n");
195 printf(" --profile-path=directory - use this directory to look for profile files.\n\n");
196
197 printf(" --protocol=protocol,protocol,protocol - enable protocol filter.\n"); 140 printf(" --protocol=protocol,protocol,protocol - enable protocol filter.\n");
198 printf("\tProtocol values: unix, inet, inet6, netlink, packet.\n\n"); 141 printf(" --protocol.print=name|pid - print the protocol filter.\n");
199 printf(" --protocol.print=name|pid - print the protocol filter for the sandbox\n"); 142 printf(" --put=name|pid src-filename dest-filename - put a file in sandbox container.\n");
200 printf("\tidentified by name or PID.\n\n"); 143 printf(" --quiet - turn off Firejail's output.\n");
201 144 printf(" --read-only=filename - set directory or file read-only..\n");
202 printf(" --quiet - turn off Firejail's output.\n\n"); 145 printf(" --read-write=filename - set directory or file read-write..\n");
203 printf(" --read-only=dirname_or_filename - set directory or file read-only..\n\n");
204 printf(" --rlimit-fsize=number - set the maximum file size that can be created\n"); 146 printf(" --rlimit-fsize=number - set the maximum file size that can be created\n");
205 printf("\tby a process.\n\n"); 147 printf("\tby a process.\n");
206 printf(" --rlimit-nofile=number - set the maximum number of files that can be\n"); 148 printf(" --rlimit-nofile=number - set the maximum number of files that can be\n");
207 printf("\topened by a process.\n\n"); 149 printf("\topened by a process.\n");
208 printf(" --rlimit-nproc=number - set the maximum number of processes that can be\n"); 150 printf(" --rlimit-nproc=number - set the maximum number of processes that can be\n");
209 printf("\tcreated for the real user ID of the calling process.\n\n"); 151 printf("\tcreated for the real user ID of the calling process.\n");
210 printf(" --rlimit-sigpending=number - set the maximum number of pending signals\n"); 152 printf(" --rlimit-sigpending=number - set the maximum number of pending signals\n");
211 printf("\tfor a process.\n\n"); 153 printf("\tfor a process.\n");
154 printf(" --rmenv=name - remove environment variable in the new sandbox.\n");
212#ifdef HAVE_NETWORK 155#ifdef HAVE_NETWORK
213 printf(" --scan - ARP-scan all the networks from inside a network namespace.\n"); 156 printf(" --scan - ARP-scan all the networks from inside a network namespace.\n");
214 printf("\tThis makes it possible to detect macvlan kernel device drivers\n");
215 printf("\trunning on the current host.\n\n");
216#endif 157#endif
217#ifdef HAVE_SECCOMP 158#ifdef HAVE_SECCOMP
218 printf(" --seccomp - enable seccomp filter and apply the default blacklist.\n\n"); 159 printf(" --seccomp - enable seccomp filter and apply the default blacklist.\n");
219
220 printf(" --seccomp=syscall,syscall,syscall - enable seccomp filter, blacklist the\n"); 160 printf(" --seccomp=syscall,syscall,syscall - enable seccomp filter, blacklist the\n");
221 printf("\tdefault syscall list and the syscalls specified by the command.\n\n"); 161 printf("\tdefault syscall list and the syscalls specified by the command.\n");
222
223 printf(" --seccomp.drop=syscall,syscall,syscall - enable seccomp filter, and\n"); 162 printf(" --seccomp.drop=syscall,syscall,syscall - enable seccomp filter, and\n");
224 printf("\tblacklist the syscalls specified by the command.\n\n"); 163 printf("\tblacklist the syscalls specified by the command.\n");
225
226 printf(" --seccomp.keep=syscall,syscall,syscall - enable seccomp filter, and\n"); 164 printf(" --seccomp.keep=syscall,syscall,syscall - enable seccomp filter, and\n");
227 printf("\twhitelist the syscalls specified by the command.\n\n"); 165 printf("\twhitelist the syscalls specified by the command.\n");
228
229 printf(" --seccomp.<errno>=syscall,syscall,syscall - enable seccomp filter, and\n"); 166 printf(" --seccomp.<errno>=syscall,syscall,syscall - enable seccomp filter, and\n");
230 printf("\treturn errno for the syscalls specified by the command.\n\n"); 167 printf("\treturn errno for the syscalls specified by the command.\n");
231
232 printf(" --seccomp.print=name|pid - print the seccomp filter for the sandbox\n"); 168 printf(" --seccomp.print=name|pid - print the seccomp filter for the sandbox\n");
233 printf("\tidentified by name or PID.\n\n"); 169 printf("\tidentified by name or PID.\n");
234#endif 170#endif
235 171 printf(" --shell=none - run the program directly without a user shell.\n");
236 printf(" --shell=none - run the program directly without a user shell.\n\n"); 172 printf(" --shell=program - set default user shell.\n");
237 printf(" --shell=program - set default user shell.\n\n"); 173 printf(" --shutdown=name|pid - shutdown the sandbox identified by name or PID.\n");
238 printf(" --shutdown=name|pid - shutdown the sandbox identified by name or PID.\n\n");
239 printf(" --tmpfs=dirname - mount a tmpfs filesystem on directory dirname.\n"); 174 printf(" --tmpfs=dirname - mount a tmpfs filesystem on directory dirname.\n");
240 printf("\tThis option is available only when running the sandbox as root.\n\n"); 175 printf(" --top - monitor the most CPU-intensive sandboxes.\n");
241 printf(" --top - monitor the most CPU-intensive sandboxes.\n\n"); 176 printf(" --trace - trace open, access and connect system calls.\n");
242 printf(" --trace - trace open, access and connect system calls.\n\n");
243 printf(" --tracelog - add a syslog message for every access to files or\n"); 177 printf(" --tracelog - add a syslog message for every access to files or\n");
244 printf("\tdirectoires blacklisted by the security profile.\n\n"); 178 printf("\tdirectoires blacklisted by the security profile.\n");
245 printf(" --tree - print a tree of all sandboxed processes.\n\n"); 179 printf(" --tree - print a tree of all sandboxed processes.\n");
246 printf(" --user=new_user - switch the user before starting the sandbox.\n\n"); 180 printf(" --version - print program version and exit.\n");
247 printf(" --version - print program version and exit.\n\n");
248 printf(" --whitelist=dirname_or_filename - whitelist directory or file.\n\n");
249 printf(" --x11 - enable X11 server. The software checks first if Xpra is installed,\n");
250 printf("\tthen it checks if Xephyr is installed.\n\n");
251 printf(" --x11=xpra - enable Xpra X11 server.\n\n");
252 printf(" --x11=xephyr - enable Xephyr X11 server. The window size is 800x600.\n\n");
253 printf(" --zsh - use /usr/bin/zsh as default shell.\n\n");
254 printf("\n");
255 printf("\n");
256
257
258#ifdef HAVE_NETWORK 181#ifdef HAVE_NETWORK
259 printf("Traffic Shaping\n\n"); 182 printf(" --veth-name=name - use this name for the interface connected to the bridge.\n");
260 183#endif
261 printf("Network bandwidth is an expensive resource shared among all sandboxes\n"); 184#ifdef HAVE_WHITELIST
262 printf("running on a system. Traffic shaping allows the user to increase network\n"); 185 printf(" --whitelist=filename - whitelist directory or file.\n");
263 printf("performance by controlling the amount of data that flows into and out of the\n"); 186#endif
264 printf("sandboxes. Firejail implements a simple rate-limiting shaper based on Linux\n"); 187 printf(" --writable-etc - /etc directory is mounted read-write.\n");
265 printf("command tc. The shaper works at sandbox level, and can be used only for\n"); 188 printf(" --writable-var - /var directory is mounted read-write.\n");
266 printf("sandboxes configured with new network namespaces.\n\n"); 189 printf(" --x11 - enable X11 sandboxing. The software checks first if Xpra is\n");
267 190 printf("\tinstalled, then it checks if Xephyr is installed. If all fails, it will\n");
268 printf("Set rate-limits:\n"); 191 printf("\tattempt to use X11 security extension.\n");
269 printf(" firejail --bandwidth={name|pid} set network-name down-speed up-speed\n\n"); 192 printf(" --x11=none - disable access to X11 sockets.\n");
270 printf("Clear rate-limits:\n"); 193 printf(" --x11=xephyr - enable Xephyr X11 server. The window size is 800x600.\n");
271 printf(" firejail --bandwidth={name|pid} clear network-name\n\n"); 194 printf(" --x11=xorg - enable X11 security extension.\n");
272 printf("Status:\n"); 195 printf(" --x11=xpra - enable Xpra X11 server.\n");
273 printf(" firejail --bandwidth={name|pid} status\n\n"); 196 printf(" --zsh - use /usr/bin/zsh as default shell.\n");
274 printf("where:\n");
275 printf(" name - sandbox name\n");
276 printf(" pid - sandbox pid\n");
277 printf(" network-name - network name as used by --net option\n");
278 printf(" down-speed - download speed in KB/s (decimal kilobyte per second)\n");
279 printf(" up-speed - upload speed in KB/s (decimal kilobyte per second)\n");
280 printf("\n");
281 printf("Example:\n");
282 printf(" $ firejail --name=mybrowser --net=eth0 firefox &\n");
283 printf(" $ firejail --bandwidth=mybrowser set eth0 80 20\n");
284 printf(" $ firejail --bandwidth=mybrowser status\n");
285 printf(" $ firejail --bandwidth=mybrowser clear eth0\n");
286 printf("\n");
287 printf("\n");
288#endif
289
290
291 printf("Monitoring\n\n");
292
293 printf("Option --list prints a list of all sandboxes. The format for each entry is as\n");
294 printf("follows:\n\n");
295 printf(" PID:USER:Command\n\n");
296
297 printf("Option --tree prints the tree of processes running in the sandbox. The format\n");
298 printf("for each process entry is as follows:\n\n");
299 printf(" PID:USER:Command\n\n");
300
301 printf("Option --top is similar to the UNIX top command, however it applies only to\n");
302 printf("sandboxes. Listed below are the available fields (columns) in alphabetical\n");
303 printf("order:\n\n");
304 printf(" Command - command used to start the sandbox.\n");
305 printf(" CPU%% - CPU usage, the sandbox share of the elapsed CPU time since the\n");
306 printf("\tlast screen update\n");
307 printf(" PID - Unique process ID for the task controlling the sandbox.\n");
308 printf(" Prcs - number of processes running in sandbox, including the controlling\n");
309 printf("\tprocess.\n");
310 printf(" RES - Resident Memory Size (KiB), sandbox non-swapped physical memory.\n");
311 printf("\tIt is a sum of the RES values for all processes running in the\n");
312 printf("\tsandbox.\n");
313 printf(" SHR - Shared Memory Size (KiB), it reflects memory shared with other\n");
314 printf("\tprocesses. It is a sum of the SHR values for all processes running\n");
315 printf("\tin the sandbox, including the controlling process.\n");
316 printf(" Uptime - sandbox running time in hours:minutes:seconds format.\n");
317 printf(" User - The owner of the sandbox.\n");
318 printf("\n");
319 printf("\n");
320 printf("Profile files\n\n");
321 printf("Several command line configuration options can be passed to the program using\n");
322 printf("profile files. Default Firejail profile files are stored in /etc/firejail\n");
323 printf("directory, user profile files are stored in ~/.config/firejail directory. See\n");
324 printf("man 5 firejail-profile for more information.\n\n");
325 printf("\n");
326 printf("Restricted shell\n\n");
327 printf("To configure a restricted shell, replace /bin/bash with /usr/bin/firejail in\n");
328 printf("/etc/password file for each user that needs to be restricted.\n");
329 printf("Alternatively, you can specify /usr/bin/firejail in adduser command:\n\n");
330 printf(" adduser --shell /usr/bin/firejail username\n\n");
331 printf("Arguments to be passed to firejail executable upon login are declared in\n");
332 printf("/etc/firejail/login.users file.\n\n");
333 printf("\n"); 197 printf("\n");
334 printf("Examples:\n\n"); 198 printf("Examples:\n");
335 printf(" $ firejail\n");
336 printf("\tstart a regular /bin/bash session in sandbox\n");
337 printf(" $ firejail firefox\n"); 199 printf(" $ firejail firefox\n");
338 printf("\tstart Mozilla Firefox\n"); 200 printf("\tstart Mozilla Firefox\n");
339 printf(" $ firejail --debug firefox\n"); 201 printf(" $ firejail --debug firefox\n");
340 printf("\tdebug Firefox sandbox\n"); 202 printf("\tdebug Firefox sandbox\n");
341 printf(" $ firejail --private firefox\n"); 203 printf(" $ firejail --private --sna=8.8.8.8 firefox\n");
342 printf("\tstart Firefox with a new, empty home directory\n"); 204 printf("\tstart Firefox with a new, empty home directory, and a well-known DNS\n");
343 printf(" $ firejail --net=br0 ip=10.10.20.10\n"); 205 printf("\tserver setting.\n");
344 printf("\tstart a /bin/bash session in a new network namespace; the session is\n"); 206 printf(" $ firejail --net=eth0 firefox\n");
345 printf("\tconnected to the main network using br0 bridge device, an IP address\n"); 207 printf("\tstart Firefox in a new network namespace\n");
346 printf("\tof 10.10.20.10 is assigned to the sandbox\n"); 208 printf(" $ firejail --x11=xorg firefox\n");
347 printf(" $ firejail --net=br0 --net=br1 --net=br2\n"); 209 printf("\tstart Firefox and sandbox X11\n");
348 printf("\tstart a /bin/bash session in a new network namespace and connect it\n");
349 printf("\tto br0, br1, and br2 host bridge devices\n");
350 printf(" $ firejail --list\n"); 210 printf(" $ firejail --list\n");
351 printf("\tlist all running sandboxes\n"); 211 printf("\tlist all running sandboxes\n");
352 printf("\n"); 212 printf("\n");
diff --git a/src/firejail/user.c b/src/firejail/user.c
deleted file mode 100644
index a2f34392c..000000000
--- a/src/firejail/user.c
+++ /dev/null
@@ -1,115 +0,0 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20#include "firejail.h"
21#include <sys/types.h>
22#include <sys/stat.h>
23#include <unistd.h>
24#include <grp.h>
25#include <pwd.h>
26
27
28void check_user(int argc, char **argv) {
29 EUID_ASSERT();
30 int i;
31 char *user = NULL;
32
33 int found = 0;
34 for (i = 1; i < argc; i++) {
35 // check options
36 if (strcmp(argv[i], "--") == 0)
37 break;
38 if (strncmp(argv[i], "--", 2) != 0)
39 break;
40
41 // check user option
42 if (strncmp(argv[i], "--user=", 7) == 0) {
43 found = 1;
44 user = argv[i] + 7;
45 break;
46 }
47 }
48 if (!found)
49 return;
50
51 // check root
52 if (getuid() != 0) {
53 fprintf(stderr, "Error: you need to be root to use --user command line option\n");
54 exit(1);
55 }
56
57 // switch user
58 struct passwd *pw = getpwnam(user);
59 if (!pw) {
60 fprintf(stderr, "Error: cannot find user %s\n", user);
61 exit(1);
62 }
63
64 printf("Switching to user %s, UID %d, GID %d\n", user, pw->pw_uid, pw->pw_gid);
65 int rv = initgroups(user, pw->pw_gid);
66 if (rv == -1) {
67 perror("initgroups");
68 fprintf(stderr, "Error: cannot switch to user %s\n", user);
69 }
70
71 rv = setgid(pw->pw_gid);
72 if (rv == -1) {
73 perror("setgid");
74 fprintf(stderr, "Error: cannot switch to user %s\n", user);
75 }
76
77 rv = setuid(pw->pw_uid);
78 if (rv == -1) {
79 perror("setuid");
80 fprintf(stderr, "Error: cannot switch to user %s\n", user);
81 }
82
83 // build the new command line
84 int len = 0;
85 for (i = 0; i < argc; i++) {
86 len += strlen(argv[i]) + 1; // + ' '
87 }
88
89 char *cmd = malloc(len + 1); // + '\0'
90 if (!cmd)
91 errExit("malloc");
92
93 char *ptr = cmd;
94 int first = 1;
95 for (i = 0; i < argc; i++) {
96 if (strncmp(argv[i], "--user=", 7) == 0 && first) {
97 first = 0;
98 continue;
99 }
100
101 ptr += sprintf(ptr, "%s ", argv[i]);
102 }
103
104 // run command
105 char *a[4];
106 a[0] = "/bin/bash";
107 a[1] = "-c";
108 a[2] = cmd;
109 a[3] = NULL;
110
111 execvp(a[0], a);
112
113 perror("execvp");
114 exit(1);
115}
diff --git a/src/firejail/util.c b/src/firejail/util.c
index da73bbfd5..d928c6b42 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -17,18 +17,23 @@
17 * with this program; if not, write to the Free Software Foundation, Inc., 17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */ 19 */
20#define _XOPEN_SOURCE 500
20#include "firejail.h" 21#include "firejail.h"
22#include <ftw.h>
21#include <sys/stat.h> 23#include <sys/stat.h>
22#include <fcntl.h> 24#include <fcntl.h>
23#include <syslog.h> 25#include <syslog.h>
24#include <errno.h> 26#include <errno.h>
25#include <dirent.h> 27#include <dirent.h>
26#include <grp.h> 28#include <grp.h>
29#include <sys/ioctl.h>
30#include <termios.h>
27 31
28#define MAX_GROUPS 1024 32#define MAX_GROUPS 1024
29// drop privileges 33// drop privileges
30// - for root group or if nogroups is set, supplementary groups are not configured 34// - for root group or if nogroups is set, supplementary groups are not configured
31void drop_privs(int nogroups) { 35void drop_privs(int nogroups) {
36 EUID_ROOT();
32 gid_t gid = getgid(); 37 gid_t gid = getgid();
33 38
34 // configure supplementary groups 39 // configure supplementary groups
@@ -77,7 +82,7 @@ void drop_privs(int nogroups) {
77 82
78int mkpath_as_root(const char* path) { 83int mkpath_as_root(const char* path) {
79 assert(path && *path); 84 assert(path && *path);
80 85
81 // work on a copy of the path 86 // work on a copy of the path
82 char *file_path = strdup(path); 87 char *file_path = strdup(path);
83 if (!file_path) 88 if (!file_path)
@@ -95,24 +100,21 @@ int mkpath_as_root(const char* path) {
95 } 100 }
96 } 101 }
97 else { 102 else {
98 if (chmod(file_path, 0755) == -1) 103 if (set_perms(file_path, 0, 0, 0755))
99 errExit("chmod"); 104 errExit("set_perms");
100 if (chown(file_path, 0, 0) == -1)
101 errExit("chown");
102 done = 1; 105 done = 1;
103 } 106 }
104 107
105 *p='/'; 108 *p='/';
106 } 109 }
107 if (done) 110 if (done)
108 fs_logger2("mkpath", path); 111 fs_logger2("mkpath", path);
109 112
110 free(file_path); 113 free(file_path);
111 return 0; 114 return 0;
112} 115}
113 116
114 117
115
116void logsignal(int s) { 118void logsignal(int s) {
117 if (!arg_debug) 119 if (!arg_debug)
118 return; 120 return;
@@ -167,8 +169,8 @@ void logerr(const char *msg) {
167} 169}
168 170
169 171
170// return -1 if error, 0 if no error 172// return -1 if error, 0 if no error; if destname already exists, return error
171int copy_file(const char *srcname, const char *destname) { 173int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode) {
172 assert(srcname); 174 assert(srcname);
173 assert(destname); 175 assert(destname);
174 176
@@ -205,17 +207,23 @@ int copy_file(const char *srcname, const char *destname) {
205 } 207 }
206 } 208 }
207 209
210 if (fchown(dst, uid, gid) == -1)
211 errExit("fchown");
212 if (fchmod(dst, mode) == -1)
213 errExit("fchmod");
214
208 close(src); 215 close(src);
209 close(dst); 216 close(dst);
210 return 0; 217 return 0;
211} 218}
212 219
220
213// return 1 if the file is a directory 221// return 1 if the file is a directory
214int is_dir(const char *fname) { 222int is_dir(const char *fname) {
215 assert(fname); 223 assert(fname);
216 if (*fname == '\0') 224 if (*fname == '\0')
217 return 0; 225 return 0;
218 226
219 // if fname doesn't end in '/', add one 227 // if fname doesn't end in '/', add one
220 int rv; 228 int rv;
221 struct stat s; 229 struct stat s;
@@ -226,20 +234,21 @@ int is_dir(const char *fname) {
226 if (asprintf(&tmp, "%s/", fname) == -1) { 234 if (asprintf(&tmp, "%s/", fname) == -1) {
227 fprintf(stderr, "Error: cannot allocate memory, %s:%d\n", __FILE__, __LINE__); 235 fprintf(stderr, "Error: cannot allocate memory, %s:%d\n", __FILE__, __LINE__);
228 errExit("asprintf"); 236 errExit("asprintf");
229 } 237 }
230 rv = stat(tmp, &s); 238 rv = stat(tmp, &s);
231 free(tmp); 239 free(tmp);
232 } 240 }
233 241
234 if (rv == -1) 242 if (rv == -1)
235 return 0; 243 return 0;
236 244
237 if (S_ISDIR(s.st_mode)) 245 if (S_ISDIR(s.st_mode))
238 return 1; 246 return 1;
239 247
240 return 0; 248 return 0;
241} 249}
242 250
251
243// return 1 if the file is a link 252// return 1 if the file is a link
244int is_link(const char *fname) { 253int is_link(const char *fname) {
245 assert(fname); 254 assert(fname);
@@ -324,7 +333,7 @@ char *split_comma(char *str) {
324 333
325int not_unsigned(const char *str) { 334int not_unsigned(const char *str) {
326 EUID_ASSERT(); 335 EUID_ASSERT();
327 336
328 int rv = 0; 337 int rv = 0;
329 const char *ptr = str; 338 const char *ptr = str;
330 while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0') { 339 while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0') {
@@ -346,7 +355,7 @@ int find_child(pid_t parent, pid_t *child) {
346 *child = 0; // use it to flag a found child 355 *child = 0; // use it to flag a found child
347 356
348 DIR *dir; 357 DIR *dir;
349 EUID_ROOT(); // grsecurity fix 358 EUID_ROOT(); // grsecurity fix
350 if (!(dir = opendir("/proc"))) { 359 if (!(dir = opendir("/proc"))) {
351 // sleep 2 seconds and try again 360 // sleep 2 seconds and try again
352 sleep(2); 361 sleep(2);
@@ -403,13 +412,11 @@ int find_child(pid_t parent, pid_t *child) {
403} 412}
404 413
405 414
406
407void extract_command_name(int index, char **argv) { 415void extract_command_name(int index, char **argv) {
408 EUID_ASSERT(); 416 EUID_ASSERT();
409 assert(argv); 417 assert(argv);
410 assert(argv[index]); 418 assert(argv[index]);
411 419
412
413 // configure command index 420 // configure command index
414 cfg.original_program_index = index; 421 cfg.original_program_index = index;
415 422
@@ -418,13 +425,13 @@ void extract_command_name(int index, char **argv) {
418 errExit("strdup"); 425 errExit("strdup");
419 426
420 // if we have a symbolic link, use the real path to extract the name 427 // if we have a symbolic link, use the real path to extract the name
421 if (is_link(argv[index])) { 428// if (is_link(argv[index])) {
422 char*newname = realpath(argv[index], NULL); 429// char*newname = realpath(argv[index], NULL);
423 if (newname) { 430// if (newname) {
424 free(str); 431// free(str);
425 str = newname; 432// str = newname;
426 } 433// }
427 } 434// }
428 435
429 // configure command name 436 // configure command name
430 cfg.command_name = str; 437 cfg.command_name = str;
@@ -446,7 +453,6 @@ void extract_command_name(int index, char **argv) {
446 exit(1); 453 exit(1);
447 } 454 }
448 455
449
450 char *tmp = strdup(ptr); 456 char *tmp = strdup(ptr);
451 if (!tmp) 457 if (!tmp)
452 errExit("strdup"); 458 errExit("strdup");
@@ -532,6 +538,7 @@ void notify_other(int fd) {
532 fclose(stream); 538 fclose(stream);
533} 539}
534 540
541
535// This function takes a pathname supplied by the user and expands '~' and 542// This function takes a pathname supplied by the user and expands '~' and
536// '${HOME}' at the start, to refer to a path relative to the user's home 543// '${HOME}' at the start, to refer to a path relative to the user's home
537// directory (supplied). 544// directory (supplied).
@@ -540,7 +547,7 @@ void notify_other(int fd) {
540char *expand_home(const char *path, const char* homedir) { 547char *expand_home(const char *path, const char* homedir) {
541 assert(path); 548 assert(path);
542 assert(homedir); 549 assert(homedir);
543 550
544 // Replace home macro 551 // Replace home macro
545 char *new_name = NULL; 552 char *new_name = NULL;
546 if (strncmp(path, "${HOME}", 7) == 0) { 553 if (strncmp(path, "${HOME}", 7) == 0) {
@@ -548,15 +555,16 @@ char *expand_home(const char *path, const char* homedir) {
548 errExit("asprintf"); 555 errExit("asprintf");
549 return new_name; 556 return new_name;
550 } 557 }
551 else if (strncmp(path, "~/", 2) == 0) { 558 else if (*path == '~') {
552 if (asprintf(&new_name, "%s%s", homedir, path + 1) == -1) 559 if (asprintf(&new_name, "%s%s", homedir, path + 1) == -1)
553 errExit("asprintf"); 560 errExit("asprintf");
554 return new_name; 561 return new_name;
555 } 562 }
556 563
557 return strdup(path); 564 return strdup(path);
558} 565}
559 566
567
560// Equivalent to the GNU version of basename, which is incompatible with 568// Equivalent to the GNU version of basename, which is incompatible with
561// the POSIX basename. A few lines of code saves any portability pain. 569// the POSIX basename. A few lines of code saves any portability pain.
562// https://www.gnu.org/software/libc/manual/html_node/Finding-Tokens-in-a-String.html#index-basename 570// https://www.gnu.org/software/libc/manual/html_node/Finding-Tokens-in-a-String.html#index-basename
@@ -567,17 +575,18 @@ const char *gnu_basename(const char *path) {
567 return last_slash+1; 575 return last_slash+1;
568} 576}
569 577
578
570uid_t pid_get_uid(pid_t pid) { 579uid_t pid_get_uid(pid_t pid) {
571 EUID_ASSERT(); 580 EUID_ASSERT();
572 uid_t rv = 0; 581 uid_t rv = 0;
573 582
574 // open status file 583 // open status file
575 char *file; 584 char *file;
576 if (asprintf(&file, "/proc/%u/status", pid) == -1) { 585 if (asprintf(&file, "/proc/%u/status", pid) == -1) {
577 perror("asprintf"); 586 perror("asprintf");
578 exit(1); 587 exit(1);
579 } 588 }
580 EUID_ROOT(); // grsecurity fix 589 EUID_ROOT(); // grsecurity fix
581 FILE *fp = fopen(file, "r"); 590 FILE *fp = fopen(file, "r");
582 if (!fp) { 591 if (!fp) {
583 free(file); 592 free(file);
@@ -596,16 +605,16 @@ uid_t pid_get_uid(pid_t pid) {
596 } 605 }
597 if (*ptr == '\0') 606 if (*ptr == '\0')
598 break; 607 break;
599 608
600 rv = atoi(ptr); 609 rv = atoi(ptr);
601 break; // break regardless! 610 break; // break regardless!
602 } 611 }
603 } 612 }
604 613
605 fclose(fp); 614 fclose(fp);
606 free(file); 615 free(file);
607 EUID_USER(); // grsecurity fix 616 EUID_USER(); // grsecurity fix
608 617
609 if (rv == 0) { 618 if (rv == 0) {
610 fprintf(stderr, "Error: cannot read /proc file\n"); 619 fprintf(stderr, "Error: cannot read /proc file\n");
611 exit(1); 620 exit(1);
@@ -613,14 +622,15 @@ uid_t pid_get_uid(pid_t pid) {
613 return rv; 622 return rv;
614} 623}
615 624
625
616void invalid_filename(const char *fname) { 626void invalid_filename(const char *fname) {
617 EUID_ASSERT(); 627 EUID_ASSERT();
618 assert(fname); 628 assert(fname);
619 const char *ptr = fname; 629 const char *ptr = fname;
620 630
621 if (arg_debug_check_filename) 631 if (arg_debug_check_filename)
622 printf("Checking filename %s\n", fname); 632 printf("Checking filename %s\n", fname);
623 633
624 if (strncmp(ptr, "${HOME}", 7) == 0) 634 if (strncmp(ptr, "${HOME}", 7) == 0)
625 ptr = fname + 7; 635 ptr = fname + 7;
626 else if (strncmp(ptr, "${PATH}", 7) == 0) 636 else if (strncmp(ptr, "${PATH}", 7) == 0)
@@ -636,22 +646,125 @@ void invalid_filename(const char *fname) {
636 } 646 }
637} 647}
638 648
639uid_t get_tty_gid(void) { 649
650uid_t get_group_id(const char *group) {
640 // find tty group id 651 // find tty group id
641 gid_t ttygid = 0; 652 gid_t gid = 0;
642 struct group *g = getgrnam("tty"); 653 struct group *g = getgrnam(group);
643 if (g) 654 if (g)
644 ttygid = g->gr_gid; 655 gid = g->gr_gid;
645 656
646 return ttygid; 657 return gid;
647} 658}
648 659
649uid_t get_audio_gid(void) {
650 // find tty group id
651 gid_t audiogid = 0;
652 struct group *g = getgrnam("audio");
653 if (g)
654 audiogid = g->gr_gid;
655 660
656 return audiogid; 661static int remove_callback(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) {
662 (void) sb;
663 (void) typeflag;
664 (void) ftwbuf;
665
666 int rv = remove(fpath);
667 if (rv)
668 perror(fpath);
669
670 return rv;
671}
672
673
674int remove_directory(const char *path) {
675 // FTW_PHYS - do not follow symbolic links
676 return nftw(path, remove_callback, 64, FTW_DEPTH | FTW_PHYS);
677}
678
679void flush_stdin(void) {
680 if (isatty(STDIN_FILENO)) {
681 int cnt = 0;
682 ioctl(STDIN_FILENO, FIONREAD, &cnt);
683 if (cnt) {
684 if (!arg_quiet)
685 printf("Warning: removing %d bytes from stdin\n", cnt);
686 ioctl(STDIN_FILENO, TCFLSH, TCIFLUSH);
687 }
688 }
689}
690
691void create_empty_dir_as_root(const char *dir, mode_t mode) {
692 assert(dir);
693 struct stat s;
694
695 if (stat(dir, &s)) {
696 if (arg_debug)
697 printf("Creating empty %s directory\n", dir);
698 if (mkdir(dir, mode) == -1)
699 errExit("mkdir");
700 if (set_perms(dir, 0, 0, mode))
701 errExit("set_perms");
702 ASSERT_PERMS(dir, 0, 0, mode);
703 }
704}
705
706void create_empty_file_as_root(const char *fname, mode_t mode) {
707 assert(fname);
708 struct stat s;
709
710 if (stat(fname, &s)) {
711 if (arg_debug)
712 printf("Creating empty %s file\n", fname);
713
714 FILE *fp = fopen(fname, "w");
715 if (!fp)
716 errExit("fopen");
717 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR);
718 fclose(fp);
719 if (chmod(fname, mode) == -1)
720 errExit("chmod");
721 }
722}
723
724// return 1 if error
725int set_perms(const char *fname, uid_t uid, gid_t gid, mode_t mode) {
726 assert(fname);
727 if (chmod(fname, mode) == -1)
728 return 1;
729 if (chown(fname, uid, gid) == -1)
730 return 1;
731 return 0;
732}
733
734void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid) {
735 assert(fname);
736 mode &= 07777;
737#if 0
738 printf("fname %s, uid %d, gid %d, mode %x - ", fname, uid, gid, (unsigned) mode);
739 if (S_ISLNK(mode))
740 printf("l");
741 else if (S_ISDIR(mode))
742 printf("d");
743 else if (S_ISCHR(mode))
744 printf("c");
745 else if (S_ISBLK(mode))
746 printf("b");
747 else if (S_ISSOCK(mode))
748 printf("s");
749 else
750 printf("-");
751 printf( (mode & S_IRUSR) ? "r" : "-");
752 printf( (mode & S_IWUSR) ? "w" : "-");
753 printf( (mode & S_IXUSR) ? "x" : "-");
754 printf( (mode & S_IRGRP) ? "r" : "-");
755 printf( (mode & S_IWGRP) ? "w" : "-");
756 printf( (mode & S_IXGRP) ? "x" : "-");
757 printf( (mode & S_IROTH) ? "r" : "-");
758 printf( (mode & S_IWOTH) ? "w" : "-");
759 printf( (mode & S_IXOTH) ? "x" : "-");
760 printf("\n");
761#endif
762 if (mkdir(fname, mode) == -1 ||
763 chmod(fname, mode) == -1 ||
764 chown(fname, uid, gid)) {
765 fprintf(stderr, "Error: failed to create %s directory\n", fname);
766 errExit("mkdir/chmod");
767 }
768
769 ASSERT_PERMS(fname, uid, gid, mode);
657} 770}
diff --git a/src/firejail/x11.c b/src/firejail/x11.c
index ef1095a49..9da6d3e30 100644
--- a/src/firejail/x11.c
+++ b/src/firejail/x11.c
@@ -20,11 +20,14 @@
20#include "firejail.h" 20#include "firejail.h"
21#include <sys/types.h> 21#include <sys/types.h>
22#include <sys/stat.h> 22#include <sys/stat.h>
23#include <fcntl.h>
23#include <unistd.h> 24#include <unistd.h>
24#include <signal.h> 25#include <signal.h>
25#include <stdlib.h> 26#include <stdlib.h>
26#include <dirent.h> 27#include <dirent.h>
27#include <sys/mount.h> 28#include <sys/mount.h>
29#include <sys/wait.h>
30int mask_x11_abstract_socket = 0;
28 31
29#ifdef HAVE_X11 32#ifdef HAVE_X11
30// return 1 if xpra is installed on the system 33// return 1 if xpra is installed on the system
@@ -49,6 +52,31 @@ static int x11_check_xephyr(void) {
49 return 1; 52 return 1;
50} 53}
51 54
55// check for X11 abstract sockets
56static int x11_abstract_sockets_present(void) {
57 char *path;
58
59 EUID_ROOT(); // grsecurity fix
60 FILE *fp = fopen("/proc/net/unix", "r");
61 EUID_USER();
62
63 if (!fp)
64 errExit("fopen");
65
66 while (fscanf(fp, "%*s %*s %*s %*s %*s %*s %*s %ms\n", &path) != EOF) {
67 if (path && strncmp(path, "@/tmp/.X11-unix/", 16) == 0) {
68 free(path);
69 fclose(fp);
70 return 1;
71 }
72 }
73
74 free(path);
75 fclose(fp);
76
77 return 0;
78}
79
52static int random_display_number(void) { 80static int random_display_number(void) {
53 int i; 81 int i;
54 int found = 1; 82 int found = 1;
@@ -109,10 +137,8 @@ void fs_x11(void) {
109 int rv = mkdir(RUN_WHITELIST_X11_DIR, 1777); 137 int rv = mkdir(RUN_WHITELIST_X11_DIR, 1777);
110 if (rv == -1) 138 if (rv == -1)
111 errExit("mkdir"); 139 errExit("mkdir");
112 if (chown(RUN_WHITELIST_X11_DIR, 0, 0) < 0) 140 if (set_perms(RUN_WHITELIST_X11_DIR, 0, 0, 1777))
113 errExit("chown"); 141 errExit("set_perms");
114 if (chmod(RUN_WHITELIST_X11_DIR, 1777) < 0)
115 errExit("chmod");
116 142
117 if (mount("/tmp/.X11-unix", RUN_WHITELIST_X11_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) 143 if (mount("/tmp/.X11-unix", RUN_WHITELIST_X11_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
118 errExit("mount bind"); 144 errExit("mount bind");
@@ -130,13 +156,9 @@ void fs_x11(void) {
130 fprintf(stderr, "Error: cannot create empty file in x11 directory\n"); 156 fprintf(stderr, "Error: cannot create empty file in x11 directory\n");
131 exit(1); 157 exit(1);
132 } 158 }
133 fclose(fp);
134
135 // set file properties 159 // set file properties
136 if (chown(x11file, s.st_uid, s.st_gid) < 0) 160 SET_PERMS_STREAM(fp, s.st_uid, s.st_gid, s.st_mode);
137 errExit("chown"); 161 fclose(fp);
138 if (chmod(x11file, s.st_mode) < 0)
139 errExit("chmod");
140 162
141 // mount 163 // mount
142 char *wx11file; 164 char *wx11file;
@@ -164,15 +186,17 @@ void x11_start_xephyr(int argc, char **argv) {
164 EUID_ASSERT(); 186 EUID_ASSERT();
165 int i; 187 int i;
166 struct stat s; 188 struct stat s;
167 pid_t client = 0; 189 pid_t jail = 0;
168 pid_t server = 0; 190 pid_t server = 0;
169 191
192 setenv("FIREJAIL_X11", "yes", 1);
170 193
171 // unfortunately, xephyr does a number of weird things when started by root user!!! 194 // unfortunately, xephyr does a number of weird things when started by root user!!!
172 if (getuid() == 0) { 195 if (getuid() == 0) {
173 fprintf(stderr, "Error: this feature is not available when running as root\n"); 196 fprintf(stderr, "Error: X11 sandboxing is not available when running as root\n");
174 exit(1); 197 exit(1);
175 } 198 }
199 drop_privs(0);
176 200
177 // check xephyr 201 // check xephyr
178 if (x11_check_xephyr() == 0) { 202 if (x11_check_xephyr() == 0) {
@@ -183,23 +207,78 @@ void x11_start_xephyr(int argc, char **argv) {
183 } 207 }
184 208
185 int display = random_display_number(); 209 int display = random_display_number();
186 210 char *display_str;
187 // start xephyr 211 if (asprintf(&display_str, ":%d", display) == -1)
188 char *cmd1;
189 if (asprintf(&cmd1, "Xephyr -ac -br -title \"firejail x11 sandbox\" -noreset -screen %s :%d", xephyr_screen, display) == -1)
190 errExit("asprintf"); 212 errExit("asprintf");
191 213
192 int len = 50; // DISPLAY... 214 assert(xephyr_screen);
193 for (i = 0; i < argc; i++) { 215 char *server_argv[256] = { "Xephyr", "-ac", "-br", "-noreset", "-screen", xephyr_screen }; // rest initialyzed to NULL
194 len += strlen(argv[i]) + 1; // + ' ' 216 unsigned pos = 0;
217 while (server_argv[pos] != NULL) pos++;
218 if (checkcfg(CFG_XEPHYR_WINDOW_TITLE)) {
219 server_argv[pos++] = "-title";
220 server_argv[pos++] = "firejail x11 sandbox";
221 }
222
223 assert(xephyr_extra_params); // should be "" if empty
224
225 // parse xephyr_extra_params
226 // very basic quoting support
227 char *temp = strdup(xephyr_extra_params);
228 if (*xephyr_extra_params != '\0') {
229 if (!temp)
230 errExit("strdup");
231 bool dquote = false;
232 bool squote = false;
233 for (i = 0; i < (int) strlen(xephyr_extra_params); i++) {
234 if (temp[i] == '\"') {
235 dquote = !dquote;
236 if (dquote) temp[i] = '\0'; // replace closing quote by \0
237 }
238 if (temp[i] == '\'') {
239 squote = !squote;
240 if (squote) temp[i] = '\0'; // replace closing quote by \0
241 }
242 if (!dquote && !squote && temp[i] == ' ') temp[i] = '\0';
243 if (dquote && squote) {
244 fprintf(stderr, "Error: mixed quoting found while parsing xephyr_extra_params\n");
245 exit(1);
246 }
247 }
248 if (dquote) {
249 fprintf(stderr, "Error: unclosed quote found while parsing xephyr_extra_params\n");
250 exit(1);
251 }
252
253 for (i = 0; i < (int) strlen(xephyr_extra_params)-1; i++) {
254 if (pos >= (sizeof(server_argv)/sizeof(*server_argv))) {
255 fprintf(stderr, "Error: arg count limit exceeded while parsing xephyr_extra_params\n");
256 exit(1);
257 }
258 if (temp[i] == '\0' && (temp[i+1] == '\"' || temp[i+1] == '\'')) server_argv[pos++] = temp + i + 2;
259 else if (temp[i] == '\0' && temp[i+1] != '\0') server_argv[pos++] = temp + i + 1;
260 }
195 } 261 }
196 262
197 char *cmd2 = malloc(len + 1); // + '\0' 263 server_argv[pos++] = display_str;
198 if (!cmd2) 264 server_argv[pos++] = NULL;
199 errExit("malloc"); 265
266 assert(pos < (sizeof(server_argv)/sizeof(*server_argv))); // no overrun
267 assert(server_argv[pos-1] == NULL); // last element is null
200 268
201 sprintf(cmd2, "DISPLAY=:%d ", display); 269 if (arg_debug) {
202 char *ptr = cmd2 + strlen(cmd2); 270 size_t i = 0;
271 printf("xephyr server:");
272 while (server_argv[i]!=NULL) {
273 printf(" \"%s\"", server_argv[i]);
274 i++;
275 }
276 putchar('\n');
277 }
278
279 // remove --x11 arg
280 char *jail_argv[argc+2];
281 int j = 0;
203 for (i = 0; i < argc; i++) { 282 for (i = 0; i < argc; i++) {
204 if (strcmp(argv[i], "--x11") == 0) 283 if (strcmp(argv[i], "--x11") == 0)
205 continue; 284 continue;
@@ -207,32 +286,40 @@ void x11_start_xephyr(int argc, char **argv) {
207 continue; 286 continue;
208 if (strcmp(argv[i], "--x11=xephyr") == 0) 287 if (strcmp(argv[i], "--x11=xephyr") == 0)
209 continue; 288 continue;
210 ptr += sprintf(ptr, "%s ", argv[i]); 289 jail_argv[j] = argv[i];
290 j++;
291 }
292 jail_argv[j] = NULL;
293
294 assert(j < argc+2); // no overrun
295
296 if (arg_debug) {
297 size_t i = 0;
298 printf("xephyr client:");
299 while (jail_argv[i]!=NULL) {
300 printf(" \"%s\"", jail_argv[i]);
301 i++;
302 }
303 putchar('\n');
211 } 304 }
212 if (arg_debug)
213 printf("xephyr server: %s\n", cmd1);
214 if (arg_debug)
215 printf("xephyr client: %s\n", cmd2);
216 305
217 signal(SIGHUP,SIG_IGN); // fix sleep(1) below
218 server = fork(); 306 server = fork();
219 if (server < 0) 307 if (server < 0)
220 errExit("fork"); 308 errExit("fork");
221 if (server == 0) { 309 if (server == 0) {
222 if (arg_debug) 310 if (arg_debug)
223 printf("Starting xephyr...\n"); 311 printf("Starting xephyr...\n");
224 312
225 char *a[4]; 313 // running without privileges - see drop_privs call above
226 a[0] = "/bin/bash"; 314 assert(getenv("LD_PRELOAD") == NULL);
227 a[1] = "-c"; 315 execvp(server_argv[0], server_argv);
228 a[2] = cmd1;
229 a[3] = NULL;
230
231 execvp(a[0], a);
232 perror("execvp"); 316 perror("execvp");
233 exit(1); 317 _exit(1);
234 } 318 }
235 319
320 if (arg_debug)
321 printf("xephyr server pid %d\n", server);
322
236 // check X11 socket 323 // check X11 socket
237 char *fname; 324 char *fname;
238 if (asprintf(&fname, "/tmp/.X11-unix/X%d", display) == -1) 325 if (asprintf(&fname, "/tmp/.X11-unix/X%d", display) == -1)
@@ -250,7 +337,6 @@ void x11_start_xephyr(int argc, char **argv) {
250 exit(1); 337 exit(1);
251 } 338 }
252 free(fname); 339 free(fname);
253 sleep(1);
254 340
255 if (arg_debug) { 341 if (arg_debug) {
256 printf("X11 sockets: "); fflush(0); 342 printf("X11 sockets: "); fflush(0);
@@ -258,26 +344,40 @@ void x11_start_xephyr(int argc, char **argv) {
258 (void) rv; 344 (void) rv;
259 } 345 }
260 346
347 setenv("DISPLAY", display_str, 1);
261 // run attach command 348 // run attach command
262 client = fork(); 349 jail = fork();
263 if (client < 0) 350 if (jail < 0)
264 errExit("fork"); 351 errExit("fork");
265 if (client == 0) { 352 if (jail == 0) {
266 printf("\n*** Attaching to Xephyr display %d ***\n\n", display); 353 if (!arg_quiet)
267 char *a[4]; 354 printf("\n*** Attaching to Xephyr display %d ***\n\n", display);
268 a[0] = "/bin/bash"; 355
269 a[1] = "-c"; 356 // running without privileges - see drop_privs call above
270 a[2] = cmd2; 357 assert(getenv("LD_PRELOAD") == NULL);
271 a[3] = NULL; 358 execvp(jail_argv[0], jail_argv);
272
273 execvp(a[0], a);
274 perror("execvp"); 359 perror("execvp");
275 exit(1); 360 _exit(1);
276 } 361 }
277 sleep(1); 362
278 363 // cleanup
279 if (!arg_quiet) 364 free(display_str);
280 printf("Xephyr server pid %d, client pid %d\n", server, client); 365 free(temp);
366
367 // wait for either server or jail termination
368 pid_t pid = wait(NULL);
369
370 // see which process terminated and kill other
371 if (pid == server) {
372 kill(jail, SIGTERM);
373 } else if (pid == jail) {
374 kill(server, SIGTERM);
375 }
376
377 // without this closing Xephyr window may mess your terminal:
378 // "monitoring" process will release terminal before
379 // jail process ends and releases terminal
380 wait(NULL); // fulneral
281 381
282 exit(0); 382 exit(0);
283} 383}
@@ -289,12 +389,14 @@ void x11_start_xpra(int argc, char **argv) {
289 pid_t client = 0; 389 pid_t client = 0;
290 pid_t server = 0; 390 pid_t server = 0;
291 391
392 setenv("FIREJAIL_X11", "yes", 1);
292 393
293 // unfortunately, xpra does a number of weird things when started by root user!!! 394 // unfortunately, xpra does a number of weird things when started by root user!!!
294 if (getuid() == 0) { 395 if (getuid() == 0) {
295 fprintf(stderr, "Error: this feature is not available when running as root\n"); 396 fprintf(stderr, "Error: X11 sandboxing is not available when running as root\n");
296 exit(1); 397 exit(1);
297 } 398 }
399 drop_privs(0);
298 400
299 // check xpra 401 // check xpra
300 if (x11_check_xpra() == 0) { 402 if (x11_check_xpra() == 0) {
@@ -304,56 +406,39 @@ void x11_start_xpra(int argc, char **argv) {
304 } 406 }
305 407
306 int display = random_display_number(); 408 int display = random_display_number();
409 char *display_str;
410 if (asprintf(&display_str, ":%d", display) == -1)
411 errExit("asprintf");
307 412
308 // build the start command 413 // build the start command
309 int len = 50; // xpra start... 414 char *server_argv[] = { "xpra", "start", display_str, "--no-daemon", NULL };
310 for (i = 0; i < argc; i++) { 415
311 len += strlen(argv[i]) + 1; // + ' ' 416 int fd_null = -1;
312 } 417 if (arg_quiet) {
313 418 fd_null = open("/dev/null", O_RDWR);
314 char *cmd1 = malloc(len + 1); // + '\0' 419 if (fd_null == -1)
315 if (!cmd1) 420 errExit("open");
316 errExit("malloc");
317
318 sprintf(cmd1, "xpra start :%d --exit-with-children --start-child=\"", display);
319 char *ptr = cmd1 + strlen(cmd1);
320 for (i = 0; i < argc; i++) {
321 if (strcmp(argv[i], "--x11") == 0)
322 continue;
323 if (strcmp(argv[i], "--x11=xpra") == 0)
324 continue;
325 if (strcmp(argv[i], "--x11=xephyr") == 0)
326 continue;
327 ptr += sprintf(ptr, "%s ", argv[i]);
328 } 421 }
329 sprintf(ptr, "\"");
330 if (arg_debug)
331 printf("xpra server: %s\n", cmd1);
332
333 // build the attach command
334 char *cmd2;
335 if (asprintf(&cmd2, "xpra --title=\"firejail x11 sandbox\" attach :%d", display) == -1)
336 errExit("asprintf");
337 if (arg_debug)
338 printf("xpra client: %s\n", cmd2);
339 422
340 signal(SIGHUP,SIG_IGN); // fix sleep(1) below 423 // start
341 server = fork(); 424 server = fork();
342 if (server < 0) 425 if (server < 0)
343 errExit("fork"); 426 errExit("fork");
344 if (server == 0) { 427 if (server == 0) {
345 if (arg_debug) 428 if (arg_debug)
346 printf("Starting xpra...\n"); 429 printf("Starting xpra...\n");
430
431 if (arg_quiet && fd_null != -1) {
432 dup2(fd_null,0);
433 dup2(fd_null,1);
434 dup2(fd_null,2);
435 }
347 436
348 char *a[4]; 437 // running without privileges - see drop_privs call above
349 a[0] = "/bin/bash"; 438 assert(getenv("LD_PRELOAD") == NULL);
350 a[1] = "-c"; 439 execvp(server_argv[0], server_argv);
351 a[2] = cmd1;
352 a[3] = NULL;
353
354 execvp(a[0], a);
355 perror("execvp"); 440 perror("execvp");
356 exit(1); 441 _exit(1);
357 } 442 }
358 443
359 // check X11 socket 444 // check X11 socket
@@ -366,14 +451,13 @@ void x11_start_xpra(int argc, char **argv) {
366 sleep(1); 451 sleep(1);
367 if (stat(fname, &s) == 0) 452 if (stat(fname, &s) == 0)
368 break; 453 break;
369 }; 454 }
370 455
371 if (n == 10) { 456 if (n == 10) {
372 fprintf(stderr, "Error: failed to start xpra\n"); 457 fprintf(stderr, "Error: failed to start xpra\n");
373 exit(1); 458 exit(1);
374 } 459 }
375 free(fname); 460 free(fname);
376 sleep(1);
377 461
378 if (arg_debug) { 462 if (arg_debug) {
379 printf("X11 sockets: "); fflush(0); 463 printf("X11 sockets: "); fflush(0);
@@ -381,28 +465,118 @@ void x11_start_xpra(int argc, char **argv) {
381 (void) rv; 465 (void) rv;
382 } 466 }
383 467
468 // build attach command
469 char *attach_argv[] = { "xpra", "--title=\"firejail x11 sandbox\"", "attach", display_str, NULL };
470
384 // run attach command 471 // run attach command
385 client = fork(); 472 client = fork();
386 if (client < 0) 473 if (client < 0)
387 errExit("fork"); 474 errExit("fork");
388 if (client == 0) { 475 if (client == 0) {
389 printf("\n*** Attaching to xpra display %d ***\n\n", display); 476 if (arg_quiet && fd_null != -1) {
390 char *a[4]; 477 dup2(fd_null,0);
391 a[0] = "/bin/bash"; 478 dup2(fd_null,1);
392 a[1] = "-c"; 479 dup2(fd_null,2);
393 a[2] = cmd2; 480 }
394 a[3] = NULL; 481
395 482 if (!arg_quiet)
396 execvp(a[0], a); 483 printf("\n*** Attaching to xpra display %d ***\n\n", display);
484
485 // running without privileges - see drop_privs call above
486 assert(getenv("LD_PRELOAD") == NULL);
487 execvp(attach_argv[0], attach_argv);
488 perror("execvp");
489 _exit(1);
490 }
491
492 setenv("DISPLAY", display_str, 1);
493
494 // build jail command
495 char *firejail_argv[argc+2];
496 int pos = 0;
497 for (i = 0; i < argc; i++) {
498 if (strcmp(argv[i], "--x11") == 0)
499 continue;
500 if (strcmp(argv[i], "--x11=xpra") == 0)
501 continue;
502 if (strcmp(argv[i], "--x11=xephyr") == 0)
503 continue;
504 firejail_argv[pos] = argv[i];
505 pos++;
506 }
507 firejail_argv[pos] = NULL;
508
509 assert(pos < (argc+2));
510 assert(!firejail_argv[pos]);
511
512 // start jail
513 pid_t jail = fork();
514 if (jail < 0)
515 errExit("fork");
516 if (jail == 0) {
517 // running without privileges - see drop_privs call above
518 assert(getenv("LD_PRELOAD") == NULL);
519 if (firejail_argv[0]) // shut up llvm scan-build
520 execvp(firejail_argv[0], firejail_argv);
397 perror("execvp"); 521 perror("execvp");
398 exit(1); 522 exit(1);
399 } 523 }
400 sleep(1);
401
402 if (!arg_quiet)
403 printf("Xpra server pid %d, client pid %d\n", server, client);
404 524
405 exit(0); 525 if (!arg_quiet)
526 printf("Xpra server pid %d, xpra client pid %d, jail %d\n", server, client, jail);
527
528 sleep(1); // let jail start
529
530 // wait for jail or server to end
531 while (1) {
532 pid_t pid = wait(NULL);
533
534 if (pid == jail) {
535 char *stop_argv[] = { "xpra", "stop", display_str, NULL };
536 pid_t stop = fork();
537 if (stop < 0)
538 errExit("fork");
539 if (stop == 0) {
540 if (arg_quiet && fd_null != -1) {
541 dup2(fd_null,0);
542 dup2(fd_null,1);
543 dup2(fd_null,2);
544 }
545 // running without privileges - see drop_privs call above
546 assert(getenv("LD_PRELOAD") == NULL);
547 execvp(stop_argv[0], stop_argv);
548 perror("execvp");
549 _exit(1);
550 }
551
552 // wait for xpra server to stop, 10 seconds limit
553 while (++n < 10) {
554 sleep(1);
555 pid = waitpid(server, NULL, WNOHANG);
556 if (pid == server)
557 break;
558 }
559
560 if (arg_debug) {
561 if (n == 10)
562 printf("failed to stop xpra server gratefully\n");
563 else
564 printf("xpra server successfully stopped in %d secs\n", n);
565 }
566
567 // kill xpra server and xpra client
568 kill(client, SIGTERM);
569 kill(server, SIGTERM);
570 exit(0);
571 }
572 else if (pid == server) {
573 // kill firejail process
574 kill(jail, SIGTERM);
575 // kill xpra client (should die with server, but...)
576 kill(client, SIGTERM);
577 exit(0);
578 }
579 }
406} 580}
407 581
408void x11_start(int argc, char **argv) { 582void x11_start(int argc, char **argv) {
@@ -410,7 +584,7 @@ void x11_start(int argc, char **argv) {
410 584
411 // unfortunately, xpra does a number of weird things when started by root user!!! 585 // unfortunately, xpra does a number of weird things when started by root user!!!
412 if (getuid() == 0) { 586 if (getuid() == 0) {
413 fprintf(stderr, "Error: this feature is not available when running as root\n"); 587 fprintf(stderr, "Error: X11 sandboxing is not available when running as root\n");
414 exit(1); 588 exit(1);
415 } 589 }
416 590
@@ -428,3 +602,128 @@ void x11_start(int argc, char **argv) {
428} 602}
429 603
430#endif 604#endif
605
606void x11_block(void) {
607#ifdef HAVE_X11
608 mask_x11_abstract_socket = 1;
609
610 // check abstract socket presence and network namespace options
611 if ((!arg_nonetwork && !cfg.bridge0.configured && !cfg.interface0.configured)
612 && x11_abstract_sockets_present()) {
613 fprintf(stderr, "ERROR: --x11=none specified, but abstract X11 socket still accessible.\n"
614 "Additional setup required. To block abstract X11 socket you can either:\n"
615 " * use network namespace in firejail (--net=none, --net=...)\n"
616 " * add \"-nolisten local\" to xserver options\n"
617 " (eg. to your display manager config, or /etc/X11/xinit/xserverrc)\n");
618 exit(1);
619 }
620
621 // blacklist sockets
622 profile_check_line("blacklist /tmp/.X11-unix", 0, NULL);
623 profile_add(strdup("blacklist /tmp/.X11-unix"));
624
625 // blacklist .Xauthority
626 profile_check_line("blacklist ${HOME}/.Xauthority", 0, NULL);
627 profile_add(strdup("blacklist ${HOME}/.Xauthority"));
628 char *xauthority = getenv("XAUTHORITY");
629 if (xauthority) {
630 char *line;
631 if (asprintf(&line, "blacklist %s", xauthority) == -1)
632 errExit("asprintf");
633 profile_check_line(line, 0, NULL);
634 profile_add(line);
635 }
636
637 // clear environment
638 env_store("DISPLAY", RMENV);
639 env_store("XAUTHORITY", RMENV);
640#endif
641}
642
643void x11_xorg(void) {
644#ifdef HAVE_X11
645 // destination - create an empty ~/.Xauthotrity file if it doesn't exist already, and use it as a mount point
646 char *dest;
647 if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1)
648 errExit("asprintf");
649 struct stat s;
650 if (stat(dest, &s) == -1) {
651 // create an .Xauthority file
652 FILE *fp = fopen(dest, "w");
653 if (!fp)
654 errExit("fopen");
655 SET_PERMS_STREAM(fp, getuid(), getgid(), 0600);
656 fclose(fp);
657 }
658
659 // check xauth utility is present in the system
660 if (stat("/usr/bin/xauth", &s) == -1) {
661 fprintf(stderr, "Error: cannot find /usr/bin/xauth executable\n");
662 exit(1);
663 }
664
665 // create a temporary .Xauthority file
666 char tmpfname[] = "/tmp/.tmpXauth-XXXXXX";
667 int fd = mkstemp(tmpfname);
668 if (fd == -1) {
669 fprintf(stderr, "Error: cannot create .Xauthority file\n");
670 exit(1);
671 }
672 close(fd);
673 if (chown(tmpfname, getuid(), getgid()) == -1)
674 errExit("chown");
675
676 pid_t child = fork();
677 if (child < 0)
678 errExit("fork");
679 if (child == 0) {
680 // generate the new .Xauthority file using xauth utility
681 if (arg_debug)
682 printf("Generating a new .Xauthority file\n");
683 drop_privs(1);
684
685 char *display = getenv("DISPLAY");
686 if (!display)
687 display = ":0.0";
688
689 clearenv();
690 execlp("/usr/bin/xauth", "/usr/bin/xauth", "-f", tmpfname,
691 "generate", display, "MIT-MAGIC-COOKIE-1", "untrusted", NULL);
692
693#ifdef HAVE_GCOV
694 __gcov_flush();
695#endif
696 _exit(0);
697 }
698
699 // wait for the child to finish
700 waitpid(child, NULL, 0);
701
702 // check the file was created and set mode and ownership
703 if (stat(tmpfname, &s) == -1) {
704 fprintf(stderr, "Error: cannot create the new .Xauthority file\n");
705 exit(1);
706 }
707 if (set_perms(tmpfname, getuid(), getgid(), 0600))
708 errExit("set_perms");
709
710 // move the temporary file in RUN_XAUTHORITY_SEC_FILE in order to have it deleted
711 // automatically when the sandbox is closed
712 if (copy_file(tmpfname, RUN_XAUTHORITY_SEC_FILE, getuid(), getgid(), 0600)) {
713 fprintf(stderr, "Error: cannot create the new .Xauthority file\n");
714 exit(1);
715 }
716 if (set_perms(RUN_XAUTHORITY_SEC_FILE, getuid(), getgid(), 0600))
717 errExit("set_perms");
718 unlink(tmpfname);
719
720 // mount
721 if (mount(RUN_XAUTHORITY_SEC_FILE, dest, "none", MS_BIND, "mode=0600") == -1) {
722 fprintf(stderr, "Error: cannot mount the new .Xauthority file\n");
723 exit(1);
724 }
725 if (set_perms(dest, getuid(), getgid(), 0600))
726 errExit("set_perms");
727 free(dest);
728#endif
729}
diff --git a/src/firemon/Makefile.in b/src/firemon/Makefile.in
index 21888d354..efc48b212 100644
--- a/src/firemon/Makefile.in
+++ b/src/firemon/Makefile.in
@@ -4,21 +4,26 @@ PREFIX=@prefix@
4VERSION=@PACKAGE_VERSION@ 4VERSION=@PACKAGE_VERSION@
5NAME=@PACKAGE_NAME@ 5NAME=@PACKAGE_NAME@
6HAVE_FATAL_WARNINGS=@HAVE_FATAL_WARNINGS@ 6HAVE_FATAL_WARNINGS=@HAVE_FATAL_WARNINGS@
7HAVE_GCOV=@HAVE_GCOV@
8EXTRA_LDFLAGS +=@EXTRA_LDFLAGS@
7 9
8H_FILE_LIST = $(sort $(wildcard *.[h])) 10H_FILE_LIST = $(sort $(wildcard *.[h]))
9C_FILE_LIST = $(sort $(wildcard *.c)) 11C_FILE_LIST = $(sort $(wildcard *.c))
10OBJS = $(C_FILE_LIST:.c=.o) 12OBJS = $(C_FILE_LIST:.c=.o)
11BINOBJS = $(foreach file, $(OBJS), $file) 13BINOBJS = $(foreach file, $(OBJS), $file)
12CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security 14CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' $(HAVE_GCOV) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security
13LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now 15LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now
16HAVE_GCOV=@HAVE_GCOV@
17EXTRA_LDFLAGS +=@EXTRA_LDFLAGS@
18
14 19
15%.o : %.c $(H_FILE_LIST) 20%.o : %.c $(H_FILE_LIST)
16 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ 21 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
17 22
18firemon: $(OBJS) ../lib/common.o ../lib/pid.o 23firemon: $(OBJS) ../lib/common.o ../lib/pid.o
19 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o ../lib/pid.o $(LIBS) 24 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o ../lib/pid.o $(LIBS) $(EXTRA_LDFLAGS)
20 25
21clean:; rm -f *.o firemon 26clean:; rm -f *.o firemon *.gcov *.gcda *.gcno
22 27
23distclean: clean 28distclean: clean
24 rm -fr Makefile 29 rm -fr Makefile
diff --git a/src/firemon/arp.c b/src/firemon/arp.c
index 7cb8ff4c3..014f6a904 100644
--- a/src/firemon/arp.c
+++ b/src/firemon/arp.c
@@ -72,17 +72,15 @@ static void print_arp(const char *fname) {
72 72
73} 73}
74 74
75void arp(pid_t pid) { 75void arp(pid_t pid, int print_procs) {
76 if (getuid() == 0)
77 firemon_drop_privs();
78
79 pid_read(pid); 76 pid_read(pid);
80 77
81 // print processes 78 // print processes
82 int i; 79 int i;
83 for (i = 0; i < max_pids; i++) { 80 for (i = 0; i < max_pids; i++) {
84 if (pids[i].level == 1) { 81 if (pids[i].level == 1) {
85 pid_print_list(i, 0); 82 if (print_procs || pid == 0)
83 pid_print_list(i, 0);
86 int child = find_child(i); 84 int child = find_child(i);
87 if (child != -1) { 85 if (child != -1) {
88 char *fname; 86 char *fname;
@@ -90,10 +88,10 @@ void arp(pid_t pid) {
90 errExit("asprintf"); 88 errExit("asprintf");
91 print_arp(fname); 89 print_arp(fname);
92 free(fname); 90 free(fname);
93 printf("\n");
94 } 91 }
95 } 92 }
96 } 93 }
94 printf("\n");
97} 95}
98 96
99 97
diff --git a/src/firemon/caps.c b/src/firemon/caps.c
index 5cd9b5d0d..81877ab87 100644
--- a/src/firemon/caps.c
+++ b/src/firemon/caps.c
@@ -48,17 +48,15 @@ static void print_caps(int pid) {
48 free(file); 48 free(file);
49} 49}
50 50
51void caps(pid_t pid) { 51void caps(pid_t pid, int print_procs) {
52 if (getuid() == 0)
53 firemon_drop_privs();
54
55 pid_read(pid); // include all processes 52 pid_read(pid); // include all processes
56 53
57 // print processes 54 // print processes
58 int i; 55 int i;
59 for (i = 0; i < max_pids; i++) { 56 for (i = 0; i < max_pids; i++) {
60 if (pids[i].level == 1) { 57 if (pids[i].level == 1) {
61 pid_print_list(i, 0); 58 if (print_procs || pid == 0)
59 pid_print_list(i, 0);
62 int child = find_child(i); 60 int child = find_child(i);
63 if (child != -1) 61 if (child != -1)
64 print_caps(child); 62 print_caps(child);
diff --git a/src/firemon/cgroup.c b/src/firemon/cgroup.c
index 0b93390ae..e20e1d449 100644
--- a/src/firemon/cgroup.c
+++ b/src/firemon/cgroup.c
@@ -44,21 +44,20 @@ static void print_cgroup(int pid) {
44 free(file); 44 free(file);
45} 45}
46 46
47void cgroup(pid_t pid) { 47void cgroup(pid_t pid, int print_procs) {
48 if (getuid() == 0)
49 firemon_drop_privs();
50
51 pid_read(pid); 48 pid_read(pid);
52 49
53 // print processes 50 // print processes
54 int i; 51 int i;
55 for (i = 0; i < max_pids; i++) { 52 for (i = 0; i < max_pids; i++) {
56 if (pids[i].level == 1) { 53 if (pids[i].level == 1) {
57 pid_print_list(i, 0); 54 if (print_procs || pid == 0)
55 pid_print_list(i, 0);
58 int child = find_child(i); 56 int child = find_child(i);
59 if (child != -1) 57 if (child != -1)
60 print_cgroup(child); 58 print_cgroup(child);
61 } 59 }
62 } 60 }
61 printf("\n");
63} 62}
64 63
diff --git a/src/firemon/cpu.c b/src/firemon/cpu.c
index 06658f58c..47c935686 100644
--- a/src/firemon/cpu.c
+++ b/src/firemon/cpu.c
@@ -48,21 +48,20 @@ static void print_cpu(int pid) {
48 free(file); 48 free(file);
49} 49}
50 50
51void cpu(pid_t pid) { 51void cpu(pid_t pid, int print_procs) {
52 if (getuid() == 0)
53 firemon_drop_privs();
54
55 pid_read(pid); 52 pid_read(pid);
56 53
57 // print processes 54 // print processes
58 int i; 55 int i;
59 for (i = 0; i < max_pids; i++) { 56 for (i = 0; i < max_pids; i++) {
60 if (pids[i].level == 1) { 57 if (pids[i].level == 1) {
61 pid_print_list(i, 0); 58 if (print_procs || pid == 0)
59 pid_print_list(i, 0);
62 int child = find_child(i); 60 int child = find_child(i);
63 if (child != -1) 61 if (child != -1)
64 print_cpu(child); 62 print_cpu(child);
65 } 63 }
66 } 64 }
65 printf("\n");
67} 66}
68 67
diff --git a/src/firemon/firemon.c b/src/firemon/firemon.c
index 3140c5f70..b63e37444 100644
--- a/src/firemon/firemon.c
+++ b/src/firemon/firemon.c
@@ -25,7 +25,6 @@
25#include <grp.h> 25#include <grp.h>
26#include <sys/stat.h> 26#include <sys/stat.h>
27 27
28
29static int arg_route = 0; 28static int arg_route = 0;
30static int arg_arp = 0; 29static int arg_arp = 0;
31static int arg_tree = 0; 30static int arg_tree = 0;
@@ -35,6 +34,9 @@ static int arg_caps = 0;
35static int arg_cpu = 0; 34static int arg_cpu = 0;
36static int arg_cgroup = 0; 35static int arg_cgroup = 0;
37static int arg_x11 = 0; 36static int arg_x11 = 0;
37static int arg_top = 0;
38static int arg_list = 0;
39static int arg_netstats = 0;
38int arg_nowrap = 0; 40int arg_nowrap = 0;
39 41
40static struct termios tlocal; // startup terminal setting 42static struct termios tlocal; // startup terminal setting
@@ -62,17 +64,6 @@ int find_child(int id) {
62 return -1; 64 return -1;
63} 65}
64 66
65// drop privileges
66void firemon_drop_privs(void) {
67 // drop privileges
68 if (setgroups(0, NULL) < 0)
69 errExit("setgroups");
70 if (setgid(getgid()) < 0)
71 errExit("setgid/getgid");
72 if (setuid(getuid()) < 0)
73 errExit("setuid/getuid");
74}
75
76// sleep and wait for a key to be pressed 67// sleep and wait for a key to be pressed
77void firemon_sleep(int st) { 68void firemon_sleep(int st) {
78 if (terminal_set == 0) { 69 if (terminal_set == 0) {
@@ -129,53 +120,44 @@ int main(int argc, char **argv) {
129 } 120 }
130 121
131 // options without a pid argument 122 // options without a pid argument
132 else if (strcmp(argv[i], "--top") == 0) { 123 else if (strcmp(argv[i], "--top") == 0)
133 top(); // never to return 124 arg_top = 1;
134 } 125 else if (strcmp(argv[i], "--list") == 0)
135 else if (strcmp(argv[i], "--list") == 0) { 126 arg_list = 1;
136 list(); 127 else if (strcmp(argv[i], "--tree") == 0)
137 return 0; 128 arg_tree = 1;
138 }
139 else if (strcmp(argv[i], "--netstats") == 0) { 129 else if (strcmp(argv[i], "--netstats") == 0) {
140 struct stat s; 130 struct stat s;
141 if (getuid() != 0 && stat("/proc/sys/kernel/grsecurity", &s) == 0) { 131 if (getuid() != 0 && stat("/proc/sys/kernel/grsecurity", &s) == 0) {
142 fprintf(stderr, "Error: this feature is not available on Grsecurity systems\n"); 132 fprintf(stderr, "Error: this feature is not available on Grsecurity systems\n");
143 exit(1); 133 exit(1);
144 } 134 }
145 135 arg_netstats = 1;
146 netstats();
147 return 0;
148 } 136 }
149 137
150 138
151 // cumulative options with or without a pid argument 139 // cumulative options with or without a pid argument
152 else if (strcmp(argv[i], "--x11") == 0) { 140 else if (strcmp(argv[i], "--x11") == 0)
153 arg_x11 = 1; 141 arg_x11 = 1;
154 } 142 else if (strcmp(argv[i], "--cgroup") == 0)
155 else if (strcmp(argv[i], "--cgroup") == 0) {
156 arg_cgroup = 1; 143 arg_cgroup = 1;
157 } 144 else if (strcmp(argv[i], "--cpu") == 0)
158 else if (strcmp(argv[i], "--cpu") == 0) {
159 arg_cpu = 1; 145 arg_cpu = 1;
160 } 146 else if (strcmp(argv[i], "--seccomp") == 0)
161 else if (strcmp(argv[i], "--seccomp") == 0) {
162 arg_seccomp = 1; 147 arg_seccomp = 1;
163 } 148 else if (strcmp(argv[i], "--caps") == 0)
164 else if (strcmp(argv[i], "--caps") == 0) {
165 arg_caps = 1; 149 arg_caps = 1;
166 }
167 else if (strcmp(argv[i], "--tree") == 0) {
168 arg_tree = 1;
169 }
170 else if (strcmp(argv[i], "--interface") == 0) { 150 else if (strcmp(argv[i], "--interface") == 0) {
151 if (getuid() != 0) {
152 fprintf(stderr, "Error: you need to be root to run this command\n");
153 exit(1);
154 }
171 arg_interface = 1; 155 arg_interface = 1;
172 } 156 }
173 else if (strcmp(argv[i], "--route") == 0) { 157 else if (strcmp(argv[i], "--route") == 0)
174 arg_route = 1; 158 arg_route = 1;
175 } 159 else if (strcmp(argv[i], "--arp") == 0)
176 else if (strcmp(argv[i], "--arp") == 0) {
177 arg_arp = 1; 160 arg_arp = 1;
178 }
179 161
180 else if (strncmp(argv[i], "--name=", 7) == 0) { 162 else if (strncmp(argv[i], "--name=", 7) == 0) {
181 char *name = argv[i] + 7; 163 char *name = argv[i] + 7;
@@ -212,27 +194,66 @@ int main(int argc, char **argv) {
212 } 194 }
213 } 195 }
214 196
215 if (arg_tree) 197 // allow only root user if /proc is mounted hidepid
198 if (pid_hidepid() && getuid() != 0) {
199 fprintf(stderr, "Error: /proc is mounted hidepid, you would need to be root to run this command\n");
200 exit(1);
201 }
202
203 if (arg_top) {
204 top();
205 return 0;
206 }
207 if (arg_list) {
208 list();
209 return 0;
210 }
211 if (arg_netstats) {
212 netstats();
213 return 0;
214 }
215
216 // cumulative options
217 int print_procs = 1;
218 if (arg_tree) {
216 tree((pid_t) pid); 219 tree((pid_t) pid);
217 if (arg_interface) 220 print_procs = 0;
218 interface((pid_t) pid); 221 }
219 if (arg_route) 222 if (arg_cpu) {
220 route((pid_t) pid); 223 cpu((pid_t) pid, print_procs);
221 if (arg_arp) 224 print_procs = 0;
222 arp((pid_t) pid); 225 }
223 if (arg_seccomp) 226 if (arg_seccomp) {
224 seccomp((pid_t) pid); 227 seccomp((pid_t) pid, print_procs);
225 if (arg_caps) 228 print_procs = 0;
226 caps((pid_t) pid); 229 }
227 if (arg_cpu) 230 if (arg_caps) {
228 cpu((pid_t) pid); 231 caps((pid_t) pid, print_procs);
229 if (arg_cgroup) 232 print_procs = 0;
230 cgroup((pid_t) pid); 233 }
231 if (arg_x11) 234 if (arg_cgroup) {
232 x11((pid_t) pid); 235 cgroup((pid_t) pid, print_procs);
236 print_procs = 0;
237 }
238 if (arg_x11) {
239 x11((pid_t) pid, print_procs);
240 print_procs = 0;
241 }
242 if (arg_interface) {
243 interface((pid_t) pid, print_procs);
244 print_procs = 0;
245 }
246 if (arg_route) {
247 route((pid_t) pid, print_procs);
248 print_procs = 0;
249 }
250 if (arg_arp) {
251 arp((pid_t) pid, print_procs);
252 print_procs = 0;
253 }
233 254
234 if (!arg_route && !arg_arp && !arg_interface && !arg_tree && !arg_caps && !arg_seccomp && !arg_x11) 255 if (print_procs)
235 procevent((pid_t) pid); // never to return 256 procevent((pid_t) pid);
236 257
237 return 0; 258 return 0;
238} 259}
diff --git a/src/firemon/firemon.h b/src/firemon/firemon.h
index 522ece077..c78023888 100644
--- a/src/firemon/firemon.h
+++ b/src/firemon/firemon.h
@@ -38,7 +38,6 @@ static inline void firemon_clrscr(void) {
38// firemon.c 38// firemon.c
39extern int arg_nowrap; 39extern int arg_nowrap;
40int find_child(int id); 40int find_child(int id);
41void firemon_drop_privs(void);
42void firemon_sleep(int st); 41void firemon_sleep(int st);
43 42
44 43
@@ -55,25 +54,25 @@ void top(void);
55void list(void); 54void list(void);
56 55
57// interface.c 56// interface.c
58void interface(pid_t pid); 57void interface(pid_t pid, int print_procs);
59 58
60// arp.c 59// arp.c
61void arp(pid_t pid); 60void arp(pid_t pid, int print_procs);
62 61
63// route.c 62// route.c
64void route(pid_t pid); 63void route(pid_t pid, int print_procs);
65 64
66// caps.c 65// caps.c
67void caps(pid_t pid); 66void caps(pid_t pid, int print_procs);
68 67
69// seccomp.c 68// seccomp.c
70void seccomp(pid_t pid); 69void seccomp(pid_t pid, int print_procs);
71 70
72// cpu.c 71// cpu.c
73void cpu(pid_t pid); 72void cpu(pid_t pid, int print_procs);
74 73
75// cgroup.c 74// cgroup.c
76void cgroup(pid_t pid); 75void cgroup(pid_t pid, int print_procs);
77 76
78// tree.c 77// tree.c
79void tree(pid_t pid); 78void tree(pid_t pid);
@@ -82,6 +81,6 @@ void tree(pid_t pid);
82void netstats(void); 81void netstats(void);
83 82
84// x11.c 83// x11.c
85void x11(pid_t pid); 84void x11(pid_t pid, int print_procs);
86 85
87#endif 86#endif
diff --git a/src/firemon/interface.c b/src/firemon/interface.c
index 5a89e1491..def9cd5ac 100644
--- a/src/firemon/interface.c
+++ b/src/firemon/interface.c
@@ -145,32 +145,31 @@ static void print_sandbox(pid_t pid) {
145 if (rv) 145 if (rv)
146 return; 146 return;
147 net_ifprint(); 147 net_ifprint();
148 printf("\n"); 148#ifdef HAVE_GCOV
149 exit(0); 149 __gcov_flush();
150#endif
151 _exit(0);
150 } 152 }
151 153
152 // wait for the child to finish 154 // wait for the child to finish
153 waitpid(child, NULL, 0); 155 waitpid(child, NULL, 0);
154} 156}
155 157
156void interface(pid_t pid) { 158void interface(pid_t pid, int print_procs) {
157 if (getuid() != 0) {
158 fprintf(stderr, "Error: you need to be root to run this command\n");
159 exit(1);
160 }
161
162 pid_read(pid); // a pid of 0 will include all processes 159 pid_read(pid); // a pid of 0 will include all processes
163 160
164 // print processes 161 // print processes
165 int i; 162 int i;
166 for (i = 0; i < max_pids; i++) { 163 for (i = 0; i < max_pids; i++) {
167 if (pids[i].level == 1) { 164 if (pids[i].level == 1) {
168 pid_print_list(i, 0); 165 if (print_procs || pid == 0)
166 pid_print_list(i, 0);
169 int child = find_child(i); 167 int child = find_child(i);
170 if (child != -1) { 168 if (child != -1) {
171 print_sandbox(child); 169 print_sandbox(child);
172 } 170 }
173 } 171 }
174 } 172 }
173 printf("\n");
175} 174}
176 175
diff --git a/src/firemon/list.c b/src/firemon/list.c
index 901627c2a..acff13a28 100644
--- a/src/firemon/list.c
+++ b/src/firemon/list.c
@@ -20,9 +20,6 @@
20#include "firemon.h" 20#include "firemon.h"
21 21
22void list(void) { 22void list(void) {
23 if (getuid() == 0)
24 firemon_drop_privs();
25
26 pid_read(0); // include all processes 23 pid_read(0); // include all processes
27 24
28 // print processes 25 // print processes
diff --git a/src/firemon/netstats.c b/src/firemon/netstats.c
index 89e4202bd..3c020d630 100644
--- a/src/firemon/netstats.c
+++ b/src/firemon/netstats.c
@@ -26,6 +26,10 @@
26 26
27#define MAXBUF 4096 27#define MAXBUF 4096
28 28
29// ip -s link: device stats
30// ss -s: socket stats
31
32
29static char *get_header(void) { 33static char *get_header(void) {
30 char *rv; 34 char *rv;
31 if (asprintf(&rv, "%-5.5s %-9.9s %-10.10s %-10.10s %s", 35 if (asprintf(&rv, "%-5.5s %-9.9s %-10.10s %-10.10s %s",
@@ -166,9 +170,6 @@ static void print_proc(int index, int itv, int col) {
166} 170}
167 171
168void netstats(void) { 172void netstats(void) {
169 if (getuid() == 0)
170 firemon_drop_privs();
171
172 pid_read(0); // include all processes 173 pid_read(0); // include all processes
173 174
174 printf("Displaying network statistics only for sandboxes using a new network namespace.\n"); 175 printf("Displaying network statistics only for sandboxes using a new network namespace.\n");
diff --git a/src/firemon/procevent.c b/src/firemon/procevent.c
index e2dd5aaa2..1940f4a34 100644
--- a/src/firemon/procevent.c
+++ b/src/firemon/procevent.c
@@ -28,6 +28,8 @@
28#include <arpa/inet.h> 28#include <arpa/inet.h>
29#include <time.h> 29#include <time.h>
30#include <fcntl.h> 30#include <fcntl.h>
31#include <sys/uio.h>
32
31#define PIDS_BUFLEN 4096 33#define PIDS_BUFLEN 4096
32#define SERVER_PORT 889 // 889-899 is left unassigned by IANA 34#define SERVER_PORT 889 // 889-899 is left unassigned by IANA
33 35
@@ -89,7 +91,8 @@ static int pid_is_firejail(pid_t pid) {
89 91
90 // list of firejail arguments that don't trigger sandbox creation 92 // list of firejail arguments that don't trigger sandbox creation
91 // the initial -- is not included 93 // the initial -- is not included
92 char *firejail_args = "ls list tree x11 help version top netstats debug-syscalls debug-errnos debug-protocols"; 94 char *firejail_args = "ls list tree x11 help version top netstats debug-syscalls debug-errnos debug-protocols "
95 "protocol.print debug.caps shutdown bandwidth caps.print cpu.print debug-caps fs.print get overlay-clean ";
93 96
94 int i; 97 int i;
95 char *start; 98 char *start;
@@ -189,6 +192,10 @@ static int procevent_monitor(const int sock, pid_t mypid) {
189 tv.tv_usec = 0; 192 tv.tv_usec = 0;
190 193
191 while (1) { 194 while (1) {
195#ifdef HAVE_GCOV
196 __gcov_flush();
197#endif
198
192#define BUFFSIZE 4096 199#define BUFFSIZE 4096
193 char __attribute__ ((aligned(NLMSG_ALIGNTO)))buf[BUFFSIZE]; 200 char __attribute__ ((aligned(NLMSG_ALIGNTO)))buf[BUFFSIZE];
194 201
diff --git a/src/firemon/route.c b/src/firemon/route.c
index 398965671..fb58b169d 100644
--- a/src/firemon/route.c
+++ b/src/firemon/route.c
@@ -181,17 +181,15 @@ static void print_route(const char *fname) {
181 181
182} 182}
183 183
184void route(pid_t pid) { 184void route(pid_t pid, int print_procs) {
185 if (getuid() == 0)
186 firemon_drop_privs();
187
188 pid_read(pid); 185 pid_read(pid);
189 186
190 // print processes 187 // print processes
191 int i; 188 int i;
192 for (i = 0; i < max_pids; i++) { 189 for (i = 0; i < max_pids; i++) {
193 if (pids[i].level == 1) { 190 if (pids[i].level == 1) {
194 pid_print_list(i, 0); 191 if (print_procs || pid == 0)
192 pid_print_list(i, 0);
195 int child = find_child(i); 193 int child = find_child(i);
196 if (child != -1) { 194 if (child != -1) {
197 char *fname; 195 char *fname;
@@ -204,10 +202,10 @@ void route(pid_t pid) {
204 errExit("asprintf"); 202 errExit("asprintf");
205 print_route(fname); 203 print_route(fname);
206 free(fname); 204 free(fname);
207 printf("\n");
208 } 205 }
209 } 206 }
210 } 207 }
208 printf("\n");
211} 209}
212 210
213 211
diff --git a/src/firemon/seccomp.c b/src/firemon/seccomp.c
index 71771c72d..abc698bb8 100644
--- a/src/firemon/seccomp.c
+++ b/src/firemon/seccomp.c
@@ -48,17 +48,15 @@ static void print_seccomp(int pid) {
48 free(file); 48 free(file);
49} 49}
50 50
51void seccomp(pid_t pid) { 51void seccomp(pid_t pid, int print_procs) {
52 if (getuid() == 0)
53 firemon_drop_privs();
54
55 pid_read(pid); // include all processes 52 pid_read(pid); // include all processes
56 53
57 // print processes 54 // print processes
58 int i; 55 int i;
59 for (i = 0; i < max_pids; i++) { 56 for (i = 0; i < max_pids; i++) {
60 if (pids[i].level == 1) { 57 if (pids[i].level == 1) {
61 pid_print_list(i, 0); 58 if (print_procs || pid == 0)
59 pid_print_list(i, 0);
62 int child = find_child(i); 60 int child = find_child(i);
63 if (child != -1) 61 if (child != -1)
64 print_seccomp(child); 62 print_seccomp(child);
diff --git a/src/firemon/top.c b/src/firemon/top.c
index a6da6f64e..b804761dd 100644
--- a/src/firemon/top.c
+++ b/src/firemon/top.c
@@ -232,9 +232,6 @@ void head_print(int col, int row) {
232} 232}
233 233
234void top(void) { 234void top(void) {
235 if (getuid() == 0)
236 firemon_drop_privs();
237
238 while (1) { 235 while (1) {
239 // clear linked list 236 // clear linked list
240 head_clear(); 237 head_clear();
diff --git a/src/firemon/tree.c b/src/firemon/tree.c
index b05eb92f9..6d8b37ecb 100644
--- a/src/firemon/tree.c
+++ b/src/firemon/tree.c
@@ -20,10 +20,7 @@
20#include "firemon.h" 20#include "firemon.h"
21 21
22void tree(pid_t pid) { 22void tree(pid_t pid) {
23 if (getuid() == 0) 23 pid_read(pid);
24 firemon_drop_privs();
25
26 pid_read(pid); // include all processes
27 24
28 // print processes 25 // print processes
29 int i; 26 int i;
diff --git a/src/firemon/x11.c b/src/firemon/x11.c
index e30c2d78b..b0efb090a 100644
--- a/src/firemon/x11.c
+++ b/src/firemon/x11.c
@@ -22,17 +22,15 @@
22#include <sys/stat.h> 22#include <sys/stat.h>
23#include <unistd.h> 23#include <unistd.h>
24 24
25void x11(pid_t pid) { 25void x11(pid_t pid, int print_procs) {
26 if (getuid() == 0)
27 firemon_drop_privs();
28
29 pid_read(pid); 26 pid_read(pid);
30 27
31 // print processes 28 // print processes
32 int i; 29 int i;
33 for (i = 0; i < max_pids; i++) { 30 for (i = 0; i < max_pids; i++) {
34 if (pids[i].level == 1) { 31 if (pids[i].level == 1) {
35 pid_print_list(i, 0); 32 if (print_procs || pid == 0)
33 pid_print_list(i, 0);
36 34
37 char *x11file; 35 char *x11file;
38 // todo: use macro from src/firejail/firejail.h for /run/firejail/x11 directory 36 // todo: use macro from src/firejail/firejail.h for /run/firejail/x11 directory
@@ -49,12 +47,13 @@ void x11(pid_t pid) {
49 int display; 47 int display;
50 int rv = fscanf(fp, "%d", &display); 48 int rv = fscanf(fp, "%d", &display);
51 if (rv == 1) 49 if (rv == 1)
52 printf(" DISPLAY :%d\n", display); 50 printf(" DISPLAY :%d\n", display);
53 fclose(fp); 51 fclose(fp);
54 } 52 }
55 53
56 free(x11file); 54 free(x11file);
57 } 55 }
58 } 56 }
57 printf("\n");
59} 58}
60 59
diff --git a/src/fnet/Makefile.in b/src/fnet/Makefile.in
new file mode 100644
index 000000000..32f08882a
--- /dev/null
+++ b/src/fnet/Makefile.in
@@ -0,0 +1,45 @@
1all: fnet
2
3prefix=@prefix@
4exec_prefix=@exec_prefix@
5libdir=@libdir@
6sysconfdir=@sysconfdir@
7
8VERSION=@PACKAGE_VERSION@
9NAME=@PACKAGE_NAME@
10HAVE_SECCOMP_H=@HAVE_SECCOMP_H@
11HAVE_SECCOMP=@HAVE_SECCOMP@
12HAVE_CHROOT=@HAVE_CHROOT@
13HAVE_BIND=@HAVE_BIND@
14HAVE_FATAL_WARNINGS=@HAVE_FATAL_WARNINGS@
15HAVE_NETWORK=@HAVE_NETWORK@
16HAVE_USERNS=@HAVE_USERNS@
17HAVE_X11=@HAVE_X11@
18HAVE_FILE_TRANSFER=@HAVE_FILE_TRANSFER@
19HAVE_WHITELIST=@HAVE_WHITELIST@
20HAVE_GLOBALCFG=@HAVE_GLOBALCFG@
21HAVE_APPARMOR=@HAVE_APPARMOR@
22HAVE_OVERLAYFS=@HAVE_OVERLAYFS@
23HAVE_PRIVATE_HOME=@HAVE_PRIVATE_HOME@
24EXTRA_LDFLAGS +=@EXTRA_LDFLAGS@
25HAVE_GCOV=@HAVE_GCOV@
26EXTRA_LDFLAGS +=@EXTRA_LDFLAGS@
27
28H_FILE_LIST = $(sort $(wildcard *.[h]))
29C_FILE_LIST = $(sort $(wildcard *.c))
30OBJS = $(C_FILE_LIST:.c=.o)
31BINOBJS = $(foreach file, $(OBJS), $file)
32CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' $(HAVE_GCOV) -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' $(HAVE_X11) $(HAVE_PRIVATE_HOME) $(HAVE_APPARMOR) $(HAVE_OVERLAYFS) $(HAVE_SECCOMP) $(HAVE_GLOBALCFG) $(HAVE_SECCOMP_H) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_BIND) $(HAVE_FILE_TRANSFER) $(HAVE_WHITELIST) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security
33LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread
34
35%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/libnetlink.h
36 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
37
38fnet: $(OBJS) ../lib/libnetlink.o
39 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/libnetlink.o $(LIBS) $(EXTRA_LDFLAGS)
40
41clean:; rm -f *.o fnet *.gcov *.gcda *.gcno
42
43distclean: clean
44 rm -fr Makefile
45
diff --git a/src/fnet/arp.c b/src/fnet/arp.c
new file mode 100644
index 000000000..96684fdf9
--- /dev/null
+++ b/src/fnet/arp.c
@@ -0,0 +1,208 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "fnet.h"
21#include <sys/socket.h>
22#include <sys/ioctl.h>
23#include <linux/if_ether.h> //TCP/IP Protocol Suite for Linux
24#include <net/if.h>
25#include <netinet/in.h>
26#include <linux/ip.h>
27#include <linux/udp.h>
28#include <linux/tcp.h>
29#include <linux/if_packet.h>
30
31typedef struct arp_hdr_t {
32 uint16_t htype;
33 uint16_t ptype;
34 uint8_t hlen;
35 uint8_t plen;
36 uint16_t opcode;
37 uint8_t sender_mac[6];
38 uint8_t sender_ip[4];
39 uint8_t target_mac[6];
40 uint8_t target_ip[4];
41} ArpHdr;
42
43
44// scan interface (--scan option)
45void arp_scan(const char *dev, uint32_t ifip, uint32_t ifmask) {
46 assert(dev);
47 assert(ifip);
48
49// printf("Scanning interface %s (%d.%d.%d.%d/%d)\n",
50// dev, PRINT_IP(ifip & ifmask), mask2bits(ifmask));
51
52 if (strlen(dev) > IFNAMSIZ) {
53 fprintf(stderr, "Error: invalid network device name %s\n", dev);
54 exit(1);
55 }
56
57 // find interface mac address
58 int sock;
59 if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
60 errExit("socket");
61 struct ifreq ifr;
62 memset(&ifr, 0, sizeof (ifr));
63 strncpy(ifr.ifr_name, dev, IFNAMSIZ);
64 if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0)
65 errExit("ioctl");
66 close(sock);
67 uint8_t mac[6];
68 memcpy (mac, ifr.ifr_hwaddr.sa_data, 6);
69
70 // open layer2 socket
71 if ((sock = socket(PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 0)
72 errExit("socket");
73
74 // try all possible ip addresses in ascending order
75 uint32_t range = ~ifmask + 1; // the number of potential addresses
76 // this software is not supported for /31 networks
77 if (range < 4) {
78 fprintf(stderr, "Warning: this option is not supported for /31 networks\n");
79 close(sock);
80 return;
81 }
82
83 uint32_t dest = (ifip & ifmask) + 1;
84 uint32_t last = dest + range - 1;
85 uint32_t src = htonl(ifip);
86
87 // wait not more than one second for an answer
88 int header_printed = 0;
89 uint32_t last_ip = 0;
90 struct timeval ts;
91 ts.tv_sec = 2; // 2 seconds receive timeout
92 ts.tv_usec = 0;
93
94 while (1) {
95 fd_set rfds;
96 FD_ZERO(&rfds);
97 FD_SET(sock, &rfds);
98 fd_set wfds;
99 FD_ZERO(&wfds);
100 FD_SET(sock, &wfds);
101 int maxfd = sock;
102
103 uint8_t frame[ETH_FRAME_LEN]; // includes eht header, vlan, and crc
104 memset(frame, 0, ETH_FRAME_LEN);
105
106 int nready;
107 if (dest < last)
108 nready = select(maxfd + 1, &rfds, &wfds, (fd_set *) 0, NULL);
109 else
110 nready = select(maxfd + 1, &rfds, (fd_set *) 0, (fd_set *) 0, &ts);
111
112 if (nready < 0)
113 errExit("select");
114
115 if (nready == 0) { // timeout
116 break;
117 }
118
119 if (FD_ISSET(sock, &wfds) && dest < last) {
120 // configure layer2 socket address information
121 struct sockaddr_ll addr;
122 memset(&addr, 0, sizeof(addr));
123 if ((addr.sll_ifindex = if_nametoindex(dev)) == 0)
124 errExit("if_nametoindex");
125 addr.sll_family = AF_PACKET;
126 memcpy (addr.sll_addr, mac, 6);
127 addr.sll_halen = htons(6);
128
129 // build the arp packet header
130 ArpHdr hdr;
131 memset(&hdr, 0, sizeof(hdr));
132 hdr.htype = htons(1);
133 hdr.ptype = htons(ETH_P_IP);
134 hdr.hlen = 6;
135 hdr.plen = 4;
136 hdr.opcode = htons(1); //ARPOP_REQUEST
137 memcpy(hdr.sender_mac, mac, 6);
138 memcpy(hdr.sender_ip, (uint8_t *)&src, 4);
139 uint32_t dst = htonl(dest);
140 memcpy(hdr.target_ip, (uint8_t *)&dst, 4);
141
142 // build ethernet frame
143 uint8_t frame[ETH_FRAME_LEN]; // includes eht header, vlan, and crc
144 memset(frame, 0, sizeof(frame));
145 frame[0] = frame[1] = frame[2] = frame[3] = frame[4] = frame[5] = 0xff;
146 memcpy(frame + 6, mac, 6);
147 frame[12] = ETH_P_ARP / 256;
148 frame[13] = ETH_P_ARP % 256;
149 memcpy (frame + 14, &hdr, sizeof(hdr));
150
151 // send packet
152 int len;
153 if ((len = sendto (sock, frame, 14 + sizeof(ArpHdr), 0, (struct sockaddr *) &addr, sizeof (addr))) <= 0)
154 errExit("send");
155//printf("send %d bytes to %d.%d.%d.%d\n", len, PRINT_IP(dest));
156 fflush(0);
157 dest++;
158 }
159
160 if (FD_ISSET(sock, &rfds)) {
161 // read the incoming packet
162 int len = recvfrom(sock, frame, ETH_FRAME_LEN, 0, NULL, NULL);
163 if (len < 0) {
164 perror("recvfrom");
165 }
166
167 // parse the incoming packet
168 if ((unsigned int) len < 14 + sizeof(ArpHdr))
169 continue;
170
171 // look only at ARP packets
172 if (frame[12] != (ETH_P_ARP / 256) || frame[13] != (ETH_P_ARP % 256))
173 continue;
174
175 ArpHdr hdr;
176 memcpy(&hdr, frame + 14, sizeof(ArpHdr));
177
178 if (hdr.opcode == htons(2)) {
179 // check my mac and my address
180 if (memcmp(mac, hdr.target_mac, 6) != 0)
181 continue;
182 uint32_t ip;
183 memcpy(&ip, hdr.target_ip, 4);
184 if (ip != src)
185 continue;
186 memcpy(&ip, hdr.sender_ip, 4);
187 ip = ntohl(ip);
188
189 if (ip == last_ip) // filter duplicates
190 continue;
191 last_ip = ip;
192
193 // printing
194 if (header_printed == 0) {
195 printf(" Network scan:\n");
196 header_printed = 1;
197 }
198 printf(" %02x:%02x:%02x:%02x:%02x:%02x\t%d.%d.%d.%d\n",
199 PRINT_MAC(hdr.sender_mac), PRINT_IP(ip));
200 }
201 }
202 }
203
204 close(sock);
205}
206
207
208
diff --git a/src/fnet/fnet.h b/src/fnet/fnet.h
new file mode 100644
index 000000000..0c5e5baef
--- /dev/null
+++ b/src/fnet/fnet.h
@@ -0,0 +1,49 @@
1 /*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#ifndef FNET_H
21#define FNET_H
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <assert.h>
27#include "../include/common.h"
28
29// veth.c
30int net_create_veth(const char *dev, const char *nsdev, unsigned pid);
31int net_create_macvlan(const char *dev, const char *parent, unsigned pid);
32int net_move_interface(const char *dev, unsigned pid);
33
34// interface.c
35void net_bridge_add_interface(const char *bridge, const char *dev);
36void net_if_up(const char *ifname);
37int net_get_mtu(const char *ifname);
38void net_set_mtu(const char *ifname, int mtu);
39void net_ifprint(int scan);
40int net_get_mac(const char *ifname, unsigned char mac[6]);
41void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask, int mtu);
42int net_if_mac(const char *ifname, const unsigned char mac[6]);
43void net_if_ip6(const char *ifname, const char *addr6);
44
45
46// arp.c
47void arp_scan(const char *dev, uint32_t ifip, uint32_t ifmask);
48
49#endif
diff --git a/src/fnet/interface.c b/src/fnet/interface.c
new file mode 100644
index 000000000..3958efddd
--- /dev/null
+++ b/src/fnet/interface.c
@@ -0,0 +1,370 @@
1 /*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20
21#include "fnet.h"
22#include <arpa/inet.h>
23#include <sys/socket.h>
24#include <sys/ioctl.h>
25#include <netdb.h>
26#include <ifaddrs.h>
27#include <net/if.h>
28#include <net/if_arp.h>
29#include <net/route.h>
30#include <linux/if_bridge.h>
31
32static void check_if_name(const char *ifname) {
33 if (strlen(ifname) > IFNAMSIZ) {
34 fprintf(stderr, "Error fnet: invalid network device name %s\n", ifname);
35 exit(1);
36 }
37}
38
39// add a veth device to a bridge
40void net_bridge_add_interface(const char *bridge, const char *dev) {
41 check_if_name(bridge);
42 check_if_name(dev);
43
44 // somehow adding the interface to the bridge resets MTU on bridge device!!!
45 // workaround: restore MTU on the bridge device
46 // todo: put a real fix in
47 int mtu1 = net_get_mtu(bridge);
48
49 struct ifreq ifr;
50 int err;
51 int ifindex = if_nametoindex(dev);
52
53 if (ifindex <= 0)
54 errExit("if_nametoindex");
55
56 int sock;
57 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
58 errExit("socket");
59
60 memset(&ifr, 0, sizeof(ifr));
61 strncpy(ifr.ifr_name, bridge, IFNAMSIZ);
62#ifdef SIOCBRADDIF
63 ifr.ifr_ifindex = ifindex;
64 err = ioctl(sock, SIOCBRADDIF, &ifr);
65 if (err < 0)
66#endif
67 {
68 unsigned long args[4] = { BRCTL_ADD_IF, ifindex, 0, 0 };
69
70 ifr.ifr_data = (char *) args;
71 err = ioctl(sock, SIOCDEVPRIVATE, &ifr);
72 }
73 (void) err;
74 close(sock);
75
76 int mtu2 = net_get_mtu(bridge);
77 if (mtu1 != mtu2)
78 net_set_mtu(bridge, mtu1);
79}
80
81
82// bring interface up
83void net_if_up(const char *ifname) {
84 check_if_name(ifname);
85
86 int sock = socket(AF_INET,SOCK_DGRAM,0);
87 if (sock < 0)
88 errExit("socket");
89
90 // get the existing interface flags
91 struct ifreq ifr;
92 memset(&ifr, 0, sizeof(ifr));
93 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
94 ifr.ifr_addr.sa_family = AF_INET;
95
96 // read the existing flags
97 if (ioctl(sock, SIOCGIFFLAGS, &ifr ) < 0)
98 errExit("ioctl");
99
100 ifr.ifr_flags |= IFF_UP;
101
102 // set the new flags
103 if (ioctl( sock, SIOCSIFFLAGS, &ifr ) < 0)
104 errExit("ioctl");
105
106 // checking
107 // read the existing flags
108 if (ioctl(sock, SIOCGIFFLAGS, &ifr ) < 0)
109 errExit("ioctl");
110
111 // wait not more than 500ms for the interface to come up
112 int cnt = 0;
113 while (cnt < 50) {
114 usleep(10000); // sleep 10ms
115
116 // read the existing flags
117 if (ioctl(sock, SIOCGIFFLAGS, &ifr ) < 0)
118 errExit("ioctl");
119 if (ifr.ifr_flags & IFF_RUNNING)
120 break;
121 cnt++;
122 }
123
124 close(sock);
125}
126
127int net_get_mtu(const char *ifname) {
128 check_if_name(ifname);
129 int mtu = 0;
130 int s;
131 struct ifreq ifr;
132
133 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
134 errExit("socket");
135
136 memset(&ifr, 0, sizeof(ifr));
137 ifr.ifr_addr.sa_family = AF_INET;
138 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
139 if (ioctl(s, SIOCGIFMTU, (caddr_t)&ifr) == 0)
140 mtu = ifr.ifr_mtu;
141 close(s);
142
143
144 return mtu;
145}
146
147void net_set_mtu(const char *ifname, int mtu) {
148 check_if_name(ifname);
149 int s;
150 struct ifreq ifr;
151
152 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
153 errExit("socket");
154
155 memset(&ifr, 0, sizeof(ifr));
156 ifr.ifr_addr.sa_family = AF_INET;
157 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
158 ifr.ifr_mtu = mtu;
159 if (ioctl(s, SIOCSIFMTU, (caddr_t)&ifr) != 0)
160 fprintf(stderr, "Warning fnet: cannot set mtu for interface %s\n", ifname);
161 close(s);
162}
163
164// scan interfaces in current namespace and print IP address/mask for each interface
165void net_ifprint(int scan) {
166 uint32_t ip;
167 uint32_t mask;
168 struct ifaddrs *ifaddr, *ifa;
169
170 if (getifaddrs(&ifaddr) == -1)
171 errExit("getifaddrs");
172
173 printf("%-17.17s%-19.19s%-17.17s%-17.17s%-6.6s\n",
174 "Interface", "MAC", "IP", "Mask", "Status");
175 // walk through the linked list
176 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
177 if (ifa->ifa_addr == NULL)
178 continue;
179
180 if (ifa->ifa_addr->sa_family == AF_INET) {
181 struct sockaddr_in *si = (struct sockaddr_in *) ifa->ifa_netmask;
182 mask = ntohl(si->sin_addr.s_addr);
183 si = (struct sockaddr_in *) ifa->ifa_addr;
184 ip = ntohl(si->sin_addr.s_addr);
185
186 // interface status
187 char *status;
188 if (ifa->ifa_flags & IFF_RUNNING && ifa->ifa_flags & IFF_UP)
189 status = "UP";
190 else
191 status = "DOWN";
192
193 // ip address and mask
194 char ipstr[30];
195 sprintf(ipstr, "%d.%d.%d.%d", PRINT_IP(ip));
196 char maskstr[30];
197 sprintf(maskstr, "%d.%d.%d.%d", PRINT_IP(mask));
198
199 // mac address
200 unsigned char mac[6];
201 net_get_mac(ifa->ifa_name, mac);
202 char macstr[30];
203 if (strcmp(ifa->ifa_name, "lo") == 0)
204 macstr[0] = '\0';
205 else
206 sprintf(macstr, "%02x:%02x:%02x:%02x:%02x:%02x", PRINT_MAC(mac));
207
208 // print
209 printf("%-17.17s%-19.19s%-17.17s%-17.17s%-6.6s\n",
210 ifa->ifa_name, macstr, ipstr, maskstr, status);
211
212 // network scanning
213 if (!scan) // scanning disabled
214 continue;
215 if (strcmp(ifa->ifa_name, "lo") == 0) // no loopbabck scanning
216 continue;
217 if (mask2bits(mask) < 16) // not scanning large networks
218 continue;
219 if (!ip) // if not configured
220 continue;
221 // only if the interface is up and running
222 if (ifa->ifa_flags & IFF_RUNNING && ifa->ifa_flags & IFF_UP)
223 arp_scan(ifa->ifa_name, ip, mask);
224 }
225 }
226 freeifaddrs(ifaddr);
227}
228
229int net_get_mac(const char *ifname, unsigned char mac[6]) {
230 check_if_name(ifname);
231
232 struct ifreq ifr;
233 int sock;
234
235 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
236 errExit("socket");
237
238 memset(&ifr, 0, sizeof(ifr));
239 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
240 ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
241
242 if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1)
243 errExit("ioctl");
244 memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
245
246 close(sock);
247 return 0;
248}
249
250// configure interface ipv4 address
251void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask, int mtu) {
252 check_if_name(ifname);
253 int sock = socket(AF_INET,SOCK_DGRAM,0);
254 if (sock < 0)
255 errExit("socket");
256
257 struct ifreq ifr;
258 memset(&ifr, 0, sizeof(ifr));
259 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
260 ifr.ifr_addr.sa_family = AF_INET;
261
262 ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr = htonl(ip);
263 if (ioctl( sock, SIOCSIFADDR, &ifr ) < 0)
264 errExit("ioctl");
265
266 if (ip != 0) {
267 ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr = htonl(mask);
268 if (ioctl( sock, SIOCSIFNETMASK, &ifr ) < 0)
269 errExit("ioctl");
270 }
271
272 // configure mtu
273 if (mtu > 0) {
274 ifr.ifr_mtu = mtu;
275 if (ioctl( sock, SIOCSIFMTU, &ifr ) < 0)
276 errExit("ioctl");
277 }
278
279 close(sock);
280 usleep(10000); // sleep 10ms
281 return;
282}
283
284int net_if_mac(const char *ifname, const unsigned char mac[6]) {
285 check_if_name(ifname);
286 struct ifreq ifr;
287 int sock;
288
289 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
290 errExit("socket");
291
292 memset(&ifr, 0, sizeof(ifr));
293 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
294 ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
295 memcpy(ifr.ifr_hwaddr.sa_data, mac, 6);
296
297 if (ioctl(sock, SIOCSIFHWADDR, &ifr) == -1)
298 errExit("ioctl");
299 close(sock);
300 return 0;
301}
302
303// configure interface ipv6 address
304// ex: firejail --net=eth0 --ip6=2001:0db8:0:f101::1/64
305struct ifreq6 {
306 struct in6_addr ifr6_addr;
307 uint32_t ifr6_prefixlen;
308 unsigned int ifr6_ifindex;
309};
310void net_if_ip6(const char *ifname, const char *addr6) {
311 check_if_name(ifname);
312 if (strchr(addr6, ':') == NULL) {
313 fprintf(stderr, "Error fnet: invalid IPv6 address %s\n", addr6);
314 exit(1);
315 }
316
317 // extract prefix
318 unsigned long prefix;
319 char *ptr;
320 if ((ptr = strchr(addr6, '/'))) {
321 prefix = atol(ptr + 1);
322 if (prefix > 128) {
323 fprintf(stderr, "Error fnet: invalid prefix for IPv6 address %s\n", addr6);
324 exit(1);
325 }
326 *ptr = '\0'; // mark the end of the address
327 }
328 else
329 prefix = 128;
330
331 // extract address
332 struct sockaddr_in6 sin6;
333 memset(&sin6, 0, sizeof(sin6));
334 sin6.sin6_family = AF_INET6;
335 int rv = inet_pton(AF_INET6, addr6, sin6.sin6_addr.s6_addr);
336 if (rv <= 0) {
337 fprintf(stderr, "Error fnet: invalid IPv6 address %s\n", addr6);
338 exit(1);
339 }
340
341 // open socket
342 int sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
343 if (sock < 0) {
344 fprintf(stderr, "Error fnet: IPv6 is not supported on this system\n");
345 exit(1);
346 }
347
348 // find interface index
349 struct ifreq ifr;
350 memset(&ifr, 0, sizeof(ifr));
351 strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
352 ifr.ifr_addr.sa_family = AF_INET;
353 if (ioctl(sock, SIOGIFINDEX, &ifr) < 0) {
354 perror("ioctl SIOGIFINDEX");
355 exit(1);
356 }
357
358 // configure address
359 struct ifreq6 ifr6;
360 memset(&ifr6, 0, sizeof(ifr6));
361 ifr6.ifr6_prefixlen = prefix;
362 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
363 memcpy((char *) &ifr6.ifr6_addr, (char *) &sin6.sin6_addr, sizeof(struct in6_addr));
364 if (ioctl(sock, SIOCSIFADDR, &ifr6) < 0) {
365 perror("ioctl SIOCSIFADDR");
366 exit(1);
367 }
368
369 close(sock);
370}
diff --git a/src/fnet/main.c b/src/fnet/main.c
new file mode 100644
index 000000000..4ae9eb6e3
--- /dev/null
+++ b/src/fnet/main.c
@@ -0,0 +1,103 @@
1 /*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "fnet.h"
21
22static void usage(void) {
23 printf("Usage:\n");
24 printf("\tfnet create veth dev1 dev2 bridge child\n");
25 printf("\tfnet create macvlan dev parent child\n");
26 printf("\tfnet moveif dev proc\n");
27 printf("\tfnet printif\n");
28 printf("\tfnet printif scan\n");
29 printf("\tfnet config interface dev ip mask mtu\n");
30 printf("\tfnet config mac addr\n");
31 printf("\tfnet config ipv6 dev ipn");
32 printf("\tfmet ifup dev\n");
33}
34
35int main(int argc, char **argv) {
36#if 0
37{
38//system("cat /proc/self/status");
39int i;
40for (i = 0; i < argc; i++)
41 printf("*%s* ", argv[i]);
42printf("\n");
43}
44#endif
45 if (argc < 2)
46 return 1;
47
48
49
50 if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") ==0) {
51 usage();
52 return 0;
53 }
54 else if (argc == 3 && strcmp(argv[1], "ifup") == 0) {
55 net_if_up(argv[2]);
56 }
57 else if (argc == 2 && strcmp(argv[1], "printif") == 0) {
58 net_ifprint(0);
59 }
60 else if (argc == 3 && strcmp(argv[1], "printif") == 0 && strcmp(argv[2], "scan") == 0) {
61 net_ifprint(1);
62 }
63 else if (argc == 7 && strcmp(argv[1], "create") == 0 && strcmp(argv[2], "veth") == 0) {
64 // create veth pair and move one end in the the namespace
65 net_create_veth(argv[3], argv[4], atoi(argv[6]));
66 // connect the ohter veth end to the bridge ...
67 net_bridge_add_interface(argv[5], argv[3]);
68 // ... and bring it up
69 net_if_up(argv[3]);
70 }
71 else if (argc == 6 && strcmp(argv[1], "create") == 0 && strcmp(argv[2], "macvlan") == 0) {
72 net_create_macvlan(argv[3], argv[4], atoi(argv[5]));
73 }
74 else if (argc == 7 && strcmp(argv[1], "config") == 0 && strcmp(argv[2], "interface") == 0) {
75 char *dev = argv[3];
76 uint32_t ip = (uint32_t) atoll(argv[4]);
77 uint32_t mask = (uint32_t) atoll(argv[5]);
78 int mtu = atoi(argv[6]);
79 // configure interface
80 net_if_ip(dev, ip, mask, mtu);
81 // ... and bring it up
82 net_if_up(dev);
83 }
84 else if (argc == 5 && strcmp(argv[1], "config") == 0 && strcmp(argv[2], "mac") == 0) {
85 unsigned char mac[6];
86 if (atomac(argv[4], mac)) {
87 fprintf(stderr, "Error fnet: invalid mac address %s\n", argv[4]);
88 }
89 net_if_mac(argv[3], mac);
90 }
91 else if (argc == 4 && strcmp(argv[1], "moveif") == 0) {
92 net_move_interface(argv[2], atoi(argv[3]));
93 }
94 else if (argc == 5 && strcmp(argv[1], "config") == 0 && strcmp(argv[2], "ipv6") == 0) {
95 net_if_ip6(argv[3], argv[4]);
96 }
97 else {
98 fprintf(stderr, "Error fnet: invalid arguments\n");
99 return 1;
100 }
101
102 return 0;
103}
diff --git a/src/firejail/veth.c b/src/fnet/veth.c
index df3c1d1f9..546fafcec 100644
--- a/src/firejail/veth.c
+++ b/src/fnet/veth.c
@@ -45,7 +45,7 @@
45 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 45 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
46*/ 46*/
47 47
48#include "firejail.h" 48#include "fnet.h"
49#include "../include/libnetlink.h" 49#include "../include/libnetlink.h"
50#include <linux/veth.h> 50#include <linux/veth.h>
51#include <net/if.h> 51#include <net/if.h>
@@ -63,8 +63,6 @@ int net_create_veth(const char *dev, const char *nsdev, unsigned pid) {
63 int len; 63 int len;
64 struct iplink_req req; 64 struct iplink_req req;
65 65
66 if (arg_debug)
67 printf("create veth %s/%s/%u\n", dev, nsdev, pid);
68 assert(dev); 66 assert(dev);
69 assert(nsdev); 67 assert(nsdev);
70 assert(pid); 68 assert(pid);
@@ -113,6 +111,8 @@ int net_create_veth(const char *dev, const char *nsdev, unsigned pid) {
113 if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0) 111 if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0)
114 exit(2); 112 exit(2);
115 113
114 rtnl_close(&rth);
115
116 return 0; 116 return 0;
117} 117}
118 118
@@ -120,8 +120,6 @@ int net_create_veth(const char *dev, const char *nsdev, unsigned pid) {
120int net_create_macvlan(const char *dev, const char *parent, unsigned pid) { 120int net_create_macvlan(const char *dev, const char *parent, unsigned pid) {
121 int len; 121 int len;
122 struct iplink_req req; 122 struct iplink_req req;
123 if (arg_debug)
124 printf("create macvlan %s, parent %s\n", dev, parent);
125 assert(dev); 123 assert(dev);
126 assert(parent); 124 assert(parent);
127 125
@@ -177,6 +175,8 @@ int net_create_macvlan(const char *dev, const char *parent, unsigned pid) {
177 if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0) 175 if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0)
178 exit(2); 176 exit(2);
179 177
178 rtnl_close(&rth);
179
180 return 0; 180 return 0;
181} 181}
182 182
@@ -184,8 +184,6 @@ int net_create_macvlan(const char *dev, const char *parent, unsigned pid) {
184// when the interface is moved, netlink does not preserve interface configuration 184// when the interface is moved, netlink does not preserve interface configuration
185int net_move_interface(const char *dev, unsigned pid) { 185int net_move_interface(const char *dev, unsigned pid) {
186 struct iplink_req req; 186 struct iplink_req req;
187 if (arg_debug)
188 printf("move device %s inside the namespace\n", dev);
189 assert(dev); 187 assert(dev);
190 188
191 if (rtnl_open(&rth, 0) < 0) { 189 if (rtnl_open(&rth, 0) < 0) {
@@ -215,6 +213,8 @@ int net_move_interface(const char *dev, unsigned pid) {
215 if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0) 213 if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0)
216 exit(2); 214 exit(2);
217 215
216 rtnl_close(&rth);
217
218 return 0; 218 return 0;
219} 219}
220 220
diff --git a/src/fseccomp/Makefile.in b/src/fseccomp/Makefile.in
new file mode 100644
index 000000000..04c46f128
--- /dev/null
+++ b/src/fseccomp/Makefile.in
@@ -0,0 +1,45 @@
1all: fseccomp
2
3prefix=@prefix@
4exec_prefix=@exec_prefix@
5libdir=@libdir@
6sysconfdir=@sysconfdir@
7
8VERSION=@PACKAGE_VERSION@
9NAME=@PACKAGE_NAME@
10HAVE_SECCOMP_H=@HAVE_SECCOMP_H@
11HAVE_SECCOMP=@HAVE_SECCOMP@
12HAVE_CHROOT=@HAVE_CHROOT@
13HAVE_BIND=@HAVE_BIND@
14HAVE_FATAL_WARNINGS=@HAVE_FATAL_WARNINGS@
15HAVE_NETWORK=@HAVE_NETWORK@
16HAVE_USERNS=@HAVE_USERNS@
17HAVE_X11=@HAVE_X11@
18HAVE_FILE_TRANSFER=@HAVE_FILE_TRANSFER@
19HAVE_WHITELIST=@HAVE_WHITELIST@
20HAVE_GLOBALCFG=@HAVE_GLOBALCFG@
21HAVE_APPARMOR=@HAVE_APPARMOR@
22HAVE_OVERLAYFS=@HAVE_OVERLAYFS@
23HAVE_PRIVATE_HOME=@HAVE_PRIVATE_HOME@
24EXTRA_LDFLAGS +=@EXTRA_LDFLAGS@
25HAVE_GCOV=@HAVE_GCOV@
26EXTRA_LDFLAGS +=@EXTRA_LDFLAGS@
27
28H_FILE_LIST = $(sort $(wildcard *.[h]))
29C_FILE_LIST = $(sort $(wildcard *.c))
30OBJS = $(C_FILE_LIST:.c=.o)
31BINOBJS = $(foreach file, $(OBJS), $file)
32CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' $(HAVE_GCOV) -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' $(HAVE_X11) $(HAVE_PRIVATE_HOME) $(HAVE_APPARMOR) $(HAVE_OVERLAYFS) $(HAVE_SECCOMP) $(HAVE_GLOBALCFG) $(HAVE_SECCOMP_H) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_BIND) $(HAVE_FILE_TRANSFER) $(HAVE_WHITELIST) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security
33LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread
34
35%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/syscall.h
36 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
37
38fseccomp: $(OBJS)
39 $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTRA_LDFLAGS)
40
41clean:; rm -f *.o fseccomp *.gcov *.gcda *.gcno
42
43distclean: clean
44 rm -fr Makefile
45
diff --git a/src/firejail/errno.c b/src/fseccomp/errno.c
index c493dfa09..dbee916d4 100644
--- a/src/firejail/errno.c
+++ b/src/fseccomp/errno.c
@@ -17,9 +17,8 @@
17 * with this program; if not, write to the Free Software Foundation, Inc., 17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/ 19*/
20#include "fseccomp.h"
20 21
21#ifdef HAVE_SECCOMP
22#include "firejail.h"
23#include <errno.h> 22#include <errno.h>
24//#include <attr/xattr.h> 23//#include <attr/xattr.h>
25 24
@@ -171,20 +170,7 @@ static ErrnoEntry errnolist[] = {
171#endif 170#endif
172}; 171};
173 172
174int errno_highest_nr(void) {
175 int i, max = 0;
176 int elems = sizeof(errnolist) / sizeof(errnolist[0]);
177 for (i = 0; i < elems; i++) {
178 if (errnolist[i].nr > max)
179 max = errnolist[i].nr;
180 }
181
182 return max;
183}
184
185int errno_find_name(const char *name) { 173int errno_find_name(const char *name) {
186 EUID_ASSERT();
187
188 int i; 174 int i;
189 int elems = sizeof(errnolist) / sizeof(errnolist[0]); 175 int elems = sizeof(errnolist) / sizeof(errnolist[0]);
190 for (i = 0; i < elems; i++) { 176 for (i = 0; i < elems; i++) {
@@ -206,9 +192,9 @@ char *errno_find_nr(int nr) {
206 return "unknown"; 192 return "unknown";
207} 193}
208 194
195
196
209void errno_print(void) { 197void errno_print(void) {
210 EUID_ASSERT();
211
212 int i; 198 int i;
213 int elems = sizeof(errnolist) / sizeof(errnolist[0]); 199 int elems = sizeof(errnolist) / sizeof(errnolist[0]);
214 for (i = 0; i < elems; i++) { 200 for (i = 0; i < elems; i++) {
@@ -216,5 +202,3 @@ void errno_print(void) {
216 } 202 }
217 printf("\n"); 203 printf("\n");
218} 204}
219
220#endif // HAVE_SECCOMP
diff --git a/src/fseccomp/fseccomp.h b/src/fseccomp/fseccomp.h
new file mode 100644
index 000000000..504f1c23f
--- /dev/null
+++ b/src/fseccomp/fseccomp.h
@@ -0,0 +1,68 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#ifndef FSECCOMP_H
21#define FSECCOMP_H
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <assert.h>
26#include "../include/common.h"
27
28// syscall.c
29void syscall_print(void);
30int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall, int arg), int fd, int arg);
31int syscall_find_name(const char *name);
32char *syscall_find_nr(int nr);
33
34// errno.c
35void errno_print(void);
36int errno_find_name(const char *name);
37char *errno_find_nr(int nr);
38
39// protocol.c
40void protocol_print(void);
41void protocol_build_filter(const char *prlist, const char *fname);
42
43// seccomp_secondary.c
44void seccomp_secondary_64(const char *fname);
45void seccomp_secondary_32(const char *fname);
46
47// seccomp_file.c
48void filter_init(int fd);
49void filter_add_whitelist(int fd, int syscall, int arg);
50void filter_add_blacklist(int fd, int syscall, int arg);
51void filter_add_errno(int fd, int syscall, int arg);
52void filter_end_blacklist(int fd);
53void filter_end_whitelist(int fd);
54
55// seccomp.c
56// default list
57void seccomp_default(const char *fname, int allow_debuggers);
58// drop list
59void seccomp_drop(const char *fname, char *list, int allow_debuggers);
60// default+drop list
61void seccomp_default_drop(const char *fname, char *list, int allow_debuggers);
62// whitelisted filter
63void seccomp_keep(const char *fname, char *list);
64
65// seccomp_print
66void filter_print(const char *fname);
67
68#endif
diff --git a/src/fseccomp/main.c b/src/fseccomp/main.c
new file mode 100644
index 000000000..39e72fdf9
--- /dev/null
+++ b/src/fseccomp/main.c
@@ -0,0 +1,91 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "fseccomp.h"
21
22static void usage(void) {
23 printf("Usage:\n");
24 printf("\tfseccomp debug-syscalls\n");
25 printf("\tfseccomp debug-errnos\n");
26 printf("\tfseccomp debug-protocols\n");
27 printf("\tfseccomp protocol build list file\n");
28 printf("\tfseccomp secondary 64 file\n");
29 printf("\tfseccomp secondary 32 file\n");
30 printf("\tfseccomp default file\n");
31 printf("\tfseccomp default file allow-debuggers\n");
32 printf("\tfseccomp drop file list\n");
33 printf("\tfseccomp drop file list allow-debuggers\n");
34 printf("\tfseccomp default drop file list\n");
35 printf("\tfseccomp default drop file list allow-debuggers\n");
36 printf("\tfseccomp keep file list\n");
37 printf("\tfseccomp print file\n");
38}
39
40int main(int argc, char **argv) {
41#if 0
42{
43//system("cat /proc/self/status");
44int i;
45for (i = 0; i < argc; i++)
46 printf("*%s* ", argv[i]);
47printf("\n");
48}
49#endif
50 if (argc < 2)
51 return 1;
52
53 if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") ==0) {
54 usage();
55 return 0;
56 }
57 else if (argc == 2 && strcmp(argv[1], "debug-syscalls") == 0)
58 syscall_print();
59 else if (argc == 2 && strcmp(argv[1], "debug-errnos") == 0)
60 errno_print();
61 else if (argc == 2 && strcmp(argv[1], "debug-protocols") == 0)
62 protocol_print();
63 else if (argc == 5 && strcmp(argv[1], "protocol") == 0 && strcmp(argv[2], "build") == 0)
64 protocol_build_filter(argv[3], argv[4]);
65 else if (argc == 4 && strcmp(argv[1], "secondary") == 0 && strcmp(argv[2], "64") == 0)
66 seccomp_secondary_64(argv[3]);
67 else if (argc == 4 && strcmp(argv[1], "secondary") == 0 && strcmp(argv[2], "32") == 0)
68 seccomp_secondary_32(argv[3]);
69 else if (argc == 3 && strcmp(argv[1], "default") == 0)
70 seccomp_default(argv[2], 0);
71 else if (argc == 4 && strcmp(argv[1], "default") == 0 && strcmp(argv[3], "allow-debuggers") == 0)
72 seccomp_default(argv[2], 1);
73 else if (argc == 4 && strcmp(argv[1], "drop") == 0)
74 seccomp_drop(argv[2], argv[3], 0);
75 else if (argc == 5 && strcmp(argv[1], "drop") == 0 && strcmp(argv[4], "allow-debuggers") == 0)
76 seccomp_drop(argv[2], argv[3], 1);
77 else if (argc == 5 && strcmp(argv[1], "default") == 0 && strcmp(argv[2], "drop") == 0)
78 seccomp_default_drop(argv[3], argv[4], 0);
79 else if (argc == 6 && strcmp(argv[1], "default") == 0 && strcmp(argv[2], "drop") == 0 && strcmp(argv[5], "allow-debuggers") == 0)
80 seccomp_default_drop(argv[3], argv[4], 1);
81 else if (argc == 4 && strcmp(argv[1], "keep") == 0)
82 seccomp_keep(argv[2], argv[3]);
83 else if (argc == 3 && strcmp(argv[1], "print") == 0)
84 filter_print(argv[2]);
85 else {
86 fprintf(stderr, "Error fseccomp: invalid arguments\n");
87 return 1;
88 }
89
90 return 0;
91} \ No newline at end of file
diff --git a/src/fseccomp/protocol.c b/src/fseccomp/protocol.c
new file mode 100644
index 000000000..7bf560fe1
--- /dev/null
+++ b/src/fseccomp/protocol.c
@@ -0,0 +1,219 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20
21/*
22 struct sock_filter filter[] = {
23 VALIDATE_ARCHITECTURE,
24 EXAMINE_SYSCALL,
25 ONLY(SYS_socket),
26 EXAMINE_ARGUMENT(0), // allow only AF_INET and AF_INET6, drop everything else
27 WHITELIST(AF_INET),
28 WHITELIST(AF_INET6),
29 WHITELIST(AF_PACKET),
30 RETURN_ERRNO(ENOTSUP)
31 };
32 struct sock_fprog prog = {
33 .len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
34 .filter = filter,
35 };
36
37
38 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
39 perror("prctl(NO_NEW_PRIVS)");
40 return 1;
41 }
42 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
43 perror("prctl");
44 return 1;
45 }
46*/
47
48#include "fseccomp.h"
49#include "../include/seccomp.h"
50#include <sys/syscall.h>
51#include <sys/types.h>
52#include <sys/socket.h>
53
54static char *protocol[] = {
55 "unix",
56 "inet",
57 "inet6",
58 "netlink",
59 "packet",
60 NULL
61};
62
63static struct sock_filter protocol_filter_command[] = {
64 WHITELIST(AF_UNIX),
65 WHITELIST(AF_INET),
66 WHITELIST(AF_INET6),
67 WHITELIST(AF_NETLINK),
68 WHITELIST(AF_PACKET)
69};
70// Note: protocol[] and protocol_filter_command are synchronized
71
72// command length
73struct sock_filter whitelist[] = {
74 WHITELIST(AF_UNIX)
75};
76unsigned whitelist_len = sizeof(whitelist) / sizeof(struct sock_filter);
77
78static struct sock_filter *find_protocol_domain(const char *p) {
79 int i = 0;
80 while (protocol[i] != NULL) {
81 if (strcmp(protocol[i], p) == 0)
82 return &protocol_filter_command[i * whitelist_len];
83 i++;
84 }
85
86 return NULL;
87}
88
89
90void protocol_print(void) {
91#ifndef SYS_socket
92 fprintf(stderr, "Warning fseccomp: firejail --protocol not supported on this platform\n");
93 return;
94#endif
95
96 int i = 0;
97 while (protocol[i] != NULL) {
98 printf("%s, ", protocol[i]);
99 i++;
100 }
101 printf("\n");
102}
103
104// install protocol filter
105void protocol_build_filter(const char *prlist, const char *fname) {
106 assert(prlist);
107 assert(fname);
108
109#ifndef SYS_socket
110 fprintf(stderr, "Warning fseccomp: --protocol not supported on this platform\n");
111 return;
112#else
113 // build the filter
114 struct sock_filter filter[32]; // big enough
115 memset(&filter[0], 0, sizeof(filter));
116 uint8_t *ptr = (uint8_t *) &filter[0];
117
118 // header
119 struct sock_filter filter_start[] = {
120 VALIDATE_ARCHITECTURE,
121 EXAMINE_SYSCALL,
122 ONLY(SYS_socket),
123 EXAMINE_ARGUMENT(0)
124 };
125 memcpy(ptr, &filter_start[0], sizeof(filter_start));
126 ptr += sizeof(filter_start);
127
128#if 0
129printf("entries %u\n", (unsigned) (sizeof(filter_start) / sizeof(struct sock_filter)));
130{
131 unsigned j;
132 unsigned char *ptr2 = (unsigned char *) &filter[0];
133 for (j = 0; j < sizeof(filter); j++, ptr2++) {
134 if ((j % (sizeof(struct sock_filter))) == 0)
135 printf("\n%u: ", 1 + (unsigned) (j / (sizeof(struct sock_filter))));
136 printf("%02x, ", (*ptr2) & 0xff);
137 }
138 printf("\n");
139}
140printf("whitelist_len %u, struct sock_filter len %u\n", whitelist_len, (unsigned) sizeof(struct sock_filter));
141#endif
142
143
144 // parse list and add commands
145 char *tmplist = strdup(prlist);
146 if (!tmplist)
147 errExit("strdup");
148 char *token = strtok(tmplist, ",");
149 if (!token)
150 errExit("strtok");
151
152 while (token) {
153 struct sock_filter *domain = find_protocol_domain(token);
154 if (domain == NULL) {
155 fprintf(stderr, "Error fseccomp: %s is not a valid protocol\n", token);
156 exit(1);
157 }
158 memcpy(ptr, domain, whitelist_len * sizeof(struct sock_filter));
159 ptr += whitelist_len * sizeof(struct sock_filter);
160 token = strtok(NULL, ",");
161
162#if 0
163printf("entries %u\n", (unsigned) ((uint64_t) ptr - (uint64_t) (filter)) / (unsigned) sizeof(struct sock_filter));
164{
165 unsigned j;
166 unsigned char *ptr2 = (unsigned char *) &filter[0];
167 for (j = 0; j < sizeof(filter); j++, ptr2++) {
168 if ((j % (sizeof(struct sock_filter))) == 0)
169 printf("\n%u: ", 1 + (unsigned) (j / (sizeof(struct sock_filter))));
170 printf("%02x, ", (*ptr2) & 0xff);
171 }
172 printf("\n");
173}
174#endif
175
176
177 }
178 free(tmplist);
179
180 // add end of filter
181 struct sock_filter filter_end[] = {
182 RETURN_ERRNO(ENOTSUP)
183 };
184 memcpy(ptr, &filter_end[0], sizeof(filter_end));
185 ptr += sizeof(filter_end);
186
187#if 0
188printf("entries %u\n", (unsigned) ((uint64_t) ptr - (uint64_t) (filter)) / (unsigned) sizeof(struct sock_filter));
189{
190 unsigned j;
191 unsigned char *ptr2 = (unsigned char *) &filter[0];
192 for (j = 0; j < sizeof(filter); j++, ptr2++) {
193 if ((j % (sizeof(struct sock_filter))) == 0)
194 printf("\n%u: ", 1 + (unsigned) (j / (sizeof(struct sock_filter))));
195 printf("%02x, ", (*ptr2) & 0xff);
196 }
197 printf("\n");
198}
199#endif
200 // save filter to file
201 int dst = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
202 if (dst < 0) {
203 fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname);
204 exit(1);
205 }
206
207 int size = (int) ((uintptr_t) ptr - (uintptr_t) (filter));
208 int written = 0;
209 while (written < size) {
210 int rv = write(dst, (unsigned char *) filter + written, size - written);
211 if (rv == -1) {
212 fprintf(stderr, "Error fseccomp: cannot write %s file\n", fname);
213 exit(1);
214 }
215 written += rv;
216 }
217 close(dst);
218#endif // SYS_socket
219}
diff --git a/src/fseccomp/seccomp.c b/src/fseccomp/seccomp.c
new file mode 100644
index 000000000..cc6edc8ca
--- /dev/null
+++ b/src/fseccomp/seccomp.c
@@ -0,0 +1,292 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "fseccomp.h"
21#include "../include/seccomp.h"
22#include <sys/syscall.h>
23
24static void add_default_list(int fd, int allow_debuggers) {
25#ifdef SYS_mount
26 filter_add_blacklist(fd, SYS_mount, 0);
27#endif
28#ifdef SYS_umount2
29 filter_add_blacklist(fd, SYS_umount2, 0);
30#endif
31
32 if (!allow_debuggers) {
33#ifdef SYS_ptrace
34 filter_add_blacklist(fd, SYS_ptrace, 0);
35#endif
36 }
37
38#ifdef SYS_kexec_load
39 filter_add_blacklist(fd, SYS_kexec_load, 0);
40#endif
41#ifdef SYS_kexec_file_load
42 filter_add_blacklist(fd, SYS_kexec_file_load, 0);
43#endif
44#ifdef SYS_open_by_handle_at
45 filter_add_blacklist(fd, SYS_open_by_handle_at, 0);
46#endif
47#ifdef SYS_name_to_handle_at
48 filter_add_blacklist(fd, SYS_name_to_handle_at, 0);
49#endif
50#ifdef SYS_init_module
51 filter_add_blacklist(fd, SYS_init_module, 0);
52#endif
53#ifdef SYS_finit_module
54 filter_add_blacklist(fd, SYS_finit_module, 0);
55#endif
56#ifdef SYS_create_module
57 filter_add_blacklist(fd, SYS_create_module, 0);
58#endif
59#ifdef SYS_delete_module
60 filter_add_blacklist(fd, SYS_delete_module, 0);
61#endif
62#ifdef SYS_iopl
63 filter_add_blacklist(fd, SYS_iopl, 0);
64#endif
65#ifdef SYS_ioperm
66 filter_add_blacklist(fd, SYS_ioperm, 0);
67#endif
68#ifdef SYS_ioprio_set
69 filter_add_blacklist(fd, SYS_ioprio_set, 0);
70#endif
71#ifdef SYS_ni_syscall
72 filter_add_blacklist(fd, SYS_ni_syscall, 0);
73#endif
74#ifdef SYS_swapon
75 filter_add_blacklist(fd, SYS_swapon, 0);
76#endif
77#ifdef SYS_swapoff
78 filter_add_blacklist(fd, SYS_swapoff, 0);
79#endif
80#ifdef SYS_syslog
81 filter_add_blacklist(fd, SYS_syslog, 0);
82#endif
83
84 if (!allow_debuggers) {
85#ifdef SYS_process_vm_readv
86 filter_add_blacklist(fd, SYS_process_vm_readv, 0);
87#endif
88 }
89
90#ifdef SYS_process_vm_writev
91 filter_add_blacklist(fd, SYS_process_vm_writev, 0);
92#endif
93
94 // mknod removed in 0.9.29 - it brakes Zotero extension
95 //#ifdef SYS_mknod
96 // filter_add_blacklist(SYS_mknod, 0);
97 //#endif
98
99#ifdef SYS_sysfs
100 filter_add_blacklist(fd, SYS_sysfs, 0);
101#endif
102#ifdef SYS__sysctl
103 filter_add_blacklist(fd, SYS__sysctl, 0);
104#endif
105#ifdef SYS_adjtimex
106 filter_add_blacklist(fd, SYS_adjtimex, 0);
107#endif
108#ifdef SYS_clock_adjtime
109 filter_add_blacklist(fd, SYS_clock_adjtime, 0);
110#endif
111#ifdef SYS_lookup_dcookie
112 filter_add_blacklist(fd, SYS_lookup_dcookie, 0);
113#endif
114#ifdef SYS_perf_event_open
115 filter_add_blacklist(fd, SYS_perf_event_open, 0);
116#endif
117#ifdef SYS_fanotify_init
118 filter_add_blacklist(fd, SYS_fanotify_init, 0);
119#endif
120#ifdef SYS_kcmp
121 filter_add_blacklist(fd, SYS_kcmp, 0);
122#endif
123#ifdef SYS_add_key
124 filter_add_blacklist(fd, SYS_add_key, 0);
125#endif
126#ifdef SYS_request_key
127 filter_add_blacklist(fd, SYS_request_key, 0);
128#endif
129#ifdef SYS_keyctl
130 filter_add_blacklist(fd, SYS_keyctl, 0);
131#endif
132#ifdef SYS_uselib
133 filter_add_blacklist(fd, SYS_uselib, 0);
134#endif
135#ifdef SYS_acct
136 filter_add_blacklist(fd, SYS_acct, 0);
137#endif
138#ifdef SYS_modify_ldt
139 filter_add_blacklist(fd, SYS_modify_ldt, 0);
140#endif
141#ifdef SYS_pivot_root
142 filter_add_blacklist(fd, SYS_pivot_root, 0);
143#endif
144#ifdef SYS_io_setup
145 filter_add_blacklist(fd, SYS_io_setup, 0);
146#endif
147#ifdef SYS_io_destroy
148 filter_add_blacklist(fd, SYS_io_destroy, 0);
149#endif
150#ifdef SYS_io_getevents
151 filter_add_blacklist(fd, SYS_io_getevents, 0);
152#endif
153#ifdef SYS_io_submit
154 filter_add_blacklist(fd, SYS_io_submit, 0);
155#endif
156#ifdef SYS_io_cancel
157 filter_add_blacklist(fd, SYS_io_cancel, 0);
158#endif
159#ifdef SYS_remap_file_pages
160 filter_add_blacklist(fd, SYS_remap_file_pages, 0);
161#endif
162#ifdef SYS_mbind
163 filter_add_blacklist(fd, SYS_mbind, 0);
164#endif
165#ifdef SYS_get_mempolicy
166 filter_add_blacklist(fd, SYS_get_mempolicy, 0);
167#endif
168#ifdef SYS_set_mempolicy
169 filter_add_blacklist(fd, SYS_set_mempolicy, 0);
170#endif
171#ifdef SYS_migrate_pages
172 filter_add_blacklist(fd, SYS_migrate_pages, 0);
173#endif
174#ifdef SYS_move_pages
175 filter_add_blacklist(fd, SYS_move_pages, 0);
176#endif
177#ifdef SYS_vmsplice
178 filter_add_blacklist(fd, SYS_vmsplice, 0);
179#endif
180#ifdef SYS_chroot
181 filter_add_blacklist(fd, SYS_chroot, 0);
182#endif
183#ifdef SYS_tuxcall
184 filter_add_blacklist(fd, SYS_tuxcall, 0);
185#endif
186#ifdef SYS_reboot
187 filter_add_blacklist(fd, SYS_reboot, 0);
188#endif
189#ifdef SYS_nfsservctl
190 filter_add_blacklist(fd, SYS_nfsservctl, 0);
191#endif
192#ifdef SYS_get_kernel_syms
193 filter_add_blacklist(fd, SYS_get_kernel_syms, 0);
194#endif
195}
196
197// default list
198void seccomp_default(const char *fname, int allow_debuggers) {
199 assert(fname);
200
201 // open file
202 int fd = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
203 if (fd < 0) {
204 fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname);
205 exit(1);
206 }
207
208 // build filter
209 filter_init(fd);
210 add_default_list(fd, allow_debuggers);
211 filter_end_blacklist(fd);
212
213 // close file
214 close(fd);
215}
216
217// drop list
218void seccomp_drop(const char *fname, char *list, int allow_debuggers) {
219 assert(fname);
220 (void) allow_debuggers; // todo: to implemnet it
221
222 // open file
223 int fd = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
224 if (fd < 0) {
225 fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname);
226 exit(1);
227 }
228
229 // build filter
230 filter_init(fd);
231 if (syscall_check_list(list, filter_add_blacklist, fd, 0)) {
232 fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n");
233 exit(1);
234 }
235 filter_end_blacklist(fd);
236
237 // close file
238 close(fd);
239}
240
241// default+drop
242void seccomp_default_drop(const char *fname, char *list, int allow_debuggers) {
243 assert(fname);
244
245 // open file
246 int fd = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
247 if (fd < 0) {
248 fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname);
249 exit(1);
250 }
251
252 // build filter
253 filter_init(fd);
254 add_default_list(fd, allow_debuggers);
255 if (syscall_check_list(list, filter_add_blacklist, fd, 0)) {
256 fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n");
257 exit(1);
258 }
259 filter_end_blacklist(fd);
260
261 // close file
262 close(fd);
263}
264
265void seccomp_keep(const char *fname, char *list) {
266 // open file
267 int fd = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
268 if (fd < 0) {
269 fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname);
270 exit(1);
271 }
272
273 // build filter
274 filter_init(fd);
275 // these 4 syscalls are used by firejail after the seccomp filter is initialized
276 filter_add_whitelist(fd, SYS_setuid, 0);
277 filter_add_whitelist(fd, SYS_setgid, 0);
278 filter_add_whitelist(fd, SYS_setgroups, 0);
279 filter_add_whitelist(fd, SYS_dup, 0);
280 filter_add_whitelist(fd, SYS_prctl, 0);
281
282 if (syscall_check_list(list, filter_add_whitelist, fd, 0)) {
283 fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n");
284 exit(1);
285 }
286
287 filter_end_whitelist(fd);
288
289 // close file
290 close(fd);
291}
292
diff --git a/src/fseccomp/seccomp_file.c b/src/fseccomp/seccomp_file.c
new file mode 100644
index 000000000..10ef9dd31
--- /dev/null
+++ b/src/fseccomp/seccomp_file.c
@@ -0,0 +1,108 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "fseccomp.h"
21#include "../include/seccomp.h"
22#include <sys/syscall.h>
23
24static void write_to_file(int fd, void *data, int size) {
25 assert(data);
26 assert(size);
27
28 int written = 0;
29 while (written < size) {
30 int rv = write(fd, (unsigned char *) data + written, size - written);
31 if (rv == -1) {
32 fprintf(stderr, "Error fseccomp: cannot write seccomp file\n");
33 exit(1);
34 }
35 written += rv;
36 }
37}
38
39void filter_init(int fd) {
40#if defined(__x86_64__)
41#define X32_SYSCALL_BIT 0x40000000
42 struct sock_filter filter[] = {
43 VALIDATE_ARCHITECTURE,
44 EXAMINE_SYSCALL,
45 // handle X32 ABI
46 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, X32_SYSCALL_BIT, 1, 0),
47 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 0, 1, 0),
48 RETURN_ERRNO(EPERM)
49 };
50#else
51 struct sock_filter filter[] = {
52 VALIDATE_ARCHITECTURE,
53 EXAMINE_SYSCALL
54 };
55#endif
56
57#if 0
58{
59 int i;
60 unsigned char *ptr = (unsigned char *) &filter[0];
61 for (i = 0; i < sizeof(filter); i++, ptr++)
62 printf("%x, ", (*ptr) & 0xff);
63 printf("\n");
64}
65#endif
66
67 write_to_file(fd, filter, sizeof(filter));
68}
69
70void filter_add_whitelist(int fd, int syscall, int arg) {
71 (void) arg;
72
73 struct sock_filter filter[] = {
74 WHITELIST(syscall)
75 };
76 write_to_file(fd, filter, sizeof(filter));
77}
78
79void filter_add_blacklist(int fd, int syscall, int arg) {
80 (void) arg;
81
82 struct sock_filter filter[] = {
83 BLACKLIST(syscall)
84 };
85 write_to_file(fd, filter, sizeof(filter));
86}
87
88void filter_add_errno(int fd, int syscall, int arg) {
89 struct sock_filter filter[] = {
90 BLACKLIST_ERRNO(syscall, arg)
91 };
92 write_to_file(fd, filter, sizeof(filter));
93}
94
95void filter_end_blacklist(int fd) {
96 struct sock_filter filter[] = {
97 RETURN_ALLOW
98 };
99 write_to_file(fd, filter, sizeof(filter));
100}
101
102void filter_end_whitelist(int fd) {
103 struct sock_filter filter[] = {
104 KILL_PROCESS
105 };
106 write_to_file(fd, filter, sizeof(filter));
107}
108
diff --git a/src/fseccomp/seccomp_print.c b/src/fseccomp/seccomp_print.c
new file mode 100644
index 000000000..7dc983b12
--- /dev/null
+++ b/src/fseccomp/seccomp_print.c
@@ -0,0 +1,116 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "fseccomp.h"
21#include "../include/seccomp.h"
22#include <sys/syscall.h>
23
24static struct sock_filter *filter = NULL;
25static int filter_cnt = 0;
26
27static void load_seccomp(const char *fname) {
28 assert(fname);
29
30 // check file
31 struct stat s;
32 if (stat(fname, &s) == -1) {
33 fprintf(stderr, "Error fseccomp: cannot read protocol filter file\n");
34 exit(1);
35 }
36 int size = s.st_size;
37 unsigned short entries = (unsigned short) size / (unsigned short) sizeof(struct sock_filter);
38 filter_cnt = entries;
39//printf("size %d, entries %d\n", s.st_size, entries);
40
41 filter = malloc(sizeof(struct sock_filter) * entries);
42 if (!filter)
43 errExit("malloc");
44
45 // read filter
46 memset(filter, 0, sizeof(struct sock_filter) * entries);
47 int src = open(fname, O_RDONLY);
48 int rd = 0;
49 while (rd < size) {
50 int rv = read(src, (unsigned char *) filter + rd, size - rd);
51 if (rv == -1) {
52 fprintf(stderr, "Error fseccomp: cannot read %s file\n", fname);
53 exit(1);
54 }
55 rd += rv;
56 }
57 close(src);
58}
59
60// debug filter
61void filter_print(const char *fname) {
62 assert(fname);
63 load_seccomp(fname);
64
65 // start filter
66 struct sock_filter start[] = {
67 VALIDATE_ARCHITECTURE,
68 EXAMINE_SYSCALL
69 };
70
71 // print sizes
72 printf("SECCOMP Filter:\n");
73
74 // test the start of the filter
75 if (memcmp(&start[0], filter, sizeof(start)) == 0) {
76 printf(" VALIDATE_ARCHITECTURE\n");
77 printf(" EXAMINE_SYSCAL\n");
78 }
79 else {
80 printf("Invalid seccomp filter %s\n", fname);
81 return;
82 }
83
84 // loop trough blacklists
85 int i = 4;
86 while (i < filter_cnt) {
87 // minimal parsing!
88 unsigned char *ptr = (unsigned char *) &filter[i];
89 int *nr = (int *) (ptr + 4);
90 if (*ptr == 0x15 && *(ptr +14) == 0xff && *(ptr + 15) == 0x7f ) {
91 printf(" WHITELIST %d %s\n", *nr, syscall_find_nr(*nr));
92 i += 2;
93 }
94 else if (*ptr == 0x15 && *(ptr +14) == 0 && *(ptr + 15) == 0) {
95 printf(" BLACKLIST %d %s\n", *nr, syscall_find_nr(*nr));
96 i += 2;
97 }
98 else if (*ptr == 0x15 && *(ptr +14) == 0x5 && *(ptr + 15) == 0) {
99 int err = *(ptr + 13) << 8 | *(ptr + 12);
100 printf(" ERRNO %d %s %d %s\n", *nr, syscall_find_nr(*nr), err, errno_find_nr(err));
101 i += 2;
102 }
103 else if (*ptr == 0x06 && *(ptr +6) == 0 && *(ptr + 7) == 0 ) {
104 printf(" KILL_PROCESS\n");
105 i++;
106 }
107 else if (*ptr == 0x06 && *(ptr +6) == 0xff && *(ptr + 7) == 0x7f ) {
108 printf(" RETURN_ALLOW\n");
109 i++;
110 }
111 else {
112 printf(" UNKNOWN ENTRY!!!\n");
113 i++;
114 }
115 }
116}
diff --git a/src/fseccomp/seccomp_secondary.c b/src/fseccomp/seccomp_secondary.c
new file mode 100644
index 000000000..a856e5aef
--- /dev/null
+++ b/src/fseccomp/seccomp_secondary.c
@@ -0,0 +1,183 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "fseccomp.h"
21#include "../include/seccomp.h"
22#include <sys/syscall.h>
23
24void seccomp_secondary_64(const char *fname) {
25 // hardcoded syscall values
26 struct sock_filter filter[] = {
27 VALIDATE_ARCHITECTURE_64,
28 EXAMINE_SYSCALL,
29 BLACKLIST(165), // mount
30 BLACKLIST(166), // umount2
31// todo: implement --allow-debuggers
32 BLACKLIST(101), // ptrace
33 BLACKLIST(246), // kexec_load
34 BLACKLIST(304), // open_by_handle_at
35 BLACKLIST(303), // name_to_handle_at
36 BLACKLIST(174), // create_module
37 BLACKLIST(175), // init_module
38 BLACKLIST(313), // finit_module
39 BLACKLIST(176), // delete_module
40 BLACKLIST(172), // iopl
41 BLACKLIST(173), // ioperm
42 BLACKLIST(251), // ioprio_set
43 BLACKLIST(167), // swapon
44 BLACKLIST(168), // swapoff
45 BLACKLIST(103), // syslog
46 BLACKLIST(310), // process_vm_readv
47 BLACKLIST(311), // process_vm_writev
48 BLACKLIST(139), // sysfs
49 BLACKLIST(156), // _sysctl
50 BLACKLIST(159), // adjtimex
51 BLACKLIST(305), // clock_adjtime
52 BLACKLIST(212), // lookup_dcookie
53 BLACKLIST(298), // perf_event_open
54 BLACKLIST(300), // fanotify_init
55 BLACKLIST(312), // kcmp
56 BLACKLIST(248), // add_key
57 BLACKLIST(249), // request_key
58 BLACKLIST(250), // keyctl
59 BLACKLIST(134), // uselib
60 BLACKLIST(163), // acct
61 BLACKLIST(154), // modify_ldt
62 BLACKLIST(155), // pivot_root
63 BLACKLIST(206), // io_setup
64 BLACKLIST(207), // io_destroy
65 BLACKLIST(208), // io_getevents
66 BLACKLIST(209), // io_submit
67 BLACKLIST(210), // io_cancel
68 BLACKLIST(216), // remap_file_pages
69 BLACKLIST(237), // mbind
70 BLACKLIST(239), // get_mempolicy
71 BLACKLIST(238), // set_mempolicy
72 BLACKLIST(256), // migrate_pages
73 BLACKLIST(279), // move_pages
74 BLACKLIST(278), // vmsplice
75 BLACKLIST(161), // chroot
76 BLACKLIST(184), // tuxcall
77 BLACKLIST(169), // reboot
78 BLACKLIST(180), // nfsservctl
79 BLACKLIST(177), // get_kernel_syms
80
81 RETURN_ALLOW
82 };
83
84 // save filter to file
85 int dst = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
86 if (dst < 0) {
87 fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname);
88 exit(1);
89 }
90
91 int size = (int) sizeof(filter);
92 int written = 0;
93 while (written < size) {
94 int rv = write(dst, (unsigned char *) filter + written, size - written);
95 if (rv == -1) {
96 fprintf(stderr, "Error fseccomp: cannot write %s file\n", fname);
97 exit(1);
98 }
99 written += rv;
100 }
101 close(dst);
102}
103
104// i386 filter installed on amd64 architectures
105void seccomp_secondary_32(const char *fname) {
106 // hardcoded syscall values
107 struct sock_filter filter[] = {
108 VALIDATE_ARCHITECTURE_32,
109 EXAMINE_SYSCALL,
110 BLACKLIST(21), // mount
111 BLACKLIST(52), // umount2
112// todo: implement --allow-debuggers
113 BLACKLIST(26), // ptrace
114 BLACKLIST(283), // kexec_load
115 BLACKLIST(341), // name_to_handle_at
116 BLACKLIST(342), // open_by_handle_at
117 BLACKLIST(127), // create_module
118 BLACKLIST(128), // init_module
119 BLACKLIST(350), // finit_module
120 BLACKLIST(129), // delete_module
121 BLACKLIST(110), // iopl
122 BLACKLIST(101), // ioperm
123 BLACKLIST(289), // ioprio_set
124 BLACKLIST(87), // swapon
125 BLACKLIST(115), // swapoff
126 BLACKLIST(103), // syslog
127 BLACKLIST(347), // process_vm_readv
128 BLACKLIST(348), // process_vm_writev
129 BLACKLIST(135), // sysfs
130 BLACKLIST(149), // _sysctl
131 BLACKLIST(124), // adjtimex
132 BLACKLIST(343), // clock_adjtime
133 BLACKLIST(253), // lookup_dcookie
134 BLACKLIST(336), // perf_event_open
135 BLACKLIST(338), // fanotify_init
136 BLACKLIST(349), // kcmp
137 BLACKLIST(286), // add_key
138 BLACKLIST(287), // request_key
139 BLACKLIST(288), // keyctl
140 BLACKLIST(86), // uselib
141 BLACKLIST(51), // acct
142 BLACKLIST(123), // modify_ldt
143 BLACKLIST(217), // pivot_root
144 BLACKLIST(245), // io_setup
145 BLACKLIST(246), // io_destroy
146 BLACKLIST(247), // io_getevents
147 BLACKLIST(248), // io_submit
148 BLACKLIST(249), // io_cancel
149 BLACKLIST(257), // remap_file_pages
150 BLACKLIST(274), // mbind
151 BLACKLIST(275), // get_mempolicy
152 BLACKLIST(276), // set_mempolicy
153 BLACKLIST(294), // migrate_pages
154 BLACKLIST(317), // move_pages
155 BLACKLIST(316), // vmsplice
156 BLACKLIST(61), // chroot
157 BLACKLIST(88), // reboot
158 BLACKLIST(169), // nfsservctl
159 BLACKLIST(130), // get_kernel_syms
160
161 RETURN_ALLOW
162 };
163
164 // save filter to file
165 int dst = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
166 if (dst < 0) {
167 fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname);
168 exit(1);
169 }
170
171 int size = (int) sizeof(filter);
172 int written = 0;
173 while (written < size) {
174 int rv = write(dst, (unsigned char *) filter + written, size - written);
175 if (rv == -1) {
176 fprintf(stderr, "Error fseccomp: cannot write %s file\n", fname);
177 exit(1);
178 }
179 written += rv;
180 }
181 close(dst);
182}
183
diff --git a/src/firejail/syscall.c b/src/fseccomp/syscall.c
index 985cc8bb8..7c2c4cbb2 100644
--- a/src/firejail/syscall.c
+++ b/src/fseccomp/syscall.c
@@ -17,9 +17,7 @@
17 * with this program; if not, write to the Free Software Foundation, Inc., 17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/ 19*/
20 20#include "fseccomp.h"
21#ifdef HAVE_SECCOMP
22#include "firejail.h"
23#include <sys/syscall.h> 21#include <sys/syscall.h>
24 22
25typedef struct { 23typedef struct {
@@ -31,13 +29,25 @@ static SyscallEntry syslist[] = {
31// 29//
32// code generated using tools/extract-syscall 30// code generated using tools/extract-syscall
33// 31//
34#include "syscall.h" 32#include "../include/syscall.h"
35// 33//
36// end of generated code 34// end of generated code
37// 35//
38}; // end of syslist 36}; // end of syslist
39 37
40const char *syscall_find_nr(int nr) { 38// return -1 if error, or syscall number
39int syscall_find_name(const char *name) {
40 int i;
41 int elems = sizeof(syslist) / sizeof(syslist[0]);
42 for (i = 0; i < elems; i++) {
43 if (strcmp(name, syslist[i].name) == 0)
44 return syslist[i].nr;
45 }
46
47 return -1;
48}
49
50char *syscall_find_nr(int nr) {
41 int i; 51 int i;
42 int elems = sizeof(syslist) / sizeof(syslist[0]); 52 int elems = sizeof(syslist) / sizeof(syslist[0]);
43 for (i = 0; i < elems; i++) { 53 for (i = 0; i < elems; i++) {
@@ -48,24 +58,61 @@ const char *syscall_find_nr(int nr) {
48 return "unknown"; 58 return "unknown";
49} 59}
50 60
51// return -1 if error, or syscall number 61void syscall_print(void) {
52static int syscall_find_name(const char *name) {
53 int i; 62 int i;
54 int elems = sizeof(syslist) / sizeof(syslist[0]); 63 int elems = sizeof(syslist) / sizeof(syslist[0]);
55 for (i = 0; i < elems; i++) { 64 for (i = 0; i < elems; i++) {
56 if (strcmp(name, syslist[i].name) == 0) 65 printf("%d\t- %s\n", syslist[i].nr, syslist[i].name);
57 return syslist[i].nr;
58 } 66 }
67 printf("\n");
68}
69
70// allowed input:
71// - syscall
72// - syscall(error)
73static void syscall_process_name(const char *name, int *syscall_nr, int *error_nr) {
74 assert(name);
75 if (strlen(name) == 0)
76 goto error;
77 *error_nr = -1;
59 78
60 return -1; 79 // syntax check
80 char *str = strdup(name);
81 if (!str)
82 errExit("strdup");
83
84 char *syscall_name = str;
85 char *error_name = strchr(str, ':');
86 if (error_name) {
87 *error_name = '\0';
88 error_name++;
89 }
90 if (strlen(syscall_name) == 0) {
91 free(str);
92 goto error;
93 }
94
95 *syscall_nr = syscall_find_name(syscall_name);
96 if (error_name) {
97 *error_nr = errno_find_name(error_name);
98 if (*error_nr == -1)
99 *syscall_nr = -1;
100 }
101
102 free(str);
103 return;
104
105error:
106 fprintf(stderr, "Error fseccomp: invalid syscall list entry %s\n", name);
107 exit(1);
61} 108}
62 109
63// return 1 if error, 0 if OK 110// return 1 if error, 0 if OK
64int syscall_check_list(const char *slist, void (*callback)(int syscall, int arg), int arg) { 111int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall, int arg), int fd, int arg) {
65 // don't allow empty lists 112 // don't allow empty lists
66 if (slist == NULL || *slist == '\0') { 113 if (slist == NULL || *slist == '\0') {
67 fprintf(stderr, "Error: empty syscall lists are not allowed\n"); 114 fprintf(stderr, "Error fseccomp: empty syscall lists are not allowed\n");
68 return -1; 115 exit(1);
69 } 116 }
70 117
71 // work on a copy of the string 118 // work on a copy of the string
@@ -73,44 +120,27 @@ int syscall_check_list(const char *slist, void (*callback)(int syscall, int arg)
73 if (!str) 120 if (!str)
74 errExit("strdup"); 121 errExit("strdup");
75 122
76 char *ptr = str; 123 char *ptr =strtok(str, ",");
77 char *start = str; 124 if (ptr == NULL) {
78 while (*ptr != '\0') { 125 fprintf(stderr, "Error fseccomp: empty syscall lists are not allowed\n");
79 if (islower(*ptr) || isdigit(*ptr) || *ptr == '_') 126 exit(1);
80 ;
81 else if (*ptr == ',') {
82 *ptr = '\0';
83 int nr = syscall_find_name(start);
84 if (nr == -1)
85 fprintf(stderr, "Warning: syscall %s not found\n", start);
86 else if (callback != NULL)
87 callback(nr, arg);
88
89 start = ptr + 1;
90 }
91 ptr++;
92 } 127 }
93 if (*start != '\0') { 128
94 int nr = syscall_find_name(start); 129 while (ptr) {
95 if (nr == -1) 130 int syscall_nr;
96 fprintf(stderr, "Warning: syscall %s not found\n", start); 131 int error_nr;
97 else if (callback != NULL) 132 syscall_process_name(ptr, &syscall_nr, &error_nr);
98 callback(nr, arg); 133 if (syscall_nr == -1)
134 fprintf(stderr, "Warning fseccomp: syscall %s not found\n", ptr);
135 else if (callback != NULL) {
136 if (error_nr != -1)
137 filter_add_errno(fd, syscall_nr, error_nr);
138 else
139 callback(fd, syscall_nr, arg);
140 }
141 ptr = strtok(NULL, ",");
99 } 142 }
100 143
101 free(str); 144 free(str);
102 return 0; 145 return 0;
103} 146}
104
105void syscall_print(void) {
106 EUID_ASSERT();
107
108 int i;
109 int elems = sizeof(syslist) / sizeof(syslist[0]);
110 for (i = 0; i < elems; i++) {
111 printf("%d\t- %s\n", syslist[i].nr, syslist[i].name);
112 }
113 printf("\n");
114}
115
116#endif // HAVE_SECCOMP
diff --git a/src/ftee/Makefile.in b/src/ftee/Makefile.in
index be159225f..ad508cadd 100644
--- a/src/ftee/Makefile.in
+++ b/src/ftee/Makefile.in
@@ -4,21 +4,23 @@ PREFIX=@prefix@
4VERSION=@PACKAGE_VERSION@ 4VERSION=@PACKAGE_VERSION@
5NAME=@PACKAGE_NAME@ 5NAME=@PACKAGE_NAME@
6HAVE_FATAL_WARNINGS=@HAVE_FATAL_WARNINGS@ 6HAVE_FATAL_WARNINGS=@HAVE_FATAL_WARNINGS@
7HAVE_GCOV=@HAVE_GCOV@
8EXTRA_LDFLAGS +=@EXTRA_LDFLAGS@
7 9
8H_FILE_LIST = $(sort $(wildcard *.[h])) 10H_FILE_LIST = $(sort $(wildcard *.[h]))
9C_FILE_LIST = $(sort $(wildcard *.c)) 11C_FILE_LIST = $(sort $(wildcard *.c))
10OBJS = $(C_FILE_LIST:.c=.o) 12OBJS = $(C_FILE_LIST:.c=.o)
11BINOBJS = $(foreach file, $(OBJS), $file) 13BINOBJS = $(foreach file, $(OBJS), $file)
12CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -DPREFIX='"$(PREFIX)"' -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security 14CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' $(HAVE_GCOV) -DPREFIX='"$(PREFIX)"' -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security
13LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread 15LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread
14 16
15%.o : %.c $(H_FILE_LIST) 17%.o : %.c $(H_FILE_LIST)
16 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ 18 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
17 19
18ftee: $(OBJS) 20ftee: $(OBJS)
19 $(CC) $(LDFLAGS) -o $@ $(OBJS) 21 $(CC) $(LDFLAGS) -o $@ $(OBJS) $(EXTRA_LDFLAGS)
20 22
21clean:; rm -f *.o ftee 23clean:; rm -f *.o ftee *.gcov *.gcda *.gcno
22 24
23distclean: clean 25distclean: clean
24 rm -fr Makefile 26 rm -fr Makefile
diff --git a/src/ftee/main.c b/src/ftee/main.c
index 8daea8487..e6aa5f567 100644
--- a/src/ftee/main.c
+++ b/src/ftee/main.c
@@ -193,6 +193,10 @@ int main(int argc, char **argv) {
193 usage(); 193 usage();
194 exit(1); 194 exit(1);
195 } 195 }
196 if (strcmp(argv[1], "--help") == 0) {
197 usage();
198 return 0;
199 }
196 char *fname = argv[1]; 200 char *fname = argv[1];
197 201
198 202
diff --git a/src/include/common.h b/src/include/common.h
index cd4b9c874..108820290 100644
--- a/src/include/common.h
+++ b/src/include/common.h
@@ -32,7 +32,7 @@
32#include <ctype.h> 32#include <ctype.h>
33#include <assert.h> 33#include <assert.h>
34 34
35#define errExit(msg) do { char msgout[500]; sprintf(msgout, "Error %s:%s(%d)", msg, __FUNCTION__, __LINE__); perror(msgout); exit(1);} while (0) 35#define errExit(msg) do { char msgout[500]; sprintf(msgout, "Error %s: %s:%d %s", msg, __FILE__, __LINE__, __FUNCTION__); perror(msgout); exit(1);} while (0)
36 36
37// macro to print ip addresses in a printf statement 37// macro to print ip addresses in a printf statement
38#define PRINT_IP(A) \ 38#define PRINT_IP(A) \
@@ -113,4 +113,6 @@ int join_namespace(pid_t pid, char *type);
113int name2pid(const char *name, pid_t *pid); 113int name2pid(const char *name, pid_t *pid);
114char *pid_proc_comm(const pid_t pid); 114char *pid_proc_comm(const pid_t pid);
115char *pid_proc_cmdline(const pid_t pid); 115char *pid_proc_cmdline(const pid_t pid);
116int pid_proc_cmdline_x11_xpra_xephyr(const pid_t pid);
117int pid_hidepid(void);
116#endif 118#endif
diff --git a/src/include/euid_common.h b/src/include/euid_common.h
index f07cf2868..752df5fff 100644
--- a/src/include/euid_common.h
+++ b/src/include/euid_common.h
@@ -31,25 +31,32 @@
31} 31}
32 32
33extern uid_t firejail_uid; 33extern uid_t firejail_uid;
34extern uid_t firejail_gid;
34 35
35 36
36 37
37static inline void EUID_ROOT(void) { 38static inline void EUID_ROOT(void) {
38 if (seteuid(0) == -1) 39 if (seteuid(0) == -1)
39 fprintf(stderr, "Error: cannot switch euid to root\n"); 40 fprintf(stderr, "Warning: cannot switch euid to root\n");
41 if (setegid(0) == -1)
42 fprintf(stderr, "Warning: cannot switch egid to root\n");
40} 43}
41 44
42static inline void EUID_USER(void) { 45static inline void EUID_USER(void) {
43 if (seteuid(firejail_uid) == -1) 46 if (seteuid(firejail_uid) == -1)
44 fprintf(stderr, "Error: cannot switch euid to user\n"); 47 errExit("seteuid");
48 if (setegid(firejail_gid) == -1)
49 errExit("setegid");
45} 50}
46 51
47static inline void EUID_PRINT(void) { 52static inline void EUID_PRINT(void) {
48 printf("debug: uid %d, euid %d\n", getuid(), geteuid()); 53 printf("debug: uid %d, euid %d\n", getuid(), geteuid());
54 printf("debug: gid %d, egid %d\n", getgid(), getegid());
49} 55}
50 56
51static inline void EUID_INIT(void) { 57static inline void EUID_INIT(void) {
52 firejail_uid = getuid(); 58 firejail_uid = getuid();
59 firejail_gid = getgid();
53} 60}
54 61
55#endif 62#endif
diff --git a/src/firejail/seccomp.h b/src/include/seccomp.h
index 7d646dd9e..7d646dd9e 100644
--- a/src/firejail/seccomp.h
+++ b/src/include/seccomp.h
diff --git a/src/firejail/syscall.h b/src/include/syscall.h
index 5b2cb4915..9a29779c9 100644
--- a/src/firejail/syscall.h
+++ b/src/include/syscall.h
@@ -20,7 +20,6 @@
20 20
21// content extracted from /bits/syscall.h file form glibc 2.22 21// content extracted from /bits/syscall.h file form glibc 2.22
22// using ../tools/extract_syscall tool 22// using ../tools/extract_syscall tool
23
24#if !defined __x86_64__ 23#if !defined __x86_64__
25#ifdef SYS__llseek 24#ifdef SYS__llseek
26#ifdef __NR__llseek 25#ifdef __NR__llseek
@@ -37,6 +36,11 @@
37 {"_sysctl", __NR__sysctl}, 36 {"_sysctl", __NR__sysctl},
38#endif 37#endif
39#endif 38#endif
39#ifdef SYS_accept4
40#ifdef __NR_accept4
41 {"accept4", __NR_accept4},
42#endif
43#endif
40#ifdef SYS_access 44#ifdef SYS_access
41#ifdef __NR_access 45#ifdef __NR_access
42 {"access", __NR_access}, 46 {"access", __NR_access},
@@ -72,6 +76,11 @@
72 {"bdflush", __NR_bdflush}, 76 {"bdflush", __NR_bdflush},
73#endif 77#endif
74#endif 78#endif
79#ifdef SYS_bind
80#ifdef __NR_bind
81 {"bind", __NR_bind},
82#endif
83#endif
75#ifdef SYS_bpf 84#ifdef SYS_bpf
76#ifdef __NR_bpf 85#ifdef __NR_bpf
77 {"bpf", __NR_bpf}, 86 {"bpf", __NR_bpf},
@@ -157,6 +166,16 @@
157 {"close", __NR_close}, 166 {"close", __NR_close},
158#endif 167#endif
159#endif 168#endif
169#ifdef SYS_connect
170#ifdef __NR_connect
171 {"connect", __NR_connect},
172#endif
173#endif
174#ifdef SYS_copy_file_range
175#ifdef __NR_copy_file_range
176 {"copy_file_range", __NR_copy_file_range},
177#endif
178#endif
160#ifdef SYS_creat 179#ifdef SYS_creat
161#ifdef __NR_creat 180#ifdef __NR_creat
162 {"creat", __NR_creat}, 181 {"creat", __NR_creat},
@@ -492,6 +511,11 @@
492 {"getitimer", __NR_getitimer}, 511 {"getitimer", __NR_getitimer},
493#endif 512#endif
494#endif 513#endif
514#ifdef SYS_getpeername
515#ifdef __NR_getpeername
516 {"getpeername", __NR_getpeername},
517#endif
518#endif
495#ifdef SYS_getpgid 519#ifdef SYS_getpgid
496#ifdef __NR_getpgid 520#ifdef __NR_getpgid
497 {"getpgid", __NR_getpgid}, 521 {"getpgid", __NR_getpgid},
@@ -562,6 +586,16 @@
562 {"getsid", __NR_getsid}, 586 {"getsid", __NR_getsid},
563#endif 587#endif
564#endif 588#endif
589#ifdef SYS_getsockname
590#ifdef __NR_getsockname
591 {"getsockname", __NR_getsockname},
592#endif
593#endif
594#ifdef SYS_getsockopt
595#ifdef __NR_getsockopt
596 {"getsockopt", __NR_getsockopt},
597#endif
598#endif
565#ifdef SYS_gettid 599#ifdef SYS_gettid
566#ifdef __NR_gettid 600#ifdef __NR_gettid
567 {"gettid", __NR_gettid}, 601 {"gettid", __NR_gettid},
@@ -722,6 +756,11 @@
722 {"linkat", __NR_linkat}, 756 {"linkat", __NR_linkat},
723#endif 757#endif
724#endif 758#endif
759#ifdef SYS_listen
760#ifdef __NR_listen
761 {"listen", __NR_listen},
762#endif
763#endif
725#ifdef SYS_listxattr 764#ifdef SYS_listxattr
726#ifdef __NR_listxattr 765#ifdef __NR_listxattr
727 {"listxattr", __NR_listxattr}, 766 {"listxattr", __NR_listxattr},
@@ -777,6 +816,11 @@
777 {"mbind", __NR_mbind}, 816 {"mbind", __NR_mbind},
778#endif 817#endif
779#endif 818#endif
819#ifdef SYS_membarrier
820#ifdef __NR_membarrier
821 {"membarrier", __NR_membarrier},
822#endif
823#endif
780#ifdef SYS_memfd_create 824#ifdef SYS_memfd_create
781#ifdef __NR_memfd_create 825#ifdef __NR_memfd_create
782 {"memfd_create", __NR_memfd_create}, 826 {"memfd_create", __NR_memfd_create},
@@ -817,6 +861,11 @@
817 {"mlock", __NR_mlock}, 861 {"mlock", __NR_mlock},
818#endif 862#endif
819#endif 863#endif
864#ifdef SYS_mlock2
865#ifdef __NR_mlock2
866 {"mlock2", __NR_mlock2},
867#endif
868#endif
820#ifdef SYS_mlockall 869#ifdef SYS_mlockall
821#ifdef __NR_mlockall 870#ifdef __NR_mlockall
822 {"mlockall", __NR_mlockall}, 871 {"mlockall", __NR_mlockall},
@@ -1122,11 +1171,21 @@
1122 {"reboot", __NR_reboot}, 1171 {"reboot", __NR_reboot},
1123#endif 1172#endif
1124#endif 1173#endif
1174#ifdef SYS_recvfrom
1175#ifdef __NR_recvfrom
1176 {"recvfrom", __NR_recvfrom},
1177#endif
1178#endif
1125#ifdef SYS_recvmmsg 1179#ifdef SYS_recvmmsg
1126#ifdef __NR_recvmmsg 1180#ifdef __NR_recvmmsg
1127 {"recvmmsg", __NR_recvmmsg}, 1181 {"recvmmsg", __NR_recvmmsg},
1128#endif 1182#endif
1129#endif 1183#endif
1184#ifdef SYS_recvmsg
1185#ifdef __NR_recvmsg
1186 {"recvmsg", __NR_recvmsg},
1187#endif
1188#endif
1130#ifdef SYS_remap_file_pages 1189#ifdef SYS_remap_file_pages
1131#ifdef __NR_remap_file_pages 1190#ifdef __NR_remap_file_pages
1132 {"remap_file_pages", __NR_remap_file_pages}, 1191 {"remap_file_pages", __NR_remap_file_pages},
@@ -1292,6 +1351,16 @@
1292 {"sendmmsg", __NR_sendmmsg}, 1351 {"sendmmsg", __NR_sendmmsg},
1293#endif 1352#endif
1294#endif 1353#endif
1354#ifdef SYS_sendmsg
1355#ifdef __NR_sendmsg
1356 {"sendmsg", __NR_sendmsg},
1357#endif
1358#endif
1359#ifdef SYS_sendto
1360#ifdef __NR_sendto
1361 {"sendto", __NR_sendto},
1362#endif
1363#endif
1295#ifdef SYS_set_mempolicy 1364#ifdef SYS_set_mempolicy
1296#ifdef __NR_set_mempolicy 1365#ifdef __NR_set_mempolicy
1297 {"set_mempolicy", __NR_set_mempolicy}, 1366 {"set_mempolicy", __NR_set_mempolicy},
@@ -1432,6 +1501,11 @@
1432 {"setsid", __NR_setsid}, 1501 {"setsid", __NR_setsid},
1433#endif 1502#endif
1434#endif 1503#endif
1504#ifdef SYS_setsockopt
1505#ifdef __NR_setsockopt
1506 {"setsockopt", __NR_setsockopt},
1507#endif
1508#endif
1435#ifdef SYS_settimeofday 1509#ifdef SYS_settimeofday
1436#ifdef __NR_settimeofday 1510#ifdef __NR_settimeofday
1437 {"settimeofday", __NR_settimeofday}, 1511 {"settimeofday", __NR_settimeofday},
@@ -1457,6 +1531,11 @@
1457 {"sgetmask", __NR_sgetmask}, 1531 {"sgetmask", __NR_sgetmask},
1458#endif 1532#endif
1459#endif 1533#endif
1534#ifdef SYS_shutdown
1535#ifdef __NR_shutdown
1536 {"shutdown", __NR_shutdown},
1537#endif
1538#endif
1460#ifdef SYS_sigaction 1539#ifdef SYS_sigaction
1461#ifdef __NR_sigaction 1540#ifdef __NR_sigaction
1462 {"sigaction", __NR_sigaction}, 1541 {"sigaction", __NR_sigaction},
@@ -1502,11 +1581,21 @@
1502 {"sigsuspend", __NR_sigsuspend}, 1581 {"sigsuspend", __NR_sigsuspend},
1503#endif 1582#endif
1504#endif 1583#endif
1584#ifdef SYS_socket
1585#ifdef __NR_socket
1586 {"socket", __NR_socket},
1587#endif
1588#endif
1505#ifdef SYS_socketcall 1589#ifdef SYS_socketcall
1506#ifdef __NR_socketcall 1590#ifdef __NR_socketcall
1507 {"socketcall", __NR_socketcall}, 1591 {"socketcall", __NR_socketcall},
1508#endif 1592#endif
1509#endif 1593#endif
1594#ifdef SYS_socketpair
1595#ifdef __NR_socketpair
1596 {"socketpair", __NR_socketpair},
1597#endif
1598#endif
1510#ifdef SYS_splice 1599#ifdef SYS_splice
1511#ifdef __NR_splice 1600#ifdef __NR_splice
1512 {"splice", __NR_splice}, 1601 {"splice", __NR_splice},
@@ -1722,6 +1811,11 @@
1722 {"uselib", __NR_uselib}, 1811 {"uselib", __NR_uselib},
1723#endif 1812#endif
1724#endif 1813#endif
1814#ifdef SYS_userfaultfd
1815#ifdef __NR_userfaultfd
1816 {"userfaultfd", __NR_userfaultfd},
1817#endif
1818#endif
1725#ifdef SYS_ustat 1819#ifdef SYS_ustat
1726#ifdef __NR_ustat 1820#ifdef __NR_ustat
1727 {"ustat", __NR_ustat}, 1821 {"ustat", __NR_ustat},
@@ -1934,6 +2028,11 @@
1934 {"connect", __NR_connect}, 2028 {"connect", __NR_connect},
1935#endif 2029#endif
1936#endif 2030#endif
2031#ifdef SYS_copy_file_range
2032#ifdef __NR_copy_file_range
2033 {"copy_file_range", __NR_copy_file_range},
2034#endif
2035#endif
1937#ifdef SYS_creat 2036#ifdef SYS_creat
1938#ifdef __NR_creat 2037#ifdef __NR_creat
1939 {"creat", __NR_creat}, 2038 {"creat", __NR_creat},
@@ -2484,6 +2583,11 @@
2484 {"mbind", __NR_mbind}, 2583 {"mbind", __NR_mbind},
2485#endif 2584#endif
2486#endif 2585#endif
2586#ifdef SYS_membarrier
2587#ifdef __NR_membarrier
2588 {"membarrier", __NR_membarrier},
2589#endif
2590#endif
2487#ifdef SYS_memfd_create 2591#ifdef SYS_memfd_create
2488#ifdef __NR_memfd_create 2592#ifdef __NR_memfd_create
2489 {"memfd_create", __NR_memfd_create}, 2593 {"memfd_create", __NR_memfd_create},
@@ -2524,6 +2628,11 @@
2524 {"mlock", __NR_mlock}, 2628 {"mlock", __NR_mlock},
2525#endif 2629#endif
2526#endif 2630#endif
2631#ifdef SYS_mlock2
2632#ifdef __NR_mlock2
2633 {"mlock2", __NR_mlock2},
2634#endif
2635#endif
2527#ifdef SYS_mlockall 2636#ifdef SYS_mlockall
2528#ifdef __NR_mlockall 2637#ifdef __NR_mlockall
2529 {"mlockall", __NR_mlockall}, 2638 {"mlockall", __NR_mlockall},
@@ -3354,6 +3463,11 @@
3354 {"uselib", __NR_uselib}, 3463 {"uselib", __NR_uselib},
3355#endif 3464#endif
3356#endif 3465#endif
3466#ifdef SYS_userfaultfd
3467#ifdef __NR_userfaultfd
3468 {"userfaultfd", __NR_userfaultfd},
3469#endif
3470#endif
3357#ifdef SYS_ustat 3471#ifdef SYS_ustat
3358#ifdef __NR_ustat 3472#ifdef __NR_ustat
3359 {"ustat", __NR_ustat}, 3473 {"ustat", __NR_ustat},
@@ -3546,6 +3660,11 @@
3546 {"connect", __NR_connect}, 3660 {"connect", __NR_connect},
3547#endif 3661#endif
3548#endif 3662#endif
3663#ifdef SYS_copy_file_range
3664#ifdef __NR_copy_file_range
3665 {"copy_file_range", __NR_copy_file_range},
3666#endif
3667#endif
3549#ifdef SYS_creat 3668#ifdef SYS_creat
3550#ifdef __NR_creat 3669#ifdef __NR_creat
3551 {"creat", __NR_creat}, 3670 {"creat", __NR_creat},
@@ -4071,6 +4190,11 @@
4071 {"mbind", __NR_mbind}, 4190 {"mbind", __NR_mbind},
4072#endif 4191#endif
4073#endif 4192#endif
4193#ifdef SYS_membarrier
4194#ifdef __NR_membarrier
4195 {"membarrier", __NR_membarrier},
4196#endif
4197#endif
4074#ifdef SYS_memfd_create 4198#ifdef SYS_memfd_create
4075#ifdef __NR_memfd_create 4199#ifdef __NR_memfd_create
4076 {"memfd_create", __NR_memfd_create}, 4200 {"memfd_create", __NR_memfd_create},
@@ -4111,6 +4235,11 @@
4111 {"mlock", __NR_mlock}, 4235 {"mlock", __NR_mlock},
4112#endif 4236#endif
4113#endif 4237#endif
4238#ifdef SYS_mlock2
4239#ifdef __NR_mlock2
4240 {"mlock2", __NR_mlock2},
4241#endif
4242#endif
4114#ifdef SYS_mlockall 4243#ifdef SYS_mlockall
4115#ifdef __NR_mlockall 4244#ifdef __NR_mlockall
4116 {"mlockall", __NR_mlockall}, 4245 {"mlockall", __NR_mlockall},
@@ -4921,6 +5050,11 @@
4921 {"unshare", __NR_unshare}, 5050 {"unshare", __NR_unshare},
4922#endif 5051#endif
4923#endif 5052#endif
5053#ifdef SYS_userfaultfd
5054#ifdef __NR_userfaultfd
5055 {"userfaultfd", __NR_userfaultfd},
5056#endif
5057#endif
4924#ifdef SYS_ustat 5058#ifdef SYS_ustat
4925#ifdef __NR_ustat 5059#ifdef __NR_ustat
4926 {"ustat", __NR_ustat}, 5060 {"ustat", __NR_ustat},
diff --git a/src/lib/Makefile.in b/src/lib/Makefile.in
index 71f96bab1..5549aca11 100644
--- a/src/lib/Makefile.in
+++ b/src/lib/Makefile.in
@@ -2,12 +2,14 @@ PREFIX=@prefix@
2VERSION=@PACKAGE_VERSION@ 2VERSION=@PACKAGE_VERSION@
3NAME=@PACKAGE_NAME@ 3NAME=@PACKAGE_NAME@
4HAVE_FATAL_WARNINGS=@HAVE_FATAL_WARNINGS@ 4HAVE_FATAL_WARNINGS=@HAVE_FATAL_WARNINGS@
5HAVE_GCOV=@HAVE_GCOV@
6EXTRA_LDFLAGS +=@EXTRA_LDFLAGS@
5 7
6H_FILE_LIST = $(sort $(wildcard *.[h])) 8H_FILE_LIST = $(sort $(wildcard *.[h]))
7C_FILE_LIST = $(sort $(wildcard *.c)) 9C_FILE_LIST = $(sort $(wildcard *.c))
8OBJS = $(C_FILE_LIST:.c=.o) 10OBJS = $(C_FILE_LIST:.c=.o)
9BINOBJS = $(foreach file, $(OBJS), $file) 11BINOBJS = $(foreach file, $(OBJS), $file)
10CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIC -Wformat -Wformat-security 12CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' $(HAVE_GCOV) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIC -Wformat -Wformat-security
11LDFLAGS:=-pic -Wl,-z,relro -Wl,-z,now 13LDFLAGS:=-pic -Wl,-z,relro -Wl,-z,now
12 14
13all: $(OBJS) 15all: $(OBJS)
@@ -15,7 +17,7 @@ all: $(OBJS)
15%.o : %.c $(H_FILE_LIST) 17%.o : %.c $(H_FILE_LIST)
16 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ 18 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
17 19
18clean:; rm -f $(OBJS) 20clean:; rm -f $(OBJS) *.gcov *.gcda *.gcno
19 21
20distclean: clean 22distclean: clean
21 rm -fr Makefile 23 rm -fr Makefile
diff --git a/src/lib/common.c b/src/lib/common.c
index 8ea926df1..2f2340963 100644
--- a/src/lib/common.c
+++ b/src/lib/common.c
@@ -199,3 +199,88 @@ char *pid_proc_cmdline(const pid_t pid) {
199 } 199 }
200 return rv; 200 return rv;
201} 201}
202
203// return 1 if firejail --x11 on command line
204int pid_proc_cmdline_x11_xpra_xephyr(const pid_t pid) {
205 // if comm is not firejail return 0
206 char *comm = pid_proc_comm(pid);
207 if (strcmp(comm, "firejail") != 0) {
208 free(comm);
209 return 0;
210 }
211 free(comm);
212
213 // open /proc/pid/cmdline file
214 char *fname;
215 int fd;
216 if (asprintf(&fname, "/proc/%d/cmdline", pid) == -1)
217 return 0;
218 if ((fd = open(fname, O_RDONLY)) < 0) {
219 free(fname);
220 return 0;
221 }
222 free(fname);
223
224 // read file
225 unsigned char buffer[BUFLEN];
226 ssize_t len;
227 if ((len = read(fd, buffer, sizeof(buffer) - 1)) <= 0) {
228 close(fd);
229 return 0;
230 }
231 buffer[len] = '\0';
232 close(fd);
233
234 // skip the first argument
235 int i;
236 for (i = 0; buffer[i] != '\0'; i++);
237
238 // parse remaining command line options
239 while (1) {
240 // extract argument
241 i++;
242 if (i >= len)
243 break;
244 char *arg = (char *)buffer + i;
245
246 // detect the last command line option
247 if (strcmp(arg, "--") == 0)
248 break;
249 if (strncmp(arg, "--", 2) != 0)
250 break;
251
252 if (strcmp(arg, "--x11=xorg") == 0)
253 return 0;
254
255 // check x11 xpra or xephyr
256 if (strncmp(arg, "--x11", 5) == 0)
257 return 1;
258 i += strlen(arg);
259 }
260 return 0;
261}
262
263// return 1 if /proc is mounted hidepid, or if /proc/mouns access is denied
264#define BUFLEN 4096
265int pid_hidepid(void) {
266 FILE *fp = fopen("/proc/mounts", "r");
267 if (!fp)
268 return 1;
269
270 char buf[BUFLEN];
271 while (fgets(buf, BUFLEN, fp)) {
272 if (strstr(buf, "proc /proc proc")) {
273 fclose(fp);
274 // check hidepid
275 if (strstr(buf, "hidepid=2") || strstr(buf, "hidepid=1"))
276 return 1;
277 return 0;
278 }
279 }
280
281 fclose(fp);
282 return 0;
283}
284
285
286
diff --git a/src/lib/libnetlink.c b/src/lib/libnetlink.c
index 07457eefe..836cf417d 100644
--- a/src/lib/libnetlink.c
+++ b/src/lib/libnetlink.c
@@ -723,7 +723,7 @@ int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data)
723 int len = RTA_LENGTH(4); 723 int len = RTA_LENGTH(4);
724 struct rtattr *subrta; 724 struct rtattr *subrta;
725 725
726 if (RTA_ALIGN(rta->rta_len) + len > maxlen) { 726 if ((int) (RTA_ALIGN(rta->rta_len) + len) > maxlen) {
727 fprintf(stderr,"rta_addattr32: Error! max allowed bound %d exceeded\n",maxlen); 727 fprintf(stderr,"rta_addattr32: Error! max allowed bound %d exceeded\n",maxlen);
728 return -1; 728 return -1;
729 } 729 }
@@ -741,7 +741,7 @@ int rta_addattr_l(struct rtattr *rta, int maxlen, int type,
741 struct rtattr *subrta; 741 struct rtattr *subrta;
742 int len = RTA_LENGTH(alen); 742 int len = RTA_LENGTH(alen);
743 743
744 if (RTA_ALIGN(rta->rta_len) + RTA_ALIGN(len) > maxlen) { 744 if ((int) (RTA_ALIGN(rta->rta_len) + RTA_ALIGN(len)) > maxlen) {
745 fprintf(stderr,"rta_addattr_l: Error! max allowed bound %d exceeded\n",maxlen); 745 fprintf(stderr,"rta_addattr_l: Error! max allowed bound %d exceeded\n",maxlen);
746 return -1; 746 return -1;
747 } 747 }
diff --git a/src/lib/pid.c b/src/lib/pid.c
index d1ade389e..ed583c51d 100644
--- a/src/lib/pid.c
+++ b/src/lib/pid.c
@@ -29,7 +29,6 @@
29//Process pids[max_pids]; 29//Process pids[max_pids];
30Process *pids = NULL; 30Process *pids = NULL;
31int max_pids=32769; 31int max_pids=32769;
32#define PIDS_BUFLEN 4096
33 32
34// get the memory associated with this pid 33// get the memory associated with this pid
35void pid_getmem(unsigned pid, unsigned *rss, unsigned *shared) { 34void pid_getmem(unsigned pid, unsigned *rss, unsigned *shared) {
@@ -340,18 +339,12 @@ void pid_read(pid_t mon_pid) {
340 exit(1); 339 exit(1);
341 } 340 }
342 341
343 if (mon_pid == 0 && strncmp(ptr, "firejail", 8) == 0) { 342 if ((strncmp(ptr, "firejail", 8) == 0) && (mon_pid == 0 || mon_pid == pid)) {
344 pids[pid].level = 1; 343 if (pid_proc_cmdline_x11_xpra_xephyr(pid))
345 } 344 pids[pid].level = -1;
346 else if (mon_pid == pid && strncmp(ptr, "firejail", 8) == 0) { 345 else
347 pids[pid].level = 1; 346 pids[pid].level = 1;
348 } 347 }
349// else if (mon_pid == 0 && strncmp(ptr, "lxc-execute", 11) == 0) {
350// pids[pid].level = 1;
351// }
352// else if (mon_pid == pid && strncmp(ptr, "lxc-execute", 11) == 0) {
353// pids[pid].level = 1;
354// }
355 else 348 else
356 pids[pid].level = -1; 349 pids[pid].level = -1;
357 } 350 }
diff --git a/src/libconnect/Makefile.in b/src/libconnect/Makefile.in
new file mode 100644
index 000000000..5b7a8d0f1
--- /dev/null
+++ b/src/libconnect/Makefile.in
@@ -0,0 +1,25 @@
1PREFIX=@prefix@
2VERSION=@PACKAGE_VERSION@
3NAME=@PACKAGE_NAME@
4HAVE_FATAL_WARNINGS=@HAVE_FATAL_WARNINGS@
5
6H_FILE_LIST = $(sort $(wildcard *.[h]))
7C_FILE_LIST = $(sort $(wildcard *.c))
8OBJS = $(C_FILE_LIST:.c=.o)
9BINOBJS = $(foreach file, $(OBJS), $file)
10CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIC -Wformat -Wformat-security
11LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now
12
13all: libconnect.so
14
15%.o : %.c $(H_FILE_LIST)
16 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
17
18libconnect.so: $(OBJS)
19 $(CC) $(LDFLAGS) -shared -fPIC -z relro -o $@ $(OBJS) -ldl
20
21
22clean:; rm -f $(OBJS) libconnect.so
23
24distclean: clean
25 rm -fr Makefile
diff --git a/src/libconnect/libconnect.c b/src/libconnect/libconnect.c
new file mode 100644
index 000000000..18c4d81f5
--- /dev/null
+++ b/src/libconnect/libconnect.c
@@ -0,0 +1,66 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#define _GNU_SOURCE
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <dlfcn.h>
25#include <sys/types.h>
26#include <unistd.h>
27#include <sys/socket.h>
28#include <netinet/in.h>
29#include <arpa/inet.h>
30#include <sys/un.h>
31#include <sys/stat.h>
32#include <dirent.h>
33#include <errno.h>
34
35//#define DEBUG
36
37//static int check_sockaddr(int sockfd, const char *call, const struct sockaddr *addr, int rv) {
38static int check_sockaddr(const struct sockaddr *addr) {
39 if (addr->sa_family == AF_UNIX) {
40 struct sockaddr_un *a = (struct sockaddr_un *) addr;
41 if (a->sun_path[0] == '\0' && strstr(a->sun_path + 1, "X11-unix")) {
42// printf("@%s\n", a->sun_path + 1);
43 errno = ENOENT;
44 return -1;
45 }
46 }
47
48 return 0;
49}
50
51//
52// syscalls
53//
54
55// connect
56typedef int (*orig_connect_t)(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
57static orig_connect_t orig_connect = NULL;
58int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
59 if (!orig_connect)
60 orig_connect = (orig_connect_t)dlsym(RTLD_NEXT, "connect");
61
62 if (check_sockaddr(addr) == -1)
63 return -1;
64
65 return orig_connect(sockfd, addr, addrlen);
66}
diff --git a/src/libtrace/libtrace.c b/src/libtrace/libtrace.c
index a3d1571f7..dde3df2ea 100644
--- a/src/libtrace/libtrace.c
+++ b/src/libtrace/libtrace.c
@@ -423,11 +423,36 @@ int stat(const char *pathname, struct stat *buf) {
423typedef int (*orig_stat64_t)(const char *pathname, struct stat64 *buf); 423typedef int (*orig_stat64_t)(const char *pathname, struct stat64 *buf);
424static orig_stat64_t orig_stat64 = NULL; 424static orig_stat64_t orig_stat64 = NULL;
425int stat64(const char *pathname, struct stat64 *buf) { 425int stat64(const char *pathname, struct stat64 *buf) {
426 if (!orig_stat) 426 if (!orig_stat64)
427 orig_stat64 = (orig_stat64_t)dlsym(RTLD_NEXT, "stat64"); 427 orig_stat64 = (orig_stat64_t)dlsym(RTLD_NEXT, "stat64");
428 428
429 int rv = orig_stat64(pathname, buf); 429 int rv = orig_stat64(pathname, buf);
430 printf("%u:%s:stat %s:%d\n", pid(), name(), pathname, rv); 430 printf("%u:%s:stat64 %s:%d\n", pid(), name(), pathname, rv);
431 return rv;
432}
433#endif /* __GLIBC__ */
434
435// lstat
436typedef int (*orig_lstat_t)(const char *pathname, struct stat *buf);
437static orig_lstat_t orig_lstat = NULL;
438int lstat(const char *pathname, struct stat *buf) {
439 if (!orig_lstat)
440 orig_lstat = (orig_lstat_t)dlsym(RTLD_NEXT, "lstat");
441
442 int rv = orig_lstat(pathname, buf);
443 printf("%u:%s:lstat %s:%d\n", pid(), name(), pathname, rv);
444 return rv;
445}
446
447#ifdef __GLIBC__
448typedef int (*orig_lstat64_t)(const char *pathname, struct stat64 *buf);
449static orig_lstat64_t orig_lstat64 = NULL;
450int lstat64(const char *pathname, struct stat64 *buf) {
451 if (!orig_lstat64)
452 orig_lstat64 = (orig_lstat64_t)dlsym(RTLD_NEXT, "lstat64");
453
454 int rv = orig_lstat64(pathname, buf);
455 printf("%u:%s:lstat64 %s:%d\n", pid(), name(), pathname, rv);
431 return rv; 456 return rv;
432} 457}
433#endif /* __GLIBC__ */ 458#endif /* __GLIBC__ */
diff --git a/src/libtracelog/libtracelog.c b/src/libtracelog/libtracelog.c
index c3fd40a67..ff884c7d7 100644
--- a/src/libtracelog/libtracelog.c
+++ b/src/libtracelog/libtracelog.c
@@ -31,6 +31,7 @@
31#include <sys/stat.h> 31#include <sys/stat.h>
32#include <syslog.h> 32#include <syslog.h>
33#include <dirent.h> 33#include <dirent.h>
34#include <limits.h>
34 35
35//#define DEBUG 36//#define DEBUG
36 37
@@ -91,9 +92,9 @@ static void storage_add(const char *str) {
91 storage[h] = ptr; 92 storage[h] = ptr;
92} 93}
93 94
94char* cwd = NULL; // global variable for keeping current working directory 95// global variable to keep current working directory
95typedef int (*orig_chdir_t)(const char *pathname); 96static char* cwd = NULL;
96static orig_chdir_t orig_chdir = NULL; 97
97static char *storage_find(const char *str) { 98static char *storage_find(const char *str) {
98#ifdef DEBUG 99#ifdef DEBUG
99 printf("storage find %s\n", str); 100 printf("storage find %s\n", str);
@@ -107,17 +108,23 @@ static char *storage_find(const char *str) {
107 const char *tofind = str; 108 const char *tofind = str;
108 int allocated = 0; 109 int allocated = 0;
109 110
110 if (strstr(str, "..") || strstr(str, "/./") || strstr(str, "//") || str[0]!='/') { 111 if (strstr(str, "..") || strstr(str, "/./") || strstr(str, "//") || str[0] != '/') {
111 if (!orig_chdir) 112 if (cwd != NULL && str[0] != '/') {
112 orig_chdir = (orig_chdir_t)dlsym(RTLD_NEXT, "chdir"); 113 char *fullpath=malloc(PATH_MAX);
113 if (!orig_chdir(cwd)) { 114 if (!fullpath) {
114#ifdef DEBUG 115 fprintf(stderr, "Error: cannot allocate memory\n");
115 printf("chdir failed\n"); 116 return NULL;
116#endif 117 }
117 return NULL; 118 if (snprintf(fullpath, PATH_MAX, "%s/%s", cwd, str)<3) {
119 fprintf(stderr, "Error: snprintf failed\n");
120 free(fullpath);
121 return NULL;
122 }
123 tofind = realpath(fullpath, NULL);
124 free(fullpath);
125 } else {
126 tofind = realpath(str, NULL);
118 } 127 }
119
120 tofind = realpath(str, NULL);
121 if (!tofind) { 128 if (!tofind) {
122#ifdef DEBUG 129#ifdef DEBUG
123 printf("realpath failed\n"); 130 printf("realpath failed\n");
@@ -556,7 +563,7 @@ int stat64(const char *pathname, struct stat64 *buf) {
556#ifdef DEBUG 563#ifdef DEBUG
557 printf("%s %s\n", __FUNCTION__, pathname); 564 printf("%s %s\n", __FUNCTION__, pathname);
558#endif 565#endif
559 if (!orig_stat) 566 if (!orig_stat64)
560 orig_stat64 = (orig_stat64_t)dlsym(RTLD_NEXT, "stat64"); 567 orig_stat64 = (orig_stat64_t)dlsym(RTLD_NEXT, "stat64");
561 if (!blacklist_loaded) 568 if (!blacklist_loaded)
562 load_blacklist(); 569 load_blacklist();
@@ -592,7 +599,7 @@ int lstat64(const char *pathname, struct stat64 *buf) {
592#ifdef DEBUG 599#ifdef DEBUG
593 printf("%s %s\n", __FUNCTION__, pathname); 600 printf("%s %s\n", __FUNCTION__, pathname);
594#endif 601#endif
595 if (!orig_lstat) 602 if (!orig_lstat64)
596 orig_lstat64 = (orig_lstat64_t)dlsym(RTLD_NEXT, "lstat64"); 603 orig_lstat64 = (orig_lstat64_t)dlsym(RTLD_NEXT, "lstat64");
597 if (!blacklist_loaded) 604 if (!blacklist_loaded)
598 load_blacklist(); 605 load_blacklist();
@@ -641,9 +648,8 @@ DIR *opendir(const char *pathname) {
641} 648}
642 649
643// chdir 650// chdir
644// definition of orig_chdir placed before storage_find function 651typedef int (*orig_chdir_t)(const char *pathname);
645//typedef int (*orig_chdir_t)(const char *pathname); 652static orig_chdir_t orig_chdir = NULL;
646//static orig_chdir_t orig_chdir = NULL;
647int chdir(const char *pathname) { 653int chdir(const char *pathname) {
648#ifdef DEBUG 654#ifdef DEBUG
649 printf("%s %s\n", __FUNCTION__, pathname); 655 printf("%s %s\n", __FUNCTION__, pathname);
@@ -662,3 +668,32 @@ int chdir(const char *pathname) {
662 int rv = orig_chdir(pathname); 668 int rv = orig_chdir(pathname);
663 return rv; 669 return rv;
664} 670}
671
672// fchdir
673typedef int (*orig_fchdir_t)(int fd);
674static orig_fchdir_t orig_fchdir = NULL;
675int fchdir(int fd) {
676#ifdef DEBUG
677 printf("%s %d\n", __FUNCTION__, fd);
678#endif
679 if (!orig_fchdir)
680 orig_fchdir = (orig_fchdir_t)dlsym(RTLD_NEXT, "fchdir");
681
682 free(cwd);
683 char *pathname=malloc(PATH_MAX);
684 if (pathname) {
685 if (snprintf(pathname,PATH_MAX,"/proc/self/fd/%d", fd)>0) {
686 cwd = realpath(pathname, NULL);
687 } else {
688 cwd = NULL;
689 fprintf(stderr, "Error: snprintf failed\n");
690 }
691 free(pathname);
692 } else {
693 fprintf(stderr, "Error: cannot allocate memory\n");
694 cwd = NULL;
695 }
696
697 int rv = orig_fchdir(fd);
698 return rv;
699}
diff --git a/src/man/firecfg.txt b/src/man/firecfg.txt
index decc1af73..b9d336c4c 100644
--- a/src/man/firecfg.txt
+++ b/src/man/firecfg.txt
@@ -10,19 +10,25 @@ sandbox applications automatically, just by clicking on a regular desktop
10menus and icons. 10menus and icons.
11 11
12The symbolic links are placed in /usr/local/bin. For more information, see 12The symbolic links are placed in /usr/local/bin. For more information, see
13DESKTOP INTEGRATION section in man 1 firejail. 13\fBDESKTOP INTEGRATION\fR section in \fBman 1 firejail\fR.
14 14
15.SH OPTIONS 15.SH OPTIONS
16.TP 16.TP
17\fB\-\-clean 17\fB\-\-clean
18Remove all firejail symbolic links. 18Remove all firejail symbolic links.
19.TP 19.TP
20\fB\-\-debug
21Print debug messages.
22.TP
20\fB\-?\fR, \fB\-\-help\fR 23\fB\-?\fR, \fB\-\-help\fR
21Print options end exit. 24Print options end exit.
22.TP 25.TP
23\fB\-\-list 26\fB\-\-list
24List all firejail symbolic links 27List all firejail symbolic links
25.TP 28.TP
29\fB\-\-fix
30Fix .desktop files. Some .desktop files use full path to executable. Firecfg will check .desktop files in /usr/share/applications/, replace full path by name if it is in PATH, and write result to $HOME/.local/share/applications/.
31.TP
26\fB\-\-version 32\fB\-\-version
27Print program version and exit. 33Print program version and exit.
28 34
@@ -48,13 +54,22 @@ $ firecfg --list
48.br 54.br
49[...] 55[...]
50.br 56.br
51$ sudo firecfg --clear 57$ sudo firecfg --clean
52.br 58.br
53/usr/local/bin/firefox removed 59/usr/local/bin/firefox removed
54.br 60.br
55/usr/local/bin/vlc removed 61/usr/local/bin/vlc removed
56.br 62.br
57[...] 63[...]
64.br
65$ firecfg --fix
66.br
67/home/user/.local/share/applications/chromium.desktop created
68.br
69/home/user/.local/share/applications/vlc.desktop created
70.br
71[...]
72
58 73
59.SH LICENSE 74.SH LICENSE
60This 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. 75This 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.
@@ -65,6 +80,5 @@ Homepage: http://firejail.wordpress.com
65\&\flfiremon\fR\|(1), 80\&\flfiremon\fR\|(1),
66\&\flfirejail-profile\fR\|(5), 81\&\flfirejail-profile\fR\|(5),
67\&\flfirejail-login\fR\|(5) 82\&\flfirejail-login\fR\|(5)
68\&\flfirejail-config\fR\|(5)
69 83
70 84
diff --git a/src/man/firejail-config.txt b/src/man/firejail-config.txt
deleted file mode 100644
index fcf4109ee..000000000
--- a/src/man/firejail-config.txt
+++ /dev/null
@@ -1,81 +0,0 @@
1.TH FIREJAIL-CONFIG 5 "MONTH YEAR" "VERSION" "firejail.config man page"
2.SH NAME
3firejail.config \- Firejail run time configuration file
4
5.SH DESCRIPTION
6/etc/firejail/firejail.config is the system-wide configuration file for Firejail.
7It allows the system administrator to enable or disable a number of
8features and Linux kernel security technologies used by Firejail sandbox.
9The file contains keyword-argument pairs, one per line.
10Use 'yes' or 'no' as configuration values.
11
12Note that some of these features can also be enabled or disabled at compile
13time. Most features are enabled by default both at compile time and
14at run time.
15
16.TP
17\fBbind
18Enable or disable bind support, default enabled.
19
20.TP
21\fBchroot
22Enable or disable chroot support, default enabled.
23
24.TP
25\fBfile-transfer
26Enable or disable file transfer support, default enabled.
27
28.TP
29\fBnetwork
30Enable or disable networking features, default enabled.
31
32.TP
33\fBrestricted-network
34Enable or disable restricted network support, default disabled. If enabled,
35networking features should also be enabled (network yes).
36Restricted networking grants access to --interface and --net=ethXXX
37only to root user. Regular users are only allowed --net=none.
38
39.TP
40\fBsecomp
41Enable or disable seccomp support, default enabled.
42
43.TP
44\fBuserns
45Enable or disable user namespace support, default enabled.
46
47.TP
48\fBx11
49Enable or disable X11 sandboxing support, default enabled.
50
51.TP
52\fBxephyr-screen
53Screen size for --x11=xephyr, default 800x600. Run /usr/bin/xrandr for
54a full list of resolutions available on your specific setup. Examples:
55.br
56
57.br
58xephyr-screen 640x480
59.br
60xephyr-screen 800x600
61.br
62xephyr-screen 1024x768
63.br
64xephyr-screen 1280x1024
65
66.SH FILES
67/etc/firejail/firejail.config
68
69.SH LICENSE
70Firejail 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.
71.PP
72Homepage: http://firejail.wordpress.com
73.SH SEE ALSO
74\&\flfirejail\fR\|(1),
75\&\flfiremon\fR\|(1),
76\&\flfirecfg\fR\|(1),
77\&\flfirejail-profile\fR\|(5)
78\&\flfirejail-login\fR\|(5)
79
80
81
diff --git a/src/man/firejail-login.txt b/src/man/firejail-login.txt
index 6cd9ce3cb..796179d0b 100644
--- a/src/man/firejail-login.txt
+++ b/src/man/firejail-login.txt
@@ -13,9 +13,13 @@ Example:
13 13
14 netblue:--net=none --protocol=unix 14 netblue:--net=none --protocol=unix
15 15
16Wildcard patterns are accepted in the user name field:
17
18 user*: --private
19
16.SH RESTRICTED SHELL 20.SH RESTRICTED SHELL
17To configure a restricted shell, replace /bin/bash with /usr/bin/firejail in 21To configure a restricted shell, replace /bin/bash with /usr/bin/firejail in
18/etc/password file for each user that needs to be restricted. Alternatively, 22/etc/passwd file for each user that needs to be restricted. Alternatively,
19you can specify /usr/bin/firejail using adduser or usermod commands: 23you can specify /usr/bin/firejail using adduser or usermod commands:
20 24
21adduser \-\-shell /usr/bin/firejail username 25adduser \-\-shell /usr/bin/firejail username
@@ -34,6 +38,5 @@ Homepage: http://firejail.wordpress.com
34\&\flfiremon\fR\|(1), 38\&\flfiremon\fR\|(1),
35\&\flfirecfg\fR\|(1), 39\&\flfirecfg\fR\|(1),
36\&\flfirejail-profile\fR\|(5) 40\&\flfirejail-profile\fR\|(5)
37\&\flfirejail-config\fR\|(5)
38 41
39 42
diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt
index 9045c1122..d6113218c 100644
--- a/src/man/firejail-profile.txt
+++ b/src/man/firejail-profile.txt
@@ -44,7 +44,7 @@ To disable default profile loading, use --noprofile command option. Example:
44.RS 44.RS
45$ firejail 45$ firejail
46.br 46.br
47Reading profile /etc/firejail/generic.profile 47Reading profile /etc/firejail/default.profile
48.br 48.br
49Parent pid 8553, child pid 8554 49Parent pid 8553, child pid 8554
50.br 50.br
@@ -93,11 +93,17 @@ If the file name matches file_name, the file will not be blacklisted in any blac
93Example: "noblacklist ${HOME}/.mozilla" 93Example: "noblacklist ${HOME}/.mozilla"
94 94
95.TP 95.TP
96\fBignore command 96\fBignore
97Ignore command. 97Ignore command.
98 98
99Example: "ignore seccomp" 99Example: "ignore seccomp"
100 100
101.TP
102\fBquiet
103Disable Firejail's output. This should be the first uncommented command in the profile file.
104
105Example: "quiet"
106
101.SH Filesystem 107.SH Filesystem
102These profile entries define a chroot filesystem built on top of the existing 108These profile entries define a chroot filesystem built on top of the existing
103host filesystem. Each line describes a file element that is removed from 109host filesystem. Each line describes a file element that is removed from
@@ -122,11 +128,16 @@ blacklist ${PATH}/ifconfig
122blacklist ${HOME}/.ssh 128blacklist ${HOME}/.ssh
123 129
124.TP 130.TP
125\fBread-only file_or_directory 131\fBblacklist-nolog file_or_directory
126Make directory or file read-only. 132When --tracelog flag is set, blacklisting generates syslog messages if the sandbox tries to access the file or directory.
127.TP 133blacklist-nolog command disables syslog messages for this particular file or directory. Examples:
128\fBtmpfs directory 134.br
129Mount an empty tmpfs filesystem on top of directory. This option is available only when running the sandbox as root. 135
136.br
137blacklist-nolog /usr/bin
138.br
139blacklist-nolog /usr/bin/gcc*
140
130.TP 141.TP
131\fBbind directory1,directory2 142\fBbind directory1,directory2
132Mount-bind directory1 on top of directory2. This option is only available when running as root. 143Mount-bind directory1 on top of directory2. This option is only available when running as root.
@@ -135,8 +146,14 @@ Mount-bind directory1 on top of directory2. This option is only available when r
135Mount-bind file1 on top of file2. This option is only available when running as root. 146Mount-bind file1 on top of file2. This option is only available when running as root.
136.TP 147.TP
137\fBmkdir directory 148\fBmkdir directory
138Create a directory in user home. Use this command for whitelisted directories you need to preserve 149Create a directory in user home before the sandbox is started.
139when the sandbox is closed. Subdirectories also need to be created using mkdir. Example from 150The directory is created if it doesn't already exist.
151.br
152
153.br
154Use this command for whitelisted directories you need to preserve
155when the sandbox is closed. Without it, the application will create the directory, and the directory
156will be deleted when the sandbox is closed. Subdirectories are recursively created. Example from
140firefox profile: 157firefox profile:
141.br 158.br
142 159
@@ -145,14 +162,17 @@ mkdir ~/.mozilla
145.br 162.br
146whitelist ~/.mozilla 163whitelist ~/.mozilla
147.br 164.br
148mkdir ~/.cache
149.br
150mkdir ~/.cache/mozilla
151.br
152mkdir ~/.cache/mozilla/firefox 165mkdir ~/.cache/mozilla/firefox
153.br 166.br
154whitelist ~/.cache/mozilla/firefox 167whitelist ~/.cache/mozilla/firefox
155.TP 168.TP
169\fBmkfile file
170Similar to mkdir, this command creates a file in user home before the sandbox is started.
171The file is created if it doesn't already exist, but it's target directory has to exist.
172.TP
173\fBnoexec file_or_directory
174Remount the file or the directory noexec, nodev and nosuid.
175.TP
156\fBprivate 176\fBprivate
157Mount new /root and /home/user directories in temporary 177Mount new /root and /home/user directories in temporary
158filesystems. All modifications are discarded when the sandbox is 178filesystems. All modifications are discarded when the sandbox is
@@ -161,6 +181,12 @@ closed.
161\fBprivate directory 181\fBprivate directory
162Use directory as user home. 182Use directory as user home.
163.TP 183.TP
184\f\private-home file,directory
185Build a new user home in a temporary
186filesystem, and copy the files and directories in the list in the
187new home. All modifications are discarded when the sandbox is
188closed.
189.TP
164\fBprivate-bin file,file 190\fBprivate-bin file,file
165Build a new /bin in a temporary filesystem, and copy the programs in the list. 191Build a new /bin in a temporary filesystem, and copy the programs in the list.
166The same directory is also bind-mounted over /sbin, /usr/bin and /usr/sbin. 192The same directory is also bind-mounted over /sbin, /usr/bin and /usr/sbin.
@@ -174,19 +200,43 @@ filesystem, and copy the files and directories in the list.
174All modifications are discarded when the sandbox is closed. 200All modifications are discarded when the sandbox is closed.
175.TP 201.TP
176\fBprivate-tmp 202\fBprivate-tmp
177Mount an empty temporary filesystem on top of /tmp directory. 203Mount an empty temporary filesystem on top of /tmp directory whitelisting /tmp/.X11-unix.
178.TP 204.TP
179\fBwhitelist file_or_directory 205\fBread-only file_or_directory
180Build a new user home in a temporary filesystem, and mount-bind file_or_directory. 206Make directory or file read-only.
181The modifications to file_or_directory are persistent, everything else is discarded 207.TP
182when the sandbox is closed. 208\fBread-write file_or_directory
209Make directory or file read-write.
210.TP
211\fBtmpfs directory
212Mount an empty tmpfs filesystem on top of directory. This option is available only when running the sandbox as root.
183.TP 213.TP
184\fBtracelog 214\fBtracelog
185Blacklist violations logged to syslog. 215Blacklist violations logged to syslog.
216.TP
217\fBwhitelist file_or_directory
218Whitelist directory or file. A temporary file system is mounted on the top directory, and the
219whitelisted files are mount-binded inside. Modifications to whitelisted files are persistent,
220everything else is discarded when the sandbox is closed. The top directory could be
221user home, /dev, /media, /mnt, /opt, /srv, /var, and /tmp.
222.br
223
224.br
225Symbolic link handling: with the exception of user home, both the link and the real file should be in
226the same top directory. For user home, both the link and the real file should be owned by the user.
227.TP
228\fBwritable-etc
229Mount /etc directory read-write.
230.TP
231\fBwritable-var
232Mount /var directory read-write.
186.SH Security filters 233.SH Security filters
187The following security filters are currently implemented: 234The following security filters are currently implemented:
188 235
189.TP 236.TP
237\fBapparmor
238Enable AppArmor confinement.
239.TP
190\fBcaps 240\fBcaps
191Enable default Linux capabilities filter. 241Enable default Linux capabilities filter.
192.TP 242.TP
@@ -205,10 +255,7 @@ first argument to socket system call. Recognized values: \fBunix\fR,
205\fBinet\fR, \fBinet6\fR, \fBnetlink\fR and \fBpacket\fR. 255\fBinet\fR, \fBinet6\fR, \fBnetlink\fR and \fBpacket\fR.
206.TP 256.TP
207\fBseccomp 257\fBseccomp
208Enable default seccomp filter. The default list is as follows: 258Enable seccomp filter and blacklist the syscalls in the default list. See man 1 firejail for more details.
209mount, umount2, ptrace, kexec_load, open_by_handle_at, init_module, finit_module, delete_module,
210iopl, ioperm, swapon, swapoff, syslog, process_vm_readv and process_vm_writev,
211sysfs,_sysctl, adjtimex, clock_adjtime, lookup_dcookie, perf_event_open, fanotify_init and kcmp.
212.TP 259.TP
213\fBseccomp syscall,syscall,syscall 260\fBseccomp syscall,syscall,syscall
214Enable seccomp filter and blacklist the system calls in the list on top of default seccomp filter. 261Enable seccomp filter and blacklist the system calls in the list on top of default seccomp filter.
@@ -219,9 +266,32 @@ Enable seccomp filter and blacklist the system calls in the list.
219\fBseccomp.keep syscall,syscall,syscall 266\fBseccomp.keep syscall,syscall,syscall
220Enable seccomp filter and whitelist the system calls in the list. 267Enable seccomp filter and whitelist the system calls in the list.
221.TP 268.TP
269\fBnonewprivs
270Sets the NO_NEW_PRIVS prctl. This ensures that child processes
271cannot acquire new privileges using execve(2); in particular,
272this means that calling a suid binary (or one with file capabilities)
273does not result in an increase of privilege.
274.TP
222\fBnoroot 275\fBnoroot
223Use this command to enable an user namespace. The namespace has only one user, the current user. 276Use this command to enable an user namespace. The namespace has only one user, the current user.
224There is no root account (uid 0) defined in the namespace. 277There is no root account (uid 0) defined in the namespace.
278.TP
279\fBx11
280Enable X11 sandboxing.
281.TP
282\fBx11 none
283Blacklist /tmp/.X11-unix directory, ${HOME}/.Xauthority and file specified in ${XAUTHORITY} environment variable.
284Remove DISPLAY and XAUTHORITY environment variables.
285Stop with error message if X11 abstract socket will be accessible in jail.
286.TP
287\fBx11 xephyr
288Enable X11 sandboxing with xephyr.
289.TP
290\fBx11 xorg
291Enable X11 sandboxing with X11 security extension.
292.TP
293\fBx11 xpra
294Enable X11 sandboxing with xpra.
225 295
226.SH Resource limits, CPU affinity, Control Groups 296.SH Resource limits, CPU affinity, Control Groups
227These profile entries define the limits on system resources (rlimits) for the processes inside the sandbox. 297These profile entries define the limits on system resources (rlimits) for the processes inside the sandbox.
@@ -255,6 +325,10 @@ The sandbox is placed in g1 control group.
255 325
256.SH User Environment 326.SH User Environment
257.TP 327.TP
328\fBallusers
329All user home directories are visible inside the sandbox. By default, only current user home directory is visible.
330
331.TP
258\fBname sandboxname 332\fBname sandboxname
259Set sandbox name. Example: 333Set sandbox name. Example:
260.br 334.br
@@ -284,9 +358,18 @@ Enable IPC namespace.
284.TP 358.TP
285\fBnosound 359\fBnosound
286Disable sound system. 360Disable sound system.
361.TP
362\fBno3d
363Disable 3D hardware acceleration.
364
287.SH Networking 365.SH Networking
288Networking features available in profile files. 366Networking features available in profile files.
289 367
368.TP
369\fBdefaultgw address
370Use this address as default gateway in the new network namespace.
371
372.TP
290\fBdns address 373\fBdns address
291Set a DNS server for the sandbox. Up to three DNS servers can be defined. 374Set a DNS server for the sandbox. Up to three DNS servers can be defined.
292 375
@@ -295,6 +378,45 @@ Set a DNS server for the sandbox. Up to three DNS servers can be defined.
295Set a hostname for the sandbox. 378Set a hostname for the sandbox.
296 379
297.TP 380.TP
381\fBip address
382Assign IP addresses to the last network interface defined by a net command. A
383default gateway is assigned by default.
384.br
385
386.br
387Example:
388.br
389net eth0
390.br
391ip 10.10.20.56
392
393.TP
394\fBip none
395No IP address and no default gateway are configured for the last interface
396defined by a net command. Use this option
397in case you intend to start an external DHCP client in the sandbox.
398.br
399
400.br
401Example:
402.br
403net eth0
404.br
405ip none
406
407.TP
408\fBip6 address
409Assign IPv6 addresses to the last network interface defined by a net command.
410.br
411
412.br
413Example:
414.br
415net eth0
416.br
417ip6 2001:0db8:0:f101::1/64
418
419.TP
298\fBiprange address,address 420\fBiprange address,address
299Assign an IP address in the provided range to the last network 421Assign an IP address in the provided range to the last network
300interface defined by a net command. A default gateway is assigned by default. 422interface defined by a net command. A default gateway is assigned by default.
@@ -311,6 +433,16 @@ iprange 192.168.1.150,192.168.1.160
311.br 433.br
312 434
313.TP 435.TP
436\fBmac address
437Assign MAC addresses to the last network interface defined by a net command.
438
439.TP
440\fBmtu number
441Assign a MTU value to the last network interface defined by a net command.
442
443
444
445.TP
314\fBnetfilter 446\fBnetfilter
315If a new network namespace is created, enabled default network filter. 447If a new network namespace is created, enabled default network filter.
316 448
@@ -345,6 +477,17 @@ available in the new namespace is a new loopback interface (lo).
345Use this option to deny network access to programs that don't 477Use this option to deny network access to programs that don't
346really need network access. 478really need network access.
347 479
480.TP
481\fBveth-name name
482Use this name for the interface connected to the bridge for --net=bridge_interface commands,
483instead of the default one.
484
485.SH Other
486.TP
487\fBjoin-or-start sandboxname
488Join the sandbox identified by name or start a new one.
489Same as "firejail --join=sandboxname" command if sandbox with specified name exists, otherwise same as "name sandboxname".
490
348.SH RELOCATING PROFILES 491.SH RELOCATING PROFILES
349For various reasons some users might want to keep the profile files in a different directory. 492For various reasons some users might want to keep the profile files in a different directory.
350Using \fB--profile-path\fR command line option, Firejail can be instructed to look for profiles 493Using \fB--profile-path\fR command line option, Firejail can be instructed to look for profiles
@@ -388,7 +531,6 @@ Homepage: http://firejail.wordpress.com
388\&\flfiremon\fR\|(1), 531\&\flfiremon\fR\|(1),
389\&\flfirecfg\fR\|(1), 532\&\flfirecfg\fR\|(1),
390\&\flfirejail-login\fR\|(5) 533\&\flfirejail-login\fR\|(5)
391\&\flfirejail-config\fR\|(5)
392 534
393 535
394 536
diff --git a/src/man/firejail.txt b/src/man/firejail.txt
index 23db832c1..bb9ae270c 100644
--- a/src/man/firejail.txt
+++ b/src/man/firejail.txt
@@ -11,7 +11,7 @@ firejail [OPTIONS] [program and arguments]
11File transfer from an existing sandbox 11File transfer from an existing sandbox
12.PP 12.PP
13.RS 13.RS
14firejail {\-\-ls | \-\-get} dir_or_filename 14firejail {\-\-ls | \-\-get | \-\-put} dir_or_filename
15.RE 15.RE
16.PP 16.PP
17Network traffic shaping for an existing sandbox: 17Network traffic shaping for an existing sandbox:
@@ -50,15 +50,16 @@ of applications. The software includes security profiles for a number of more co
50Linux programs, such as Mozilla Firefox, Chromium, VLC, Transmission etc. 50Linux programs, such as Mozilla Firefox, Chromium, VLC, Transmission etc.
51 51
52.SH USAGE 52.SH USAGE
53Without any options, the sandbox consists of a chroot filesystem build in a new mount namespace, 53Without any options, the sandbox consists of a filesystem build in a new mount namespace,
54and new PID and UTS namespaces. IPC, network and user namespaces can be added using the command line options. 54and new PID and UTS namespaces. IPC, network and user namespaces can be added using the
55The default Firejail filesystem is based on the host filesystem with the main directories mounted read-only. 55command line options. The default Firejail filesystem is based on the host filesystem with the main
56Only /home and /tmp are writable. 56system directories mounted read-only. These directories are /etc, /var, /usr, /bin, /sbin, /lib, /lib32,
57/libx32 and /lib64. Only /home and /tmp are writable.
57.PP 58.PP
58As it starts up, Firejail tries to find a security profile based on the name of the application. 59As it starts up, Firejail tries to find a security profile based on the name of the application.
59If an appropriate profile is not found, Firejail will use a default profile. 60If an appropriate profile is not found, Firejail will use a default profile.
60The default profile is quite restrictive. In case the application doesn't work, use --noprofile option 61The default profile is quite restrictive. In case the application doesn't work, use --noprofile option
61to disable it. For more information, please see \fBSECURITY PROFILES\fR section. 62to disable it. For more information, please see \fBSECURITY PROFILES\fR section below.
62.PP 63.PP
63If a program argument is not specified, Firejail starts /bin/bash shell. 64If a program argument is not specified, Firejail starts /bin/bash shell.
64Examples: 65Examples:
@@ -74,6 +75,46 @@ $ firejail [OPTIONS] firefox # starting Mozilla Firefox
74\fB\-\- 75\fB\-\-
75Signal the end of options and disables further option processing. 76Signal the end of options and disables further option processing.
76.TP 77.TP
78\fB\-\-allow-debuggers
79Allow tools such as strace and gdb inside the sandbox.
80.br
81
82.br
83Example:
84.br
85$ firejail --allow-debuggers --profile=/etc/firejail/firefox.profile strace -f firefox
86.TP
87\fB\-\-allusers
88All user home directories are visible inside the sandbox. By default, only current user home directory is visible.
89.br
90
91.br
92Example:
93.br
94$ firejail --allusers
95.TP
96\fB\-\-apparmor
97Enable AppArmor confinement. For more information, please see \fBAPPARMOR\fR section below.
98.TP
99\fB\-\-appimage
100Sandbox an AppImage (http://appimage.org/) application.
101.br
102
103.br
104Example:
105.br
106$ firejail --appimage krita-3.0-x86_64.appimage
107.br
108$ firejail --appimage --private krita-3.0-x86_64.appimage
109.br
110$ firejail --appimage --net=none --x11 krita-3.0-x86_64.appimage
111.TP
112\fB\-\-audit
113Audit the sandbox, see \fBAUDIT\fR section for more details.
114.TP
115\fB\-\-audit=test-program
116Audit the sandbox, see \fBAUDIT\fR section for more details.
117.TP
77\fB\-\-bandwidth=name|pid 118\fB\-\-bandwidth=name|pid
78Set bandwidth limits for the sandbox identified by name or PID, see \fBTRAFFIC SHAPING\fR section for more details. 119Set bandwidth limits for the sandbox identified by name or PID, see \fBTRAFFIC SHAPING\fR section for more details.
79.TP 120.TP
@@ -152,14 +193,7 @@ Example:
152.br 193.br
153$ sudo firejail \-\-caps.keep=chown,net_bind_service,setgid,\\ 194$ sudo firejail \-\-caps.keep=chown,net_bind_service,setgid,\\
154setuid /etc/init.d/nginx start 195setuid /etc/init.d/nginx start
155.br
156 196
157.br
158A short note about mixing \-\-whitelist and \-\-read-only options. Whitelisted directories
159should be made read-only independently. Making a parent directory read-only, will not
160make the whitelist read-only. Example:
161.br
162$ firejail --whitelist=~/work --read-only=~/ --read-only=~/work
163.TP 197.TP
164\fB\-\-caps.print=name|pid 198\fB\-\-caps.print=name|pid
165Print the caps filter for the sandbox identified by name or by PID. 199Print the caps filter for the sandbox identified by name or by PID.
@@ -194,7 +228,8 @@ Example:
194 228
195.TP 229.TP
196\fB\-\-chroot=dirname 230\fB\-\-chroot=dirname
197Chroot the sandbox into a root filesystem. If the sandbox is started as a 231Chroot the sandbox into a root filesystem. Unlike the regular filesystem container,
232the system directories are mounted read-write. If the sandbox is started as a
198regular user, default seccomp and capabilities filters are enabled. This 233regular user, default seccomp and capabilities filters are enabled. This
199option is not available on Grsecurity systems. 234option is not available on Grsecurity systems.
200.br 235.br
@@ -465,6 +500,11 @@ in case you intend to start an external DHCP client in the sandbox.
465Example: 500Example:
466.br 501.br
467$ firejail \-\-net=eth0 \-\-\ip=none 502$ firejail \-\-net=eth0 \-\-\ip=none
503.br
504
505.br
506If the corresponding interface doesn't have an IP address configured, this
507option is enabled by default.
468 508
469.TP 509.TP
470\fB\-\-ip6=address 510\fB\-\-ip6=address
@@ -547,19 +587,19 @@ $ firejail --net=eth0 --name=browser firefox &
547.br 587.br
548# change netfilter configuration 588# change netfilter configuration
549.br 589.br
550$ sudo firejail --join-network=browser "cat /etc/firejail/nolocal.net | /sbin/iptables-restore" 590$ sudo firejail --join-network=browser bash -c "cat /etc/firejail/nolocal.net | /sbin/iptables-restore"
551.br 591.br
552 592
553.br 593.br
554# verify netfilter configuration 594# verify netfilter configuration
555.br 595.br
556$ sudo firejail --join-network=browser "/sbin/iptables -vL" 596$ sudo firejail --join-network=browser /sbin/iptables -vL
557.br 597.br
558 598
559.br 599.br
560# verify IP addresses 600# verify IP addresses
561.br 601.br
562$ sudo firejail --join-network=browser "ip addr" 602$ sudo firejail --join-network=browser ip addr
563.br 603.br
564Switching to pid 1932, the first child process inside the sandbox 604Switching to pid 1932, the first child process inside the sandbox
565.br 605.br
@@ -588,6 +628,13 @@ Switching to pid 1932, the first child process inside the sandbox
588 valid_lft forever preferred_lft forever 628 valid_lft forever preferred_lft forever
589 629
590.TP 630.TP
631\fB\-\-join-or-start=name
632Join the sandbox identified by name or start a new one.
633Same as "firejail --join=name" if sandbox with specified name exists, otherwise same as "firejail --name=name ..."
634.br
635Note that in contrary to other join options there is respective profile option.
636
637.TP
591\fB\-\-ls=name|pid dir_or_filename 638\fB\-\-ls=name|pid dir_or_filename
592List files in sandbox container, see \fBFILE TRANSFER\fR section for more details. 639List files in sandbox container, see \fBFILE TRANSFER\fR section for more details.
593 640
@@ -798,13 +845,23 @@ PID User RX(KB/s) TX(KB/s) Command
798.TP 845.TP
799\fB\-\-nice=value 846\fB\-\-nice=value
800Set nice value for all processes running inside the sandbox. 847Set nice value for all processes running inside the sandbox.
848Only root may specify a negative value.
801.br 849.br
802 850
803.br 851.br
804Example: 852Example:
805.br 853.br
806$ firejail --nice=-5 firefox 854$ firejail --nice=2 firefox
855
856.TP
857\fB\-\-no3d
858Disable 3D hardware acceleration.
859.br
807 860
861.br
862Example:
863.br
864$ firejail --no3d firefox
808 865
809.TP 866.TP
810\fB\-\-noblacklist=dirname_or_filename 867\fB\-\-noblacklist=dirname_or_filename
@@ -831,6 +888,21 @@ $ nc dict.org 2628
831220 pan.alephnull.com dictd 1.12.1/rf on Linux 3.14-1-amd64 888220 pan.alephnull.com dictd 1.12.1/rf on Linux 3.14-1-amd64
832.br 889.br
833.TP 890.TP
891\fB\-\-noexec=dirname_or_filename
892Remount directory or file noexec, nodev and nosuid.
893.br
894
895.br
896Example:
897.br
898$ firejail \-\-noexec=/tmp
899.br
900
901.br
902/etc and /var are noexec by default if the sandbox was started as a regular user. If there are more than one mount operation
903on the path of the file or directory, noexec should be applied to the last one. Always check if the change took effect inside the sandbox.
904
905.TP
834\fB\-\-nogroups 906\fB\-\-nogroups
835Disable supplementary groups. Without this option, supplementary groups are enabled for the user starting the 907Disable supplementary groups. Without this option, supplementary groups are enabled for the user starting the
836sandbox. For root user supplementary groups are always disabled. 908sandbox. For root user supplementary groups are always disabled.
@@ -865,7 +937,7 @@ Example:
865.br 937.br
866$ firejail 938$ firejail
867.br 939.br
868Reading profile /etc/firejail/generic.profile 940Reading profile /etc/firejail/default.profile
869.br 941.br
870Parent pid 8553, child pid 8554 942Parent pid 8553, child pid 8554
871.br 943.br
@@ -908,6 +980,14 @@ ping: icmp open socket: Operation not permitted
908$ 980$
909 981
910.TP 982.TP
983\fB\-\-nonewprivs
984Sets the NO_NEW_PRIVS prctl. This ensures that child processes
985cannot acquire new privileges using execve(2); in particular,
986this means that calling a suid binary (or one with file capabilities)
987does not result in an increase of privilege. This option
988is enabled by default if seccomp filter is activated.
989
990.TP
911\fB\-\-nosound 991\fB\-\-nosound
912Disable sound system. 992Disable sound system.
913.br 993.br
@@ -946,13 +1026,15 @@ $ ls -l sandboxlog*
946 1026
947.TP 1027.TP
948\fB\-\-overlay 1028\fB\-\-overlay
949Mount a filesystem overlay on top of the current filesystem. All filesystem modifications go into the overlay. 1029Mount a filesystem overlay on top of the current filesystem. Unlike the regular filesystem container,
950The overlay is stored in $HOME/.firejail directory. This option is not available on Grsecurity systems. 1030the system directories are mounted read-write. All filesystem modifications go into the overlay.
1031The overlay is stored in $HOME/.firejail/<PID> directory.
951.br 1032.br
952 1033
953.br 1034.br
954OverlayFS support is required in Linux kernel for this option to work. 1035OverlayFS support is required in Linux kernel for this option to work.
955OverlayFS was officially introduced in Linux kernel version 3.18 1036OverlayFS was officially introduced in Linux kernel version 3.18.
1037This option is not available on Grsecurity systems.
956.br 1038.br
957 1039
958.br 1040.br
@@ -961,14 +1043,34 @@ Example:
961$ firejail \-\-overlay firefox 1043$ firejail \-\-overlay firefox
962 1044
963.TP 1045.TP
1046\fB\-\-overlay-named=name
1047Mount a filesystem overlay on top of the current filesystem. Unlike the regular filesystem container,
1048the system directories are mounted read-write. All filesystem modifications go into the overlay.
1049The overlay is stored in $HOME/.firejail/<NAME> directory. The created overlay can be reused between multiple
1050sessions.
1051.br
1052
1053.br
1054OverlayFS support is required in Linux kernel for this option to work.
1055OverlayFS was officially introduced in Linux kernel version 3.18.
1056This option is not available on Grsecurity systems.
1057.br
1058
1059.br
1060Example:
1061.br
1062$ firejail \-\-overlay-named=jail1 firefox
1063
1064.TP
964\fB\-\-overlay-tmpfs 1065\fB\-\-overlay-tmpfs
965Mount a filesystem overlay on top of the current filesystem. All filesystem modifications go into the overlay, 1066Mount a filesystem overlay on top of the current filesystem. All filesystem modifications go into the overlay,
966and are discarded when the sandbox is closed. This option is not available on Grsecurity systems. 1067and are discarded when the sandbox is closed.
967.br 1068.br
968 1069
969.br 1070.br
970OverlayFS support is required in Linux kernel for this option to work. 1071OverlayFS support is required in Linux kernel for this option to work.
971OverlayFS was officially introduced in Linux kernel version 3.18 1072OverlayFS was officially introduced in Linux kernel version 3.18.
1073This option is not available on Grsecurity systems.
972.br 1074.br
973 1075
974.br 1076.br
@@ -977,6 +1079,17 @@ Example:
977$ firejail \-\-overlay-tmpfs firefox 1079$ firejail \-\-overlay-tmpfs firefox
978 1080
979.TP 1081.TP
1082\fB\-\-overlay-clean
1083Clean all overlays stored in $HOME/.firejail directory. Overlays created with --overlay-path=path
1084outside $HOME/.firejail will not be deleted.
1085.br
1086
1087.br
1088Example:
1089.br
1090$ firejail \-\-overlay-clean
1091
1092.TP
980\fB\-\-private 1093\fB\-\-private
981Mount new /root and /home/user directories in temporary 1094Mount new /root and /home/user directories in temporary
982filesystems. All modifications are discarded when the sandbox is 1095filesystems. All modifications are discarded when the sandbox is
@@ -998,9 +1111,24 @@ Example:
998$ firejail \-\-private=/home/netblue/firefox-home firefox 1111$ firejail \-\-private=/home/netblue/firefox-home firefox
999 1112
1000.TP 1113.TP
1114\fB\-\-private-home=file,directory
1115Build a new user home in a temporary
1116filesystem, and copy the files and directories in the list in the
1117new home. All modifications are discarded when the sandbox is
1118closed.
1119.br
1120
1121.br
1122Example:
1123.br
1124$ firejail \-\-private-home=.mozilla firefox
1125
1126.TP
1001\fB\-\-private-bin=file,file 1127\fB\-\-private-bin=file,file
1002Build a new /bin in a temporary filesystem, and copy the programs in the list. 1128Build a new /bin in a temporary filesystem, and copy the programs in the list.
1129If no listed file is found, /bin directory will be empty.
1003The same directory is also bind-mounted over /sbin, /usr/bin, /usr/sbin and /usr/local/bin. 1130The same directory is also bind-mounted over /sbin, /usr/bin, /usr/sbin and /usr/local/bin.
1131All modifications are discarded when the sandbox is closed.
1004.br 1132.br
1005 1133
1006.br 1134.br
@@ -1018,7 +1146,7 @@ bash cat ls sed
1018 1146
1019.TP 1147.TP
1020\fB\-\-private-dev 1148\fB\-\-private-dev
1021Create a new /dev directory. Only dri, null, full, zero, tty, pts, ptmx, random, urandom, log and shm devices are available. 1149Create a new /dev directory. Only dri, null, full, zero, tty, pts, ptmx, random, snd, urandom, log and shm devices are available.
1022.br 1150.br
1023 1151
1024.br 1152.br
@@ -1032,14 +1160,15 @@ Child process initialized
1032.br 1160.br
1033$ ls /dev 1161$ ls /dev
1034.br 1162.br
1035dri full log null ptmx pts random shm tty urandom zero 1163dri full log null ptmx pts random shm snd tty urandom zero
1036.br 1164.br
1037$ 1165$
1038.TP 1166.TP
1039\fB\-\-private-etc=file,directory 1167\fB\-\-private-etc=file,directory
1040Build a new /etc in a temporary 1168Build a new /etc in a temporary
1041filesystem, and copy the files and directories in the list. 1169filesystem, and copy the files and directories in the list.
1042All modifications are discarded when the sandbox is closed. 1170If no listed file is found, /etc directory will be empty.
1171All modifications are discarded when the sandbox is closed.
1043.br 1172.br
1044 1173
1045.br 1174.br
@@ -1051,7 +1180,7 @@ nsswitch.conf,passwd,resolv.conf
1051 1180
1052.TP 1181.TP
1053\fB\-\-private-tmp 1182\fB\-\-private-tmp
1054Mount an empty temporary filesystem on top of /tmp directory. 1183Mount an empty temporary filesystem on top of /tmp directory whitelisting /tmp/.X11-unix.
1055.br 1184.br
1056 1185
1057.br 1186.br
@@ -1120,6 +1249,9 @@ $ firejail \-\-protocol.print=3272
1120.br 1249.br
1121unix,inet,inet6,netlink 1250unix,inet,inet6,netlink
1122.TP 1251.TP
1252\fB\-\-put=name|pid src-filename dest-filename
1253Put a file in sandbox container, see \fBFILE TRANSFER\fR section for more details.
1254.TP
1123\fB\-\-quiet 1255\fB\-\-quiet
1124Turn off Firejail's output. 1256Turn off Firejail's output.
1125.TP 1257.TP
@@ -1131,6 +1263,31 @@ Set directory or file read-only.
1131Example: 1263Example:
1132.br 1264.br
1133$ firejail \-\-read-only=~/.mozilla firefox 1265$ firejail \-\-read-only=~/.mozilla firefox
1266.br
1267
1268.br
1269A short note about mixing \-\-whitelist and \-\-read-only options. Whitelisted directories
1270should be made read-only independently. Making a parent directory read-only, will not
1271make the whitelist read-only. Example:
1272.br
1273
1274.br
1275$ firejail --whitelist=~/work --read-only=~ --read-only=~/work
1276
1277.TP
1278\fB\-\-read-write=dirname_or_filename
1279Set directory or file read-write. Only files or directories belonging to the current user are allowed for
1280this operation. Example:
1281.br
1282
1283.br
1284$ mkdir ~/test
1285.br
1286$ touch ~/test/a
1287.br
1288$ firejail --read-only=~/test --read-write=~/test/a
1289
1290
1134.TP 1291.TP
1135\fB\-\-rlimit-fsize=number 1292\fB\-\-rlimit-fsize=number
1136Set the maximum file size that can be created by a process. 1293Set the maximum file size that can be created by a process.
@@ -1143,6 +1300,17 @@ Set the maximum number of processes that can be created for the real user ID of
1143.TP 1300.TP
1144\fB\-\-rlimit-sigpending=number 1301\fB\-\-rlimit-sigpending=number
1145Set the maximum number of pending signals for a process. 1302Set the maximum number of pending signals for a process.
1303
1304.TP
1305\fB\-\-rmenv=name
1306Remove environment variable in the new sandbox.
1307.br
1308
1309.br
1310Example:
1311.br
1312$ firejail \-\-rmenv=DBUS_SESSION_BUS_ADDRESS
1313
1146.TP 1314.TP
1147\fB\-\-scan 1315\fB\-\-scan
1148ARP-scan all the networks from inside a network namespace. 1316ARP-scan all the networks from inside a network namespace.
@@ -1156,13 +1324,13 @@ $ firejail \-\-net=eth0 \-\-scan
1156.TP 1324.TP
1157\fB\-\-seccomp 1325\fB\-\-seccomp
1158Enable seccomp filter and blacklist the syscalls in the default list. The default list is as follows: 1326Enable seccomp filter and blacklist the syscalls in the default list. The default list is as follows:
1159mount, umount2, ptrace, kexec_load, kexec_file_load, open_by_handle_at, init_module, finit_module, delete_module, 1327mount, umount2, ptrace, kexec_load, kexec_file_load, name_to_handle_at, open_by_handle_at, create_module, init_module, finit_module, delete_module,
1160iopl, ioperm, swapon, swapoff, syslog, process_vm_readv, process_vm_writev, 1328iopl, ioperm, ioprio_set, swapon, swapoff, syslog, process_vm_readv, process_vm_writev,
1161sysfs,_sysctl, adjtimex, clock_adjtime, lookup_dcookie, perf_event_open, fanotify_init, kcmp, 1329sysfs,_sysctl, adjtimex, clock_adjtime, lookup_dcookie, perf_event_open, fanotify_init, kcmp,
1162add_key, request_key, keyctl, uselib, acct, modify_ldt, pivot_root, io_setup, 1330add_key, request_key, keyctl, uselib, acct, modify_ldt, pivot_root, io_setup,
1163io_destroy, io_getevents, io_submit, io_cancel, 1331io_destroy, io_getevents, io_submit, io_cancel,
1164remap_file_pages, mbind, get_mempolicy, set_mempolicy, 1332remap_file_pages, mbind, get_mempolicy, set_mempolicy,
1165migrate_pages, move_pages, vmsplice, perf_event_open, chroot, 1333migrate_pages, move_pages, vmsplice, chroot,
1166tuxcall, reboot, mfsservctl and get_kernel_syms. 1334tuxcall, reboot, mfsservctl and get_kernel_syms.
1167.br 1335.br
1168 1336
@@ -1425,15 +1593,7 @@ $ firejail \-\-tree
142511969:netblue:firejail \-\-net=eth0 transmission-gtk 159311969:netblue:firejail \-\-net=eth0 transmission-gtk
1426.br 1594.br
1427 11970:netblue:transmission-gtk 1595 11970:netblue:transmission-gtk
1428.TP
1429\fB\-\-user=new-user
1430Switch the user before starting the sandbox. This command should be run as root.
1431.br
1432 1596
1433.br
1434Example:
1435.br
1436# firejail \-\-user=www-data
1437.TP 1597.TP
1438\fB\-\-version 1598\fB\-\-version
1439Print program version and exit. 1599Print program version and exit.
@@ -1445,66 +1605,106 @@ Example:
1445$ firejail \-\-version 1605$ firejail \-\-version
1446.br 1606.br
1447firejail version 0.9.27 1607firejail version 0.9.27
1608
1609.TP
1610\fB\-\-veth-name=name
1611Use this name for the interface connected to the bridge for --net=bridge_interface commands,
1612instead of the default one.
1613.br
1614
1615.br
1616Example:
1617.br
1618$ firejail \-\-net=br0 --veth-name=if0
1619
1448.TP 1620.TP
1449\fB\-\-whitelist=dirname_or_filename 1621\fB\-\-whitelist=dirname_or_filename
1450Whitelist directory or file. This feature is implemented only for user home, /dev, /media, /opt, /var, and /tmp directories. 1622Whitelist directory or file. A temporary file system is mounted on the top directory, and the
1451When whitlisting symbolic links, both the link and the real file should be in the same top directory 1623whitelisted files are mount-binded inside. Modifications to whitelisted files are persistent,
1452(home user, /media, /var etc.) 1624everything else is discarded when the sandbox is closed. The top directory could be
1625user home, /dev, /media, /mnt, /opt, /srv, /var, and /tmp.
1626.br
1627
1628.br
1629Symbolic link handling: with the exception of user home, both the link and the real file should be in
1630the same top directory. For user home, both the link and the real file should be owned by the user.
1453.br 1631.br
1454 1632
1455.br 1633.br
1456Example: 1634Example:
1457.br 1635.br
1458$ firejail \-\-whitelist=~/.mozilla \-\-whitelist=~/Downloads 1636$ firejail \-\-noprofile \-\-whitelist=~/.mozilla
1459.br 1637.br
1460$ firejail \-\-whitelist=/tmp/.X11-unix --whitelist=/dev/null 1638$ firejail \-\-whitelist=/tmp/.X11-unix --whitelist=/dev/null
1461.br 1639.br
1462$ firejail "\-\-whitelist=/home/username/My Virtual Machines" 1640$ firejail "\-\-whitelist=/home/username/My Virtual Machines"
1463 1641
1464.TP 1642.TP
1465\fB\-\-x11 1643\fB\-\-writable-etc
1466Start a new X11 server using Xpra or Xephyr and attach the sandbox to this server. 1644Mount /etc directory read-write.
1467The regular X11 server (display 0) is not visible in the sandbox. This prevents screenshot and keylogger
1468applications started in the sandbox from accessing other X11 displays.
1469A network namespace needs to be instantiated in order to deny access to X11 abstract Unix domain socket.
1470.br 1645.br
1471 1646
1472.br 1647.br
1473Firejail will try first Xpra, and if Xpra is not installed on the system, it will try to find Xephyr. 1648Example:
1474This feature is not available when running as root. 1649.br
1650$ sudo firejail --writable-etc
1651
1652.TP
1653\fB\-\-writable-var
1654Mount /var directory read-write.
1475.br 1655.br
1476 1656
1477.br 1657.br
1478Example: 1658Example:
1479.br 1659.br
1480$ firejail \-\-x11 --net=eth0 firefox 1660$ sudo firejail --writable-var
1661
1481 1662
1482.TP 1663.TP
1483\fB\-\-x11=xpra 1664\fB\-\-x11
1484Start a new X11 server using Xpra (http://xpra.org) and attach the sandbox to this server. 1665Sandbox the application using Xpra, Xephyr or Xorg security extension.
1485Xpra is a persistent remote display server and client for forwarding X11 applications and desktop screens. 1666The sandbox will prevents screenshot and keylogger applications started inside the sandbox from accessing
1486On Debian platforms Xpra is installed with the command \fBsudo apt-get install xpra\fR. 1667clients running outside the sandbox.
1487This feature is not available when running as root. 1668Firejail will try first Xpra, and if Xpra is not installed on the system, it will try to find Xephyr.
1669If all fails, Firejail will not attempt to use X11 security extension.
1670.br
1671
1672.br
1673Xpra and Xephyr modes require a network namespace to be instantiated in order to disable
1674X11 abstract Unix socket. If this is not possible, the user can disable the abstract socket
1675by adding "-nolisten local" on Xorg command line.
1488.br 1676.br
1489 1677
1490.br 1678.br
1491Example: 1679Example:
1492.br 1680.br
1493$ firejail \-\-x11=xpra --net=eth0 firefox 1681$ firejail \-\-x11 --net=eth0 firefox
1682
1683.TP
1684\fB\-\-x11=none
1685Blacklist /tmp/.X11-unix directory, ${HOME}/.Xauthority and the file specified in ${XAUTHORITY} environment variable.
1686Remove DISPLAY and XAUTHORITY environment variables.
1687Stop with error message if X11 abstract socket will be accessible in jail.
1494 1688
1495.TP 1689.TP
1496\fB\-\-x11=xephyr 1690\fB\-\-x11=xephyr
1497Start a new X11 server using Xephyr and attach the sandbox to this server. 1691Start Xephyr and attach the sandbox to this server.
1498Xephyr is a display server implementing the X11 display server protocol. 1692Xephyr is a display server implementing the X11 display server protocol.
1499It runs in a window just like other X applications, but it is an X server itself in which you can run other software. 1693A network namespace needs to be instantiated in order to deny access to X11 abstract Unix domain socket.
1500The default Xephyr window size is 800x600. This can be modified in /etc/firejail/firejail.config file, 1694.br
1501see \fBman 5 firejail-config\fR for more details. 1695
1696.br
1697Xephyr runs in a window just like any other X11 application. The default window size is 800x600.
1698This can be modified in /etc/firejail/firejail.config file.
1502.br 1699.br
1503 1700
1504.br 1701.br
1505The recommended way to use this feature is to run a window manager inside the sandbox. 1702The recommended way to use this feature is to run a window manager inside the sandbox.
1506A security profile for OpenBox is provided. 1703A security profile for OpenBox is provided.
1507On Debian platforms Xephyr is installed with the command \fBsudo apt-get install xserver-xephyr\fR. 1704.br
1705
1706.br
1707Xephyr is developed by Xorg project. On Debian platforms it is installed with the command \fBsudo apt-get install xserver-xephyr\fR.
1508This feature is not available when running as root. 1708This feature is not available when running as root.
1509.br 1709.br
1510 1710
@@ -1514,6 +1714,42 @@ Example:
1514$ firejail \-\-x11=xephyr --net=eth0 openbox 1714$ firejail \-\-x11=xephyr --net=eth0 openbox
1515 1715
1516.TP 1716.TP
1717\fB\-\-x11=xorg
1718Sandbox the application using the untrusted mode implemented by X11 security extension.
1719The extension is available in Xorg package
1720and it is installed by default on most Linux distributions. It provides support for a simple trusted/untrusted
1721connection model. Untrusted clients are restricted in certain ways to prevent them from reading window
1722contents of other clients, stealing input events, etc.
1723
1724The untrusted mode has several limitations. A lot of regular programs assume they are a trusted X11 clients
1725and will crash or lock up when run in untrusted mode. Chromium browser and xterm are two examples.
1726Firefox and transmission-gtk seem to be working fine.
1727A network namespace is not required for this option.
1728.br
1729
1730.br
1731Example:
1732.br
1733$ firejail \-\-x11=xorg firefox
1734
1735.TP
1736\fB\-\-x11=xpra
1737Start Xpra (http://xpra.org) and attach the sandbox to this server.
1738Xpra is a persistent remote display server and client for forwarding X11 applications and desktop screens.
1739A network namespace needs to be instantiated in order to deny access to X11 abstract Unix domain socket.
1740.br
1741
1742.br
1743On Debian platforms Xpra is installed with the command \fBsudo apt-get install xpra\fR.
1744This feature is not available when running as root.
1745.br
1746
1747.br
1748Example:
1749.br
1750$ firejail \-\-x11=xpra --net=eth0 firefox
1751
1752.TP
1517\fB\-\-zsh 1753\fB\-\-zsh
1518Use /usr/bin/zsh as default user shell. 1754Use /usr/bin/zsh as default user shell.
1519.br 1755.br
@@ -1576,6 +1812,44 @@ $ firejail --tree
1576 1221:netblue:/usr/lib/firefox/firefox 1812 1221:netblue:/usr/lib/firefox/firefox
1577.RE 1813.RE
1578 1814
1815.SH APPARMOR
1816.TP
1817AppArmor support is disabled by default at compile time. Use --enable-apparmor configuration option to enable it:
1818.br
1819
1820.br
1821$ ./configure --prefix=/usr --enable-apparmor
1822.TP
1823During software install, a generic AppArmor profile file, firejail-default, is placed in /etc/apparmor.d directory. The profile needs to be loaded into the kernel by running the following command as root:
1824.br
1825
1826.br
1827# aa-enforce firejail-default
1828.TP
1829The installed profile tries to replicate some advanced security features inspired by kernel-based Grsecurity:
1830.br
1831
1832.br
1833- Prevent information leakage in /proc and /sys directories. The resulting filesystem is barely enough for running
1834commands such as "top" and "ps aux".
1835.br
1836
1837.br
1838- Allow running programs only from well-known system paths, such as /bin, /sbin, /usr/bin etc. Running
1839programs and scripts from user home or other directories writable by the user is not allowed.
1840.br
1841
1842.br
1843- Disable D-Bus. D-Bus has long been a huge security hole, and most programs don't use it anyway.
1844You should have no problems running Chromium or Firefox.
1845
1846.TP
1847To 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:
1848.br
1849
1850.br
1851$ firejail --apparmor firefox
1852
1579.SH FILE TRANSFER 1853.SH FILE TRANSFER
1580These features allow the user to inspect the filesystem container of an existing sandbox 1854These features allow the user to inspect the filesystem container of an existing sandbox
1581and transfer files from the container to the host filesystem. 1855and transfer files from the container to the host filesystem.
@@ -1583,12 +1857,16 @@ and transfer files from the container to the host filesystem.
1583.TP 1857.TP
1584\fB\-\-get=name|pid filename 1858\fB\-\-get=name|pid filename
1585Retrieve the container file and store it on the host in the current working directory. 1859Retrieve the container file and store it on the host in the current working directory.
1586The container is specified by name or PID. Full path is needed for filename. 1860The container is specified by name or PID.
1587 1861
1588.TP 1862.TP
1589\fB\-\-ls=name|pid dir_or_filename 1863\fB\-\-ls=name|pid dir_or_filename
1590List container files. The container is specified by name or PID. 1864List container files. The container is specified by name or PID.
1591Full path is needed for dir_or_filename. 1865
1866.TP
1867\fB\-\-put=name|pid src-filename dest-filename
1868Put src-filename in sandbox container.
1869The container is specified by name or PID.
1592 1870
1593.TP 1871.TP
1594Examples: 1872Examples:
@@ -1614,7 +1892,11 @@ drwxr-xr-x netblue netblue 4096 ..
1614 1892
1615.br 1893.br
1616$ firejail \-\-get=mybrowser ~/Downloads/xpra-clipboard.png 1894$ firejail \-\-get=mybrowser ~/Downloads/xpra-clipboard.png
1895.br
1617 1896
1897.br
1898$ firejail \-\-put=mybrowser xpra-clipboard.png ~/Downloads/xpra-clipboard.png
1899.br
1618 1900
1619.SH TRAFFIC SHAPING 1901.SH TRAFFIC SHAPING
1620Network bandwidth is an expensive resource shared among all sandboxes running on a system. 1902Network bandwidth is an expensive resource shared among all sandboxes running on a system.
@@ -1626,15 +1908,15 @@ The shaper works at sandbox level, and can be used only for sandboxes configured
1626 1908
1627Set rate-limits: 1909Set rate-limits:
1628 1910
1629 firejail --bandwidth=name|pid set network download upload 1911 $ firejail --bandwidth=name|pid set network download upload
1630 1912
1631Clear rate-limits: 1913Clear rate-limits:
1632 1914
1633 firejail --bandwidth=name|pid clear network 1915 $ firejail --bandwidth=name|pid clear network
1634 1916
1635Status: 1917Status:
1636 1918
1637 firejail --bandwidth=name|pid status 1919 $ firejail --bandwidth=name|pid status
1638 1920
1639where: 1921where:
1640.br 1922.br
@@ -1658,6 +1940,26 @@ Example:
1658.br 1940.br
1659 $ firejail \-\-bandwidth=mybrowser clear eth0 1941 $ firejail \-\-bandwidth=mybrowser clear eth0
1660 1942
1943.SH AUDIT
1944Audit feature allows the user to point out gaps in security profiles. The
1945implementation replaces the program to be sandboxed with a test program. By
1946default, we use faudit program distributed with Firejail. A custom test program
1947can also be supplied by the user. Examples:
1948
1949Running the default audit program:
1950.br
1951 $ firejail --audit transmission-gtk
1952
1953Running a custom audit program:
1954.br
1955 $ firejail --audit=~/sandbox-test transmission-gtk
1956
1957In the examples above, the sandbox configures transmission-gtk profile and
1958starts the test program. The real program, transmission-gtk, will not be
1959started.
1960
1961Limitations: audit feature is not implemented for --x11 commands.
1962
1661.SH MONITORING 1963.SH MONITORING
1662Option \-\-list prints a list of all sandboxes. The format 1964Option \-\-list prints a list of all sandboxes. The format
1663for each process entry is as follows: 1965for each process entry is as follows:
@@ -1751,7 +2053,7 @@ To disable default profile loading, use --noprofile command option. Example:
1751.RS 2053.RS
1752$ firejail 2054$ firejail
1753.br 2055.br
1754Reading profile /etc/firejail/generic.profile 2056Reading profile /etc/firejail/default.profile
1755.br 2057.br
1756Parent pid 8553, child pid 8554 2058Parent pid 8553, child pid 8554
1757.br 2059.br
@@ -1818,7 +2120,6 @@ Homepage: http://firejail.wordpress.com
1818\&\flfirecfg\fR\|(1), 2120\&\flfirecfg\fR\|(1),
1819\&\flfirejail-profile\fR\|(5), 2121\&\flfirejail-profile\fR\|(5),
1820\&\flfirejail-login\fR\|(5) 2122\&\flfirejail-login\fR\|(5)
1821\&\flfirejail-config\fR\|(5)
1822 2123
1823 2124
1824 2125
diff --git a/src/man/firemon.txt b/src/man/firemon.txt
index ef99b0927..bd84401af 100644
--- a/src/man/firemon.txt
+++ b/src/man/firemon.txt
@@ -109,6 +109,5 @@ Homepage: http://firejail.wordpress.com
109\&\flfirecfg\fR\|(1), 109\&\flfirecfg\fR\|(1),
110\&\flfirejail-profile\fR\|(5), 110\&\flfirejail-profile\fR\|(5),
111\&\flfirejail-login\fR\|(5) 111\&\flfirejail-login\fR\|(5)
112\&\flfirejail-config\fR\|(5)
113 112
114 113
diff --git a/src/tools/mkcoverit.sh b/src/tools/mkcoverit.sh
index 4af84a7a1..65b06f9fa 100755
--- a/src/tools/mkcoverit.sh
+++ b/src/tools/mkcoverit.sh
@@ -1,13 +1,13 @@
1#!/bin/bash 1#!/bin/bash
2 2
3# unpack firejail archive 3# unpack firejail archive
4ARCFIREJAIL=`ls *.tar.bz2| grep firejail` 4ARCFIREJAIL=`ls *.tar.xz| grep firejail`
5if [ "$?" -eq 0 ]; 5if [ "$?" -eq 0 ];
6then 6then
7 echo "preparing $ARCFIREJAIL" 7 echo "preparing $ARCFIREJAIL"
8 DIRFIREJAIL=`basename $ARCFIREJAIL .tar.bz2` 8 DIRFIREJAIL=`basename $ARCFIREJAIL .tar.xz`
9 rm -fr $DIRFIREJAIL 9 rm -fr $DIRFIREJAIL
10 tar -xjvf $ARCFIREJAIL 10 tar -xJvf $ARCFIREJAIL
11 cd $DIRFIREJAIL 11 cd $DIRFIREJAIL
12 ./configure --prefix=/usr 12 ./configure --prefix=/usr
13 cd .. 13 cd ..
diff --git a/test/appimage/Leafpad-0.8.17-x86_64.AppImage b/test/appimage/Leafpad-0.8.17-x86_64.AppImage
new file mode 100644
index 000000000..865f6b44c
--- /dev/null
+++ b/test/appimage/Leafpad-0.8.17-x86_64.AppImage
Binary files differ
diff --git a/test/appimage/Leafpad-0.8.18.1.glibc2.4-x86_64.AppImage b/test/appimage/Leafpad-0.8.18.1.glibc2.4-x86_64.AppImage
new file mode 100644
index 000000000..d167431f3
--- /dev/null
+++ b/test/appimage/Leafpad-0.8.18.1.glibc2.4-x86_64.AppImage
Binary files differ
diff --git a/test/appimage/appimage-v1.exp b/test/appimage/appimage-v1.exp
new file mode 100755
index 000000000..503da2b9b
--- /dev/null
+++ b/test/appimage/appimage-v1.exp
@@ -0,0 +1,85 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --name=appimage-test --appimage Leafpad-0.8.17-x86_64.AppImage\r"
11expect {
12 timeout {puts "TESTING ERROR 1\n";exit}
13 "Child process initialized"
14}
15sleep 2
16
17spawn $env(SHELL)
18send -- "firejail --list\r"
19expect {
20 timeout {puts "TESTING ERROR 3\n";exit}
21 ":firejail"
22}
23expect {
24 timeout {puts "TESTING ERROR 3.1\n";exit}
25 "appimage Leafpad"
26}
27after 100
28
29# grsecurity exit
30send -- "file /proc/sys/kernel/grsecurity\r"
31expect {
32 timeout {puts "TESTING ERROR - grsecurity detection\n";exit}
33 "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit}
34 "cannot open" {puts "grsecurity not present\n"}
35}
36
37
38send -- "firejail --name=blablabla\r"
39expect {
40 timeout {puts "TESTING ERROR 4\n";exit}
41 "Child process initialized"
42}
43sleep 2
44
45spawn $env(SHELL)
46send -- "firemon --seccomp\r"
47expect {
48 timeout {puts "TESTING ERROR 5\n";exit}
49 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
50 "appimage Leafpad"
51}
52expect {
53 timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit}
54 "Seccomp: 2"
55}
56expect {
57 timeout {puts "TESTING ERROR 5.1\n";exit}
58 "name=blablabla"
59}
60after 100
61send -- "firemon --caps\r"
62expect {
63 timeout {puts "TESTING ERROR 6\n";exit}
64 "appimage Leafpad"
65}
66expect {
67 timeout {puts "TESTING ERROR 6.1\n";exit}
68 "CapBnd:"
69}
70expect {
71 timeout {puts "TESTING ERROR 6.2\n";exit}
72 "0000000000000000"
73}
74expect {
75 timeout {puts "TESTING ERROR 6.3\n";exit}
76 "name=blablabla"
77}
78after 100
79
80spawn $env(SHELL)
81send -- "firejail --shutdown=appimage-test\r"
82sleep 3
83
84puts "\nall done\n"
85
diff --git a/test/appimage/appimage-v2.exp b/test/appimage/appimage-v2.exp
new file mode 100755
index 000000000..5cb9d0849
--- /dev/null
+++ b/test/appimage/appimage-v2.exp
@@ -0,0 +1,85 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --appimage Leafpad-0.8.18.1.glibc2.4-x86_64.AppImage\r"
11expect {
12 timeout {puts "TESTING ERROR 1\n";exit}
13 "Child process initialized"
14}
15sleep 2
16
17spawn $env(SHELL)
18send -- "firejail --list\r"
19expect {
20 timeout {puts "TESTING ERROR 3\n";exit}
21 ":firejail"
22}
23expect {
24 timeout {puts "TESTING ERROR 3.1\n";exit}
25 "appimage Leafpad"
26}
27after 100
28
29# grsecurity exit
30send -- "file /proc/sys/kernel/grsecurity\r"
31expect {
32 timeout {puts "TESTING ERROR - grsecurity detection\n";exit}
33 "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit}
34 "cannot open" {puts "grsecurity not present\n"}
35}
36
37
38send -- "firejail --name=blablabla\r"
39expect {
40 timeout {puts "TESTING ERROR 4\n";exit}
41 "Child process initialized"
42}
43sleep 2
44
45spawn $env(SHELL)
46send -- "firemon --seccomp\r"
47expect {
48 timeout {puts "TESTING ERROR 5\n";exit}
49 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
50 "appimage Leafpad"
51}
52expect {
53 timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit}
54 "Seccomp: 2"
55}
56expect {
57 timeout {puts "TESTING ERROR 5.1\n";exit}
58 "name=blablabla"
59}
60after 100
61send -- "firemon --caps\r"
62expect {
63 timeout {puts "TESTING ERROR 6\n";exit}
64 "appimage Leafpad"
65}
66expect {
67 timeout {puts "TESTING ERROR 6.1\n";exit}
68 "CapBnd:"
69}
70expect {
71 timeout {puts "TESTING ERROR 6.2\n";exit}
72 "0000000000000000"
73}
74expect {
75 timeout {puts "TESTING ERROR 6.3\n";exit}
76 "name=blablabla"
77}
78after 100
79
80spawn $env(SHELL)
81send -- "firejail --shutdown=appimage-test\r"
82sleep 3
83
84puts "\nall done\n"
85
diff --git a/test/appimage/appimage.sh b/test/appimage/appimage.sh
new file mode 100755
index 000000000..6a73d0a7e
--- /dev/null
+++ b/test/appimage/appimage.sh
@@ -0,0 +1,14 @@
1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6export MALLOC_CHECK_=3
7export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
8
9echo "TESTING: AppImage v1 (test/appimage/appimage-v1.exp)"
10./appimage-v1.exp
11
12echo "TESTING: AppImage v2 (test/appimage/appimage-v2.exp)"
13./appimage-v1.exp
14
diff --git a/test/apps-x11-xorg/apps-x11-xorg.sh b/test/apps-x11-xorg/apps-x11-xorg.sh
new file mode 100755
index 000000000..b05914b52
--- /dev/null
+++ b/test/apps-x11-xorg/apps-x11-xorg.sh
@@ -0,0 +1,35 @@
1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6export MALLOC_CHECK_=3
7export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
8
9which firefox
10if [ "$?" -eq 0 ];
11then
12 echo "TESTING: firefox x11 xorg"
13 ./firefox.exp
14else
15 echo "TESTING SKIP: firefox not found"
16fi
17
18which transmission-gtk
19if [ "$?" -eq 0 ];
20then
21 echo "TESTING: transmission-gtk x11 xorg"
22 ./transmission-gtk.exp
23else
24 echo "TESTING SKIP: transmission-gtk not found"
25fi
26
27which icedove
28if [ "$?" -eq 0 ];
29then
30 echo "TESTING: icedove x11 xorg"
31 ./icedove.exp
32else
33 echo "TESTING SKIP: icedove not found"
34fi
35
diff --git a/test/apps-x11-xorg/firefox.exp b/test/apps-x11-xorg/firefox.exp
new file mode 100755
index 000000000..66b82fe92
--- /dev/null
+++ b/test/apps-x11-xorg/firefox.exp
@@ -0,0 +1,91 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --name=test --x11=xorg firefox -no-remote www.gentoo.org\r"
11sleep 10
12
13spawn $env(SHELL)
14send -- "firejail --list\r"
15expect {
16 timeout {puts "TESTING ERROR 3\n";exit}
17 ":firejail"
18}
19expect {
20 timeout {puts "TESTING ERROR 3.1\n";exit}
21 "firefox" {puts "firefox detected\n";}
22 "iceweasel" {puts "iceweasel detected\n";}
23}
24expect {
25 timeout {puts "TESTING ERROR 3.2\n";exit}
26 "no-remote"
27}
28sleep 1
29# grsecurity exit
30send -- "file /proc/sys/kernel/grsecurity\r"
31expect {
32 timeout {puts "TESTING ERROR - grsecurity detection\n";exit}
33 "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit}
34 "cannot open" {puts "grsecurity not present\n"}
35}
36send -- "firejail --name=blablabla\r"
37expect {
38 timeout {puts "TESTING ERROR 4\n";exit}
39 "Child process initialized"
40}
41sleep 2
42
43spawn $env(SHELL)
44send -- "firemon --seccomp\r"
45expect {
46 timeout {puts "TESTING ERROR 5\n";exit}
47 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
48 " firefox" {puts "firefox detected\n";}
49 " iceweasel" {puts "iceweasel detected\n";}
50}
51expect {
52 timeout {puts "TESTING ERROR 5.0\n";exit}
53 "no-remote"
54}
55expect {
56 timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit}
57 "Seccomp: 2"
58}
59expect {
60 timeout {puts "TESTING ERROR 5.1\n";exit}
61 "name=blablabla"
62}
63sleep 1
64send -- "firemon --caps\r"
65expect {
66 timeout {puts "TESTING ERROR 6\n";exit}
67 " firefox" {puts "firefox detected\n";}
68 " iceweasel" {puts "iceweasel detected\n";}
69}
70expect {
71 timeout {puts "TESTING ERROR 6.0\n";exit}
72 "no-remote"
73}
74expect {
75 timeout {puts "TESTING ERROR 6.1\n";exit}
76 "CapBnd:"
77}
78expect {
79 timeout {puts "TESTING ERROR 6.2\n";exit}
80 "0000000000000000"
81}
82expect {
83 timeout {puts "TESTING ERROR 6.3\n";exit}
84 "name=blablabla"
85}
86sleep 1
87send -- "firejail --shutdown=test\r"
88sleep 3
89
90puts "\nall done\n"
91
diff --git a/test/apps-x11-xorg/icedove.exp b/test/apps-x11-xorg/icedove.exp
new file mode 100755
index 000000000..667c2259f
--- /dev/null
+++ b/test/apps-x11-xorg/icedove.exp
@@ -0,0 +1,86 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --name=test --x11=xorg icedove\r"
11sleep 10
12
13spawn $env(SHELL)
14send -- "firejail --list\r"
15expect {
16 timeout {puts "TESTING ERROR 3\n";exit}
17 ":firejail"
18}
19expect {
20 timeout {puts "TESTING ERROR 3.1\n";exit}
21 "icedove"
22}
23sleep 1
24
25# grsecurity exit
26send -- "file /proc/sys/kernel/grsecurity\r"
27expect {
28 timeout {puts "TESTING ERROR - grsecurity detection\n";exit}
29 "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit}
30 "cannot open" {puts "grsecurity not present\n"}
31}
32
33send -- "firejail --name=blablabla\r"
34expect {
35 timeout {puts "TESTING ERROR 4\n";exit}
36 "Child process initialized"
37}
38sleep 2
39
40spawn $env(SHELL)
41send -- "firemon --seccomp\r"
42expect {
43 timeout {puts "TESTING ERROR 5\n";exit}
44 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
45 ":firejail"
46}
47expect {
48 timeout {puts "TESTING ERROR 5.0\n";exit}
49 "icedove"
50}
51expect {
52 timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit}
53 "Seccomp: 2"
54}
55expect {
56 timeout {puts "TESTING ERROR 5.1\n";exit}
57 "name=blablabla"
58}
59sleep 2
60send -- "firemon --caps\r"
61expect {
62 timeout {puts "TESTING ERROR 6\n";exit}
63 ":firejail"
64}
65expect {
66 timeout {puts "TESTING ERROR 6.0\n";exit}
67 "icedove"
68}
69expect {
70 timeout {puts "TESTING ERROR 6.1\n";exit}
71 "CapBnd"
72}
73expect {
74 timeout {puts "TESTING ERROR 6.2\n";exit}
75 "0000000000000000"
76}
77expect {
78 timeout {puts "TESTING ERROR 6.3\n";exit}
79 "name=blablabla"
80}
81sleep 1
82send -- "firejail --shutdown=test\r"
83sleep 3
84
85puts "\nall done\n"
86
diff --git a/test/apps-x11-xorg/transmission-gtk.exp b/test/apps-x11-xorg/transmission-gtk.exp
new file mode 100755
index 000000000..c52cb5b3a
--- /dev/null
+++ b/test/apps-x11-xorg/transmission-gtk.exp
@@ -0,0 +1,86 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --name=test --x11=xorg transmission-gtk\r"
11sleep 10
12
13spawn $env(SHELL)
14send -- "firejail --list\r"
15expect {
16 timeout {puts "TESTING ERROR 3\n";exit}
17 ":firejail"
18}
19expect {
20 timeout {puts "TESTING ERROR 3.1\n";exit}
21 "transmission-gtk"
22}
23sleep 1
24
25# grsecurity exit
26send -- "file /proc/sys/kernel/grsecurity\r"
27expect {
28 timeout {puts "TESTING ERROR - grsecurity detection\n";exit}
29 "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit}
30 "cannot open" {puts "grsecurity not present\n"}
31}
32
33send -- "firejail --name=blablabla\r"
34expect {
35 timeout {puts "TESTING ERROR 4\n";exit}
36 "Child process initialized"
37}
38sleep 2
39
40spawn $env(SHELL)
41send -- "firemon --seccomp\r"
42expect {
43 timeout {puts "TESTING ERROR 5\n";exit}
44 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
45 ":firejail"
46}
47expect {
48 timeout {puts "TESTING ERROR 5.0\n";exit}
49 "transmission-gtk"
50}
51expect {
52 timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit}
53 "Seccomp: 2"
54}
55expect {
56 timeout {puts "TESTING ERROR 5.1\n";exit}
57 "name=blablabla"
58}
59sleep 1
60send -- "firemon --caps\r"
61expect {
62 timeout {puts "TESTING ERROR 6\n";exit}
63 ":firejail"
64}
65expect {
66 timeout {puts "TESTING ERROR 6.0\n";exit}
67 "transmission-gtk"
68}
69expect {
70 timeout {puts "TESTING ERROR 6.1\n";exit}
71 "CapBnd"
72}
73expect {
74 timeout {puts "TESTING ERROR 6.2\n";exit}
75 "0000000000000000"
76}
77expect {
78 timeout {puts "TESTING ERROR 6.3\n";exit}
79 "name=blablabla"
80}
81sleep 1
82send -- "firejail --shutdown=test\r"
83sleep 3
84
85puts "\nall done\n"
86
diff --git a/test/apps-x11/apps-x11.sh b/test/apps-x11/apps-x11.sh
new file mode 100755
index 000000000..4a8671dbd
--- /dev/null
+++ b/test/apps-x11/apps-x11.sh
@@ -0,0 +1,88 @@
1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6export MALLOC_CHECK_=3
7export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
8
9echo "TESTING: no x11 (test/apps-x11/x11-none.exp)"
10./x11-none.exp
11
12
13which xterm
14if [ "$?" -eq 0 ];
15then
16 echo "TESTING: xterm x11 xorg"
17 ./xterm-xorg.exp
18
19 which xpra
20 if [ "$?" -eq 0 ];
21 then
22 echo "TESTING: xterm x11 xpra"
23 ./xterm-xpra.exp
24 fi
25
26 which Xephyr
27 if [ "$?" -eq 0 ];
28 then
29 echo "TESTING: xterm x11 xephyr"
30 ./xterm-xephyr.exp
31 fi
32else
33 echo "TESTING SKIP: xterm not found"
34fi
35
36# check xpra/xephyr
37which xpra
38if [ "$?" -eq 0 ];
39then
40 echo "xpra found"
41else
42 echo "xpra not found"
43 which Xephyr
44 if [ "$?" -eq 0 ];
45 then
46 echo "Xephyr found"
47 else
48 echo "TESTING SKIP: xpra and/or Xephyr not found"
49 exit
50 fi
51fi
52
53which firefox
54if [ "$?" -eq 0 ];
55then
56 echo "TESTING: firefox x11"
57 ./firefox.exp
58else
59 echo "TESTING SKIP: firefox not found"
60fi
61
62which chromium
63if [ "$?" -eq 0 ];
64then
65 echo "TESTING: chromium x11"
66 ./chromium.exp
67else
68 echo "TESTING SKIP: chromium not found"
69fi
70
71which transmission-gtk
72if [ "$?" -eq 0 ];
73then
74 echo "TESTING: transmission-gtk x11"
75 ./transmission-gtk.exp
76else
77 echo "TESTING SKIP: transmission-gtk not found"
78fi
79
80which icedove
81if [ "$?" -eq 0 ];
82then
83 echo "TESTING: icedove x11"
84 ./icedove.exp
85else
86 echo "TESTING SKIP: icedove not found"
87fi
88
diff --git a/test/chromium-x11.exp b/test/apps-x11/chromium.exp
index bcac3233c..2505c0c37 100755
--- a/test/chromium-x11.exp
+++ b/test/apps-x11/chromium.exp
@@ -1,10 +1,13 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
5match_max 100000 8match_max 100000
6 9
7send -- "firejail --name=test --x11 --net=br0 chromium www.gentoo.org\r" 10send -- "firejail --name=test --x11 chromium www.gentoo.org\r"
8sleep 10 11sleep 10
9 12
10spawn $env(SHELL) 13spawn $env(SHELL)
@@ -37,6 +40,7 @@ spawn $env(SHELL)
37send -- "firemon --seccomp\r" 40send -- "firemon --seccomp\r"
38expect { 41expect {
39 timeout {puts "TESTING ERROR 5\n";exit} 42 timeout {puts "TESTING ERROR 5\n";exit}
43 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
40 ":firejail" 44 ":firejail"
41} 45}
42expect { 46expect {
diff --git a/test/apps-x11/firefox.exp b/test/apps-x11/firefox.exp
new file mode 100755
index 000000000..6a50c8884
--- /dev/null
+++ b/test/apps-x11/firefox.exp
@@ -0,0 +1,91 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --name=test --x11 firefox -no-remote www.gentoo.org\r"
11sleep 10
12
13spawn $env(SHELL)
14send -- "firejail --list\r"
15expect {
16 timeout {puts "TESTING ERROR 3\n";exit}
17 ":firejail"
18}
19expect {
20 timeout {puts "TESTING ERROR 3.1\n";exit}
21 "firefox" {puts "firefox detected\n";}
22 "iceweasel" {puts "iceweasel detected\n";}
23}
24expect {
25 timeout {puts "TESTING ERROR 3.2\n";exit}
26 "no-remote"
27}
28sleep 1
29# grsecurity exit
30send -- "file /proc/sys/kernel/grsecurity\r"
31expect {
32 timeout {puts "TESTING ERROR - grsecurity detection\n";exit}
33 "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit}
34 "cannot open" {puts "grsecurity not present\n"}
35}
36send -- "firejail --name=blablabla\r"
37expect {
38 timeout {puts "TESTING ERROR 4\n";exit}
39 "Child process initialized"
40}
41sleep 2
42
43spawn $env(SHELL)
44send -- "firemon --seccomp\r"
45expect {
46 timeout {puts "TESTING ERROR 5\n";exit}
47 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
48 " firefox" {puts "firefox detected\n";}
49 " iceweasel" {puts "iceweasel detected\n";}
50}
51expect {
52 timeout {puts "TESTING ERROR 5.0\n";exit}
53 "no-remote"
54}
55expect {
56 timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit}
57 "Seccomp: 2"
58}
59expect {
60 timeout {puts "TESTING ERROR 5.1\n";exit}
61 "name=blablabla"
62}
63sleep 1
64send -- "firemon --caps\r"
65expect {
66 timeout {puts "TESTING ERROR 6\n";exit}
67 " firefox" {puts "firefox detected\n";}
68 " iceweasel" {puts "iceweasel detected\n";}
69}
70expect {
71 timeout {puts "TESTING ERROR 6.0\n";exit}
72 "no-remote"
73}
74expect {
75 timeout {puts "TESTING ERROR 6.1\n";exit}
76 "CapBnd:"
77}
78expect {
79 timeout {puts "TESTING ERROR 6.2\n";exit}
80 "0000000000000000"
81}
82expect {
83 timeout {puts "TESTING ERROR 6.3\n";exit}
84 "name=blablabla"
85}
86sleep 1
87send -- "firejail --shutdown=test\r"
88sleep 3
89
90puts "\nall done\n"
91
diff --git a/test/apps-x11/icedove.exp b/test/apps-x11/icedove.exp
new file mode 100755
index 000000000..e306e33ce
--- /dev/null
+++ b/test/apps-x11/icedove.exp
@@ -0,0 +1,86 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --name=test --x11 icedove\r"
11sleep 10
12
13spawn $env(SHELL)
14send -- "firejail --list\r"
15expect {
16 timeout {puts "TESTING ERROR 3\n";exit}
17 ":firejail"
18}
19expect {
20 timeout {puts "TESTING ERROR 3.1\n";exit}
21 "icedove"
22}
23sleep 1
24
25# grsecurity exit
26send -- "file /proc/sys/kernel/grsecurity\r"
27expect {
28 timeout {puts "TESTING ERROR - grsecurity detection\n";exit}
29 "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit}
30 "cannot open" {puts "grsecurity not present\n"}
31}
32
33send -- "firejail --name=blablabla\r"
34expect {
35 timeout {puts "TESTING ERROR 4\n";exit}
36 "Child process initialized"
37}
38sleep 2
39
40spawn $env(SHELL)
41send -- "firemon --seccomp\r"
42expect {
43 timeout {puts "TESTING ERROR 5\n";exit}
44 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
45 ":firejail"
46}
47expect {
48 timeout {puts "TESTING ERROR 5.0\n";exit}
49 "icedove"
50}
51expect {
52 timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit}
53 "Seccomp: 2"
54}
55expect {
56 timeout {puts "TESTING ERROR 5.1\n";exit}
57 "name=blablabla"
58}
59sleep 2
60send -- "firemon --caps\r"
61expect {
62 timeout {puts "TESTING ERROR 6\n";exit}
63 ":firejail"
64}
65expect {
66 timeout {puts "TESTING ERROR 6.0\n";exit}
67 "icedove"
68}
69expect {
70 timeout {puts "TESTING ERROR 6.1\n";exit}
71 "CapBnd"
72}
73expect {
74 timeout {puts "TESTING ERROR 6.2\n";exit}
75 "0000000000000000"
76}
77expect {
78 timeout {puts "TESTING ERROR 6.3\n";exit}
79 "name=blablabla"
80}
81sleep 1
82send -- "firejail --shutdown=test\r"
83sleep 3
84
85puts "\nall done\n"
86
diff --git a/test/transmission-gtk-x11.exp b/test/apps-x11/transmission-gtk.exp
index 4ee3de701..4083a121f 100755
--- a/test/transmission-gtk-x11.exp
+++ b/test/apps-x11/transmission-gtk.exp
@@ -1,10 +1,13 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
5match_max 100000 8match_max 100000
6 9
7send -- "firejail --name=test --net=br0 --x11 transmission-gtk\r" 10send -- "firejail --name=test --x11 transmission-gtk\r"
8sleep 10 11sleep 10
9 12
10spawn $env(SHELL) 13spawn $env(SHELL)
@@ -38,6 +41,7 @@ spawn $env(SHELL)
38send -- "firemon --seccomp\r" 41send -- "firemon --seccomp\r"
39expect { 42expect {
40 timeout {puts "TESTING ERROR 5\n";exit} 43 timeout {puts "TESTING ERROR 5\n";exit}
44 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
41 ":firejail" 45 ":firejail"
42} 46}
43expect { 47expect {
diff --git a/test/apps-x11/x11-none.exp b/test/apps-x11/x11-none.exp
new file mode 100755
index 000000000..e9908839b
--- /dev/null
+++ b/test/apps-x11/x11-none.exp
@@ -0,0 +1,48 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --name=test --x11=none\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "use network namespace in firejail"
14}
15sleep 1
16
17send -- "firejail --name=test --net=none --x11=none\r"
18expect {
19 timeout {puts "TESTING ERROR 1\n";exit}
20 "Child process initialized"
21}
22sleep 1
23
24send -- "ls -al /tmp/.X11-unix\r"
25expect {
26 timeout {puts "TESTING ERROR 2\n";exit}
27 "cannot open directory"
28}
29after 100
30
31send -- "xterm\r"
32expect {
33 timeout {puts "TESTING ERROR 3\n";exit}
34 "DISPLAY is not set"
35}
36after 100
37
38send -- "export DISPLAY=:0.0\r"
39after 100
40send -- "xterm\r"
41expect {
42 timeout {puts "TESTING ERROR 4\n";exit}
43 "Xt error"
44}
45after 100
46
47puts "\nall done\n"
48
diff --git a/test/apps-x11/x11-xephyr.exp b/test/apps-x11/x11-xephyr.exp
new file mode 100755
index 000000000..41a413890
--- /dev/null
+++ b/test/apps-x11/x11-xephyr.exp
@@ -0,0 +1,59 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --name=test --x11=xephyr xterm\r"
11expect {
12 timeout {puts "TESTING ERROR 1\n";exit}
13 "Child process initialized"
14}
15
16exit
17
18
19sleep 5
20
21
22expect {
23 timeout {puts "TESTING ERROR 0\n";exit}
24 "use network namespace in firejail"
25}
26sleep 1
27
28send -- "firejail --name=test --net=none --x11=none\r"
29expect {
30 timeout {puts "TESTING ERROR 1\n";exit}
31 "Child process initialized"
32}
33sleep 1
34
35send -- "ls -al /tmp/.X11-unix\r"
36expect {
37 timeout {puts "TESTING ERROR 2\n";exit}
38 "cannot open directory"
39}
40after 100
41
42send -- "xterm\r"
43expect {
44 timeout {puts "TESTING ERROR 3\n";exit}
45 "DISPLAY is not set"
46}
47after 100
48
49send -- "export DISPLAY=:0.0\r"
50after 100
51send -- "xterm\r"
52expect {
53 timeout {puts "TESTING ERROR 4\n";exit}
54 "Xt error"
55}
56after 100
57
58puts "\nall done\n"
59
diff --git a/test/apps-x11/xterm-xephyr.exp b/test/apps-x11/xterm-xephyr.exp
new file mode 100755
index 000000000..5b4299478
--- /dev/null
+++ b/test/apps-x11/xterm-xephyr.exp
@@ -0,0 +1,86 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --name=test --x11=xephyr xterm\r"
11sleep 10
12
13spawn $env(SHELL)
14send -- "firejail --list\r"
15expect {
16 timeout {puts "TESTING ERROR 3\n";exit}
17 ":firejail"
18}
19expect {
20 timeout {puts "TESTING ERROR 3.1\n";exit}
21 "xterm"
22}
23sleep 1
24
25# grsecurity exit
26send -- "file /proc/sys/kernel/grsecurity\r"
27expect {
28 timeout {puts "TESTING ERROR - grsecurity detection\n";exit}
29 "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit}
30 "cannot open" {puts "grsecurity not present\n"}
31}
32
33send -- "firejail --name=blablabla\r"
34expect {
35 timeout {puts "TESTING ERROR 4\n";exit}
36 "Child process initialized"
37}
38sleep 2
39
40spawn $env(SHELL)
41send -- "firemon --seccomp\r"
42expect {
43 timeout {puts "TESTING ERROR 5\n";exit}
44 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
45 ":firejail"
46}
47expect {
48 timeout {puts "TESTING ERROR 5.0\n";exit}
49 "xterm"
50}
51expect {
52 timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit}
53 "Seccomp: 2"
54}
55expect {
56 timeout {puts "TESTING ERROR 5.1\n";exit}
57 "name=blablabla"
58}
59sleep 1
60send -- "firemon --caps\r"
61expect {
62 timeout {puts "TESTING ERROR 6\n";exit}
63 ":firejail"
64}
65expect {
66 timeout {puts "TESTING ERROR 6.0\n";exit}
67 "xterm"
68}
69expect {
70 timeout {puts "TESTING ERROR 6.1\n";exit}
71 "CapBnd"
72}
73expect {
74 timeout {puts "TESTING ERROR 6.2\n";exit}
75 "0000000000000000"
76}
77expect {
78 timeout {puts "TESTING ERROR 6.3\n";exit}
79 "name=blablabla"
80}
81sleep 1
82send -- "firejail --shutdown=test\r"
83sleep 3
84
85puts "\nall done\n"
86
diff --git a/test/apps-x11/xterm-xorg.exp b/test/apps-x11/xterm-xorg.exp
new file mode 100755
index 000000000..fbc88f196
--- /dev/null
+++ b/test/apps-x11/xterm-xorg.exp
@@ -0,0 +1,86 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --name=test --x11=xorg xterm\r"
11sleep 10
12
13spawn $env(SHELL)
14send -- "firejail --list\r"
15expect {
16 timeout {puts "TESTING ERROR 3\n";exit}
17 ":firejail"
18}
19expect {
20 timeout {puts "TESTING ERROR 3.1\n";exit}
21 "xterm"
22}
23sleep 1
24
25# grsecurity exit
26send -- "file /proc/sys/kernel/grsecurity\r"
27expect {
28 timeout {puts "TESTING ERROR - grsecurity detection\n";exit}
29 "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit}
30 "cannot open" {puts "grsecurity not present\n"}
31}
32
33send -- "firejail --name=blablabla\r"
34expect {
35 timeout {puts "TESTING ERROR 4\n";exit}
36 "Child process initialized"
37}
38sleep 2
39
40spawn $env(SHELL)
41send -- "firemon --seccomp\r"
42expect {
43 timeout {puts "TESTING ERROR 5\n";exit}
44 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
45 ":firejail"
46}
47expect {
48 timeout {puts "TESTING ERROR 5.0\n";exit}
49 "xterm"
50}
51expect {
52 timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit}
53 "Seccomp: 2"
54}
55expect {
56 timeout {puts "TESTING ERROR 5.1\n";exit}
57 "name=blablabla"
58}
59sleep 1
60send -- "firemon --caps\r"
61expect {
62 timeout {puts "TESTING ERROR 6\n";exit}
63 ":firejail"
64}
65expect {
66 timeout {puts "TESTING ERROR 6.0\n";exit}
67 "xterm"
68}
69expect {
70 timeout {puts "TESTING ERROR 6.1\n";exit}
71 "CapBnd"
72}
73expect {
74 timeout {puts "TESTING ERROR 6.2\n";exit}
75 "0000000000000000"
76}
77expect {
78 timeout {puts "TESTING ERROR 6.3\n";exit}
79 "name=blablabla"
80}
81sleep 1
82send -- "firejail --shutdown=test\r"
83sleep 3
84
85puts "\nall done\n"
86
diff --git a/test/apps-x11/xterm-xpra.exp b/test/apps-x11/xterm-xpra.exp
new file mode 100755
index 000000000..1fb5df486
--- /dev/null
+++ b/test/apps-x11/xterm-xpra.exp
@@ -0,0 +1,98 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --name=test --x11=xpra xterm\r"
11sleep 10
12
13spawn $env(SHELL)
14send -- "firejail --list\r"
15expect {
16 timeout {puts "TESTING ERROR 3\n";exit}
17 ":firejail"
18}
19expect {
20 timeout {puts "TESTING ERROR 3.1\n";exit}
21 "xterm"
22}
23sleep 1
24
25# grsecurity exit
26send -- "file /proc/sys/kernel/grsecurity\r"
27expect {
28 timeout {puts "TESTING ERROR - grsecurity detection\n";exit}
29 "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit}
30 "cannot open" {puts "grsecurity not present\n"}
31}
32
33send -- "firejail --name=blablabla\r"
34expect {
35 timeout {puts "TESTING ERROR 4\n";exit}
36 "Child process initialized"
37}
38sleep 2
39
40spawn $env(SHELL)
41send -- "firemon --seccomp\r"
42expect {
43 timeout {puts "TESTING ERROR 5\n";exit}
44 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
45 ":firejail"
46}
47expect {
48 timeout {puts "TESTING ERROR 5.0\n";exit}
49 "xterm"
50}
51expect {
52 timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit}
53 "Seccomp: 2"
54}
55expect {
56 timeout {puts "TESTING ERROR 5.1\n";exit}
57 "name=blablabla"
58}
59sleep 1
60send -- "firemon --caps\r"
61expect {
62 timeout {puts "TESTING ERROR 6\n";exit}
63 ":firejail"
64}
65expect {
66 timeout {puts "TESTING ERROR 6.0\n";exit}
67 "xterm"
68}
69expect {
70 timeout {puts "TESTING ERROR 6.1\n";exit}
71 "CapBnd"
72}
73expect {
74 timeout {puts "TESTING ERROR 6.2\n";exit}
75 "0000000000000000"
76}
77expect {
78 timeout {puts "TESTING ERROR 6.3\n";exit}
79 "name=blablabla"
80}
81sleep 1
82
83send -- "firemon --x11\r"
84expect {
85 timeout {puts "TESTING ERROR 7\n";exit}
86 "name=test xterm"
87}
88expect {
89 timeout {puts "TESTING ERROR 7.1\n";exit}
90 "DISPLAY"
91}
92sleep 1
93
94send -- "firejail --shutdown=test\r"
95sleep 3
96
97puts "\nall done\n"
98
diff --git a/test/test-apps.sh b/test/apps/apps.sh
index 5ada20549..38307b284 100755
--- a/test/test-apps.sh
+++ b/test/apps/apps.sh
@@ -1,4 +1,10 @@
1#!/bin/bash 1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6export MALLOC_CHECK_=3
7export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
2 8
3which firefox 9which firefox
4if [ "$?" -eq 0 ]; 10if [ "$?" -eq 0 ];
@@ -6,7 +12,7 @@ then
6 echo "TESTING: firefox" 12 echo "TESTING: firefox"
7 ./firefox.exp 13 ./firefox.exp
8else 14else
9 echo "TESTING: firefox not found" 15 echo "TESTING SKIP: firefox not found"
10fi 16fi
11 17
12which midori 18which midori
@@ -15,7 +21,7 @@ then
15 echo "TESTING: midori" 21 echo "TESTING: midori"
16 ./midori.exp 22 ./midori.exp
17else 23else
18 echo "TESTING: midori not found" 24 echo "TESTING SKIP: midori not found"
19fi 25fi
20 26
21which chromium 27which chromium
@@ -24,16 +30,7 @@ then
24 echo "TESTING: chromium" 30 echo "TESTING: chromium"
25 ./chromium.exp 31 ./chromium.exp
26else 32else
27 echo "TESTING: chromium not found" 33 echo "TESTING SKIP: chromium not found"
28fi
29
30which google-chrome
31if [ "$?" -eq 0 ];
32then
33 echo "TESTING: google-chrome"
34 ./chromium.exp
35else
36 echo "TESTING: google-chrome not found"
37fi 34fi
38 35
39which opera 36which opera
@@ -42,7 +39,7 @@ then
42 echo "TESTING: opera" 39 echo "TESTING: opera"
43 ./opera.exp 40 ./opera.exp
44else 41else
45 echo "TESTING: opera not found" 42 echo "TESTING SKIP: opera not found"
46fi 43fi
47 44
48which transmission-gtk 45which transmission-gtk
@@ -51,7 +48,7 @@ then
51 echo "TESTING: transmission-gtk" 48 echo "TESTING: transmission-gtk"
52 ./transmission-gtk.exp 49 ./transmission-gtk.exp
53else 50else
54 echo "TESTING: transmission-gtk not found" 51 echo "TESTING SKIP: transmission-gtk not found"
55fi 52fi
56 53
57which transmission-qt 54which transmission-qt
@@ -60,7 +57,34 @@ then
60 echo "TESTING: transmission-qt" 57 echo "TESTING: transmission-qt"
61 ./transmission-qt.exp 58 ./transmission-qt.exp
62else 59else
63 echo "TESTING: transmission-qt not found" 60 echo "TESTING SKIP: transmission-qt not found"
61fi
62
63which qbittorrent
64if [ "$?" -eq 0 ];
65then
66 echo "TESTING: qbittorrent"
67 ./qbittorrent.exp
68else
69 echo "TESTING SKIP: qbittorrent not found"
70fi
71
72which uget-gtk
73if [ "$?" -eq 0 ];
74then
75 echo "TESTING: uget"
76 ./uget-gtk.exp
77else
78 echo "TESTING SKIP: uget-gtk not found"
79fi
80
81which filezilla
82if [ "$?" -eq 0 ];
83then
84 echo "TESTING: filezilla"
85 ./filezilla.exp
86else
87 echo "TESTING SKIP: filezilla not found"
64fi 88fi
65 89
66which evince 90which evince
@@ -69,7 +93,17 @@ then
69 echo "TESTING: evince" 93 echo "TESTING: evince"
70 ./evince.exp 94 ./evince.exp
71else 95else
72 echo "TESTING: evince not found" 96 echo "TESTING SKIP: evince not found"
97fi
98
99
100which gthumb
101if [ "$?" -eq 0 ];
102then
103 echo "TESTING: gthumb"
104 ./gthumb.exp
105else
106 echo "TESTING SKIP: gthumb not found"
73fi 107fi
74 108
75which icedove 109which icedove
@@ -78,7 +112,7 @@ then
78 echo "TESTING: icedove" 112 echo "TESTING: icedove"
79 ./icedove.exp 113 ./icedove.exp
80else 114else
81 echo "TESTING: icedove not found" 115 echo "TESTING SKIP: icedove not found"
82fi 116fi
83 117
84which vlc 118which vlc
@@ -87,7 +121,7 @@ then
87 echo "TESTING: vlc" 121 echo "TESTING: vlc"
88 ./vlc.exp 122 ./vlc.exp
89else 123else
90 echo "TESTING: vlc not found" 124 echo "TESTING SKIP: vlc not found"
91fi 125fi
92 126
93which fbreader 127which fbreader
@@ -96,7 +130,7 @@ then
96 echo "TESTING: fbreader" 130 echo "TESTING: fbreader"
97 ./fbreader.exp 131 ./fbreader.exp
98else 132else
99 echo "TESTING: fbreader not found" 133 echo "TESTING SKIP: fbreader not found"
100fi 134fi
101 135
102which deluge 136which deluge
@@ -105,7 +139,7 @@ then
105 echo "TESTING: deluge" 139 echo "TESTING: deluge"
106 ./deluge.exp 140 ./deluge.exp
107else 141else
108 echo "TESTING: deluge not found" 142 echo "TESTING SKIP: deluge not found"
109fi 143fi
110 144
111which gnome-mplayer 145which gnome-mplayer
@@ -114,7 +148,7 @@ then
114 echo "TESTING: gnome-mplayer" 148 echo "TESTING: gnome-mplayer"
115 ./gnome-mplayer.exp 149 ./gnome-mplayer.exp
116else 150else
117 echo "TESTING: gnome-mplayer not found" 151 echo "TESTING SKIP: gnome-mplayer not found"
118fi 152fi
119 153
120which xchat 154which xchat
@@ -123,7 +157,7 @@ then
123 echo "TESTING: xchat" 157 echo "TESTING: xchat"
124 ./xchat.exp 158 ./xchat.exp
125else 159else
126 echo "TESTING: xchat not found" 160 echo "TESTING SKIP: xchat not found"
127fi 161fi
128 162
129which hexchat 163which hexchat
@@ -132,16 +166,7 @@ then
132 echo "TESTING: hexchat" 166 echo "TESTING: hexchat"
133 ./hexchat.exp 167 ./hexchat.exp
134else 168else
135 echo "TESTING: hexchat not found" 169 echo "TESTING SKIP: hexchat not found"
136fi
137
138which weechat-curses
139if [ "$?" -eq 0 ];
140then
141 echo "TESTING: weechat"
142 ./weechat.exp
143else
144 echo "TESTING: weechat not found"
145fi 170fi
146 171
147which wine 172which wine
@@ -150,6 +175,6 @@ then
150 echo "TESTING: wine" 175 echo "TESTING: wine"
151 ./wine.exp 176 ./wine.exp
152else 177else
153 echo "TESTING: wine not found" 178 echo "TESTING SKIP: wine not found"
154fi 179fi
155 180
diff --git a/test/chromium.exp b/test/apps/chromium.exp
index 676f7e314..d43f70f8e 100755
--- a/test/chromium.exp
+++ b/test/apps/chromium.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -25,7 +28,7 @@ expect {
25 timeout {puts "TESTING ERROR 3.1\n";exit} 28 timeout {puts "TESTING ERROR 3.1\n";exit}
26 "chromium" 29 "chromium"
27} 30}
28sleep 1 31after 100
29 32
30# grsecurity exit 33# grsecurity exit
31send -- "file /proc/sys/kernel/grsecurity\r" 34send -- "file /proc/sys/kernel/grsecurity\r"
@@ -46,6 +49,7 @@ spawn $env(SHELL)
46send -- "firemon --seccomp\r" 49send -- "firemon --seccomp\r"
47expect { 50expect {
48 timeout {puts "TESTING ERROR 5\n";exit} 51 timeout {puts "TESTING ERROR 5\n";exit}
52 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
49 ":firejail chromium" 53 ":firejail chromium"
50} 54}
51expect { 55expect {
@@ -56,7 +60,7 @@ expect {
56 timeout {puts "TESTING ERROR 5.1\n";exit} 60 timeout {puts "TESTING ERROR 5.1\n";exit}
57 "name=blablabla" 61 "name=blablabla"
58} 62}
59sleep 1 63after 100
60send -- "firemon --caps\r" 64send -- "firemon --caps\r"
61expect { 65expect {
62 timeout {puts "TESTING ERROR 6\n";exit} 66 timeout {puts "TESTING ERROR 6\n";exit}
@@ -74,7 +78,7 @@ expect {
74 timeout {puts "TESTING ERROR 6.3\n";exit} 78 timeout {puts "TESTING ERROR 6.3\n";exit}
75 "name=blablabla" 79 "name=blablabla"
76} 80}
77sleep 1 81after 100
78 82
79puts "\n" 83puts "\n"
80 84
diff --git a/test/deluge.exp b/test/apps/deluge.exp
index 9f5063495..0bf1baae2 100755
--- a/test/deluge.exp
+++ b/test/apps/deluge.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -25,7 +28,7 @@ expect {
25 timeout {puts "TESTING ERROR 3.1\n";exit} 28 timeout {puts "TESTING ERROR 3.1\n";exit}
26 "deluge" 29 "deluge"
27} 30}
28sleep 1 31after 100
29 32
30# grsecurity exit 33# grsecurity exit
31send -- "file /proc/sys/kernel/grsecurity\r" 34send -- "file /proc/sys/kernel/grsecurity\r"
@@ -46,6 +49,7 @@ spawn $env(SHELL)
46send -- "firemon --seccomp\r" 49send -- "firemon --seccomp\r"
47expect { 50expect {
48 timeout {puts "TESTING ERROR 5\n";exit} 51 timeout {puts "TESTING ERROR 5\n";exit}
52 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
49 ":firejail deluge" 53 ":firejail deluge"
50} 54}
51expect { 55expect {
@@ -56,7 +60,7 @@ expect {
56 timeout {puts "TESTING ERROR 5.1\n";exit} 60 timeout {puts "TESTING ERROR 5.1\n";exit}
57 "name=blablabla" 61 "name=blablabla"
58} 62}
59sleep 1 63after 100
60send -- "firemon --caps\r" 64send -- "firemon --caps\r"
61expect { 65expect {
62 timeout {puts "TESTING ERROR 6\n";exit} 66 timeout {puts "TESTING ERROR 6\n";exit}
@@ -74,7 +78,7 @@ expect {
74 timeout {puts "TESTING ERROR 6.3\n";exit} 78 timeout {puts "TESTING ERROR 6.3\n";exit}
75 "name=blablabla" 79 "name=blablabla"
76} 80}
77sleep 1 81after 100
78 82
79puts "\n" 83puts "\n"
80 84
diff --git a/test/evince.exp b/test/apps/evince.exp
index 3c3ad4bdd..71f760a9c 100755
--- a/test/evince.exp
+++ b/test/apps/evince.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -25,7 +28,7 @@ expect {
25 timeout {puts "TESTING ERROR 3.1\n";exit} 28 timeout {puts "TESTING ERROR 3.1\n";exit}
26 "evince" 29 "evince"
27} 30}
28sleep 1 31after 100
29 32
30# grsecurity exit 33# grsecurity exit
31send -- "file /proc/sys/kernel/grsecurity\r" 34send -- "file /proc/sys/kernel/grsecurity\r"
@@ -46,6 +49,7 @@ spawn $env(SHELL)
46send -- "firemon --seccomp\r" 49send -- "firemon --seccomp\r"
47expect { 50expect {
48 timeout {puts "TESTING ERROR 5\n";exit} 51 timeout {puts "TESTING ERROR 5\n";exit}
52 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
49 ":firejail evince" 53 ":firejail evince"
50} 54}
51expect { 55expect {
@@ -56,7 +60,7 @@ expect {
56 timeout {puts "TESTING ERROR 5.1\n";exit} 60 timeout {puts "TESTING ERROR 5.1\n";exit}
57 "name=blablabla" 61 "name=blablabla"
58} 62}
59sleep 1 63after 100
60send -- "firemon --caps\r" 64send -- "firemon --caps\r"
61expect { 65expect {
62 timeout {puts "TESTING ERROR 6\n";exit} 66 timeout {puts "TESTING ERROR 6\n";exit}
@@ -74,7 +78,7 @@ expect {
74 timeout {puts "TESTING ERROR 6.3\n";exit} 78 timeout {puts "TESTING ERROR 6.3\n";exit}
75 "name=blablabla" 79 "name=blablabla"
76} 80}
77sleep 1 81after 100
78 82
79puts "\nall done\n" 83puts "\nall done\n"
80 84
diff --git a/test/fbreader.exp b/test/apps/fbreader.exp
index d2bee880e..99c48d87c 100755
--- a/test/fbreader.exp
+++ b/test/apps/fbreader.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -25,7 +28,7 @@ expect {
25 timeout {puts "TESTING ERROR 3.1\n";exit} 28 timeout {puts "TESTING ERROR 3.1\n";exit}
26 "fbreader" 29 "fbreader"
27} 30}
28sleep 1 31after 100
29 32
30# grsecurity exit 33# grsecurity exit
31send -- "file /proc/sys/kernel/grsecurity\r" 34send -- "file /proc/sys/kernel/grsecurity\r"
@@ -46,6 +49,7 @@ spawn $env(SHELL)
46send -- "firemon --seccomp\r" 49send -- "firemon --seccomp\r"
47expect { 50expect {
48 timeout {puts "TESTING ERROR 5\n";exit} 51 timeout {puts "TESTING ERROR 5\n";exit}
52 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
49 ":firejail fbreader" 53 ":firejail fbreader"
50} 54}
51expect { 55expect {
@@ -56,7 +60,7 @@ expect {
56 timeout {puts "TESTING ERROR 5.1\n";exit} 60 timeout {puts "TESTING ERROR 5.1\n";exit}
57 "name=blablabla" 61 "name=blablabla"
58} 62}
59sleep 1 63after 100
60send -- "firemon --caps\r" 64send -- "firemon --caps\r"
61expect { 65expect {
62 timeout {puts "TESTING ERROR 6\n";exit} 66 timeout {puts "TESTING ERROR 6\n";exit}
@@ -74,7 +78,7 @@ expect {
74 timeout {puts "TESTING ERROR 6.3\n";exit} 78 timeout {puts "TESTING ERROR 6.3\n";exit}
75 "name=blablabla" 79 "name=blablabla"
76} 80}
77sleep 1 81after 100
78 82
79puts "\nall done\n" 83puts "\nall done\n"
80 84
diff --git a/test/apps/filezilla.exp b/test/apps/filezilla.exp
new file mode 100755
index 000000000..2f7038184
--- /dev/null
+++ b/test/apps/filezilla.exp
@@ -0,0 +1,84 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail filezilla\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Reading profile /etc/firejail/filezilla.profile"
14}
15expect {
16 timeout {puts "TESTING ERROR 1\n";exit}
17 "Child process initialized"
18}
19sleep 3
20
21spawn $env(SHELL)
22send -- "firejail --list\r"
23expect {
24 timeout {puts "TESTING ERROR 3\n";exit}
25 ":firejail"
26}
27expect {
28 timeout {puts "TESTING ERROR 3.1\n";exit}
29 "filezilla"
30}
31after 100
32
33# grsecurity exit
34send -- "file /proc/sys/kernel/grsecurity\r"
35expect {
36 timeout {puts "TESTING ERROR - grsecurity detection\n";exit}
37 "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit}
38 "cannot open" {puts "grsecurity not present\n"}
39}
40
41send -- "firejail --name=blablabla\r"
42expect {
43 timeout {puts "TESTING ERROR 4\n";exit}
44 "Child process initialized"
45}
46sleep 2
47
48spawn $env(SHELL)
49send -- "firemon --seccomp\r"
50expect {
51 timeout {puts "TESTING ERROR 5\n";exit}
52 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
53 ":firejail filezilla"
54}
55expect {
56 timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit}
57 "Seccomp: 2"
58}
59expect {
60 timeout {puts "TESTING ERROR 5.1\n";exit}
61 "name=blablabla"
62}
63after 100
64send -- "firemon --caps\r"
65expect {
66 timeout {puts "TESTING ERROR 6\n";exit}
67 ":firejail filezilla"
68}
69expect {
70 timeout {puts "TESTING ERROR 6.1\n";exit}
71 "CapBnd:"
72}
73expect {
74 timeout {puts "TESTING ERROR 6.2\n";exit}
75 "0000000000000000"
76}
77expect {
78 timeout {puts "TESTING ERROR 6.3\n";exit}
79 "name=blablabla"
80}
81after 100
82
83puts "\nall done\n"
84
diff --git a/test/firefox.exp b/test/apps/firefox.exp
index 2585e4b5c..5745d9270 100755
--- a/test/firefox.exp
+++ b/test/apps/firefox.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -30,7 +33,7 @@ expect {
30 timeout {puts "TESTING ERROR 3.2\n";exit} 33 timeout {puts "TESTING ERROR 3.2\n";exit}
31 "no-remote" 34 "no-remote"
32} 35}
33sleep 1 36after 100
34 37
35# grsecurity exit 38# grsecurity exit
36send -- "file /proc/sys/kernel/grsecurity\r" 39send -- "file /proc/sys/kernel/grsecurity\r"
@@ -52,6 +55,7 @@ spawn $env(SHELL)
52send -- "firemon --seccomp\r" 55send -- "firemon --seccomp\r"
53expect { 56expect {
54 timeout {puts "TESTING ERROR 5\n";exit} 57 timeout {puts "TESTING ERROR 5\n";exit}
58 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
55 " firefox" {puts "firefox detected\n";} 59 " firefox" {puts "firefox detected\n";}
56 " iceweasel" {puts "iceweasel detected\n";} 60 " iceweasel" {puts "iceweasel detected\n";}
57} 61}
@@ -67,7 +71,7 @@ expect {
67 timeout {puts "TESTING ERROR 5.1\n";exit} 71 timeout {puts "TESTING ERROR 5.1\n";exit}
68 "name=blablabla" 72 "name=blablabla"
69} 73}
70sleep 1 74after 100
71send -- "firemon --caps\r" 75send -- "firemon --caps\r"
72expect { 76expect {
73 timeout {puts "TESTING ERROR 6\n";exit} 77 timeout {puts "TESTING ERROR 6\n";exit}
@@ -90,7 +94,7 @@ expect {
90 timeout {puts "TESTING ERROR 6.3\n";exit} 94 timeout {puts "TESTING ERROR 6.3\n";exit}
91 "name=blablabla" 95 "name=blablabla"
92} 96}
93sleep 1 97after 100
94 98
95puts "\n" 99puts "\n"
96 100
diff --git a/test/gnome-mplayer.exp b/test/apps/gnome-mplayer.exp
index 6965322fc..6f0e5a312 100755
--- a/test/gnome-mplayer.exp
+++ b/test/apps/gnome-mplayer.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -13,7 +16,7 @@ expect {
13 timeout {puts "TESTING ERROR 1\n";exit} 16 timeout {puts "TESTING ERROR 1\n";exit}
14 "Child process initialized" 17 "Child process initialized"
15} 18}
16sleep 10 19sleep 5
17 20
18spawn $env(SHELL) 21spawn $env(SHELL)
19send -- "firejail --list\r" 22send -- "firejail --list\r"
@@ -25,7 +28,7 @@ expect {
25 timeout {puts "TESTING ERROR 3.1\n";exit} 28 timeout {puts "TESTING ERROR 3.1\n";exit}
26 "gnome-mplayer" 29 "gnome-mplayer"
27} 30}
28sleep 1 31after 100
29 32
30# grsecurity exit 33# grsecurity exit
31send -- "file /proc/sys/kernel/grsecurity\r" 34send -- "file /proc/sys/kernel/grsecurity\r"
@@ -46,6 +49,7 @@ spawn $env(SHELL)
46send -- "firemon --seccomp\r" 49send -- "firemon --seccomp\r"
47expect { 50expect {
48 timeout {puts "TESTING ERROR 5\n";exit} 51 timeout {puts "TESTING ERROR 5\n";exit}
52 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
49 ":firejail gnome-mplayer" 53 ":firejail gnome-mplayer"
50} 54}
51expect { 55expect {
@@ -56,7 +60,7 @@ expect {
56 timeout {puts "TESTING ERROR 5.1\n";exit} 60 timeout {puts "TESTING ERROR 5.1\n";exit}
57 "name=blablabla" 61 "name=blablabla"
58} 62}
59sleep 1 63after 100
60send -- "firemon --caps\r" 64send -- "firemon --caps\r"
61expect { 65expect {
62 timeout {puts "TESTING ERROR 6\n";exit} 66 timeout {puts "TESTING ERROR 6\n";exit}
@@ -74,7 +78,7 @@ expect {
74 timeout {puts "TESTING ERROR 6.3\n";exit} 78 timeout {puts "TESTING ERROR 6.3\n";exit}
75 "name=blablabla" 79 "name=blablabla"
76} 80}
77sleep 1 81after 100
78 82
79puts "\nall done\n" 83puts "\nall done\n"
80 84
diff --git a/test/weechat.exp b/test/apps/gthumb.exp
index 630af55ee..13132cef6 100755
--- a/test/weechat.exp
+++ b/test/apps/gthumb.exp
@@ -1,13 +1,16 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
5match_max 100000 8match_max 100000
6 9
7send -- "firejail weechat-curses\r" 10send -- "firejail gthumb\r"
8expect { 11expect {
9 timeout {puts "TESTING ERROR 0\n";exit} 12 timeout {puts "TESTING ERROR 0\n";exit}
10 "Reading profile /etc/firejail/weechat.profile" 13 "Reading profile /etc/firejail/gthumb.profile"
11} 14}
12expect { 15expect {
13 timeout {puts "TESTING ERROR 1\n";exit} 16 timeout {puts "TESTING ERROR 1\n";exit}
@@ -23,9 +26,9 @@ expect {
23} 26}
24expect { 27expect {
25 timeout {puts "TESTING ERROR 3.1\n";exit} 28 timeout {puts "TESTING ERROR 3.1\n";exit}
26 "weechat-curses" 29 "gthumb"
27} 30}
28sleep 1 31after 100
29 32
30# grsecurity exit 33# grsecurity exit
31send -- "file /proc/sys/kernel/grsecurity\r" 34send -- "file /proc/sys/kernel/grsecurity\r"
@@ -46,7 +49,8 @@ spawn $env(SHELL)
46send -- "firemon --seccomp\r" 49send -- "firemon --seccomp\r"
47expect { 50expect {
48 timeout {puts "TESTING ERROR 5\n";exit} 51 timeout {puts "TESTING ERROR 5\n";exit}
49 "weechat-curses" 52 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
53 ":firejail gthumb"
50} 54}
51expect { 55expect {
52 timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} 56 timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit}
@@ -56,11 +60,11 @@ expect {
56 timeout {puts "TESTING ERROR 5.1\n";exit} 60 timeout {puts "TESTING ERROR 5.1\n";exit}
57 "name=blablabla" 61 "name=blablabla"
58} 62}
59sleep 1 63after 100
60send -- "firemon --caps\r" 64send -- "firemon --caps\r"
61expect { 65expect {
62 timeout {puts "TESTING ERROR 6\n";exit} 66 timeout {puts "TESTING ERROR 6\n";exit}
63 "weechat-curses" 67 ":firejail gthumb"
64} 68}
65expect { 69expect {
66 timeout {puts "TESTING ERROR 6.1\n";exit} 70 timeout {puts "TESTING ERROR 6.1\n";exit}
@@ -74,7 +78,7 @@ expect {
74 timeout {puts "TESTING ERROR 6.3\n";exit} 78 timeout {puts "TESTING ERROR 6.3\n";exit}
75 "name=blablabla" 79 "name=blablabla"
76} 80}
77sleep 1 81after 100
78 82
79puts "\n" 83puts "\nall done\n"
80 84
diff --git a/test/hexchat.exp b/test/apps/hexchat.exp
index 7e99c8cdf..5d0bc1093 100755
--- a/test/hexchat.exp
+++ b/test/apps/hexchat.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -25,7 +28,7 @@ expect {
25 timeout {puts "TESTING ERROR 3.1\n";exit} 28 timeout {puts "TESTING ERROR 3.1\n";exit}
26 "hexchat" 29 "hexchat"
27} 30}
28sleep 1 31after 100
29 32
30# grsecurity exit 33# grsecurity exit
31send -- "file /proc/sys/kernel/grsecurity\r" 34send -- "file /proc/sys/kernel/grsecurity\r"
@@ -46,6 +49,7 @@ spawn $env(SHELL)
46send -- "firemon --seccomp\r" 49send -- "firemon --seccomp\r"
47expect { 50expect {
48 timeout {puts "TESTING ERROR 5\n";exit} 51 timeout {puts "TESTING ERROR 5\n";exit}
52 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
49 "hexchat" 53 "hexchat"
50} 54}
51expect { 55expect {
@@ -56,7 +60,7 @@ expect {
56 timeout {puts "TESTING ERROR 5.1\n";exit} 60 timeout {puts "TESTING ERROR 5.1\n";exit}
57 "name=blablabla" 61 "name=blablabla"
58} 62}
59sleep 1 63after 100
60send -- "firemon --caps\r" 64send -- "firemon --caps\r"
61expect { 65expect {
62 timeout {puts "TESTING ERROR 6\n";exit} 66 timeout {puts "TESTING ERROR 6\n";exit}
@@ -74,7 +78,7 @@ expect {
74 timeout {puts "TESTING ERROR 6.3\n";exit} 78 timeout {puts "TESTING ERROR 6.3\n";exit}
75 "name=blablabla" 79 "name=blablabla"
76} 80}
77sleep 1 81after 100
78 82
79puts "\n" 83puts "\n"
80 84
diff --git a/test/icedove.exp b/test/apps/icedove.exp
index 344febb93..c0fbd9fc8 100755
--- a/test/icedove.exp
+++ b/test/apps/icedove.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -25,7 +28,7 @@ expect {
25 timeout {puts "TESTING ERROR 3.1\n";exit} 28 timeout {puts "TESTING ERROR 3.1\n";exit}
26 "icedove" 29 "icedove"
27} 30}
28sleep 1 31after 100
29 32
30# grsecurity exit 33# grsecurity exit
31send -- "file /proc/sys/kernel/grsecurity\r" 34send -- "file /proc/sys/kernel/grsecurity\r"
@@ -46,6 +49,7 @@ spawn $env(SHELL)
46send -- "firemon --seccomp\r" 49send -- "firemon --seccomp\r"
47expect { 50expect {
48 timeout {puts "TESTING ERROR 5\n";exit} 51 timeout {puts "TESTING ERROR 5\n";exit}
52 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
49 ":firejail icedove" 53 ":firejail icedove"
50} 54}
51expect { 55expect {
@@ -56,7 +60,7 @@ expect {
56 timeout {puts "TESTING ERROR 5.1\n";exit} 60 timeout {puts "TESTING ERROR 5.1\n";exit}
57 "name=blablabla" 61 "name=blablabla"
58} 62}
59sleep 1 63after 100
60send -- "firemon --caps\r" 64send -- "firemon --caps\r"
61expect { 65expect {
62 timeout {puts "TESTING ERROR 6\n";exit} 66 timeout {puts "TESTING ERROR 6\n";exit}
@@ -74,7 +78,7 @@ expect {
74 timeout {puts "TESTING ERROR 6.3\n";exit} 78 timeout {puts "TESTING ERROR 6.3\n";exit}
75 "name=blablabla" 79 "name=blablabla"
76} 80}
77sleep 1 81after 100
78 82
79puts "\nall done\n" 83puts "\nall done\n"
80 84
diff --git a/test/midori.exp b/test/apps/midori.exp
index 470f5de77..45d70eda1 100755
--- a/test/midori.exp
+++ b/test/apps/midori.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -13,7 +16,7 @@ expect {
13 timeout {puts "TESTING ERROR 1\n";exit} 16 timeout {puts "TESTING ERROR 1\n";exit}
14 "Child process initialized" 17 "Child process initialized"
15} 18}
16sleep 10 19sleep 5
17 20
18spawn $env(SHELL) 21spawn $env(SHELL)
19send -- "firejail --list\r" 22send -- "firejail --list\r"
@@ -25,7 +28,7 @@ expect {
25 timeout {puts "TESTING ERROR 3.1\n";exit} 28 timeout {puts "TESTING ERROR 3.1\n";exit}
26 "midori" 29 "midori"
27} 30}
28sleep 1 31after 100
29 32
30# grsecurity exit 33# grsecurity exit
31send -- "file /proc/sys/kernel/grsecurity\r" 34send -- "file /proc/sys/kernel/grsecurity\r"
@@ -46,6 +49,7 @@ spawn $env(SHELL)
46send -- "firemon --seccomp\r" 49send -- "firemon --seccomp\r"
47expect { 50expect {
48 timeout {puts "TESTING ERROR 5\n";exit} 51 timeout {puts "TESTING ERROR 5\n";exit}
52 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
49 ":firejail midori" 53 ":firejail midori"
50} 54}
51expect { 55expect {
@@ -56,7 +60,7 @@ expect {
56 timeout {puts "TESTING ERROR 5.1\n";exit} 60 timeout {puts "TESTING ERROR 5.1\n";exit}
57 "name=blablabla" 61 "name=blablabla"
58} 62}
59sleep 1 63after 100
60send -- "firemon --caps\r" 64send -- "firemon --caps\r"
61expect { 65expect {
62 timeout {puts "TESTING ERROR 6\n";exit} 66 timeout {puts "TESTING ERROR 6\n";exit}
@@ -74,7 +78,7 @@ expect {
74 timeout {puts "TESTING ERROR 6.3n";exit} 78 timeout {puts "TESTING ERROR 6.3n";exit}
75 "name=blablabla" 79 "name=blablabla"
76} 80}
77sleep 1 81after 100
78 82
79 83
80puts "\n" 84puts "\n"
diff --git a/test/opera.exp b/test/apps/opera.exp
index 23eed5504..036fc2e21 100755
--- a/test/opera.exp
+++ b/test/apps/opera.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -25,7 +28,7 @@ expect {
25 timeout {puts "TESTING ERROR 3.1\n";exit} 28 timeout {puts "TESTING ERROR 3.1\n";exit}
26 "opera" 29 "opera"
27} 30}
28sleep 1 31after 100
29 32
30# grsecurity exit 33# grsecurity exit
31send -- "file /proc/sys/kernel/grsecurity\r" 34send -- "file /proc/sys/kernel/grsecurity\r"
@@ -46,6 +49,7 @@ spawn $env(SHELL)
46send -- "firemon --seccomp\r" 49send -- "firemon --seccomp\r"
47expect { 50expect {
48 timeout {puts "TESTING ERROR 5\n";exit} 51 timeout {puts "TESTING ERROR 5\n";exit}
52 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
49 ":firejail opera" 53 ":firejail opera"
50} 54}
51expect { 55expect {
@@ -56,7 +60,7 @@ expect {
56 timeout {puts "TESTING ERROR 5.1\n";exit} 60 timeout {puts "TESTING ERROR 5.1\n";exit}
57 "name=blablabla" 61 "name=blablabla"
58} 62}
59sleep 1 63after 100
60send -- "firemon --caps\r" 64send -- "firemon --caps\r"
61expect { 65expect {
62 timeout {puts "TESTING ERROR 6\n";exit} 66 timeout {puts "TESTING ERROR 6\n";exit}
@@ -74,7 +78,7 @@ expect {
74 timeout {puts "TESTING ERROR 6.3\n";exit} 78 timeout {puts "TESTING ERROR 6.3\n";exit}
75 "name=blablabla" 79 "name=blablabla"
76} 80}
77sleep 1 81after 100
78 82
79puts "\n" 83puts "\n"
80 84
diff --git a/test/apps/qbittorrent.exp b/test/apps/qbittorrent.exp
new file mode 100755
index 000000000..8bc6d8564
--- /dev/null
+++ b/test/apps/qbittorrent.exp
@@ -0,0 +1,84 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail qbittorrent\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Reading profile /etc/firejail/qbittorrent.profile"
14}
15expect {
16 timeout {puts "TESTING ERROR 1\n";exit}
17 "Child process initialized"
18}
19sleep 3
20
21spawn $env(SHELL)
22send -- "firejail --list\r"
23expect {
24 timeout {puts "TESTING ERROR 3\n";exit}
25 ":firejail"
26}
27expect {
28 timeout {puts "TESTING ERROR 3.1\n";exit}
29 "qbittorrent"
30}
31after 100
32
33# grsecurity exit
34send -- "file /proc/sys/kernel/grsecurity\r"
35expect {
36 timeout {puts "TESTING ERROR - grsecurity detection\n";exit}
37 "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit}
38 "cannot open" {puts "grsecurity not present\n"}
39}
40
41send -- "firejail --name=blablabla\r"
42expect {
43 timeout {puts "TESTING ERROR 4\n";exit}
44 "Child process initialized"
45}
46sleep 2
47
48spawn $env(SHELL)
49send -- "firemon --seccomp\r"
50expect {
51 timeout {puts "TESTING ERROR 5\n";exit}
52 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
53 ":firejail qbittorrent"
54}
55expect {
56 timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit}
57 "Seccomp: 2"
58}
59expect {
60 timeout {puts "TESTING ERROR 5.1\n";exit}
61 "name=blablabla"
62}
63after 100
64send -- "firemon --caps\r"
65expect {
66 timeout {puts "TESTING ERROR 6\n";exit}
67 ":firejail qbittorrent"
68}
69expect {
70 timeout {puts "TESTING ERROR 6.1\n";exit}
71 "CapBnd:"
72}
73expect {
74 timeout {puts "TESTING ERROR 6.2\n";exit}
75 "0000000000000000"
76}
77expect {
78 timeout {puts "TESTING ERROR 6.3\n";exit}
79 "name=blablabla"
80}
81after 100
82
83puts "\n"
84
diff --git a/test/transmission-gtk.exp b/test/apps/transmission-gtk.exp
index 1acfc6f94..70700d523 100755
--- a/test/transmission-gtk.exp
+++ b/test/apps/transmission-gtk.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -9,7 +12,7 @@ expect {
9 timeout {puts "TESTING ERROR 1\n";exit} 12 timeout {puts "TESTING ERROR 1\n";exit}
10 "Child process initialized" 13 "Child process initialized"
11} 14}
12sleep 10 15sleep 5
13 16
14spawn $env(SHELL) 17spawn $env(SHELL)
15send -- "firejail --list\r" 18send -- "firejail --list\r"
@@ -21,7 +24,7 @@ expect {
21 timeout {puts "TESTING ERROR 3.1\n";exit} 24 timeout {puts "TESTING ERROR 3.1\n";exit}
22 "transmission-gtk" 25 "transmission-gtk"
23} 26}
24sleep 1 27after 100
25 28
26# grsecurity exit 29# grsecurity exit
27send -- "file /proc/sys/kernel/grsecurity\r" 30send -- "file /proc/sys/kernel/grsecurity\r"
@@ -41,6 +44,7 @@ spawn $env(SHELL)
41send -- "firemon --seccomp\r" 44send -- "firemon --seccomp\r"
42expect { 45expect {
43 timeout {puts "TESTING ERROR 5\n";exit} 46 timeout {puts "TESTING ERROR 5\n";exit}
47 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
44 ":firejail transmission-gtk" 48 ":firejail transmission-gtk"
45} 49}
46expect { 50expect {
@@ -51,7 +55,7 @@ expect {
51 timeout {puts "TESTING ERROR 5.1\n";exit} 55 timeout {puts "TESTING ERROR 5.1\n";exit}
52 "name=blablabla" 56 "name=blablabla"
53} 57}
54sleep 1 58after 100
55send -- "firemon --caps\r" 59send -- "firemon --caps\r"
56expect { 60expect {
57 timeout {puts "TESTING ERROR 6\n";exit} 61 timeout {puts "TESTING ERROR 6\n";exit}
@@ -69,7 +73,7 @@ expect {
69 timeout {puts "TESTING ERROR 6.3\n";exit} 73 timeout {puts "TESTING ERROR 6.3\n";exit}
70 "name=blablabla" 74 "name=blablabla"
71} 75}
72sleep 1 76after 100
73 77
74puts "\nall done\n" 78puts "\nall done\n"
75 79
diff --git a/test/transmission-qt.exp b/test/apps/transmission-qt.exp
index 944fd28a2..3773b1dc2 100755
--- a/test/transmission-qt.exp
+++ b/test/apps/transmission-qt.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -13,7 +16,7 @@ expect {
13 timeout {puts "TESTING ERROR 1\n";exit} 16 timeout {puts "TESTING ERROR 1\n";exit}
14 "Child process initialized" 17 "Child process initialized"
15} 18}
16sleep 10 19sleep 3
17 20
18spawn $env(SHELL) 21spawn $env(SHELL)
19send -- "firejail --list\r" 22send -- "firejail --list\r"
@@ -25,7 +28,7 @@ expect {
25 timeout {puts "TESTING ERROR 3.1\n";exit} 28 timeout {puts "TESTING ERROR 3.1\n";exit}
26 "transmission-qt" 29 "transmission-qt"
27} 30}
28sleep 1 31after 100
29 32
30# grsecurity exit 33# grsecurity exit
31send -- "file /proc/sys/kernel/grsecurity\r" 34send -- "file /proc/sys/kernel/grsecurity\r"
@@ -46,6 +49,7 @@ spawn $env(SHELL)
46send -- "firemon --seccomp\r" 49send -- "firemon --seccomp\r"
47expect { 50expect {
48 timeout {puts "TESTING ERROR 5\n";exit} 51 timeout {puts "TESTING ERROR 5\n";exit}
52 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
49 ":firejail transmission-qt" 53 ":firejail transmission-qt"
50} 54}
51expect { 55expect {
@@ -56,7 +60,7 @@ expect {
56 timeout {puts "TESTING ERROR 5.1\n";exit} 60 timeout {puts "TESTING ERROR 5.1\n";exit}
57 "name=blablabla" 61 "name=blablabla"
58} 62}
59sleep 1 63after 100
60send -- "firemon --caps\r" 64send -- "firemon --caps\r"
61expect { 65expect {
62 timeout {puts "TESTING ERROR 6\n";exit} 66 timeout {puts "TESTING ERROR 6\n";exit}
@@ -74,7 +78,7 @@ expect {
74 timeout {puts "TESTING ERROR 6.3\n";exit} 78 timeout {puts "TESTING ERROR 6.3\n";exit}
75 "name=blablabla" 79 "name=blablabla"
76} 80}
77sleep 1 81after 100
78 82
79puts "\nall done\n" 83puts "\nall done\n"
80 84
diff --git a/test/apps/uget-gtk.exp b/test/apps/uget-gtk.exp
new file mode 100755
index 000000000..22c2a0831
--- /dev/null
+++ b/test/apps/uget-gtk.exp
@@ -0,0 +1,84 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail uget-gtk\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Reading profile /etc/firejail/uget-gtk.profile"
14}
15expect {
16 timeout {puts "TESTING ERROR 1\n";exit}
17 "Child process initialized"
18}
19sleep 3
20
21spawn $env(SHELL)
22send -- "firejail --list\r"
23expect {
24 timeout {puts "TESTING ERROR 3\n";exit}
25 ":firejail"
26}
27expect {
28 timeout {puts "TESTING ERROR 3.1\n";exit}
29 "uget-gtk"
30}
31after 100
32
33# grsecurity exit
34send -- "file /proc/sys/kernel/grsecurity\r"
35expect {
36 timeout {puts "TESTING ERROR - grsecurity detection\n";exit}
37 "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit}
38 "cannot open" {puts "grsecurity not present\n"}
39}
40
41send -- "firejail --name=blablabla\r"
42expect {
43 timeout {puts "TESTING ERROR 4\n";exit}
44 "Child process initialized"
45}
46sleep 2
47
48spawn $env(SHELL)
49send -- "firemon --seccomp\r"
50expect {
51 timeout {puts "TESTING ERROR 5\n";exit}
52 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
53 ":firejail uget-gtk"
54}
55expect {
56 timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit}
57 "Seccomp: 2"
58}
59expect {
60 timeout {puts "TESTING ERROR 5.1\n";exit}
61 "name=blablabla"
62}
63after 100
64send -- "firemon --caps\r"
65expect {
66 timeout {puts "TESTING ERROR 6\n";exit}
67 ":firejail uget-gtk"
68}
69expect {
70 timeout {puts "TESTING ERROR 6.1\n";exit}
71 "CapBnd:"
72}
73expect {
74 timeout {puts "TESTING ERROR 6.2\n";exit}
75 "0000000000000000"
76}
77expect {
78 timeout {puts "TESTING ERROR 6.3\n";exit}
79 "name=blablabla"
80}
81after 100
82
83puts "\nall done\n"
84
diff --git a/test/vlc.exp b/test/apps/vlc.exp
index 290c0fc2f..b94ef8e12 100755
--- a/test/vlc.exp
+++ b/test/apps/vlc.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -25,7 +28,7 @@ expect {
25 timeout {puts "TESTING ERROR 3.1\n";exit} 28 timeout {puts "TESTING ERROR 3.1\n";exit}
26 "vlc" 29 "vlc"
27} 30}
28sleep 1 31after 100
29 32
30# grsecurity exit 33# grsecurity exit
31send -- "file /proc/sys/kernel/grsecurity\r" 34send -- "file /proc/sys/kernel/grsecurity\r"
@@ -46,6 +49,7 @@ spawn $env(SHELL)
46send -- "firemon --seccomp\r" 49send -- "firemon --seccomp\r"
47expect { 50expect {
48 timeout {puts "TESTING ERROR 5\n";exit} 51 timeout {puts "TESTING ERROR 5\n";exit}
52 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
49 ":firejail vlc" 53 ":firejail vlc"
50} 54}
51expect { 55expect {
@@ -56,7 +60,7 @@ expect {
56 timeout {puts "TESTING ERROR 5.1\n";exit} 60 timeout {puts "TESTING ERROR 5.1\n";exit}
57 "name=blablabla" 61 "name=blablabla"
58} 62}
59sleep 1 63after 100
60send -- "firemon --caps\r" 64send -- "firemon --caps\r"
61expect { 65expect {
62 timeout {puts "TESTING ERROR 6\n";exit} 66 timeout {puts "TESTING ERROR 6\n";exit}
@@ -74,7 +78,7 @@ expect {
74 timeout {puts "TESTING ERROR 6.3\n";exit} 78 timeout {puts "TESTING ERROR 6.3\n";exit}
75 "name=blablabla" 79 "name=blablabla"
76} 80}
77sleep 1 81after 100
78 82
79puts "\nall done\n" 83puts "\nall done\n"
80 84
diff --git a/test/wine.exp b/test/apps/wine.exp
index f5b7d12b4..a2f465acb 100755
--- a/test/wine.exp
+++ b/test/apps/wine.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
diff --git a/test/xchat.exp b/test/apps/xchat.exp
index cde89d754..f3284caf7 100755
--- a/test/xchat.exp
+++ b/test/apps/xchat.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -25,7 +28,7 @@ expect {
25 timeout {puts "TESTING ERROR 3.1\n";exit} 28 timeout {puts "TESTING ERROR 3.1\n";exit}
26 "xchat" 29 "xchat"
27} 30}
28sleep 1 31after 100
29 32
30# grsecurity exit 33# grsecurity exit
31send -- "file /proc/sys/kernel/grsecurity\r" 34send -- "file /proc/sys/kernel/grsecurity\r"
@@ -46,6 +49,7 @@ spawn $env(SHELL)
46send -- "firemon --seccomp\r" 49send -- "firemon --seccomp\r"
47expect { 50expect {
48 timeout {puts "TESTING ERROR 5\n";exit} 51 timeout {puts "TESTING ERROR 5\n";exit}
52 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
49 " xchat" 53 " xchat"
50} 54}
51expect { 55expect {
@@ -56,7 +60,7 @@ expect {
56 timeout {puts "TESTING ERROR 5.1\n";exit} 60 timeout {puts "TESTING ERROR 5.1\n";exit}
57 "name=blablabla" 61 "name=blablabla"
58} 62}
59sleep 1 63after 100
60send -- "firemon --caps\r" 64send -- "firemon --caps\r"
61expect { 65expect {
62 timeout {puts "TESTING ERROR 6\n";exit} 66 timeout {puts "TESTING ERROR 6\n";exit}
@@ -74,7 +78,7 @@ expect {
74 timeout {puts "TESTING ERROR 6.3\n";exit} 78 timeout {puts "TESTING ERROR 6.3\n";exit}
75 "name=blablabla" 79 "name=blablabla"
76} 80}
77sleep 1 81after 100
78 82
79puts "\n" 83puts "\n"
80 84
diff --git a/test/arguments/arguments.sh b/test/arguments/arguments.sh
new file mode 100755
index 000000000..db4c9b472
--- /dev/null
+++ b/test/arguments/arguments.sh
@@ -0,0 +1,23 @@
1#!/bin/bash
2
3[ -f argtest ] || make argtest
4
5echo "TESTING: 1. regular bash session"
6./bashrun.exp
7sleep 1
8
9echo "TESTING: 2. symbolic link to firejail"
10./symrun.exp
11rm -fr symtest
12sleep 1
13
14echo "TESTING: 3. --join option"
15./joinrun.exp
16sleep 1
17
18echo "TESTING: 4. --output option"
19./outrun.exp
20rm out
21rm out.*
22
23
diff --git a/test/arguments/bashrun.exp b/test/arguments/bashrun.exp
new file mode 100755
index 000000000..a3c9e382d
--- /dev/null
+++ b/test/arguments/bashrun.exp
@@ -0,0 +1,86 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "./bashrun.sh\r"
8expect {
9 timeout {puts "TESTING ERROR 1.1.1\n";exit}
10 "Arguments:"
11}
12expect {
13 timeout {puts "TESTING ERROR 1.1.2\n";exit}
14 "#arg1#"
15}
16expect {
17 timeout {puts "TESTING ERROR 1.1.3\n";exit}
18 "#arg2#"
19}
20
21expect {
22 timeout {puts "TESTING ERROR 1.2.1\n";exit}
23 "Arguments:"
24}
25expect {
26 timeout {puts "TESTING ERROR 1.2.2\n";exit}
27 "#arg1 tail#"
28}
29expect {
30 timeout {puts "TESTING ERROR 1.2.3\n";exit}
31 "#arg2 tail#"
32}
33
34expect {
35 timeout {puts "TESTING ERROR 1.3.1\n";exit}
36 "Arguments:"
37}
38expect {
39 timeout {puts "TESTING ERROR 1.3.2\n";exit}
40 "#arg1 tail#"
41}
42expect {
43 timeout {puts "TESTING ERROR 1.3.3\n";exit}
44 "#arg2 tail#"
45}
46
47expect {
48 timeout {puts "TESTING ERROR 1.4.1\n";exit}
49 "Arguments:"
50}
51expect {
52 timeout {puts "TESTING ERROR 1.4.2\n";exit}
53 "#arg1 tail#"
54}
55expect {
56 timeout {puts "TESTING ERROR 1.4.3\n";exit}
57 "#arg2 tail#"
58}
59
60expect {
61 timeout {puts "TESTING ERROR 1.5.1\n";exit}
62 "Arguments:"
63}
64expect {
65 timeout {puts "TESTING ERROR 1.5.2\n";exit}
66 "#arg1&tail#"
67}
68expect {
69 timeout {puts "TESTING ERROR 1.5.3\n";exit}
70 "#arg2&tail#"
71}
72
73expect {
74 timeout {puts "TESTING ERROR 1.6.1\n";exit}
75 "Arguments:"
76}
77expect {
78 timeout {puts "TESTING ERROR 1.6.2\n";exit}
79 "#arg1&tail#"
80}
81expect {
82 timeout {puts "TESTING ERROR 1.6.3\n";exit}
83 "#arg2&tail#"
84}
85
86puts "\nall done\n"
diff --git a/test/arguments/bashrun.sh b/test/arguments/bashrun.sh
new file mode 100755
index 000000000..0797c92c2
--- /dev/null
+++ b/test/arguments/bashrun.sh
@@ -0,0 +1,22 @@
1#!/bin/bash
2
3echo "TESTING: 1.1 - simple args"
4firejail --env=FIREJAIL_TEST_ARGUMENTS=yes --quiet /usr/lib/firejail/faudit arg1 arg2
5
6# simple quotes, testing spaces in file names
7echo "TESTING: 1.2 - args with space and \""
8firejail --env=FIREJAIL_TEST_ARGUMENTS=yes --quiet /usr/lib/firejail/faudit "arg1 tail" "arg2 tail"
9
10echo "TESTING: 1.3 - args with space and '"
11firejail --env=FIREJAIL_TEST_ARGUMENTS=yes --quiet /usr/lib/firejail/faudit 'arg1 tail' 'arg2 tail'
12
13# escaped space in file names
14echo "TESTING: 1.4 - args with space and \\"
15firejail --env=FIREJAIL_TEST_ARGUMENTS=yes --quiet /usr/lib/firejail/faudit arg1\ tail arg2\ tail
16
17# & char appears in URLs - URLs should be quoted
18echo "TESTING: 1.5 - args with & and \""
19firejail --env=FIREJAIL_TEST_ARGUMENTS=yes --quiet /usr/lib/firejail/faudit "arg1&tail" "arg2&tail"
20
21echo "TESTING: 1.6 - args with & and '"
22firejail --env=FIREJAIL_TEST_ARGUMENTS=yes --quiet /usr/lib/firejail/faudit 'arg1&tail' 'arg2&tail'
diff --git a/test/arguments/joinrun.exp b/test/arguments/joinrun.exp
new file mode 100755
index 000000000..8e8570e4f
--- /dev/null
+++ b/test/arguments/joinrun.exp
@@ -0,0 +1,91 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7
8send -- "firejail --name=joinrun\r"
9sleep 2
10
11spawn $env(SHELL)
12send -- "./joinrun.sh\r"
13expect {
14 timeout {puts "TESTING ERROR 3.1.1\n";exit}
15 "Arguments:"
16}
17expect {
18 timeout {puts "TESTING ERROR 3.1.2\n";exit}
19 "#arg1#"
20}
21expect {
22 timeout {puts "TESTING ERROR 3.1.3\n";exit}
23 "#arg2#"
24}
25
26expect {
27 timeout {puts "TESTING ERROR 3.2.1\n";exit}
28 "Arguments:"
29}
30expect {
31 timeout {puts "TESTING ERROR 3.2.2\n";exit}
32 "#arg1 tail#"
33}
34expect {
35 timeout {puts "TESTING ERROR 3.2.3\n";exit}
36 "#arg2 tail#"
37}
38
39expect {
40 timeout {puts "TESTING ERROR 3.3.1\n";exit}
41 "Arguments:"
42}
43expect {
44 timeout {puts "TESTING ERROR 3.3.2\n";exit}
45 "#arg1 tail#"
46}
47expect {
48 timeout {puts "TESTING ERROR 3.3.3\n";exit}
49 "#arg2 tail#"
50}
51
52expect {
53 timeout {puts "TESTING ERROR 3.4.1\n";exit}
54 "Arguments:"
55}
56expect {
57 timeout {puts "TESTING ERROR 3.4.2\n";exit}
58 "#arg1 tail#"
59}
60expect {
61 timeout {puts "TESTING ERROR 3.4.3\n";exit}
62 "#arg2 tail#"
63}
64
65expect {
66 timeout {puts "TESTING ERROR 3.5.1\n";exit}
67 "Arguments:"
68}
69expect {
70 timeout {puts "TESTING ERROR 3.5.2\n";exit}
71 "#arg1&tail#"
72}
73expect {
74 timeout {puts "TESTING ERROR 3.5.3\n";exit}
75 "#arg2&tail#"
76}
77
78expect {
79 timeout {puts "TESTING ERROR 3.6.1\n";exit}
80 "Arguments:"
81}
82expect {
83 timeout {puts "TESTING ERROR 3.6.2\n";exit}
84 "#arg1&tail#"
85}
86expect {
87 timeout {puts "TESTING ERROR 3.6.3\n";exit}
88 "#arg2&tail#"
89}
90
91puts "\nall done\n"
diff --git a/test/arguments/joinrun.sh b/test/arguments/joinrun.sh
new file mode 100755
index 000000000..2743d823e
--- /dev/null
+++ b/test/arguments/joinrun.sh
@@ -0,0 +1,22 @@
1#!/bin/bash
2
3echo "TESTING: 3.1 - simple args"
4firejail --env=FIREJAIL_TEST_ARGUMENTS=yes --join=joinrun /usr/lib/firejail/faudit arg1 arg2
5
6# simple quotes, testing spaces in file names
7echo "TESTING: 3.2 - args with space and \""
8firejail--env=FIREJAIL_TEST_ARGUMENTS=yes --quiet /usr/lib/firejail/faudit "arg1 tail" "arg2 tail"
9
10echo "TESTING: 3.3 - args with space and '"
11firejail --env=FIREJAIL_TEST_ARGUMENTS=yes --quiet /usr/lib/firejail/faudit 'arg1 tail' 'arg2 tail'
12
13# escaped space in file names
14echo "TESTING: 3.4 - args with space and \\"
15firejail--env=FIREJAIL_TEST_ARGUMENTS=yes --quiet /usr/lib/firejail/faudit arg1\ tail arg2\ tail
16
17# & char appears in URLs - URLs should be quoted
18echo "TESTING: 3.5 - args with & and \""
19firejail --env=FIREJAIL_TEST_ARGUMENTS=yes --quiet /usr/lib/firejail/faudit "arg1&tail" "arg2&tail"
20
21echo "TESTING: 3.6 - args with & and '"
22firejail --env=FIREJAIL_TEST_ARGUMENTS=yes --quiet /usr/lib/firejail/faudit 'arg1&tail' 'arg2&tail'
diff --git a/test/arguments/outrun.exp b/test/arguments/outrun.exp
new file mode 100755
index 000000000..d28e75661
--- /dev/null
+++ b/test/arguments/outrun.exp
@@ -0,0 +1,90 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "./outrun.sh\r"
8expect {
9 timeout {puts "TESTING ERROR 4.1.1\n";exit}
10 "Arguments:"
11}
12expect {
13 timeout {puts "TESTING ERROR 4.1.2\n";exit}
14 "#arg1#"
15}
16expect {
17 timeout {puts "TESTING ERROR 4.1.3\n";exit}
18 "#arg2#"
19}
20
21exit
22#***************************************************
23# breaking down from here on - bug to fix
24#***************************************************
25expect {
26 timeout {puts "TESTING ERROR 4.2.1\n";exit}
27 "Arguments:"
28}
29expect {
30 timeout {puts "TESTING ERROR 4.2.2\n";exit}
31 "#arg1 tail#"
32}
33expect {
34 timeout {puts "TESTING ERROR 4.2.3\n";exit}
35 "#arg2 tail#"
36}
37
38expect {
39 timeout {puts "TESTING ERROR 4.3.1\n";exit}
40 "Arguments:"
41}
42expect {
43 timeout {puts "TESTING ERROR 4.3.2\n";exit}
44 "#arg1 tail#"
45}
46expect {
47 timeout {puts "TESTING ERROR 4.3.3\n";exit}
48 "#arg2 tail#"
49}
50
51expect {
52 timeout {puts "TESTING ERROR 4.4.1\n";exit}
53 "Arguments:"
54}
55expect {
56 timeout {puts "TESTING ERROR 4.4.2\n";exit}
57 "#arg1 tail#"
58}
59expect {
60 timeout {puts "TESTING ERROR 4.4.3\n";exit}
61 "#arg2 tail#"
62}
63
64expect {
65 timeout {puts "TESTING ERROR 4.5.1\n";exit}
66 "Arguments:"
67}
68expect {
69 timeout {puts "TESTING ERROR 4.5.2\n";exit}
70 "#arg1&tail#"
71}
72expect {
73 timeout {puts "TESTING ERROR 4.5.3\n";exit}
74 "#arg2&tail#"
75}
76
77expect {
78 timeout {puts "TESTING ERROR 4.6.1\n";exit}
79 "Arguments:"
80}
81expect {
82 timeout {puts "TESTING ERROR 4.6.2\n";exit}
83 "#arg1&tail#"
84}
85expect {
86 timeout {puts "TESTING ERROR 4.6.3\n";exit}
87 "#arg2&tail#"
88}
89
90puts "\nall done\n"
diff --git a/test/arguments/outrun.sh b/test/arguments/outrun.sh
new file mode 100755
index 000000000..a21243873
--- /dev/null
+++ b/test/arguments/outrun.sh
@@ -0,0 +1,22 @@
1#!/bin/bash
2
3echo "TESTING: 4.1 - simple args"
4firejail --env=FIREJAIL_TEST_ARGUMENTS=yes --output=out /usr/lib/firejail/faudit arg1 arg2
5
6# simple quotes, testing spaces in file names
7echo "TESTING: 4.2 - args with space and \""
8firejail --env=FIREJAIL_TEST_ARGUMENTS=yes --output=out /usr/lib/firejail/faudit "arg1 tail" "arg2 tail"
9
10echo "TESTING: 4.3 - args with space and '"
11firejail--env=FIREJAIL_TEST_ARGUMENTS=yes --output=out /usr/lib/firejail/faudit 'arg1 tail' 'arg2 tail'
12
13# escaped space in file names
14echo "TESTING: 4.4 - args with space and \\"
15firejail--env=FIREJAIL_TEST_ARGUMENTS=yes --output=out /usr/lib/firejail/faudit arg1\ tail arg2\ tail
16
17# & char appears in URLs - URLs should be quoted
18echo "TESTING: 4.5 - args with & and \""
19firejail --env=FIREJAIL_TEST_ARGUMENTS=yes --output=out /usr/lib/firejail/faudit "arg1&tail" "arg2&tail"
20
21echo "TESTING: 4.6 - args with & and '"
22firejail--env=FIREJAIL_TEST_ARGUMENTS=yes --output=out /usr/lib/firejail/faudit 'arg1&tail' 'arg2&tail'
diff --git a/test/arguments/symrun.exp b/test/arguments/symrun.exp
new file mode 100755
index 000000000..10e7ac6c8
--- /dev/null
+++ b/test/arguments/symrun.exp
@@ -0,0 +1,71 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "./symrun.sh\r"
8expect {
9 timeout {puts "TESTING ERROR 2.1.1\n";exit}
10 "Arguments:"
11}
12expect {
13 timeout {puts "TESTING ERROR 2.1.2\n";exit}
14 "#arg1#"
15}
16expect {
17 timeout {puts "TESTING ERROR 2.1.3\n";exit}
18 "#arg2#"
19}
20
21expect {
22 timeout {puts "TESTING ERROR 2.3.1\n";exit}
23 "Arguments:"
24}
25expect {
26 timeout {puts "TESTING ERROR 2.3.2\n";exit}
27 "#arg1 tail#"
28}
29expect {
30 timeout {puts "TESTING ERROR 2.3.3\n";exit}
31 "#arg2 tail#"
32}
33
34expect {
35 timeout {puts "TESTING ERROR 2.4.1\n";exit}
36 "Arguments:"
37}
38expect {
39 timeout {puts "TESTING ERROR 2.4.2\n";exit}
40 "#arg1 tail#"
41}
42expect {
43 timeout {puts "TESTING ERROR 2.4.3\n";exit}
44 "#arg2 tail#"
45}
46
47expect {
48 timeout {puts "TESTING ERROR 2.5.1\n";exit}
49 "Arguments:"
50}
51expect {
52 timeout {puts "TESTING ERROR 2.5.2\n";exit}
53 "#arg1&tail#"
54}
55expect {
56 timeout {puts "TESTING ERROR 2.5.3\n";exit}
57 "#arg2&tail#"
58}
59
60expect {
61 timeout {puts "TESTING ERROR 2.6.1\n";exit}
62 "Arguments:"
63}
64expect {
65 timeout {puts "TESTING ERROR 2.6.2\n";exit}
66 "#arg1&tail#"
67}
68expect {
69 timeout {puts "TESTING ERROR 2.6.3\n";exit}
70 "#arg2&tail#"
71}
diff --git a/test/arguments/symrun.sh b/test/arguments/symrun.sh
new file mode 100755
index 000000000..d28f024a8
--- /dev/null
+++ b/test/arguments/symrun.sh
@@ -0,0 +1,30 @@
1#!/bin/bash
2
3mkdir symtest
4ln -s /usr/bin/firejail symtest/argtest
5
6# search for argtest in current directory
7export PATH=$PATH:.
8
9echo "TESTING: 2.1 - simple args"
10symtest/argtest arg1 arg2
11
12# simple quotes, testing spaces in file names
13echo "TESTING: 2.2 - args with space and \""
14symtest/argtest "arg1 tail" "arg2 tail"
15
16echo "TESTING: 2.3 - args with space and '"
17symtest/argtest 'arg1 tail' 'arg2 tail'
18
19# escaped space in file names
20echo "TESTING: 2.4 - args with space and \\"
21symtest/argtest arg1\ tail arg2\ tail
22
23# & char appears in URLs - URLs should be quoted
24echo "TESTING: 2.5 - args with & and \""
25symtest/argtest "arg1&tail" "arg2&tail"
26
27echo "TESTING: 2.6 - args with & and '"
28symtest/argtest 'arg1&tail' 'arg2&tail'
29
30rm -fr symtest
diff --git a/test/auto/autotest.sh b/test/auto/autotest.sh
deleted file mode 100755
index 0fb7565af..000000000
--- a/test/auto/autotest.sh
+++ /dev/null
@@ -1,202 +0,0 @@
1#!/bin/bash
2
3arr[1]="TEST 1: svn and standard compilation"
4arr[2]="TEST 2: cppcheck"
5arr[3]="TEST 3: compile seccomp disabled, chroot disabled, bind disabled"
6arr[4]="TEST 4: rvtest"
7arr[5]="TEST 5: expect test as root, no malloc perturb"
8arr[6]="TEST 6: expect test as user, no malloc perturb"
9arr[7]="TEST 7: expect test as root, malloc perturb"
10arr[8]="TEST 8: expect test as user, malloc perturb"
11
12
13# remove previous reports and output file
14cleanup() {
15 rm -f out-test
16 rm -f output*
17 rm -f report*
18 rm -fr firejail-trunk
19}
20
21print_title() {
22 echo
23 echo
24 echo
25 echo "**************************************************"
26 echo $1
27 echo "**************************************************"
28}
29
30while [ $# -gt 0 ]; do # Until you run out of parameters . . .
31 case "$1" in
32 --clean)
33 cleanup
34 exit
35 ;;
36 --help)
37 echo "./autotest.sh [--clean|--help]"
38 exit
39 ;;
40 esac
41 shift # Check next set of parameters.
42done
43
44cleanup
45# enable sudo
46sudo ls -al
47
48#*****************************************************************
49# TEST 1
50#*****************************************************************
51# - checkout source code
52# - check compilation
53# - install
54#*****************************************************************
55print_title "${arr[1]}"
56svn checkout svn://svn.code.sf.net/p/firejail/code-0/trunk firejail-trunk
57cd firejail-trunk
58./configure --prefix=/usr 2>&1 | tee ../output-configure
59make -j4 2>&1 | tee ../output-make
60sudo make install 2>&1 | tee ../output-install
61cd src/tools
62gcc -o rvtest rvtest.c
63cd ../..
64cd test
65sudo ./configure > /dev/null
66cd ../..
67grep warning output-configure output-make output-install > ./report-test1
68grep error output-configure output-make output-install >> ./report-test1
69cat report-test1 > out-test1
70
71#*****************************************************************
72# TEST 2
73#*****************************************************************
74# - run cppcheck
75#*****************************************************************
76print_title "${arr[2]}"
77cd firejail-trunk
78cp /home/netblue/bin/cfg/std.cfg .
79cppcheck --force . 2>&1 | tee ../output-cppcheck
80cd ..
81grep error output-cppcheck > report-test2
82cat report-test2 > out-test2
83
84#*****************************************************************
85# TEST 3
86#*****************************************************************
87# - disable seccomp configuration
88# - check compilation
89#*****************************************************************
90print_title "${arr[3]}"
91# seccomp
92cd firejail-trunk
93make distclean
94./configure --prefix=/usr --disable-seccomp 2>&1 | tee ../output-configure-noseccomp
95make -j4 2>&1 | tee ../output-make-noseccomp
96cd ..
97grep warning output-configure-noseccomp output-make-noseccomp > ./report-test3
98grep error output-configure-noseccomp output-make-noseccomp >> ./report-test3
99# chroot
100cd firejail-trunk
101make distclean
102./configure --prefix=/usr --disable-chroot 2>&1 | tee ../output-configure-nochroot
103make -j4 2>&1 | tee ../output-make-nochroot
104cd ..
105grep warning output-configure-nochroot output-make-nochroot >> ./report-test3
106grep error output-configure-nochroot output-make-nochroot >> ./report-test3
107# bind
108cd firejail-trunk
109make distclean
110./configure --prefix=/usr --disable-bind 2>&1 | tee ../output-configure-nobind
111make -j4 2>&1 | tee ../output-make-nobind
112cd ..
113grep warning output-configure-nobind output-make-nobind >> ./report-test3
114grep error output-configure-nobind output-make-nobind >> ./report-test3
115# save result
116cat report-test3 > out-test3
117
118#*****************************************************************
119# TEST 4
120#*****************************************************************
121# - rvtest
122#*****************************************************************
123print_title "${arr[4]}"
124cd firejail-trunk
125cd test
126../src/tools/rvtest test.rv 2>/dev/null | tee ../../output-test4 | grep TESTING
127cd ../..
128grep TESTING output-test4 > ./report-test4
129grep ERROR report-test4 > out-test4
130
131
132#*****************************************************************
133# TEST 5
134#*****************************************************************
135# - expect test as root, no malloc perturb
136#*****************************************************************
137print_title "${arr[5]}"
138cd firejail-trunk/test
139sudo ./test-root.sh 2>&1 | tee ../../output-test5 | grep TESTING
140cd ../..
141grep TESTING output-test5 > ./report-test5
142grep ERROR report-test5 > out-test5
143
144#*****************************************************************
145# TEST 6
146#*****************************************************************
147# - expect test as user, no malloc perturb
148#*****************************************************************
149print_title "${arr[6]}"
150cd firejail-trunk/test
151./test.sh 2>&1 | tee ../../output-test6 | grep TESTING
152cd ../..
153grep TESTING output-test6 > ./report-test6
154grep ERROR report-test6 > out-test6
155
156
157
158#*****************************************************************
159# TEST 7
160#*****************************************************************
161# - expect test as root, malloc perturb
162#*****************************************************************
163print_title "${arr[7]}"
164export MALLOC_CHECK_=3
165export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
166cd firejail-trunk/test
167sudo ./test-root.sh 2>&1 | tee ../../output-test7 | grep TESTING
168cd ../..
169grep TESTING output-test7 > ./report-test7
170grep ERROR report-test7 > out-test7
171
172#*****************************************************************
173# TEST 8
174#*****************************************************************
175# - expect test as user, malloc perturb
176#*****************************************************************
177print_title "${arr[8]}"
178cd firejail-trunk/test
179./test.sh 2>&1 | tee ../../output-test8| grep TESTING
180cd ../..
181grep TESTING output-test8 > ./report-test8
182grep ERROR report-test8 > out-test8
183
184#*****************************************************************
185# PRINT REPORTS
186#*****************************************************************
187echo
188echo
189echo
190echo
191echo "**********************************************************"
192echo "TEST RESULTS"
193echo "**********************************************************"
194
195wc -l out-test*
196rm out-test*
197echo
198
199
200
201
202exit
diff --git a/test/compile/compile.sh b/test/compile/compile.sh
index e3e9bef2b..44e67fe22 100755
--- a/test/compile/compile.sh
+++ b/test/compile/compile.sh
@@ -9,13 +9,18 @@ arr[6]="TEST 6: compile network disabled"
9arr[7]="TEST 7: compile X11 disabled" 9arr[7]="TEST 7: compile X11 disabled"
10arr[8]="TEST 8: compile network restricted" 10arr[8]="TEST 8: compile network restricted"
11arr[9]="TEST 9: compile file transfer disabled" 11arr[9]="TEST 9: compile file transfer disabled"
12 12arr[10]="TEST 10: compile disable whitelist"
13arr[11]="TEST 11: compile disable global config"
14arr[12]="TEST 12: compile apparmor"
15arr[13]="TEST 13: compile busybox"
16arr[14]="TEST 14: compile overlayfs disabled"
17arr[15]="TEST 15: compile apparmor enabled"
13 18
14# remove previous reports and output file 19# remove previous reports and output file
15cleanup() { 20cleanup() {
16 rm -f report* 21 rm -f report*
17 rm -fr firejail 22 rm -fr firejail
18 rm oc* om* 23 rm -f oc* om*
19} 24}
20 25
21print_title() { 26print_title() {
@@ -27,6 +32,7 @@ print_title() {
27 echo "**************************************************" 32 echo "**************************************************"
28} 33}
29 34
35DIST="$1"
30while [ $# -gt 0 ]; do # Until you run out of parameters . . . 36while [ $# -gt 0 ]; do # Until you run out of parameters . . .
31 case "$1" in 37 case "$1" in
32 --clean) 38 --clean)
@@ -42,36 +48,33 @@ while [ $# -gt 0 ]; do # Until you run out of parameters . . .
42done 48done
43 49
44cleanup 50cleanup
45# enable sudo
46sudo ls -al
47 51
48 52
49#***************************************************************** 53#*****************************************************************
50# TEST 1 54# TEST 1
51#***************************************************************** 55#*****************************************************************
52# - checkout source code 56# - checkout source code
53# - check compilation
54# - install
55#***************************************************************** 57#*****************************************************************
56print_title "${arr[1]}" 58print_title "${arr[1]}"
57git clone https://github.com/netblue30/firejail.git 59echo "$DIST"
60tar -xJvf ../../$DIST.tar.xz
61mv $DIST firejail
62
58cd firejail 63cd firejail
59./configure --prefix=/usr --enable-fatal-warnings 2>&1 | tee ../output-configure 64./configure --prefix=/usr --enable-fatal-warnings 2>&1 | tee ../output-configure
60make -j4 2>&1 | tee ../output-make 65make -j4 2>&1 | tee ../output-make
61sudo make install 2>&1 | tee ../output-install
62cd .. 66cd ..
63grep Warning output-configure output-make output-install > ./report-test1 67grep Warning output-configure output-make > ./report-test1
64grep Error output-configure output-make output-install >> ./report-test1 68grep Error output-configure output-make >> ./report-test1
65cp output-configure oc1 69cp output-configure oc1
66cp output-make om1 70cp output-make om1
67rm output-configure output-make output-install 71rm output-configure output-make
68 72
69 73
70#***************************************************************** 74#*****************************************************************
71# TEST 2 75# TEST 2
72#***************************************************************** 76#*****************************************************************
73# - disable seccomp configuration 77# - disable seccomp configuration
74# - check compilation
75#***************************************************************** 78#*****************************************************************
76print_title "${arr[2]}" 79print_title "${arr[2]}"
77# seccomp 80# seccomp
@@ -90,7 +93,6 @@ rm output-configure output-make
90# TEST 3 93# TEST 3
91#***************************************************************** 94#*****************************************************************
92# - disable chroot configuration 95# - disable chroot configuration
93# - check compilation
94#***************************************************************** 96#*****************************************************************
95print_title "${arr[3]}" 97print_title "${arr[3]}"
96# seccomp 98# seccomp
@@ -109,7 +111,6 @@ rm output-configure output-make
109# TEST 4 111# TEST 4
110#***************************************************************** 112#*****************************************************************
111# - disable bind configuration 113# - disable bind configuration
112# - check compilation
113#***************************************************************** 114#*****************************************************************
114print_title "${arr[4]}" 115print_title "${arr[4]}"
115# seccomp 116# seccomp
@@ -128,7 +129,6 @@ rm output-configure output-make
128# TEST 5 129# TEST 5
129#***************************************************************** 130#*****************************************************************
130# - disable user namespace configuration 131# - disable user namespace configuration
131# - check compilation
132#***************************************************************** 132#*****************************************************************
133print_title "${arr[5]}" 133print_title "${arr[5]}"
134# seccomp 134# seccomp
@@ -166,7 +166,6 @@ rm output-configure output-make
166# TEST 7 166# TEST 7
167#***************************************************************** 167#*****************************************************************
168# - disable X11 support 168# - disable X11 support
169# - check compilation
170#***************************************************************** 169#*****************************************************************
171print_title "${arr[7]}" 170print_title "${arr[7]}"
172# seccomp 171# seccomp
@@ -186,7 +185,6 @@ rm output-configure output-make
186# TEST 8 185# TEST 8
187#***************************************************************** 186#*****************************************************************
188# - enable network restricted 187# - enable network restricted
189# - check compilation
190#***************************************************************** 188#*****************************************************************
191print_title "${arr[8]}" 189print_title "${arr[8]}"
192# seccomp 190# seccomp
@@ -206,13 +204,12 @@ rm output-configure output-make
206# TEST 9 204# TEST 9
207#***************************************************************** 205#*****************************************************************
208# - disable file transfer 206# - disable file transfer
209# - check compilation
210#***************************************************************** 207#*****************************************************************
211print_title "${arr[9]}" 208print_title "${arr[9]}"
212# seccomp 209# seccomp
213cd firejail 210cd firejail
214make distclean 211make distclean
215./configure --prefix=/usr --enable-network=restricted --enable-fatal-warnings 2>&1 | tee ../output-configure 212./configure --prefix=/usr --disable-file-transfer --enable-fatal-warnings 2>&1 | tee ../output-configure
216make -j4 2>&1 | tee ../output-make 213make -j4 2>&1 | tee ../output-make
217cd .. 214cd ..
218grep Warning output-configure output-make > ./report-test9 215grep Warning output-configure output-make > ./report-test9
@@ -221,6 +218,114 @@ cp output-configure oc9
221cp output-make om9 218cp output-make om9
222rm output-configure output-make 219rm output-configure output-make
223 220
221#*****************************************************************
222# TEST 10
223#*****************************************************************
224# - disable whitelist
225#*****************************************************************
226print_title "${arr[10]}"
227# seccomp
228cd firejail
229make distclean
230./configure --prefix=/usr --disable-whitelist --enable-fatal-warnings 2>&1 | tee ../output-configure
231make -j4 2>&1 | tee ../output-make
232cd ..
233grep Warning output-configure output-make > ./report-test10
234grep Error output-configure output-make >> ./report-test10
235cp output-configure oc10
236cp output-make om10
237rm output-configure output-make
238
239#*****************************************************************
240# TEST 11
241#*****************************************************************
242# - disable global config
243#*****************************************************************
244print_title "${arr[11]}"
245# seccomp
246cd firejail
247make distclean
248./configure --prefix=/usr --disable-globalcfg --enable-fatal-warnings 2>&1 | tee ../output-configure
249make -j4 2>&1 | tee ../output-make
250cd ..
251grep Warning output-configure output-make > ./report-test11
252grep Error output-configure output-make >> ./report-test11
253cp output-configure oc11
254cp output-make om11
255rm output-configure output-make
256
257#*****************************************************************
258# TEST 12
259#*****************************************************************
260# - enable apparmor
261#*****************************************************************
262print_title "${arr[12]}"
263# seccomp
264cd firejail
265make distclean
266./configure --prefix=/usr --enable-apparmor --enable-fatal-warnings 2>&1 | tee ../output-configure
267make -j4 2>&1 | tee ../output-make
268cd ..
269grep Warning output-configure output-make > ./report-test12
270grep Error output-configure output-make >> ./report-test12
271cp output-configure oc12
272cp output-make om12
273rm output-configure output-make
274
275#*****************************************************************
276# TEST 13
277#*****************************************************************
278# - enable busybox workaround
279#*****************************************************************
280print_title "${arr[13]}"
281# seccomp
282cd firejail
283make distclean
284./configure --prefix=/usr --enable-busybox-workaround --enable-fatal-warnings 2>&1 | tee ../output-configure
285make -j4 2>&1 | tee ../output-make
286cd ..
287grep Warning output-configure output-make > ./report-test13
288grep Error output-configure output-make >> ./report-test13
289cp output-configure oc13
290cp output-make om13
291rm output-configure output-make
292
293#*****************************************************************
294# TEST 14
295#*****************************************************************
296# - disable overlayfs
297#*****************************************************************
298print_title "${arr[14]}"
299# seccomp
300cd firejail
301make distclean
302./configure --prefix=/usr --disable-overlayfs --enable-fatal-warnings 2>&1 | tee ../output-configure
303make -j4 2>&1 | tee ../output-make
304cd ..
305grep Warning output-configure output-make > ./report-test14
306grep Error output-configure output-make >> ./report-test14
307cp output-configure oc14
308cp output-make om14
309rm output-configure output-make
310
311#*****************************************************************
312# TEST 15
313#*****************************************************************
314# - enable apparmor
315#*****************************************************************
316print_title "${arr[15]}"
317# seccomp
318cd firejail
319make distclean
320./configure --prefix=/usr --enable-apparmor --enable-fatal-warnings 2>&1 | tee ../output-configure
321make -j4 2>&1 | tee ../output-make
322cd ..
323grep Warning output-configure output-make > ./report-test15
324grep Error output-configure output-make >> ./report-test15
325cp output-configure oc15
326cp output-make om15
327rm output-configure output-make
328
224 329
225#***************************************************************** 330#*****************************************************************
226# PRINT REPORTS 331# PRINT REPORTS
@@ -245,3 +350,10 @@ echo ${arr[6]}
245echo ${arr[7]} 350echo ${arr[7]}
246echo ${arr[8]} 351echo ${arr[8]}
247echo ${arr[9]} 352echo ${arr[9]}
353echo ${arr[10]}
354echo ${arr[11]}
355echo ${arr[12]}
356echo ${arr[13]}
357echo ${arr[14]}
358echo ${arr[15]}
359
diff --git a/test/configure b/test/configure
index bdf36fcad..9acd021c8 100755
--- a/test/configure
+++ b/test/configure
@@ -28,7 +28,7 @@ ROOTDIR="/tmp/chroot" # default chroot directory
28DEFAULT_FILES="/bin/bash /bin/sh " # basic chroot files 28DEFAULT_FILES="/bin/bash /bin/sh " # basic chroot files
29DEFAULT_FILES+="/etc/passwd /etc/nsswitch.conf /etc/group " 29DEFAULT_FILES+="/etc/passwd /etc/nsswitch.conf /etc/group "
30DEFAULT_FILES+=`find /lib -name libnss*` # files required by glibc 30DEFAULT_FILES+=`find /lib -name libnss*` # files required by glibc
31DEFAULT_FILES+=" /bin/cp /bin/ls /bin/cat /bin/ps /bin/netstat /bin/ping /sbin/ifconfig /usr/bin/touch /bin/hostname /bin/grep /usr/bin/dig /usr/bin/openssl /usr/bin/id /usr/bin/getent /usr/bin/whoami /usr/bin/wc /usr/bin/wget /bin/umount" 31DEFAULT_FILES+=" /bin/cp /bin/ls /bin/cat /bin/ps /bin/netstat /bin/ping /sbin/ifconfig /usr/bin/touch /bin/ip /bin/hostname /bin/grep /usr/bin/dig /usr/bin/openssl /usr/bin/id /usr/bin/getent /usr/bin/whoami /usr/bin/wc /usr/bin/wget /bin/umount"
32 32
33rm -fr $ROOTDIR 33rm -fr $ROOTDIR
34mkdir -p $ROOTDIR/{root,bin,lib,lib64,usr,home,etc,dev/shm,tmp,var/run,var/tmp,var/lock,var/log,proc} 34mkdir -p $ROOTDIR/{root,bin,lib,lib64,usr,home,etc,dev/shm,tmp,var/run,var/tmp,var/lock,var/log,proc}
diff --git a/test/dns.exp b/test/dns.exp
deleted file mode 100755
index 96513f278..000000000
--- a/test/dns.exp
+++ /dev/null
@@ -1,69 +0,0 @@
1#!/usr/bin/expect -f
2
3set timeout 30
4spawn $env(SHELL)
5match_max 100000
6
7# no chroot
8send -- "firejail --trace --dns=208.67.222.222 wget -q debian.org\r"
9expect {
10 timeout {puts "TESTING ERROR 1.1\n";exit}
11 "Child process initialized"
12}
13expect {
14 timeout {puts "TESTING ERROR 1.2\n";exit}
15 "1:wget:connect 208.67.222.222:53"
16}
17sleep 1
18
19send -- "rm index.html\r"
20sleep 1
21
22# with chroot
23send -- "firejail --chroot=/tmp/chroot --trace --dns=208.67.222.222 wget -q debian.org\r"
24expect {
25 timeout {puts "TESTING ERROR 2.1\n";exit}
26 "Child process initialized"
27}
28expect {
29 timeout {puts "TESTING ERROR 2.2\n";exit}
30 "1:wget:connect 208.67.222.222:53"
31}
32sleep 1
33
34send -- "rm index.html\r"
35sleep 1
36
37# net eth0
38send -- "firejail --net=eth0 --trace --dns=208.67.222.222 wget -q debian.org\r"
39expect {
40 timeout {puts "TESTING ERROR 3.1\n";exit}
41 "Child process initialized"
42}
43expect {
44 timeout {puts "TESTING ERROR 3.2\n";exit}
45 "1:wget:connect 208.67.222.222:53"
46}
47sleep 1
48
49send -- "rm index.html\r"
50sleep 1
51
52# net eth0 and chroot
53send -- "firejail --net=eth0 --chroot=/tmp/chroot --trace --dns=208.67.222.222 wget -q debian.org\r"
54expect {
55 timeout {puts "TESTING ERROR 4.1\n";exit}
56 "Child process initialized"
57}
58expect {
59 timeout {puts "TESTING ERROR 4.2\n";exit}
60 "1:wget:connect 208.67.222.222:53"
61}
62sleep 1
63
64send -- "rm index.html\r"
65sleep 1
66
67
68puts "\n"
69
diff --git a/test/environment/allow-debuggers.exp b/test/environment/allow-debuggers.exp
new file mode 100755
index 000000000..8a404decb
--- /dev/null
+++ b/test/environment/allow-debuggers.exp
@@ -0,0 +1,40 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4cd /home
5spawn $env(SHELL)
6match_max 100000
7
8send -- "firejail --profile=/etc/firejail/firefox.profile --allow-debuggers strace ls\r"
9expect {
10 timeout {puts "TESTING ERROR 0\n";exit}
11 "Child process initialized"
12}
13expect {
14 timeout {puts "TESTING ERROR 1\n";exit}
15 "ioctl"
16}
17expect {
18 timeout {puts "TESTING ERROR 2\n";exit}
19 "exit_group"
20}
21after 100
22
23send -- "firejail --allow-debuggers --profile=/etc/firejail/firefox.profile strace ls\r"
24expect {
25 timeout {puts "TESTING ERROR 3\n";exit}
26 "Child process initialized"
27}
28expect {
29 timeout {puts "TESTING ERROR 4\n";exit}
30 "ioctl"
31}
32expect {
33 timeout {puts "TESTING ERROR 5\n";exit}
34 "exit_group"
35}
36after 100
37
38
39puts "\nall done\n"
40
diff --git a/test/shell_csh.exp b/test/environment/csh.exp
index a2634f633..46e4bb3ca 100755
--- a/test/shell_csh.exp
+++ b/test/environment/csh.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -11,16 +14,13 @@ expect {
11} 14}
12sleep 1 15sleep 1
13 16
14send -- "ls -al;pwd\r" 17send -- "find /home\r"
15expect { 18expect {
16 timeout {puts "TESTING ERROR 1\n";exit} 19 timeout {puts "TESTING ERROR 1\n";exit}
17 ".cshrc" 20 ".cshrc"
18} 21}
19expect { 22
20 timeout {puts "TESTING ERROR 1.1\n";exit} 23send -- "env | grep SHELL\r"
21 "home"
22}
23send -- "env | grep SHELL;pwd\r"
24expect { 24expect {
25 timeout {puts "TESTING ERROR 2\n";exit} 25 timeout {puts "TESTING ERROR 2\n";exit}
26 "SHELL" 26 "SHELL"
@@ -29,12 +29,8 @@ expect {
29 timeout {puts "TESTING ERROR 2.1\n";exit} 29 timeout {puts "TESTING ERROR 2.1\n";exit}
30 "/bin/csh" 30 "/bin/csh"
31} 31}
32expect {
33 timeout {puts "TESTING ERROR 2.2\n";exit}
34 "home"
35}
36send -- "exit\r" 32send -- "exit\r"
37sleep 1 33after 100
38 34
39puts "\n" 35puts "\n"
40 36
diff --git a/test/shell_dash.exp b/test/environment/dash.exp
index f5a60719e..cd051ea7c 100755
--- a/test/shell_dash.exp
+++ b/test/environment/dash.exp
@@ -1,6 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2 2
3set timeout 10 3set timeout 10
4cd /home
4spawn $env(SHELL) 5spawn $env(SHELL)
5match_max 100000 6match_max 100000
6 7
@@ -35,7 +36,7 @@ expect {
35 "home" 36 "home"
36} 37}
37send -- "exit\r" 38send -- "exit\r"
38sleep 1 39after 100
39 40
40puts "\n" 41puts "\n"
41 42
diff --git a/test/environment/dns.exp b/test/environment/dns.exp
new file mode 100755
index 000000000..6ffb124cf
--- /dev/null
+++ b/test/environment/dns.exp
@@ -0,0 +1,30 @@
1#!/usr/bin/expect -f
2
3set timeout 30
4spawn $env(SHELL)
5match_max 100000
6
7# no chroot
8send -- "firejail --trace --dns=208.67.222.222 wget -q debian.org\r"
9expect {
10 timeout {puts "TESTING ERROR 1.1\n";exit}
11 "Child process initialized"
12}
13expect {
14 timeout {puts "TESTING ERROR 1.2\n";exit}
15 "connect"
16}
17expect {
18 timeout {puts "TESTING ERROR 1.2\n";exit}
19 "208.67.222.222"
20}
21expect {
22 timeout {puts "TESTING ERROR 1.2\n";exit}
23 "53"
24}
25
26after 100
27
28send -- "rm index.html\r"
29after 100
30puts "\nall done\n"
diff --git a/test/doubledash.exp b/test/environment/doubledash.exp
index 668468980..2eaa7d9ce 100755
--- a/test/doubledash.exp
+++ b/test/environment/doubledash.exp
@@ -36,25 +36,25 @@ expect {
36sleep 3 36sleep 3
37 37
38spawn $env(SHELL) 38spawn $env(SHELL)
39send -- "firejail --list;pwd\r" 39send -- "firejail --list;ls -d /tmp\r"
40expect { 40expect {
41 timeout {puts "TESTING ERROR 6\n";exit} 41 timeout {puts "TESTING ERROR 6\n";exit}
42 "name=testing" 42 "name=testing"
43} 43}
44expect { 44expect {
45 timeout {puts "TESTING ERROR 7\n";exit} 45 timeout {puts "TESTING ERROR 7\n";exit}
46 "home" 46 "/tmp"
47} 47}
48send -- "firejail --list;pwd\r" 48send -- "firejail --list;ls -d /tmp\r"
49expect { 49expect {
50 timeout {puts "TESTING ERROR 8 (join)\n";exit} 50 timeout {puts "TESTING ERROR 8 (join)\n";exit}
51 "join=testing" 51 "join=testing"
52} 52}
53expect { 53expect {
54 timeout {puts "TESTING ERROR 9\n";exit} 54 timeout {puts "TESTING ERROR 9\n";exit}
55 "home" 55 "/tmp"
56} 56}
57 57
58sleep 1 58after 100
59 59
60puts "\n" 60puts "\n"
diff --git a/test/env.exp b/test/environment/env.exp
index d7aee3c64..8f72400b0 100755
--- a/test/env.exp
+++ b/test/environment/env.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -28,7 +31,7 @@ expect {
28 "ENV3" 31 "ENV3"
29} 32}
30send -- "exit\r" 33send -- "exit\r"
31sleep 1 34after 100
32 35
33#*********************************************** 36#***********************************************
34send -- "firejail --profile=env.profile\r" 37send -- "firejail --profile=env.profile\r"
diff --git a/test/env.profile b/test/environment/env.profile
index ba66e6210..ba66e6210 100644
--- a/test/env.profile
+++ b/test/environment/env.profile
diff --git a/test/environment/environment.sh b/test/environment/environment.sh
new file mode 100755
index 000000000..5c4d49331
--- /dev/null
+++ b/test/environment/environment.sh
@@ -0,0 +1,87 @@
1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6export MALLOC_CHECK_=3
7export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
8
9echo "TESTING: DNS (test/environment/dns.exp)"
10./dns.exp
11
12echo "TESTING: doubledash (test/environment/doubledash.exp"
13mkdir -- -testdir
14touch -- -testdir/ttt
15cp -- /bin/bash -testdir/.
16./doubledash.exp
17rm -fr -- -testdir
18
19echo "TESTING: output (test/environment/output.exp)"
20./output.exp
21
22echo "TESTING: extract command (extract_command.exp)"
23./extract_command.exp
24
25echo "TESTING: environment variables (test/environment/env.exp)"
26./env.exp
27
28echo "TESTING: shell none(test/environment/shell-none.exp)"
29./shell-none.exp
30
31which dash
32if [ "$?" -eq 0 ];
33then
34 echo "TESTING: dash (test/environment/dash.exp)"
35 ./dash.exp
36else
37 echo "TESTING SKIP: dash not found"
38fi
39
40which csh
41if [ "$?" -eq 0 ];
42then
43 echo "TESTING: csh (test/environment/csh.exp)"
44 ./csh.exp
45else
46 echo "TESTING SKIP: csh not found"
47fi
48
49which zsh
50if [ "$?" -eq 0 ];
51then
52 echo "TESTING: zsh (test/environment/zsh.exp)"
53 ./zsh.exp
54else
55 echo "TESTING SKIP: zsh not found"
56fi
57
58echo "TESTING: firejail in firejail - single sandbox (test/environment/firejail-in-firejail.exp)"
59./firejail-in-firejail.exp
60
61echo "TESTING: firejail in firejail - force new sandbox (test/environment/firejail-in-firejail2.exp)"
62./firejail-in-firejail2.exp
63
64which aplay
65if [ "$?" -eq 0 ];
66then
67 echo "TESTING: sound (test/environment/sound.exp)"
68 ./sound.exp
69else
70 echo "TESTING SKIP: aplay not found"
71fi
72
73echo "TESTING: nice (test/environment/nice.exp)"
74./nice.exp
75
76echo "TESTING: quiet (test/environment/quiet.exp)"
77./quiet.exp
78
79which strace
80if [ "$?" -eq 0 ];
81then
82 echo "TESTING: --allow-debuggers (test/environment/allow-debuggers.exp)"
83 ./allow-debuggers.exp
84else
85 echo "TESTING SKIP: strace not found"
86fi
87
diff --git a/test/extract_command.exp b/test/environment/extract_command.exp
index 99c1cc134..266f66ff5 100755
--- a/test/extract_command.exp
+++ b/test/environment/extract_command.exp
@@ -7,7 +7,7 @@ match_max 100000
7send -- "firejail --debug ls -al\r" 7send -- "firejail --debug ls -al\r"
8expect { 8expect {
9 timeout {puts "TESTING ERROR 0\n";exit} 9 timeout {puts "TESTING ERROR 0\n";exit}
10 "Reading profile /etc/firejail/generic.profile" 10 "Reading profile /etc/firejail/default.profile"
11} 11}
12expect { 12expect {
13 timeout {puts "TESTING ERROR 2\n";exit} 13 timeout {puts "TESTING ERROR 2\n";exit}
@@ -17,7 +17,7 @@ expect {
17 timeout {puts "TESTING ERROR 2\n";exit} 17 timeout {puts "TESTING ERROR 2\n";exit}
18 "Parent is shutting down, bye" 18 "Parent is shutting down, bye"
19} 19}
20sleep 1 20after 100
21 21
22puts "\nall done\n" 22puts "\nall done\n"
23 23
diff --git a/test/firejail-in-firejail.exp b/test/environment/firejail-in-firejail.exp
index 5ba18d1fa..1122b712f 100755
--- a/test/firejail-in-firejail.exp
+++ b/test/environment/firejail-in-firejail.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -16,6 +19,6 @@ expect {
16 timeout {puts "TESTING ERROR 1\n";exit} 19 timeout {puts "TESTING ERROR 1\n";exit}
17 "Warning: an existing sandbox was detected" 20 "Warning: an existing sandbox was detected"
18} 21}
19sleep 1 22after 100
20 23
21puts "\nall done\n" 24puts "\nall done\n"
diff --git a/test/firejail-in-firejail2.exp b/test/environment/firejail-in-firejail2.exp
index b0fed0dae..37d1c2870 100755
--- a/test/firejail-in-firejail2.exp
+++ b/test/environment/firejail-in-firejail2.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -16,6 +19,6 @@ expect {
16 timeout {puts "TESTING ERROR 1\n";exit} 19 timeout {puts "TESTING ERROR 1\n";exit}
17 "Child process initialized" 20 "Child process initialized"
18} 21}
19sleep 1 22after 100
20 23
21puts "\nall done\n" 24puts "\nall done\n"
diff --git a/test/nice.exp b/test/environment/nice.exp
index f4afb547d..2e0e95ea1 100755
--- a/test/nice.exp
+++ b/test/environment/nice.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -14,7 +17,7 @@ sleep 1
14send -- "top -b -n 1\r" 17send -- "top -b -n 1\r"
15expect { 18expect {
16 timeout {puts "TESTING ERROR 1\n";exit} 19 timeout {puts "TESTING ERROR 1\n";exit}
17 "netblue" 20 $env(USER)
18} 21}
19expect { 22expect {
20 timeout {puts "TESTING ERROR 2\n";exit} 23 timeout {puts "TESTING ERROR 2\n";exit}
@@ -26,7 +29,7 @@ expect {
26} 29}
27expect { 30expect {
28 timeout {puts "TESTING ERROR 4\n";exit} 31 timeout {puts "TESTING ERROR 4\n";exit}
29 "netblu" 32 $env(USER)
30} 33}
31expect { 34expect {
32 timeout {puts "TESTING ERROR 5\n";exit} 35 timeout {puts "TESTING ERROR 5\n";exit}
@@ -39,7 +42,7 @@ expect {
39 42
40sleep 1 43sleep 1
41send -- "exit\r" 44send -- "exit\r"
42sleep 1 45after 100
43 46
44send -- "firejail --profile=nice.profile\r" 47send -- "firejail --profile=nice.profile\r"
45expect { 48expect {
@@ -51,7 +54,7 @@ sleep 1
51send -- "top -b -n 1\r" 54send -- "top -b -n 1\r"
52expect { 55expect {
53 timeout {puts "TESTING ERROR 11\n";exit} 56 timeout {puts "TESTING ERROR 11\n";exit}
54 "netblue" 57 $env(USER)
55} 58}
56expect { 59expect {
57 timeout {puts "TESTING ERROR 12\n";exit} 60 timeout {puts "TESTING ERROR 12\n";exit}
@@ -63,7 +66,7 @@ expect {
63} 66}
64expect { 67expect {
65 timeout {puts "TESTING ERROR 14\n";exit} 68 timeout {puts "TESTING ERROR 14\n";exit}
66 "netblu" 69 $env(USER)
67} 70}
68expect { 71expect {
69 timeout {puts "TESTING ERROR 15\n";exit} 72 timeout {puts "TESTING ERROR 15\n";exit}
diff --git a/test/nice.profile b/test/environment/nice.profile
index d02c8f58b..d02c8f58b 100644
--- a/test/nice.profile
+++ b/test/environment/nice.profile
diff --git a/test/output.exp b/test/environment/output.exp
index 90a9d64b6..10c325832 100755
--- a/test/output.exp
+++ b/test/environment/output.exp
@@ -59,8 +59,7 @@ expect {
59 timeout {puts "TESTING ERROR 7\n";exit} 59 timeout {puts "TESTING ERROR 7\n";exit}
60 "logfile.5" 60 "logfile.5"
61} 61}
62sleep 1 62after 100
63send -- "rm -f logfile*\r" 63send -- "rm -f logfile*\r"
64sleep 1 64after 100
65 65puts "\nall done\n"
66puts "\n"
diff --git a/test/output.sh b/test/environment/output.sh
index 2be188e3a..2be188e3a 100755
--- a/test/output.sh
+++ b/test/environment/output.sh
diff --git a/test/environment/quiet.exp b/test/environment/quiet.exp
new file mode 100755
index 000000000..8d7c8d4c0
--- /dev/null
+++ b/test/environment/quiet.exp
@@ -0,0 +1,21 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 4
7spawn $env(SHELL)
8match_max 100000
9
10# check ip address
11send -- "firejail --quiet echo done\r"
12expect {
13 timeout {puts "TESTING ERROR 1\n";exit}
14 "Reading profile" {puts "TESTING ERROR 2\n";exit}
15 "Child process initialized" {puts "TESTING ERROR 3\n";exit}
16 "done"
17}
18after 100
19
20puts "\nall done\n"
21
diff --git a/test/environment/shell-none.exp b/test/environment/shell-none.exp
new file mode 100755
index 000000000..8f3df794f
--- /dev/null
+++ b/test/environment/shell-none.exp
@@ -0,0 +1,48 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --shell=none\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "shell=none configured, but no program specified"
14}
15sleep 1
16
17send -- "firejail --profile=shell-none.profile\r"
18expect {
19 timeout {puts "TESTING ERROR 1\n";exit}
20 "shell=none configured, but no program specified"
21}
22after 100
23
24send -- "firejail --shell=none ls\r"
25expect {
26 timeout {puts "TESTING ERROR 2\n";exit}
27 "Child process initialized"
28}
29expect {
30 timeout {puts "TESTING ERROR 3\n";exit}
31 "environment.sh"
32}
33after 100
34
35send -- "firejail --profile=shell-none.profile ls\r"
36expect {
37 timeout {puts "TESTING ERROR 4\n";exit}
38 "Child process initialized"
39}
40expect {
41 timeout {puts "TESTING ERROR 5\n";exit}
42 "environment.sh"
43}
44after 100
45
46
47puts "\nall done\n"
48
diff --git a/test/environment/shell-none.profile b/test/environment/shell-none.profile
new file mode 100644
index 000000000..f16ebe3a0
--- /dev/null
+++ b/test/environment/shell-none.profile
@@ -0,0 +1 @@
shell none
diff --git a/test/sound.exp b/test/environment/sound.exp
index 078f8b416..dd55add89 100755
--- a/test/sound.exp
+++ b/test/environment/sound.exp
@@ -1,4 +1,8 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
2 6
3set timeout 10 7set timeout 10
4spawn $env(SHELL) 8spawn $env(SHELL)
@@ -73,7 +77,7 @@ expect {
73 timeout {puts "TESTING ERROR 25\n";exit} 77 timeout {puts "TESTING ERROR 25\n";exit}
74 "Parent is shutting down" 78 "Parent is shutting down"
75} 79}
76sleep 2 80after 100
77 81
78puts "\n" 82puts "\nall done\n"
79 83
diff --git a/test/sound.profile b/test/environment/sound.profile
index 2f83a0bbb..2f83a0bbb 100644
--- a/test/sound.profile
+++ b/test/environment/sound.profile
diff --git a/test/shell_zsh.exp b/test/environment/zsh.exp
index 1d73fd926..578951ce0 100755
--- a/test/shell_zsh.exp
+++ b/test/environment/zsh.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -11,15 +14,12 @@ expect {
11} 14}
12sleep 1 15sleep 1
13 16
14send -- "ls -al;pwd\r" 17send -- "find /home\r"
15expect { 18expect {
16 timeout {puts "TESTING ERROR 1\n";exit} 19 timeout {puts "TESTING ERROR 1\n";exit}
17 ".zshrc" 20 ".zshrc"
18} 21}
19expect { 22
20 timeout {puts "TESTING ERROR 1.1\n";exit}
21 "home"
22}
23send -- "env | grep SHELL;pwd\r" 23send -- "env | grep SHELL;pwd\r"
24expect { 24expect {
25 timeout {puts "TESTING ERROR 2\n";exit} 25 timeout {puts "TESTING ERROR 2\n";exit}
@@ -27,14 +27,10 @@ expect {
27} 27}
28expect { 28expect {
29 timeout {puts "TESTING ERROR 2.1\n";exit} 29 timeout {puts "TESTING ERROR 2.1\n";exit}
30 "/usr/bin/zsh" 30 "/bin/zsh"
31}
32expect {
33 timeout {puts "TESTING ERROR 2.2\n";exit}
34 "home"
35} 31}
36send -- "exit\r" 32send -- "exit\r"
37sleep 1 33after 100
38 34
39puts "\n" 35puts "\nall done\n"
40 36
diff --git a/test/features/1.2.exp b/test/features/1.2.exp
index 6f7cae888..bcb227304 100755
--- a/test/features/1.2.exp
+++ b/test/features/1.2.exp
@@ -34,7 +34,7 @@ expect {
34} 34}
35expect { 35expect {
36 timeout {puts "TESTING ERROR 1.4\n";exit} 36 timeout {puts "TESTING ERROR 1.4\n";exit}
37 "proc /proc/sysrq-trigger proc" 37 "/proc/sysrq-trigger"
38} 38}
39#expect { 39#expect {
40# timeout {puts "TESTING ERROR 1.5\n";exit} 40# timeout {puts "TESTING ERROR 1.5\n";exit}
@@ -42,11 +42,11 @@ expect {
42#} 42#}
43expect { 43expect {
44 timeout {puts "TESTING ERROR 1.6\n";exit} 44 timeout {puts "TESTING ERROR 1.6\n";exit}
45 "proc /proc/irq proc" 45 "/proc/irq"
46} 46}
47expect { 47expect {
48 timeout {puts "TESTING ERROR 1.7\n";exit} 48 timeout {puts "TESTING ERROR 1.7\n";exit}
49 "proc /proc/bus proc" 49 "/proc/bus"
50} 50}
51after 100 51after 100
52send -- "exit\r" 52send -- "exit\r"
@@ -115,22 +115,22 @@ if { $chroot == "chroot" } {
115 timeout {puts "TESTING ERROR 5.3\n";exit} 115 timeout {puts "TESTING ERROR 5.3\n";exit}
116 "proc /proc/sys proc" 116 "proc /proc/sys proc"
117 } 117 }
118 expect { 118# expect {
119 timeout {puts "TESTING ERROR 5.4\n";exit} 119# timeout {puts "TESTING ERROR 5.4\n";exit}
120 "proc /proc/sysrq-trigger proc" 120# "proc /proc/sysrq-trigger proc"
121 } 121# }
122# expect { 122# expect {
123# timeout {puts "TESTING ERROR 5.5\n";exit} 123# timeout {puts "TESTING ERROR 5.5\n";exit}
124# "proc /proc/sys/kernel/hotplug" 124# "proc /proc/sys/kernel/hotplug"
125# } 125# }
126 expect { 126# expect {
127 timeout {puts "TESTING ERROR 5.6\n";exit} 127# timeout {puts "TESTING ERROR 5.6\n";exit}
128 "proc /proc/irq proc" 128# "proc /proc/irq proc"
129 } 129# }
130 expect { 130# expect {
131 timeout {puts "TESTING ERROR 5.7\n";exit} 131# timeout {puts "TESTING ERROR 5.7\n";exit}
132 "proc /proc/bus proc" 132# "proc /proc/bus proc"
133 } 133# }
134 after 100 134 after 100
135 send -- "exit\r" 135 send -- "exit\r"
136 sleep 1 136 sleep 1
diff --git a/test/features/1.8.exp b/test/features/1.8.exp
index 493a87328..4c6d3f3dc 100755
--- a/test/features/1.8.exp
+++ b/test/features/1.8.exp
@@ -20,12 +20,6 @@ expect {
20} 20}
21sleep 1 21sleep 1
22 22
23send -- "ls /etc/firejail\r"
24expect {
25 timeout {puts "TESTING ERROR 1\n";exit}
26 "Permission denied"
27}
28after 100
29send -- "ls ~/.config/firejail\r" 23send -- "ls ~/.config/firejail\r"
30expect { 24expect {
31 timeout {puts "TESTING ERROR 1.1\n";exit} 25 timeout {puts "TESTING ERROR 1.1\n";exit}
@@ -77,12 +71,6 @@ if { $overlay == "overlay" } {
77 "Child process initialized" {puts "normal system\n"} 71 "Child process initialized" {puts "normal system\n"}
78 } 72 }
79 sleep 1 73 sleep 1
80 send -- "ls /etc/firejail\r"
81 expect {
82 timeout {puts "TESTING ERROR 3\n";exit}
83 "Permission denied"
84 }
85 after 100
86 send -- "ls ~/.config/firejail\r" 74 send -- "ls ~/.config/firejail\r"
87 expect { 75 expect {
88 timeout {puts "TESTING ERROR 3.1\n";exit} 76 timeout {puts "TESTING ERROR 3.1\n";exit}
@@ -134,12 +122,6 @@ if { $chroot == "chroot" } {
134 "Child process initialized" 122 "Child process initialized"
135 } 123 }
136 sleep 1 124 sleep 1
137 send -- "ls /etc/firejail\r"
138 expect {
139 timeout {puts "TESTING ERROR 5\n";exit}
140 "Permission denied"
141 }
142 after 100
143 send -- "ls ~/.config/firejail\r" 125 send -- "ls ~/.config/firejail\r"
144 expect { 126 expect {
145 timeout {puts "TESTING ERROR 5.1\n";exit} 127 timeout {puts "TESTING ERROR 5.1\n";exit}
diff --git a/test/features/3.5.exp b/test/features/3.5.exp
index aed5fe836..f4b544b3d 100755
--- a/test/features/3.5.exp
+++ b/test/features/3.5.exp
@@ -22,8 +22,8 @@ sleep 1
22send -- "ls -l /dev | wc -l\r" 22send -- "ls -l /dev | wc -l\r"
23expect { 23expect {
24 timeout {puts "TESTING ERROR 1.1\n";exit} 24 timeout {puts "TESTING ERROR 1.1\n";exit}
25 "12" { puts "Debian\n"} 25 "13" { puts "Debian\n"}
26 "11" { puts "Centos\n"} 26 "12" { puts "Centos\n"}
27} 27}
28 28
29after 100 29after 100
@@ -45,8 +45,8 @@ if { $overlay == "overlay" } {
45 send -- "ls -l /dev | wc -l\r" 45 send -- "ls -l /dev | wc -l\r"
46 expect { 46 expect {
47 timeout {puts "TESTING ERROR 3.1\n";exit} 47 timeout {puts "TESTING ERROR 3.1\n";exit}
48 "12" { puts "Debian\n"} 48 "13" { puts "Debian\n"}
49 "11" { puts "Centos\n"} 49 "12" { puts "Centos\n"}
50 } 50 }
51 51
52 after 100 52 after 100
@@ -68,7 +68,7 @@ if { $chroot == "chroot" } {
68 send -- "ls -l /dev | wc -l\r" 68 send -- "ls -l /dev | wc -l\r"
69 expect { 69 expect {
70 timeout {puts "TESTING ERROR 5.1\n";exit} 70 timeout {puts "TESTING ERROR 5.1\n";exit}
71 "11" 71 "12"
72 } 72 }
73 73
74 after 100 74 after 100
diff --git a/test/features/3.6.exp b/test/features/3.6.exp
index a00517716..389e63a1d 100755
--- a/test/features/3.6.exp
+++ b/test/features/3.6.exp
@@ -60,14 +60,19 @@ if { $chroot == "chroot" } {
60 expect { 60 expect {
61 timeout {puts "TESTING ERROR 4\n";exit} 61 timeout {puts "TESTING ERROR 4\n";exit}
62 "chroot option is not available" {puts "grsecurity\n"; exit} 62 "chroot option is not available" {puts "grsecurity\n"; exit}
63 "private-etc feature is disabled in chroot"
64 }
65 expect {
66 timeout {puts "TESTING ERROR 5\n";exit}
67 "chroot option is not available" {puts "grsecurity\n"; exit}
63 "Child process initialized" 68 "Child process initialized"
64 } 69 }
65 sleep 1 70 sleep 1
66 71
67 send -- "ls -al /etc | wc -l\r" 72 send -- "ls /etc | grep firejail\r"
68 expect { 73 expect {
69 timeout {puts "TESTING ERROR 5.1\n";exit} 74 timeout {puts "TESTING ERROR 6\n";exit}
70 "10" 75 "firejail"
71 } 76 }
72 77
73 after 100 78 after 100
diff --git a/test/features/3.8.exp b/test/features/3.8.exp
index 94a1abf67..d941fa9b7 100755
--- a/test/features/3.8.exp
+++ b/test/features/3.8.exp
@@ -61,14 +61,18 @@ if { $chroot == "chroot" } {
61 send -- "firejail --noprofile --chroot=/tmp/chroot --private-bin=bash,cat,cp,ls,wc\r" 61 send -- "firejail --noprofile --chroot=/tmp/chroot --private-bin=bash,cat,cp,ls,wc\r"
62 expect { 62 expect {
63 timeout {puts "TESTING ERROR 4\n";exit} 63 timeout {puts "TESTING ERROR 4\n";exit}
64 "private-bin feature is disabled in chroot"
65 }
66 expect {
67 timeout {puts "TESTING ERROR 5\n";exit}
64 "Child process initialized" 68 "Child process initialized"
65 } 69 }
66 sleep 1 70 sleep 1
67 71
68 send -- "ls -l /usr/bin | wc -l\r" 72 send -- "ls -l /usr/bin | wc -l\r"
69 expect { 73 expect {
70 timeout {puts "TESTING ERROR 5.1\n";exit} 74 timeout {puts "TESTING ERROR 6\n";exit}
71 "6" 75 "9"
72 } 76 }
73 77
74 after 100 78 after 100
diff --git a/test/filters/caps.exp b/test/filters/caps.exp
new file mode 100755
index 000000000..7f7cf7dd1
--- /dev/null
+++ b/test/filters/caps.exp
@@ -0,0 +1,72 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --caps.keep=chown,fowner --noprofile\r"
11expect {
12 timeout {puts "TESTING ERROR 1\n";exit}
13 "Child process initialized"
14}
15sleep 2
16
17send -- "cat /proc/self/status\r"
18expect {
19 timeout {puts "TESTING ERROR 2\n";exit}
20 "CapBnd: 0000000000000009"
21}
22expect {
23 timeout {puts "TESTING ERROR 3\n";exit}
24 "Seccomp:"
25}
26send -- "exit\r"
27sleep 1
28
29send -- "firejail --caps.drop=all --noprofile\r"
30expect {
31 timeout {puts "TESTING ERROR 4\n";exit}
32 "Child process initialized"
33}
34sleep 2
35
36send -- "cat /proc/self/status\r"
37expect {
38 timeout {puts "TESTING ERROR 5\n";exit}
39 "CapBnd: 0000000000000000"
40}
41expect {
42 timeout {puts "TESTING ERROR 6\n";exit}
43 "Seccomp:"
44}
45send -- "exit\r"
46sleep 1
47
48send -- "firejail --caps.drop=chown,dac_override,dac_read_search,fowner --noprofile\r"
49expect {
50 timeout {puts "TESTING ERROR 7\n";exit}
51 "Child process initialized"
52}
53sleep 2
54
55send -- "cat /proc/self/status\r"
56expect {
57 timeout {puts "TESTING ERROR 8\n";exit}
58 "CapBnd:"
59}
60expect {
61 timeout {puts "TESTING ERROR 9\n";exit}
62 "fffffff0"
63}
64expect {
65 timeout {puts "TESTING ERROR 10\n";exit}
66 "Seccomp:"
67}
68send -- "exit\r"
69after 100
70
71
72puts "\nall done\n"
diff --git a/test/filters/filters.sh b/test/filters/filters.sh
new file mode 100755
index 000000000..5c7c98b3e
--- /dev/null
+++ b/test/filters/filters.sh
@@ -0,0 +1,68 @@
1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6export MALLOC_CHECK_=3
7export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
8
9echo "TESTING: noroot (test/filters/noroot.exp)"
10./noroot.exp
11
12echo "TESTING: capabilities (test/filters/caps.exp)"
13./caps.exp
14
15rm -f seccomp-test-file
16if [ "$(uname -m)" = "x86_64" ]; then
17 echo "TESTING: fseccomp (test/filters/fseccomp.exp)"
18 ./fseccomp.exp
19else
20 echo "TESTING SKIP: fseccomp test implemented only for x86_64"
21fi
22rm -f seccomp-test-file
23
24
25if [ "$(uname -m)" = "x86_64" ]; then
26 echo "TESTING: protocol (test/filters/protocol.exp)"
27 ./protocol.exp
28else
29 echo "TESTING SKIP: protocol, running only on x86_64"
30fi
31
32echo "TESTING: seccomp bad empty (test/filters/seccomp-bad-empty.exp)"
33./seccomp-bad-empty.exp
34
35echo "TESTING: seccomp debug (test/filters/seccomp-debug.exp)"
36./seccomp-debug.exp
37
38echo "TESTING: seccomp errno (test/filters/seccomp-errno.exp)"
39./seccomp-errno.exp
40
41echo "TESTING: seccomp su (test/filters/seccomp-su.exp)"
42./seccomp-su.exp
43
44which strace
45if [ $? -eq 0 ]; then
46 echo "TESTING: seccomp ptrace (test/filters/seccomp-ptrace.exp)"
47 ./seccomp-ptrace.exp
48else
49 echo "TESTING SKIP: ptrace, strace not found"
50fi
51
52echo "TESTING: seccomp chmod - seccomp lists (test/filters/seccomp-chmod.exp)"
53./seccomp-chmod.exp
54
55echo "TESTING: seccomp chmod profile - seccomp lists (test/filters/seccomp-chmod-profile.exp)"
56./seccomp-chmod-profile.exp
57
58# todo: fix pwd and add seccomp-chown.exp
59
60echo "TESTING: seccomp empty (test/filters/seccomp-empty.exp)"
61./seccomp-empty.exp
62
63if [ "$(uname -m)" = "x86_64" ]; then
64 echo "TESTING: seccomp dual filter (test/filters/seccomp-dualfilter.exp)"
65 ./seccomp-dualfilter.exp
66else
67 echo "TESTING SKIP: seccomp dual, not running on x86_64"
68fi
diff --git a/test/filters/fseccomp.exp b/test/filters/fseccomp.exp
new file mode 100755
index 000000000..8a9a8f9dc
--- /dev/null
+++ b/test/filters/fseccomp.exp
@@ -0,0 +1,138 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10after 100
11send -- "/usr/lib/firejail/fseccomp debug-syscalls\r"
12expect {
13 timeout {puts "TESTING ERROR 1\n";exit}
14 "1 - write"
15}
16
17after 100
18send -- "/usr/lib/firejail/fseccomp debug-errnos\r"
19expect {
20 timeout {puts "TESTING ERROR 2\n";exit}
21 "1 - EPERM"
22}
23
24after 100
25send -- "/usr/lib/firejail/fseccomp debug-protocols\r"
26expect {
27 timeout {puts "TESTING ERROR 3\n";exit}
28 "unix, inet, inet6, netlink, packet,"
29}
30
31after 100
32send -- "/usr/lib/firejail/fseccomp protocol build unix,inet seccomp-test-file\r"
33after 100
34send -- "/usr/lib/firejail/fseccomp print seccomp-test-file\r"
35expect {
36 timeout {puts "TESTING ERROR 4.1\n";exit}
37 "WHITELIST 41 socket"
38}
39
40after 100
41send -- "/usr/lib/firejail/fseccomp secondary 64 seccomp-test-file\r"
42after 100
43send -- "/usr/lib/firejail/fseccomp print seccomp-test-file\r"
44expect {
45 timeout {puts "TESTING ERROR 5.1\n";exit}
46 "BLACKLIST 165 mount"
47}
48expect {
49 timeout {puts "TESTING ERROR 5.2\n";exit}
50 "BLACKLIST 166 umount2"
51}
52expect {
53 timeout {puts "TESTING ERROR 5.3\n";exit}
54 "RETURN_ALLOW"
55}
56
57after 100
58send -- "/usr/lib/firejail/fseccomp default seccomp-test-file\r"
59after 100
60send -- "/usr/lib/firejail/fseccomp print seccomp-test-file\r"
61expect {
62 timeout {puts "TESTING ERROR 6.1\n";exit}
63 "BLACKLIST 165 mount"
64}
65expect {
66 timeout {puts "TESTING ERROR 6.2\n";exit}
67 "BLACKLIST 166 umount2"
68}
69expect {
70 timeout {puts "TESTING ERROR 6.3\n";exit}
71 "RETURN_ALLOW"
72}
73
74after 100
75send -- "/usr/lib/firejail/fseccomp drop seccomp-test-file chmod,chown\r"
76after 100
77send -- "/usr/lib/firejail/fseccomp print seccomp-test-file\r"
78expect {
79 timeout {puts "TESTING ERROR 7.1\n";exit}
80 "BLACKLIST 165 mount" {puts "TESTING ERROR 7.2\n";exit}
81 "BLACKLIST 166 umount2" {puts "TESTING ERROR 7.3\n";exit}
82 "BLACKLIST 90 chmod"
83}
84expect {
85 timeout {puts "TESTING ERROR 7.4\n";exit}
86 "BLACKLIST 92 chown"
87}
88expect {
89 timeout {puts "TESTING ERROR 7.5\n";exit}
90 "RETURN_ALLOW"
91}
92
93after 100
94send -- "/usr/lib/firejail/fseccomp default drop seccomp-test-file chmod,chown\r"
95after 100
96send -- "/usr/lib/firejail/fseccomp print seccomp-test-file\r"
97expect {
98 timeout {puts "TESTING ERROR 8.1\n";exit}
99 "BLACKLIST 165 mount"
100}
101expect {
102 timeout {puts "TESTING ERROR 8.2\n";exit}
103 "BLACKLIST 166 umount2"
104}
105expect {
106 timeout {puts "TESTING ERROR 8.3\n";exit}
107 "BLACKLIST 90 chmod"
108}
109expect {
110 timeout {puts "TESTING ERROR 8.4\n";exit}
111 "BLACKLIST 92 chown"
112}
113expect {
114 timeout {puts "TESTING ERROR 8.5\n";exit}
115 "RETURN_ALLOW"
116}
117after 100
118send -- "/usr/lib/firejail/fseccomp keep seccomp-test-file chmod,chown\r"
119after 100
120send -- "/usr/lib/firejail/fseccomp print seccomp-test-file\r"
121expect {
122 timeout {puts "TESTING ERROR 9.1\n";exit}
123 "WHITELIST 90 chmod"
124}
125expect {
126 timeout {puts "TESTING ERROR 9.2\n";exit}
127 "WHITELIST 92 chown"
128}
129expect {
130 timeout {puts "TESTING ERROR 9.3\n";exit}
131 "KILL_PROCESS"
132}
133
134
135
136after 100
137puts "\nall done\n"
138
diff --git a/test/filters/noroot.exp b/test/filters/noroot.exp
new file mode 100755
index 000000000..b011f2bf9
--- /dev/null
+++ b/test/filters/noroot.exp
@@ -0,0 +1,160 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --noprofile --noroot --caps.drop=all --seccomp\r"
11expect {
12 timeout {puts "TESTING ERROR 1\n";exit}
13 "cannot create a new user namespace" {puts "TESTING SKIP: user namespace not available\n"; exit}
14 "Child process initialized"
15}
16sleep 1
17
18send -- "cat /proc/self/status\r"
19expect {
20 timeout {puts "TESTING ERROR 1\n";exit}
21 "CapBnd: 0000000000000000"
22}
23expect {
24 timeout {puts "TESTING ERROR 2\n";exit}
25 "Seccomp:"
26}
27expect {
28 timeout {puts "TESTING ERROR 3\n";exit}
29 "2"
30}
31expect {
32 timeout {puts "TESTING ERROR 4\n";exit}
33 "Cpus_allowed:"
34}
35puts "\n"
36
37send -- "ping 0\r"
38expect {
39 timeout {puts "TESTING ERROR 5\n";exit}
40 "Operation not permitted"
41}
42send -- "whoami\r"
43expect {
44 timeout {puts "TESTING ERROR 6\n";exit}
45 $env(USER)
46}
47send -- "sudo -s\r"
48expect {
49 timeout {puts "TESTING ERROR 7\n";exit}
50 "effective uid is not 0, is sudo installed setuid root?" { puts "OK\n";}
51 "sudo must be owned by uid 0 and have the setuid bit set" { puts "OK\n";}
52 "Bad system call" { puts "OK\n";}
53}
54send -- "cat /proc/self/uid_map | wc -l\r"
55expect {
56 timeout {puts "TESTING ERROR 8\n";exit}
57 "1"
58}
59send -- "cat /proc/self/gid_map | wc -l\r"
60expect {
61 timeout {puts "TESTING ERROR 9\n";exit}
62 "5"
63}
64
65puts "\n"
66send -- "exit\r"
67sleep 2
68
69
70
71send -- "firejail --name=test --noroot --noprofile\r"
72expect {
73 timeout {puts "TESTING ERROR 10\n";exit}
74 "Child process initialized"
75}
76sleep 1
77
78send -- "cat /proc/self/status\r"
79expect {
80 timeout {puts "TESTING ERROR 11\n";exit}
81 "CapBnd:"
82}
83expect {
84 timeout {puts "TESTING ERROR 12\n";exit}
85 "ffffffff"
86}
87expect {
88 timeout {puts "TESTING ERROR 13\n";exit}
89 "Seccomp:"
90}
91expect {
92 timeout {puts "TESTING ERROR 14\n";exit}
93 "0"
94}
95expect {
96 timeout {puts "TESTING ERROR 15\n";exit}
97 "Cpus_allowed:"
98}
99puts "\n"
100
101send -- "whoami\r"
102expect {
103 timeout {puts "TESTING ERROR 16\n";exit}
104 $env(USER)
105}
106send -- "sudo -s\r"
107expect {
108 timeout {puts "TESTING ERROR 17\n";exit}
109 "effective uid is not 0, is sudo installed setuid root?" { puts "OK\n";}
110 "sudo must be owned by uid 0 and have the setuid bit set" { puts "OK\n";}
111}
112send -- "ping 0\r"
113expect {
114 timeout {puts "TESTING ERROR 18\n";exit}
115 "Operation not permitted"
116}
117send -- "cat /proc/self/uid_map | wc -l\r"
118expect {
119 timeout {puts "TESTING ERROR 19\n";exit}
120 "1"
121}
122send -- "cat /proc/self/gid_map | wc -l\r"
123expect {
124 timeout {puts "TESTING ERROR 20\n";exit}
125 "5"
126}
127
128
129
130spawn $env(SHELL)
131send -- "firejail --debug --join=test\r"
132expect {
133 timeout {puts "TESTING ERROR 21\n";exit}
134 "User namespace detected"
135}
136expect {
137 timeout {puts "TESTING ERROR 22\n";exit}
138 "Joining user namespace"
139}
140sleep 1
141
142send -- "sudo -s\r"
143expect {
144 timeout {puts "TESTING ERROR 23\n";exit}
145 "effective uid is not 0, is sudo installed setuid root?" { puts "OK\n";}
146 "sudo must be owned by uid 0 and have the setuid bit set" { puts "OK\n";}
147 "Permission denied" { puts "OK\n";}
148}
149send -- "cat /proc/self/uid_map | wc -l\r"
150expect {
151 timeout {puts "TESTING ERROR 24\n";exit}
152 "1"
153}
154send -- "cat /proc/self/gid_map | wc -l\r"
155expect {
156 timeout {puts "TESTING ERROR 25\n";exit}
157 "5"
158}
159after 100
160puts "\nall done\n"
diff --git a/test/protocol.exp b/test/filters/protocol.exp
index 018f4cd9b..835f645b2 100755
--- a/test/protocol.exp
+++ b/test/filters/protocol.exp
@@ -1,16 +1,21 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
5match_max 100000 8match_max 100000
6 9
7send -- "firejail --noprofile --protocol=unix ../src/tools/syscall_test socket\r" 10send -- "firejail --noprofile --protocol=unix ./syscall_test socket\r"
8expect { 11expect {
9 timeout {puts "TESTING ERROR 1\n";exit} 12 timeout {puts "TESTING ERROR 1\n";exit}
13 "Permission denied" {puts "TESTING SKIP: permission denied\n"; exit}
10 "Child process initialized" 14 "Child process initialized"
11} 15}
12expect { 16expect {
13 timeout {puts "TESTING ERROR 1.1\n";exit} 17 timeout {puts "TESTING ERROR 1.1\n";exit}
18 "Permission denied" {puts "TESTING SKIP: permission denied\n"; exit}
14 "socket AF_INET" 19 "socket AF_INET"
15} 20}
16expect { 21expect {
@@ -47,7 +52,7 @@ expect {
47} 52}
48sleep 1 53sleep 1
49 54
50send -- "firejail --noprofile --protocol=inet6,packet ../src/tools/syscall_test socket\r" 55send -- "firejail --noprofile --protocol=inet6,packet ./syscall_test socket\r"
51expect { 56expect {
52 timeout {puts "TESTING ERROR 2\n";exit} 57 timeout {puts "TESTING ERROR 2\n";exit}
53 "Child process initialized" 58 "Child process initialized"
@@ -91,7 +96,7 @@ expect {
91sleep 1 96sleep 1
92 97
93# profile testing 98# profile testing
94send -- "firejail --profile=protocol1.profile ../src/tools/syscall_test socket\r" 99send -- "firejail --profile=protocol1.profile ./syscall_test socket\r"
95expect { 100expect {
96 timeout {puts "TESTING ERROR 3\n";exit} 101 timeout {puts "TESTING ERROR 3\n";exit}
97 "Child process initialized" 102 "Child process initialized"
@@ -134,7 +139,7 @@ expect {
134} 139}
135sleep 1 140sleep 1
136 141
137send -- "firejail --profile=protocol2.profile ../src/tools/syscall_test socket\r" 142send -- "firejail --profile=protocol2.profile ./syscall_test socket\r"
138expect { 143expect {
139 timeout {puts "TESTING ERROR 4\n";exit} 144 timeout {puts "TESTING ERROR 4\n";exit}
140 "Child process initialized" 145 "Child process initialized"
@@ -175,10 +180,6 @@ expect {
175 timeout {puts "TESTING ERROR 4.9\n";exit} 180 timeout {puts "TESTING ERROR 4.9\n";exit}
176 "after socket" 181 "after socket"
177} 182}
178sleep 1 183after 100
179
180
181
182
183 184
184puts "\nall done\n" 185puts "\nall done\n"
diff --git a/test/protocol1.profile b/test/filters/protocol1.profile
index 3e1ea2a29..3e1ea2a29 100644
--- a/test/protocol1.profile
+++ b/test/filters/protocol1.profile
diff --git a/test/protocol2.profile b/test/filters/protocol2.profile
index b7eb4ab91..b7eb4ab91 100644
--- a/test/protocol2.profile
+++ b/test/filters/protocol2.profile
diff --git a/test/seccomp-bad-empty.exp b/test/filters/seccomp-bad-empty.exp
index 631d67743..1bd9c9b1f 100755
--- a/test/seccomp-bad-empty.exp
+++ b/test/filters/seccomp-bad-empty.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -33,6 +36,6 @@ expect {
33 timeout {puts "TESTING ERROR 7\n";exit} 36 timeout {puts "TESTING ERROR 7\n";exit}
34 "Error: line 1 in seccomp-bad-empty2.profile is invalid" 37 "Error: line 1 in seccomp-bad-empty2.profile is invalid"
35} 38}
36sleep 1 39after 100
37puts "\nall done\n" 40puts "\nall done\n"
38 41
diff --git a/test/seccomp-bad-empty.profile b/test/filters/seccomp-bad-empty.profile
index 2d4fcde7c..2d4fcde7c 100644
--- a/test/seccomp-bad-empty.profile
+++ b/test/filters/seccomp-bad-empty.profile
diff --git a/test/seccomp-bad-empty2.profile b/test/filters/seccomp-bad-empty2.profile
index c4e6c9f74..c4e6c9f74 100644
--- a/test/seccomp-bad-empty2.profile
+++ b/test/filters/seccomp-bad-empty2.profile
diff --git a/test/pid.exp b/test/filters/seccomp-chmod-profile.exp
index cdeb9d5fb..463ce05e9 100755
--- a/test/pid.exp
+++ b/test/filters/seccomp-chmod-profile.exp
@@ -1,49 +1,51 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
5match_max 100000 8match_max 100000
6 9
7send -- "firejail\r" 10send -- "firejail --profile=seccomp.profile --private\r"
8expect { 11expect {
9 timeout {puts "TESTING ERROR 0\n";exit} 12 timeout {puts "TESTING ERROR 0\n";exit}
10 "Child process initialized" 13 "Child process initialized"
11} 14}
12sleep 1 15sleep 2
13 16
14# test processes 17send -- "cd ~; echo done\r"
15send -- "bash\r"
16sleep 1
17send -- "ps aux; pwd\r"
18expect { 18expect {
19 timeout {puts "TESTING ERROR 1\n";exit} 19 timeout {puts "TESTING ERROR 1\n";exit}
20 "/bin/bash" 20 "done"
21} 21}
22
23send -- "touch testfile; echo done\r"
22expect { 24expect {
23 timeout {puts "TESTING ERROR 2\n";exit} 25 timeout {puts "TESTING ERROR 2\n";exit}
24 "bash" 26 "done"
25} 27}
28
29send -- "ls -l testfile; echo done\r"
26expect { 30expect {
27 timeout {puts "TESTING ERROR 3\n";exit} 31 timeout {puts "TESTING ERROR 3\n";exit}
28 "ps aux" 32 "testfile"
29} 33}
30expect { 34expect {
31 timeout {puts "TESTING ERROR 4\n";exit} 35 timeout {puts "TESTING ERROR 4\n";exit}
32 "home" 36 "done"
33} 37}
34sleep 1
35
36 38
37send -- "ps aux |wc -l; pwd\r" 39send -- "chmod +x testfile; echo done\r"
38expect { 40expect {
39 timeout {puts "TESTING ERROR 5\n";exit} 41 timeout {puts "TESTING ERROR 5\n";exit}
40 "6" {puts "normal system\n"} 42 "Bad system call"
41 "5" {puts "grsecurity\n"}
42} 43}
43expect { 44expect {
44 timeout {puts "TESTING ERROR 6\n";exit} 45 timeout {puts "TESTING ERROR 6\n";exit}
45 "home" 46 "done"
46} 47}
47sleep 1
48 48
49send -- "exit\r"
50after 100
49puts "\nall done\n" 51puts "\nall done\n"
diff --git a/test/seccomp-chmod.exp b/test/filters/seccomp-chmod.exp
index b4a213206..b17990e3a 100755
--- a/test/seccomp-chmod.exp
+++ b/test/filters/seccomp-chmod.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -11,36 +14,38 @@ expect {
11} 14}
12sleep 2 15sleep 2
13 16
14send -- "touch testfile;pwd\r" 17send -- "cd ~; echo done\r"
15expect { 18expect {
16 timeout {puts "TESTING ERROR 1\n";exit} 19 timeout {puts "TESTING ERROR 1\n";exit}
17 "/root" {puts "running as root"} 20 "done"
18 "/home"
19} 21}
20 22
21send -- "ls -l testfile;pwd\r" 23send -- "touch testfile; echo done\r"
22expect { 24expect {
23 timeout {puts "TESTING ERROR 2\n";exit} 25 timeout {puts "TESTING ERROR 2\n";exit}
24 "testfile" 26 "done"
25} 27}
28
29send -- "ls -l testfile; echo done\r"
26expect { 30expect {
27 timeout {puts "TESTING ERROR 3\n";exit} 31 timeout {puts "TESTING ERROR 3\n";exit}
28 "/root" {puts "running as root"} 32 "testfile"
29 "/home" 33}
34expect {
35 timeout {puts "TESTING ERROR 4\n";exit}
36 "done"
30} 37}
31 38
32send -- "chmod +x testfile;pwd\r" 39send -- "chmod +x testfile; echo done\r"
33expect { 40expect {
34 timeout {puts "TESTING ERROR 2\n";exit} 41 timeout {puts "TESTING ERROR 5\n";exit}
35 "Bad system call" 42 "Bad system call"
36} 43}
37expect { 44expect {
38 timeout {puts "TESTING ERROR 3\n";exit} 45 timeout {puts "TESTING ERROR 6\n";exit}
39 "/root" {puts "running as root"} 46 "done"
40 "/home"
41} 47}
42 48
43
44send -- "exit\r" 49send -- "exit\r"
45sleep 1 50after 100
46puts "\n" 51puts "\nall done\n"
diff --git a/test/seccomp-chown.exp b/test/filters/seccomp-chown.exp
index 69b896700..a54d279f1 100755
--- a/test/seccomp-chown.exp
+++ b/test/filters/seccomp-chown.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -42,5 +45,5 @@ expect {
42 45
43 46
44send -- "exit\r" 47send -- "exit\r"
45sleep 1 48after 100
46puts "\n" 49puts "\nall done\n"
diff --git a/test/seccomp-debug.exp b/test/filters/seccomp-debug.exp
index 1034f040e..dbc0d37a9 100755
--- a/test/seccomp-debug.exp
+++ b/test/filters/seccomp-debug.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
diff --git a/test/filters/seccomp-dualfilter.exp b/test/filters/seccomp-dualfilter.exp
new file mode 100755
index 000000000..958dab528
--- /dev/null
+++ b/test/filters/seccomp-dualfilter.exp
@@ -0,0 +1,55 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 1
7spawn $env(SHELL)
8match_max 100000
9
10send -- "./syscall_test\r"
11expect {
12 timeout {puts "\nTESTING SKIP: 64-bit support missing\n";exit}
13 "Usage"
14}
15
16send -- "./syscall_test32\r"
17expect {
18 timeout {puts "\nTESTING SKIP: 32-bit support missing\n";exit}
19 "Usage"
20}
21
22set timeout 10
23send -- "firejail ./syscall_test mount\r"
24expect {
25 timeout {puts "TESTING ERROR 0\n";exit}
26 "Child process initialized"
27}
28expect {
29 timeout {puts "TESTING ERROR 1\n";exit}
30 "before mount"
31}
32expect {
33 timeout {puts "TESTING ERROR 2\n";exit}
34 "after mount" {puts "TESTING ERROR 3\n";exit}
35 "Parent is shutting down"
36}
37sleep 1
38
39send -- "firejail ./syscall_test32 mount\r"
40expect {
41 timeout {puts "TESTING ERROR 4\n";exit}
42 "Child process initialized"
43}
44expect {
45 timeout {puts "TESTING ERROR 5\n";exit}
46 "before mount"
47}
48expect {
49 timeout {puts "TESTING ERROR 6\n";exit}
50 "after mount" {puts "TESTING ERROR 7\n";exit}
51 "Parent is shutting down"
52}
53
54after 100
55puts "\nall done\n"
diff --git a/test/seccomp-empty.exp b/test/filters/seccomp-empty.exp
index 11abf2e00..d150dac7d 100755
--- a/test/seccomp-empty.exp
+++ b/test/filters/seccomp-empty.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -141,5 +144,6 @@ expect {
141} 144}
142sleep 2 145sleep 2
143send -- "exit\r" 146send -- "exit\r"
147after 100
144puts "\n" 148puts "\n"
145 149
diff --git a/test/seccomp-empty.profile b/test/filters/seccomp-empty.profile
index 8f71f55a5..8f71f55a5 100644
--- a/test/seccomp-empty.profile
+++ b/test/filters/seccomp-empty.profile
diff --git a/test/filters/seccomp-errno.exp b/test/filters/seccomp-errno.exp
new file mode 100755
index 000000000..c3af2fbe9
--- /dev/null
+++ b/test/filters/seccomp-errno.exp
@@ -0,0 +1,54 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "touch seccomp-test-file\r"
11after 100
12
13send -- "firejail --seccomp=unlinkat:ENOENT rm seccomp-test-file\r"
14expect {
15 timeout {puts "TESTING ERROR 0\n";exit}
16 "No such file or directory"
17}
18sleep 1
19
20send -- "firejail --seccomp=unlinkat:ENOENT --debug rm seccomp-test-file\r"
21expect {
22 timeout {puts "TESTING ERROR 1\n";exit}
23 "unlinkat 2 ENOENT"
24}
25sleep 1
26
27send -- "firejail --seccomp=unlinkat:ENOENT,mkdir:ENOENT\r"
28expect {
29 timeout {puts "TESTING ERROR 2\n";exit}
30 "Child process initialized"
31}
32sleep 1
33send -- "rm seccomp-test-file\r"
34expect {
35 timeout {puts "TESTING ERROR 3\n";exit}
36 "No such file or directory"
37}
38after 100
39puts "\n"
40
41send -- "mkdir seccomp-test-dir\r"
42expect {
43 timeout {puts "TESTING ERROR 4\n";exit}
44 "No such file or directory"
45}
46after 100
47puts "\n"
48
49send -- "exit\r"
50sleep 1
51
52send -- "rm seccomp-test-file\r"
53after 100
54puts "all done\n"
diff --git a/test/seccomp-ptrace.exp b/test/filters/seccomp-ptrace.exp
index 9a9b7430e..bb87b96ea 100755
--- a/test/seccomp-ptrace.exp
+++ b/test/filters/seccomp-ptrace.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -19,5 +22,5 @@ expect {
19} 22}
20 23
21send -- "exit\r" 24send -- "exit\r"
22sleep 1 25after 100
23puts "all done\n" 26puts "all done\n"
diff --git a/test/seccomp-su.exp b/test/filters/seccomp-su.exp
index dcae6f869..3feabc20f 100755
--- a/test/seccomp-su.exp
+++ b/test/filters/seccomp-su.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -14,21 +17,24 @@ sleep 2
14send -- "sudo su -\r" 17send -- "sudo su -\r"
15expect { 18expect {
16 timeout {puts "TESTING ERROR 1\n";exit} 19 timeout {puts "TESTING ERROR 1\n";exit}
17 "effective uid is not 0" 20 "effective uid is not 0" {puts "OK\n"}
21 "Bad system call" {puts "OK\n"}
18} 22}
19 23
20send -- "sudo ls\r" 24send -- "sudo ls\r"
21expect { 25expect {
22 timeout {puts "TESTING ERROR 2\n";exit} 26 timeout {puts "TESTING ERROR 2\n";exit}
23 "effective uid is not 0" 27 "effective uid is not 0" {puts "OK\n"}
28 "Bad system call" {puts "OK\n"}
24} 29}
25 30
26send -- "ping google.com\r" 31send -- "ping google.com\r"
27expect { 32expect {
28 timeout {puts "TESTING ERROR 2\n";exit} 33 timeout {puts "TESTING ERROR 3\n";exit}
29 "Operation not permitted" 34 "Operation not permitted" {puts "OK\n"}
35 "unknown host" {puts "OK\n"}
30} 36}
31 37
32send -- "exit\r" 38send -- "exit\r"
33sleep 1 39after 100
34puts "all done\n" 40puts "all done\n"
diff --git a/test/seccomp.profile b/test/filters/seccomp.profile
index cb0b15aee..cb0b15aee 100644
--- a/test/seccomp.profile
+++ b/test/filters/seccomp.profile
diff --git a/src/tools/syscall_test b/test/filters/syscall_test
index bf29c5b99..bf29c5b99 100755
--- a/src/tools/syscall_test
+++ b/test/filters/syscall_test
Binary files differ
diff --git a/src/tools/syscall_test.c b/test/filters/syscall_test.c
index b3f43c755..422af619d 100644
--- a/src/tools/syscall_test.c
+++ b/test/filters/syscall_test.c
@@ -1,3 +1,7 @@
1// This file is part of Firejail project
2// Copyright (C) 2014-2016 Firejail Authors
3// License GPL v2
4
1#include <stdlib.h> 5#include <stdlib.h>
2#include <stdio.h> 6#include <stdio.h>
3#include <unistd.h> 7#include <unistd.h>
diff --git a/src/tools/syscall_test32 b/test/filters/syscall_test32
index 8d72f58c4..8d72f58c4 100755
--- a/src/tools/syscall_test32
+++ b/test/filters/syscall_test32
Binary files differ
diff --git a/test/fs/fs.sh b/test/fs/fs.sh
new file mode 100755
index 000000000..efbf505ee
--- /dev/null
+++ b/test/fs/fs.sh
@@ -0,0 +1,99 @@
1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6export MALLOC_CHECK_=3
7export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
8
9rm -fr ~/_firejail_test_*
10echo "TESTING: mkdir/mkfile (test/fs/mkdir_mkfile.exp)"
11./mkdir_mkfile.exp
12rm -fr ~/_firejail_test_*
13
14mkdir ~/_firejail_test_dir
15touch ~/_firejail_test_dir/a
16mkdir ~/_firejail_test_dir/test1
17touch ~/_firejail_test_dir/test1/b
18echo "TESTING: read/write (test/fs/read-write.exp)"
19./read-write.exp
20rm -fr ~/_firejail_test_*
21
22echo "TESTING: /sys/fs access (test/fs/sys_fs.exp)"
23./sys_fs.exp
24
25echo "TESTING: kmsg access (test/fs/kmsg.exp)"
26./kmsg.exp
27
28echo "TESTING: read/write /var/tmp (test/fs/fs_var_tmp.exp)"
29./fs_var_tmp.exp
30
31echo "TESTING: read/write /var/lock (test/fs/fs_var_lock.exp)"
32./fs_var_lock.exp
33
34echo "TESTING: read/write /dev/shm (test/fs/fs_dev_shm.exp)"
35./fs_dev_shm.exp
36
37echo "TESTING: private (test/fs/private.exp)"
38./private.exp
39
40echo "TESTING: private home (test/fs/private-home.exp)"
41./private-home.exp
42
43echo "TESTING: private home dir (test/fs/private-home-dir.exp)"
44./private-home-dir.exp
45
46echo "TESTING: private home dir same as user home (test/fs/private-homedir.exp)"
47./private-homedir.exp
48
49echo "TESTING: private-etc (test/fs/private-etc.exp)"
50./private-etc.exp
51
52echo "TESTING: empty private-etc (test/fs/private-etc-empty.exp)"
53./private-etc-empty.exp
54
55echo "TESTING: private-bin (test/fs/private-bin.exp)"
56./private-bin.exp
57
58echo "TESTING: whitelist empty (test/fs/whitelist-empty.exp)"
59./whitelist-empty.exp
60
61echo "TESTING: private whitelist (test/fs/private-whitelist.exp)"
62./private-whitelist.exp
63
64echo "TESTING: invalid filename (test/fs/invalid_filename.exp)"
65./invalid_filename.exp
66
67echo "TESTING: blacklist directory (test/fs/option_blacklist.exp)"
68./option_blacklist.exp
69
70echo "TESTING: blacklist file (test/fs/option_blacklist_file.exp)"
71./option_blacklist_file.exp
72
73echo "TESTING: blacklist glob (test/fs/option_blacklist_glob.exp)"
74./option_blacklist_glob.exp
75
76echo "TESTING: bind as user (test/fs/option_bind_user.exp)"
77./option_bind_user.exp
78
79echo "TESTING: recursive mkdir (test/fs/mkdir.exp)"
80./mkdir.exp
81
82echo "TESTING: double whitelist (test/fs/whitelist-double.exp)"
83./whitelist-double.exp
84
85
86echo "TESTING: whitelist (test/fs/whitelist.exp)"
87./whitelist.exp
88
89#cleanup
90rm -fr ~/fjtest-dir
91rm -fr ~/fjtest-dir-lnk
92rm -f ~/fjtest-file
93rm -f ~/fjtest-file-lnk
94rm -f /tmp/fjtest-file
95rm -fr /tmp/fjtest-dir
96rm -fr ~/_firejail_test_*
97
98
99
diff --git a/test/fs_dev_shm.exp b/test/fs/fs_dev_shm.exp
index b54f24eb5..8150dfa61 100755
--- a/test/fs_dev_shm.exp
+++ b/test/fs/fs_dev_shm.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -12,33 +15,33 @@ expect {
12} 15}
13sleep 1 16sleep 1
14 17
15send -- "echo mytest > /dev/shm/ttt;pwd\r" 18send -- "echo mytest > /dev/shm/ttt;echo done\r"
16expect { 19expect {
17 timeout {puts "TESTING ERROR 1\n";exit} 20 timeout {puts "TESTING ERROR 1\n";exit}
18 "home" 21 "done"
19} 22}
20 23
21send -- "cat /dev/shm/ttt;pwd\r" 24send -- "cat /dev/shm/ttt;echo done\r"
22expect { 25expect {
23 timeout {puts "TESTING ERROR 2.1\n";exit} 26 timeout {puts "TESTING ERROR 2\n";exit}
24 "mytest" 27 "mytest"
25} 28}
26expect { 29expect {
27 timeout {puts "TESTING ERROR 2\n";exit} 30 timeout {puts "TESTING ERROR 3\n";exit}
28 "home" 31 "done"
29} 32}
30 33
31send -- "rm /dev/shm/ttt;pwd\r" 34send -- "rm /dev/shm/ttt;echo done\r"
32expect { 35expect {
33 timeout {puts "TESTING ERROR 3\n";exit} 36 timeout {puts "TESTING ERROR 4\n";exit}
34 "home" 37 "done"
35} 38}
36 39
37send -- "cat /dev/shm/ttt;pwd\r" 40send -- "cat /dev/shm/ttt;echo done\r"
38expect { 41expect {
39 timeout {puts "TESTING ERROR 4\n";exit} 42 timeout {puts "TESTING ERROR 5\n";exit}
40 "mytest" {puts "TESTING ERROR 4.1\n";exit} 43 "mytest" {puts "TESTING ERROR 6\n";exit}
41 "home" 44 "done"
42} 45}
43 46
44sleep 1 47sleep 1
@@ -48,40 +51,40 @@ sleep 1
48# redo the test with --private 51# redo the test with --private
49send -- "firejail\r" 52send -- "firejail\r"
50expect { 53expect {
51 timeout {puts "TESTING ERROR 10\n";exit} 54 timeout {puts "TESTING ERROR 7\n";exit}
52 "Child process initialized" 55 "Child process initialized"
53} 56}
54sleep 1 57sleep 1
55 58
56send -- "echo mytest > /dev/shm/ttt;pwd\r" 59send -- "echo mytest > /dev/shm/ttt;echo done\r"
57expect { 60expect {
58 timeout {puts "TESTING ERROR 11\n";exit} 61 timeout {puts "TESTING ERROR 8\n";exit}
59 "home" 62 "done"
60} 63}
61 64
62send -- "cat /dev/shm/ttt;pwd\r" 65send -- "cat /dev/shm/ttt;echo done\r"
63expect { 66expect {
64 timeout {puts "TESTING ERROR 12.1\n";exit} 67 timeout {puts "TESTING ERROR 9\n";exit}
65 "mytest" 68 "mytest"
66} 69}
67expect { 70expect {
68 timeout {puts "TESTING ERROR 12\n";exit} 71 timeout {puts "TESTING ERROR 10\n";exit}
69 "home" 72 "done"
70} 73}
71 74
72send -- "rm /dev/shm/ttt;pwd\r" 75send -- "rm /dev/shm/ttt;echo done\r"
73expect { 76expect {
74 timeout {puts "TESTING ERROR 13\n";exit} 77 timeout {puts "TESTING ERROR 11\n";exit}
75 "home" 78 "done"
76} 79}
77 80
78send -- "cat /dev/shm/ttt;pwd\r" 81send -- "cat /dev/shm/ttt;echo done\r"
79expect { 82expect {
80 timeout {puts "TESTING ERROR 14\n";exit} 83 timeout {puts "TESTING ERROR 12\n";exit}
81 "mytest" {puts "TESTING ERROR 14.1\n";exit} 84 "mytest" {puts "TESTING ERROR 13\n";exit}
82 "home" 85 "done"
83} 86}
84 87
85sleep 1 88after 100
86 89
87puts "\n" 90puts "\nall done\n"
diff --git a/test/fs/fs_var_lock.exp b/test/fs/fs_var_lock.exp
new file mode 100755
index 000000000..5879dca52
--- /dev/null
+++ b/test/fs/fs_var_lock.exp
@@ -0,0 +1,90 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10# testing read-write /var/lock
11send -- "firejail\r"
12expect {
13 timeout {puts "TESTING ERROR 0\n";exit}
14 "Child process initialized"
15}
16sleep 1
17
18send -- "echo mytest > /var/lock/ttt;echo done\r"
19expect {
20 timeout {puts "TESTING ERROR 1\n";exit}
21 "done"
22}
23
24send -- "cat /var/lock/ttt;echo done\r"
25expect {
26 timeout {puts "TESTING ERROR 2\n";exit}
27 "mytest"
28}
29expect {
30 timeout {puts "TESTING ERROR 3\n";exit}
31 "done"
32}
33
34send -- "rm /var/lock/ttt;echo done\r"
35expect {
36 timeout {puts "TESTING ERROR 4\n";exit}
37 "done"
38}
39
40send -- "cat /var/lock/ttt;echo done\r"
41expect {
42 timeout {puts "TESTING ERROR 5\n";exit}
43 "mytest" {puts "TESTING ERROR 6\n";exit}
44 "done"
45}
46
47sleep 1
48send -- "exit\r"
49sleep 1
50
51# redo the test with --private
52send -- "firejail\r"
53expect {
54 timeout {puts "TESTING ERROR 7\n";exit}
55 "Child process initialized"
56}
57sleep 1
58
59send -- "echo mytest > /var/lock/ttt;echo done\r"
60expect {
61 timeout {puts "TESTING ERROR 8\n";exit}
62 "done"
63}
64
65send -- "cat /var/lock/ttt;echo done\r"
66expect {
67 timeout {puts "TESTING ERROR 9\n";exit}
68 "mytest"
69}
70expect {
71 timeout {puts "TESTING ERROR 10\n";exit}
72 "done"
73}
74
75send -- "rm /var/lock/ttt;echo done\r"
76expect {
77 timeout {puts "TESTING ERROR 11\n";exit}
78 "done"
79}
80
81send -- "cat /var/lock/ttt;echo done\r"
82expect {
83 timeout {puts "TESTING ERROR 12\n";exit}
84 "mytest" {puts "TESTING ERROR 13\n";exit}
85 "done"
86}
87
88after 100
89
90puts "\nall done\n"
diff --git a/test/fs_var_tmp.exp b/test/fs/fs_var_tmp.exp
index 95ceeb2a4..a3bc5afe2 100755
--- a/test/fs_var_tmp.exp
+++ b/test/fs/fs_var_tmp.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -12,33 +15,33 @@ expect {
12} 15}
13sleep 1 16sleep 1
14 17
15send -- "echo mytest > /var/tmp/ttt;pwd\r" 18send -- "echo mytest > /var/tmp/ttt;echo done\r"
16expect { 19expect {
17 timeout {puts "TESTING ERROR 1\n";exit} 20 timeout {puts "TESTING ERROR 1\n";exit}
18 "home" 21 "done"
19} 22}
20 23
21send -- "cat /var/tmp/ttt;pwd\r" 24send -- "cat /var/tmp/ttt;echo done\r"
22expect { 25expect {
23 timeout {puts "TESTING ERROR 2.1\n";exit} 26 timeout {puts "TESTING ERROR 2\n";exit}
24 "mytest" 27 "mytest"
25} 28}
26expect { 29expect {
27 timeout {puts "TESTING ERROR 2\n";exit} 30 timeout {puts "TESTING ERROR 3\n";exit}
28 "home" 31 "done"
29} 32}
30 33
31send -- "rm /var/tmp/ttt;pwd\r" 34send -- "rm /var/tmp/ttt;echo done\r"
32expect { 35expect {
33 timeout {puts "TESTING ERROR 3\n";exit} 36 timeout {puts "TESTING ERROR 4\n";exit}
34 "home" 37 "done"
35} 38}
36 39
37send -- "cat /var/tmp/ttt;pwd\r" 40send -- "cat /var/tmp/ttt;echo done\r"
38expect { 41expect {
39 timeout {puts "TESTING ERROR 4\n";exit} 42 timeout {puts "TESTING ERROR 5\n";exit}
40 "mytest" {puts "TESTING ERROR 4.1\n";exit} 43 "mytest" {puts "TESTING ERROR 6\n";exit}
41 "home" 44 "done"
42} 45}
43 46
44sleep 1 47sleep 1
@@ -48,40 +51,40 @@ sleep 1
48# redo the test with --private 51# redo the test with --private
49send -- "firejail\r" 52send -- "firejail\r"
50expect { 53expect {
51 timeout {puts "TESTING ERROR 10\n";exit} 54 timeout {puts "TESTING ERROR 7\n";exit}
52 "Child process initialized" 55 "Child process initialized"
53} 56}
54sleep 1 57sleep 1
55 58
56send -- "echo mytest > /var/tmp/ttt;pwd\r" 59send -- "echo mytest > /var/tmp/ttt;echo done\r"
57expect { 60expect {
58 timeout {puts "TESTING ERROR 11\n";exit} 61 timeout {puts "TESTING ERROR 8\n";exit}
59 "home" 62 "done"
60} 63}
61 64
62send -- "cat /var/tmp/ttt;pwd\r" 65send -- "cat /var/tmp/ttt;echo done\r"
63expect { 66expect {
64 timeout {puts "TESTING ERROR 12.1\n";exit} 67 timeout {puts "TESTING ERROR 9\n";exit}
65 "mytest" 68 "mytest"
66} 69}
67expect { 70expect {
68 timeout {puts "TESTING ERROR 12\n";exit} 71 timeout {puts "TESTING ERROR 10\n";exit}
69 "home" 72 "done"
70} 73}
71 74
72send -- "rm /var/tmp/ttt;pwd\r" 75send -- "rm /var/tmp/ttt;echo done\r"
73expect { 76expect {
74 timeout {puts "TESTING ERROR 13\n";exit} 77 timeout {puts "TESTING ERROR 11\n";exit}
75 "home" 78 "done"
76} 79}
77 80
78send -- "cat /var/tmp/ttt;pwd\r" 81send -- "cat /var/tmp/ttt;echo done\r"
79expect { 82expect {
80 timeout {puts "TESTING ERROR 14\n";exit} 83 timeout {puts "TESTING ERROR 12\n";exit}
81 "mytest" {puts "TESTING ERROR 14.1\n";exit} 84 "mytest" {puts "TESTING ERROR 13\n";exit}
82 "home" 85 "done"
83} 86}
84 87
85sleep 1 88after 100
86 89
87puts "\n" 90puts "\nall done\n"
diff --git a/test/invalid_filename.exp b/test/fs/invalid_filename.exp
index fe8bd8c25..1acc85491 100755
--- a/test/invalid_filename.exp
+++ b/test/fs/invalid_filename.exp
@@ -1,23 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2 2# This file is part of Firejail project
3#invalid_filename checks: 3# Copyright (C) 2014-2016 Firejail Authors
4# 4# License GPL v2
5#--bind (two files) - profile.c - Note: The test is not implemented here, need to be root to test it
6#--blacklist - profile.c
7#--cgroup - cgroup.c
8#--chroot - main.c
9#--netfilter - netfilter.c
10#--output - output.c
11#--private - fs_home.c
12#--privte-bin (list) - fs_bin.c
13#--private-home (list) - fs_home.c
14#--private-etc (list) - fs_etc.c
15#--profile - main.c
16#--read_only - profile.c
17#--shell - main.c
18#--tmpfs - profile.c
19#--white-list
20
21 5
22set timeout 10 6set timeout 10
23spawn $env(SHELL) 7spawn $env(SHELL)
@@ -201,7 +185,5 @@ expect {
201} 185}
202after 100 186after 100
203 187
204
205
206puts "\nall done\n" 188puts "\nall done\n"
207 189
diff --git a/test/kmsg.exp b/test/fs/kmsg.exp
index 096bdb708..abc711aee 100755
--- a/test/kmsg.exp
+++ b/test/fs/kmsg.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -16,14 +19,14 @@ expect {
16 timeout {puts "TESTING ERROR 2\n";exit} 19 timeout {puts "TESTING ERROR 2\n";exit}
17 "Permission denied" 20 "Permission denied"
18} 21}
19sleep 1 22after 100
20 23
21send -- "cat /proc/kmsg\r" 24send -- "cat /proc/kmsg\r"
22expect { 25expect {
23 timeout {puts "TESTING ERROR 3\n";exit} 26 timeout {puts "TESTING ERROR 3\n";exit}
24 "Permission denied" 27 "Permission denied"
25} 28}
26sleep 1 29after 100
27 30
28puts "\nall done\n" 31puts "\nall done\n"
29 32
diff --git a/test/fs/mkdir.exp b/test/fs/mkdir.exp
new file mode 100755
index 000000000..111db06db
--- /dev/null
+++ b/test/fs/mkdir.exp
@@ -0,0 +1,20 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2016 Firejail Authors
4# License GPL v2
5
6set timeout 3
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --profile=mkdir.profile find ~/.firejail_test\r"
11expect {
12 timeout {puts "TESTING ERROR 1.1\n";exit}
13 "Warning: cannot create" { puts "TESTING ERROR 1.2\n";exit}
14 "No such file or directory" { puts "TESTING ERROR 1.3\n";exit}
15 ".firejail_test/a/b/c/d.txt"
16}
17send -- "rm -rf ~/.firejail_test\r"
18after 100
19
20puts "\nall done\n"
diff --git a/test/fs/mkdir.profile b/test/fs/mkdir.profile
new file mode 100644
index 000000000..61b44c9ac
--- /dev/null
+++ b/test/fs/mkdir.profile
@@ -0,0 +1,2 @@
1mkdir ~/.firejail_test/a/b/c
2mkfile ~/.firejail_test/a/b/c/d.txt
diff --git a/test/fs/mkdir_mkfile.exp b/test/fs/mkdir_mkfile.exp
new file mode 100755
index 000000000..98163bf77
--- /dev/null
+++ b/test/fs/mkdir_mkfile.exp
@@ -0,0 +1,46 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10
11# testing profile and private
12send -- "firejail --private --profile=mkdir_mkfile.profile\r"
13expect {
14 timeout {puts "TESTING ERROR 0\n";exit}
15 "Child process initialized"
16}
17sleep 1
18
19send -- "find ~\r"
20expect {
21 timeout {puts "TESTING ERROR 1\n";exit}
22 "_firejail_test_file"
23}
24expect {
25 timeout {puts "TESTING ERROR 1\n";exit}
26 "_firejail_test_dir"
27}
28expect {
29 timeout {puts "TESTING ERROR 1\n";exit}
30 "_firejail_test_dir/dir1"
31}
32expect {
33 timeout {puts "TESTING ERROR 1\n";exit}
34 "_firejail_test_dir/dir1/dir2"
35}
36expect {
37 timeout {puts "TESTING ERROR 1\n";exit}
38 "_firejail_test_dir/dir1/dir2/dir3"
39}
40expect {
41 timeout {puts "TESTING ERROR 1\n";exit}
42 "_firejail_test_dir/dir1/dir2/dir3/file1"
43}
44after 100
45
46puts "all done\n"
diff --git a/test/fs/mkdir_mkfile.profile b/test/fs/mkdir_mkfile.profile
new file mode 100644
index 000000000..d179c62ac
--- /dev/null
+++ b/test/fs/mkdir_mkfile.profile
@@ -0,0 +1,4 @@
1mkdir ~/_firejail_test_dir
2mkfile ~/_firejail_test_file
3mkdir ~/_firejail_test_dir/dir1/dir2/dir3
4mkfile ~/_firejail_test_dir/dir1/dir2/dir3/file1
diff --git a/test/option_bind_user.exp b/test/fs/option_bind_user.exp
index 9d2d17d7f..a2912968e 100755
--- a/test/option_bind_user.exp
+++ b/test/fs/option_bind_user.exp
@@ -9,7 +9,7 @@ expect {
9 timeout {puts "TESTING ERROR 0\n";exit} 9 timeout {puts "TESTING ERROR 0\n";exit}
10 "bind option is available only if running as root" 10 "bind option is available only if running as root"
11} 11}
12sleep 1 12after 100
13 13
14puts "\n" 14puts "\n"
15 15
diff --git a/test/option_blacklist.exp b/test/fs/option_blacklist.exp
index b80d0cc60..6554d438f 100755
--- a/test/option_blacklist.exp
+++ b/test/fs/option_blacklist.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -11,25 +14,25 @@ expect {
11} 14}
12sleep 1 15sleep 1
13 16
14send -- "ls -l /var;pwd\r" 17send -- "ls -l /var;echo done\r"
15expect { 18expect {
16 timeout {puts "TESTING ERROR 1\n";exit} 19 timeout {puts "TESTING ERROR 1\n";exit}
17 "Permission denied" 20 "Permission denied"
18} 21}
19expect { 22expect {
20 timeout {puts "TESTING ERROR 2\n";exit} 23 timeout {puts "TESTING ERROR 2\n";exit}
21 "home" 24 "done"
22} 25}
23send -- "cd /var;pwd\r" 26send -- "cd /var;echo done\r"
24expect { 27expect {
25 timeout {puts "TESTING ERROR 3\n";exit} 28 timeout {puts "TESTING ERROR 3\n";exit}
26 "Permission denied" 29 "Permission denied"
27} 30}
28expect { 31expect {
29 timeout {puts "TESTING ERROR 4\n";exit} 32 timeout {puts "TESTING ERROR 4\n";exit}
30 "home" 33 "done"
31} 34}
32sleep 1 35after 100
33 36
34puts "\n" 37puts "\n"
35 38
diff --git a/test/option_blacklist_file.exp b/test/fs/option_blacklist_file.exp
index ecdfe3b82..b0164136c 100755
--- a/test/option_blacklist_file.exp
+++ b/test/fs/option_blacklist_file.exp
@@ -11,16 +11,16 @@ expect {
11} 11}
12sleep 1 12sleep 1
13 13
14send -- "cat /etc/passwd;pwd\r" 14send -- "cat /etc/passwd;echo done\r"
15expect { 15expect {
16 timeout {puts "TESTING ERROR 1\n";exit} 16 timeout {puts "TESTING ERROR 1\n";exit}
17 "Permission denied" 17 "Permission denied"
18} 18}
19expect { 19expect {
20 timeout {puts "TESTING ERROR 2\n";exit} 20 timeout {puts "TESTING ERROR 2\n";exit}
21 "home" 21 "done"
22} 22}
23sleep 1 23after 100
24 24
25puts "\n" 25puts "\n"
26 26
diff --git a/test/fs/option_blacklist_glob.exp b/test/fs/option_blacklist_glob.exp
new file mode 100755
index 000000000..5a96cacc9
--- /dev/null
+++ b/test/fs/option_blacklist_glob.exp
@@ -0,0 +1,33 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --blacklist=testdir1/*\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Child process initialized"
14}
15sleep 1
16send -- "cd testdir1\r"
17sleep 1
18
19send -- "cat .file\r"
20expect {
21 timeout {puts "TESTING ERROR 1\n";exit}
22 "Permission denied"
23}
24
25send -- "ls .directory\r"
26expect {
27 timeout {puts "TESTING ERROR 2\n";exit}
28 "Permission denied"
29}
30after 100
31
32puts "\n"
33
diff --git a/test/private-bin.exp b/test/fs/private-bin.exp
index a82d2b213..fe9468be9 100755
--- a/test/private-bin.exp
+++ b/test/fs/private-bin.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -63,9 +66,6 @@ expect {
63} 66}
64send -- "exit\r" 67send -- "exit\r"
65 68
66 69after 100
67
68
69sleep 1
70puts "\nall done\n" 70puts "\nall done\n"
71 71
diff --git a/test/private-bin.profile b/test/fs/private-bin.profile
index 24cf5929a..24cf5929a 100644
--- a/test/private-bin.profile
+++ b/test/fs/private-bin.profile
diff --git a/test/fs/private-etc-empty.exp b/test/fs/private-etc-empty.exp
new file mode 100755
index 000000000..5ddce8678
--- /dev/null
+++ b/test/fs/private-etc-empty.exp
@@ -0,0 +1,42 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --private-etc=blablabla\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Child process initialized"
14}
15sleep 1
16
17send -- "ls -l /etc | wc -l\r"
18expect {
19 timeout {puts "TESTING ERROR 1\n";exit}
20 "0" {puts "Debian\n"}
21 "1" {puts "Arch\n"}
22}
23send -- "exit\r"
24sleep 1
25
26send -- "firejail --profile=private-etc-empty.profile\r"
27expect {
28 timeout {puts "TESTING ERROR 0\n";exit}
29 "Child process initialized"
30}
31sleep 1
32
33send -- "ls -l /etc | wc -l\r"
34expect {
35 timeout {puts "TESTING ERROR 1\n";exit}
36 "0" {puts "Debian\n"}
37 "1" {puts "Arch\n"}
38
39}
40
41after 100
42puts "\nall done\n"
diff --git a/test/fs/private-etc-empty.profile b/test/fs/private-etc-empty.profile
new file mode 100644
index 000000000..38aa8cd68
--- /dev/null
+++ b/test/fs/private-etc-empty.profile
@@ -0,0 +1 @@
private-etc blablabla
diff --git a/test/private-etc.exp b/test/fs/private-etc.exp
index db1d1df3a..e692f7382 100755
--- a/test/private-etc.exp
+++ b/test/fs/private-etc.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -12,31 +15,31 @@ expect {
12} 15}
13sleep 1 16sleep 1
14 17
15send -- "ls -al /etc\r" 18send -- "LC_ALL=C ls -al /etc\r"
16expect { 19expect {
17 timeout {puts "TESTING ERROR 3\n";exit} 20 timeout {puts "TESTING ERROR 3\n";exit}
18 "group" 21 "X11"
19} 22}
20expect { 23expect {
21 timeout {puts "TESTING ERROR 4\n";exit} 24 timeout {puts "TESTING ERROR 4\n";exit}
22 "passwd" 25 "group"
23} 26}
24expect { 27expect {
25 timeout {puts "TESTING ERROR 5\n";exit} 28 timeout {puts "TESTING ERROR 5\n";exit}
26 "resolv.conf" 29 "passwd"
27} 30}
28expect { 31expect {
29 timeout {puts "TESTING ERROR 6\n";exit} 32 timeout {puts "TESTING ERROR 6\n";exit}
30 "X11" 33 "resolv.conf"
31} 34}
32 35
33send -- "ls -al /etc\r" 36send -- "ls -al /etc; echo done\r"
34expect { 37expect {
35 timeout {puts "TESTING ERROR 7\n";exit} 38 timeout {puts "TESTING ERROR 7\n";exit}
36 "shadow" {puts "TESTING ERROR 8\n";exit} 39 "shadow" {puts "TESTING ERROR 8\n";exit}
37 "X11" 40 "done"
38} 41}
39 42
40sleep 1 43after 100
41puts "\nall done\n" 44puts "\nall done\n"
42 45
diff --git a/test/fs/private-home-dir.exp b/test/fs/private-home-dir.exp
new file mode 100755
index 000000000..5491be834
--- /dev/null
+++ b/test/fs/private-home-dir.exp
@@ -0,0 +1,70 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10
11if {[file exists ~/.asoundrc]} {
12 puts "found .asoundrc file\n"
13} else {
14 send -- "touch ~/.asoundrc\r"
15}
16after 100
17
18if {[file exists ~/.Xauthority]} {
19 puts "found .Xauthority file\n"
20} else {
21 send -- "touch ~/.Xauthority\r"
22}
23after 100
24send -- "mkdir ~/_firejail_test_dir_\r"
25sleep 1
26
27# testing profile and private
28send -- "firejail --private=~/_firejail_test_dir_\r"
29expect {
30 timeout {puts "TESTING ERROR 0\n";exit}
31 "Child process initialized"
32}
33sleep 1
34
35send -- "ls -l ~\r"
36expect {
37 timeout {puts "TESTING ERROR 1\n";exit}
38 "total 0"
39}
40after 100
41
42send -- "ls -al ~\r"
43expect {
44 timeout {puts "TESTING ERROR 2\n";exit}
45 ".asoundrc"
46}
47expect {
48 timeout {puts "TESTING ERROR 3\n";exit}
49 ".bashrc"
50}
51expect {
52 timeout {puts "TESTING ERROR 4\n";exit}
53 ".Xauthority"
54}
55after 100
56
57send -- "exit\r"
58sleep 1
59
60
61# testing profile and private
62send -- "firejail --private=/etc\r"
63expect {
64 timeout {puts "TESTING ERROR 5\n";exit}
65 "private directory should be owned by the current user"
66}
67sleep 1
68
69
70puts "all done\n"
diff --git a/test/fs/private-home.exp b/test/fs/private-home.exp
new file mode 100755
index 000000000..de5a88dea
--- /dev/null
+++ b/test/fs/private-home.exp
@@ -0,0 +1,45 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10# create some test files in user home directory
11send -- "touch ~/_firejail_test_file1\r"
12send -- "touch ~/_firejail_test_file2\r"
13send -- "mkdir ~/_firejail_test_dir1\r"
14send -- "mkdir ~/_firejail_test_dir1/_firejail_test_dir2\r"
15send -- "touch ~/_firejail_test_dir1/_firejail_test_dir2/_firejail_test_file3\r"
16after 100
17
18send -- "firejail --private-home=_firejail_test_file1,_firejail_test_file2,_firejail_test_dir1\r"
19expect {
20 timeout {puts "TESTING ERROR 1\n";exit}
21 "Child process initialized"
22}
23after 100
24
25send -- "find ~\r"
26expect {
27 timeout {puts "TESTING ERROR 2\n";exit}
28 "_firejail_test_file3"
29}
30expect {
31 timeout {puts "TESTING ERROR 3\n";exit}
32 "_firejail_test_file2"
33}
34expect {
35 timeout {puts "TESTING ERROR 4\n";exit}
36 "_firejail_test_file1"
37}
38after 100
39
40send -- "rm -f ~/_firejail_test_file*\r"
41send -- "rm -fr ~/_firejail_test_dir*\r"
42after 100
43
44puts "\nall done\n"
45
diff --git a/test/fs/private-homedir.exp b/test/fs/private-homedir.exp
new file mode 100755
index 000000000..35085948a
--- /dev/null
+++ b/test/fs/private-homedir.exp
@@ -0,0 +1,25 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --private=~\r"
11expect {
12 timeout {puts "TESTING ERROR 1\n";exit}
13 "Child process initialized"
14}
15after 100
16
17send -- "ls -l ~\r"
18expect {
19 timeout {puts "TESTING ERROR 2\n";exit}
20 "total 0"
21}
22after 100
23
24puts "\nall done\n"
25
diff --git a/test/private-whitelist.exp b/test/fs/private-whitelist.exp
index 7379241ef..4dadeacb1 100755
--- a/test/private-whitelist.exp
+++ b/test/fs/private-whitelist.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -9,26 +12,28 @@ expect {
9 timeout {puts "TESTING ERROR 1\n";exit} 12 timeout {puts "TESTING ERROR 1\n";exit}
10 "Child process initialized" 13 "Child process initialized"
11} 14}
12sleep 1 15after 100
13 16
14send -- "ls -al /tmp\r" 17send -- "ls -al /tmp\r"
15expect { 18expect {
16 timeout {puts "TESTING ERROR 2\n";exit} 19 timeout {puts "TESTING ERROR 2\n";exit}
17 ".X11-unix" 20 ".X11-unix"
18} 21}
19sleep 1 22after 100
20 23
21send -- "ls -a /tmp | wc -l\r" 24send -- "ls -a /tmp | wc -l\r"
22expect { 25expect {
23 timeout {puts "TESTING ERROR 3\n";exit} 26 timeout {puts "TESTING ERROR 3\n";exit}
24 "3" 27 "3"
25} 28}
26sleep 1 29after 100
27 30
28send -- "ls -a ~ | wc -l\r" 31send -- "ls -a ~ | wc -l\r"
29expect { 32expect {
30 timeout {puts "TESTING ERROR 4\n";exit} 33 timeout {puts "TESTING ERROR 4\n";exit}
31 "5" 34 "3" {puts "3\n"}
35 "4" {puts "4\n"}
36 "5" {puts "5\n"}
32} 37}
33 38
34sleep 1 39sleep 1
diff --git a/test/fs/private.exp b/test/fs/private.exp
new file mode 100755
index 000000000..8114ee45d
--- /dev/null
+++ b/test/fs/private.exp
@@ -0,0 +1,58 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10
11if {[file exists ~/.asoundrc]} {
12 puts "found .asoundrc file\n"
13} else {
14 send -- "touch ~/.asoundrc\r"
15}
16after 100
17
18if {[file exists ~/.Xauthority]} {
19 puts "found .Xauthority file\n"
20} else {
21 send -- "touch ~/.Xauthority\r"
22}
23after 100
24
25# testing profile and private
26send -- "firejail --private\r"
27expect {
28 timeout {puts "TESTING ERROR 0\n";exit}
29 "Child process initialized"
30}
31sleep 1
32
33send -- "ls -l ~\r"
34expect {
35 timeout {puts "TESTING ERROR 1\n";exit}
36 "total 0"
37}
38after 100
39
40send -- "ls -al ~\r"
41expect {
42 timeout {puts "TESTING ERROR 2\n";exit}
43 ".asoundrc"
44}
45expect {
46 timeout {puts "TESTING ERROR 3\n";exit}
47 ".bashrc"
48}
49expect {
50 timeout {puts "TESTING ERROR 4\n";exit}
51 ".Xauthority"
52}
53after 100
54
55send -- "exit\r"
56sleep 1
57
58puts "all done\n"
diff --git a/test/fs/read-write.exp b/test/fs/read-write.exp
new file mode 100755
index 000000000..57986488e
--- /dev/null
+++ b/test/fs/read-write.exp
@@ -0,0 +1,51 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10
11send -- "firejail --read-only=~/_firejail_test_dir --read-write=~/_firejail_test_dir/test1\r"
12expect {
13 timeout {puts "TESTING ERROR 0\n";exit}
14 "Child process initialized"
15}
16sleep 1
17
18send -- "echo mytest >~/_firejail_test_dir/a;echo done\r"
19expect {
20 timeout {puts "TESTING ERROR 1\n";exit}
21 "done"
22}
23after 100
24
25send -- "echo mytest >~/_firejail_test_dir/test1/b;echo done\r"
26expect {
27 timeout {puts "TESTING ERROR 2\n";exit}
28 "done"
29}
30after 100
31
32send -- "cat ~/_firejail_test_dir/a;echo done\r"
33expect {
34 timeout {puts "TESTING ERROR 3\n";exit}
35 "mytest" {puts "TESTING ERROR 4\n";exit}
36 "done"
37}
38after 100
39
40send -- "cat ~/_firejail_test_dir/test1/b;echo done\r"
41expect {
42 timeout {puts "TESTING ERROR 5\n";exit}
43 "mytest"
44}
45expect {
46 timeout {puts "TESTING ERROR 6\n";exit}
47 "done"
48}
49
50after 100
51puts "\nall done\n"
diff --git a/test/fs/sys_fs.exp b/test/fs/sys_fs.exp
new file mode 100755
index 000000000..f512776d9
--- /dev/null
+++ b/test/fs/sys_fs.exp
@@ -0,0 +1,44 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail\r"
11expect {
12 timeout {puts "TESTING ERROR 1\n";exit}
13 "Child process initialized"
14}
15sleep 1
16
17send -- "ls /sys/fs\r"
18expect {
19 timeout {puts "TESTING ERROR 2\n";exit}
20 "Permission denied"
21}
22after 100
23
24send -- "exit\r"
25sleep 1
26
27send -- "firejail --noblacklist=/sys/fs\r"
28expect {
29 timeout {puts "TESTING ERROR 1\n";exit}
30 "Child process initialized"
31}
32sleep 1
33
34send -- "ls /sys/fs\r"
35expect {
36 timeout {puts "TESTING ERROR 2\n";exit}
37 "cgroup"
38}
39after 100
40send -- "exit\r"
41after 100
42
43puts "\nall done\n"
44
diff --git a/test/fs/testdir1/.directory/file b/test/fs/testdir1/.directory/file
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/test/fs/testdir1/.directory/file
diff --git a/test/fs/testdir1/.file b/test/fs/testdir1/.file
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/test/fs/testdir1/.file
diff --git a/test/fs/whitelist-double.exp b/test/fs/whitelist-double.exp
new file mode 100755
index 000000000..fc05f9322
--- /dev/null
+++ b/test/fs/whitelist-double.exp
@@ -0,0 +1,42 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "echo 123 > /tmp/firejal-deleteme\r"
11sleep 1
12
13send -- "firejail --whitelist=/tmp/firejal-deleteme --whitelist=/tmp/firejal-deleteme\r"
14expect {
15 timeout {puts "TESTING ERROR 0\n";exit}
16 "Child process initialized"
17}
18sleep 1
19
20send -- "cat /tmp/firejal-deleteme\r"
21expect {
22 timeout {puts "TESTING ERROR 1\n";exit}
23 "123"
24}
25
26send -- "exit\r"
27sleep 1
28
29send -- "cat /tmp/firejal-deleteme\r"
30expect {
31 timeout {puts "TESTING ERROR 2\n";exit}
32 "123"
33}
34
35send -- "rm /tmp/firejal-deleteme\r"
36expect {
37 timeout {puts "TESTING ERROR 3\n";exit}
38 "0"
39}
40after 100
41
42puts "\nall done\n"
diff --git a/test/whitelist-empty.exp b/test/fs/whitelist-empty.exp
index 226b019db..71bb8f914 100755
--- a/test/whitelist-empty.exp
+++ b/test/fs/whitelist-empty.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 30 6set timeout 30
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -46,5 +49,6 @@ expect {
46 "0" 49 "0"
47} 50}
48 51
52after 100
49 53
50puts "\nall done\n" 54puts "\nall done\n"
diff --git a/test/fs/whitelist.exp b/test/fs/whitelist.exp
new file mode 100755
index 000000000..9a9a0f353
--- /dev/null
+++ b/test/fs/whitelist.exp
@@ -0,0 +1,226 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10# cleanup
11send -- "rm -fr ~/fjtest-dir\r"
12after 200
13send -- "rm -fr ~/fjtest-dir-lnk\r"
14after 200
15send -- "rm ~/fjtest-file\r"
16after 200
17send -- "rm ~/fjtest-file-lnk\r"
18after 200
19send -- "rm /tmp/fjtest-file\r"
20after 200
21send -- "rm -fr /tmp/fjtest-dir\r"
22after 200
23
24
25# simple files and directories
26send -- "mkdir -p ~/fjtest-dir/fjtest-dir\r"
27after 200
28send -- "echo 123 > ~/fjtest-file\r"
29after 200
30send -- "echo 123 > ~/fjtest-dir/fjtest-file\r"
31after 200
32send -- "echo 123 > ~/fjtest-dir/fjtest-dir/fjtest-file\r"
33after 200
34send -- "ln -s ~/fjtest-file ~/fjtest-file-lnk\r"
35after 200
36send -- "ln -s ~/fjtest-dir ~/fjtest-dir-lnk\r"
37after 200
38
39send -- "firejail --whitelist=~/fjtest-file --whitelist=~/fjtest-dir\r"
40expect {
41 timeout {puts "TESTING ERROR 0\n";exit}
42 "Child process initialized"
43}
44sleep 1
45
46send -- "ls -l ~/ | grep -v total | wc -l\r"
47expect {
48 timeout {puts "TESTING ERROR 1\n";exit}
49 "2"
50}
51
52send -- "cat fjtest-file\r"
53expect {
54 timeout {puts "TESTING ERROR 2\n";exit}
55 "123"
56}
57
58send -- "cat fjtest-dir/fjtest-file\r"
59expect {
60 timeout {puts "TESTING ERROR 3\n";exit}
61 "123"
62}
63
64send -- "cat fjtest-dir/fjtest-dir/fjtest-file\r"
65expect {
66 timeout {puts "TESTING ERROR 4\n";exit}
67 "123"
68}
69
70send -- "exit\r"
71sleep 1
72
73
74
75# simple files and directories
76send -- "firejail --whitelist=~/fjtest-dir/fjtest-dir/fjtest-file\r"
77expect {
78 timeout {puts "TESTING ERROR 10\n";exit}
79 "Child process initialized"
80}
81sleep 1
82
83send -- "ls -l ~/ | grep -v total | wc -l\r"
84expect {
85 timeout {puts "TESTING ERROR 11\n";exit}
86 "1"
87}
88
89send -- "cat fjtest-dir/fjtest-dir/fjtest-file\r"
90expect {
91 timeout {puts "TESTING ERROR 12\n";exit}
92 "123"
93}
94
95send -- "exit\r"
96sleep 1
97
98
99
100# symlinks
101send -- "firejail --whitelist=~/fjtest-file-lnk --whitelist=~/fjtest-dir-lnk\r"
102expect {
103 timeout {puts "TESTING ERROR 20\n";exit}
104 "Child process initialized"
105}
106sleep 1
107
108send -- "ls -l ~/ | grep -v total | wc -l\r"
109expect {
110 timeout {puts "TESTING ERROR 21\n";exit}
111 "4"
112}
113
114send -- "cat fjtest-file\r"
115expect {
116 timeout {puts "TESTING ERROR 22\n";exit}
117 "123"
118}
119
120send -- "cat fjtest-dir/fjtest-file\r"
121expect {
122 timeout {puts "TESTING ERROR 23\n";exit}
123 "123"
124}
125
126send -- "cat fjtest-dir/fjtest-dir/fjtest-file\r"
127expect {
128 timeout {puts "TESTING ERROR 24\n";exit}
129 "123"
130}
131
132send -- "cat fjtest-file-lnk\r"
133expect {
134 timeout {puts "TESTING ERROR 25\n";exit}
135 "123"
136}
137
138send -- "cat fjtest-dir-lnk/fjtest-file\r"
139expect {
140 timeout {puts "TESTING ERROR 26\n";exit}
141 "123"
142}
143
144send -- "cat fjtest-dir-lnk/fjtest-dir/fjtest-file\r"
145expect {
146 timeout {puts "TESTING ERROR 27\n";exit}
147 "123"
148}
149send -- "exit\r"
150sleep 1
151
152# symlinks outside home to a file we don't own
153send -- "rm ~/fjtest-file-lnk\r"
154after 200
155send -- "ln -s /etc/passwd ~/fjtest-file-lnk\r"
156after 200
157send -- "firejail --whitelist=~/fjtest-file-lnk --whitelist=~/fjtest-dir-lnk\r"
158expect {
159 timeout {puts "TESTING ERROR 30\n";exit}
160 "invalid whitelist path"
161}
162expect {
163 timeout {puts "TESTING ERROR 31\n";exit}
164 "exiting"
165}
166sleep 1
167
168# symlinks outside home to a file we own
169send -- "rm -fr ~/fjtest-dir-lnk\r"
170after 200
171send -- "rm ~/fjtest-file-lnk\r"
172after 200
173send -- "echo 123 > /tmp/fjtest-file\r"
174after 200
175send -- "mkdir /tmp/fjtest-dir\r"
176after 200
177send -- "echo 123 > /tmp/fjtest-dir/fjtest-file\r"
178after 200
179send -- "ln -s /tmp/fjtest-file ~/fjtest-file-lnk\r"
180after 200
181send -- "ln -s /tmp/fjtest-dir ~/fjtest-dir-lnk\r"
182after 200
183send -- "firejail --whitelist=~/fjtest-file-lnk --whitelist=~/fjtest-dir-lnk\r"
184expect {
185 timeout {puts "TESTING ERROR 40\n";exit}
186 "Child process initialized"
187}
188sleep 1
189
190send -- "ls -l ~/ | grep -v total | wc -l\r"
191expect {
192 timeout {puts "TESTING ERROR 41\n";exit}
193 "2"
194}
195
196send -- "cat fjtest-file-lnk\r"
197expect {
198 timeout {puts "TESTING ERROR 42\n";exit}
199 "123"
200}
201
202send -- "cat fjtest-dir-lnk/fjtest-file\r"
203expect {
204 timeout {puts "TESTING ERROR 43\n";exit}
205 "123"
206}
207send -- "exit\r"
208sleep 1
209
210# cleanup
211send -- "rm -fr ~/fjtest-dir\r"
212after 200
213send -- "rm -fr ~/fjtest-dir-lnk\r"
214after 200
215send -- "rm ~/fjtest-file\r"
216after 200
217send -- "rm ~/fjtest-file-lnk\r"
218after 200
219send -- "rm /tmp/fjtest-file\r"
220after 200
221send -- "rm -fr /tmp/fjtest-dir\r"
222after 200
223
224
225puts "\nall done\n"
226
diff --git a/test/fs_var_lock.exp b/test/fs_var_lock.exp
deleted file mode 100755
index dfcf571f4..000000000
--- a/test/fs_var_lock.exp
+++ /dev/null
@@ -1,87 +0,0 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7# testing read-write /var/lock
8send -- "firejail\r"
9expect {
10 timeout {puts "TESTING ERROR 0\n";exit}
11 "Child process initialized"
12}
13sleep 1
14
15send -- "echo mytest > /var/lock/ttt;pwd\r"
16expect {
17 timeout {puts "TESTING ERROR 1\n";exit}
18 "home"
19}
20
21send -- "cat /var/lock/ttt;pwd\r"
22expect {
23 timeout {puts "TESTING ERROR 2.1\n";exit}
24 "mytest"
25}
26expect {
27 timeout {puts "TESTING ERROR 2\n";exit}
28 "home"
29}
30
31send -- "rm /var/lock/ttt;pwd\r"
32expect {
33 timeout {puts "TESTING ERROR 3\n";exit}
34 "home"
35}
36
37send -- "cat /var/lock/ttt;pwd\r"
38expect {
39 timeout {puts "TESTING ERROR 4\n";exit}
40 "mytest" {puts "TESTING ERROR 4.1\n";exit}
41 "home"
42}
43
44sleep 1
45send -- "exit\r"
46sleep 1
47
48# redo the test with --private
49send -- "firejail\r"
50expect {
51 timeout {puts "TESTING ERROR 10\n";exit}
52 "Child process initialized"
53}
54sleep 1
55
56send -- "echo mytest > /var/lock/ttt;pwd\r"
57expect {
58 timeout {puts "TESTING ERROR 11\n";exit}
59 "home"
60}
61
62send -- "cat /var/lock/ttt;pwd\r"
63expect {
64 timeout {puts "TESTING ERROR 12.1\n";exit}
65 "mytest"
66}
67expect {
68 timeout {puts "TESTING ERROR 12\n";exit}
69 "home"
70}
71
72send -- "rm /var/lock/ttt;pwd\r"
73expect {
74 timeout {puts "TESTING ERROR 13\n";exit}
75 "home"
76}
77
78send -- "cat /var/lock/ttt;pwd\r"
79expect {
80 timeout {puts "TESTING ERROR 14\n";exit}
81 "mytest" {puts "TESTING ERROR 14.1\n";exit}
82 "home"
83}
84
85sleep 1
86
87puts "\n"
diff --git a/test/google-chrome.exp b/test/google-chrome.exp
deleted file mode 100755
index 389988e3c..000000000
--- a/test/google-chrome.exp
+++ /dev/null
@@ -1,80 +0,0 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "firejail google-chrome www.gentoo.org\r"
8expect {
9 timeout {puts "TESTING ERROR 0\n";exit}
10 "Reading profile /etc/firejail/google-chrome.profile"
11}
12expect {
13 timeout {puts "TESTING ERROR 1\n";exit}
14 "Child process initialized"
15}
16sleep 10
17
18spawn $env(SHELL)
19send -- "firejail --list\r"
20expect {
21 timeout {puts "TESTING ERROR 3\n";exit}
22 ":firejail"
23}
24expect {
25 timeout {puts "TESTING ERROR 3.1\n";exit}
26 "google-chrome"
27}
28sleep 1
29
30# grsecurity exit
31send -- "file /proc/sys/kernel/grsecurity\r"
32expect {
33 timeout {puts "TESTING ERROR - grsecurity detection\n";exit}
34 "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit}
35 "cannot open" {puts "grsecurity not present\n"}
36}
37
38send -- "firejail --name=blablabla\r"
39expect {
40 timeout {puts "TESTING ERROR 4\n";exit}
41 "Child process initialized"
42}
43sleep 2
44
45spawn $env(SHELL)
46send -- "firemon --seccomp\r"
47expect {
48 timeout {puts "TESTING ERROR 5\n";exit}
49 ":firejail google-chrome"
50}
51expect {
52 timeout {puts "TESTING ERROR 5.1\n";exit}
53 "Seccomp: 0"
54}
55expect {
56 timeout {puts "TESTING ERROR 5.1\n";exit}
57 "name=blablabla"
58}
59sleep 1
60send -- "firemon --caps\r"
61expect {
62 timeout {puts "TESTING ERROR 6\n";exit}
63 ":firejail google-chrome"
64}
65expect {
66 timeout {puts "TESTING ERROR 6.1\n";exit}
67 "CapBnd:"
68}
69expect {
70 timeout {puts "TESTING ERROR 6.2\n";exit}
71 "fffffffff"
72}
73expect {
74 timeout {puts "TESTING ERROR 6.3\n";exit}
75 "name=blablabla"
76}
77sleep 1
78
79puts "\n"
80
diff --git a/test/net_interface.exp b/test/net_interface.exp
deleted file mode 100755
index 4b55187ff..000000000
--- a/test/net_interface.exp
+++ /dev/null
@@ -1,88 +0,0 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "ip link add link eth0 name eth0.100 type vlan id 100\r"
8sleep 1
9send -- "ip link add link eth0 name eth0.101 type vlan id 101\r"
10sleep 1
11send -- "ip link add link eth0 name eth0.102 type vlan id 102\r"
12sleep 1
13send -- "ip link add link eth0 name eth0.103 type vlan id 103\r"
14sleep 1
15send -- "ip link add link eth0 name eth0.104 type vlan id 104\r"
16sleep 1
17puts "\n"
18
19send -- "/sbin/ifconfig eth0.100 10.200.0.1/24\r"
20sleep 1
21send -- "/sbin/ifconfig eth0.101 10.200.1.1/24\r"
22sleep 1
23send -- "/sbin/ifconfig eth0.102 10.200.2.1/24\r"
24sleep 1
25send -- "/sbin/ifconfig eth0.103 10.200.3.1/24\r"
26sleep 1
27send -- "/sbin/ifconfig eth0.104 10.200.4.1/24\r"
28sleep 1
29puts "\n"
30
31
32
33send -- "firejail --noprofile --interface=eth0.100 --interface=eth0.101 --interface=eth0.102 --interface=eth0.103 --interface=eth0.104\r"
34expect {
35 timeout {puts "TESTING ERROR 0\n";exit}
36 "maximum 4 interfaces are allowed"
37}
38sleep 1
39
40send -- "firejail --noprofile --interface=eth0.100 --interface=eth0.101 --interface=eth0.102 --interface=eth0.103\r"
41expect {
42 timeout {puts "TESTING ERROR 1\n";exit}
43 "eth0.100"
44}
45expect {
46 timeout {puts "TESTING ERROR 1.1\n";exit}
47 "UP"
48}
49expect {
50 timeout {puts "TESTING ERROR 2\n";exit}
51 "eth0.101"
52}
53expect {
54 timeout {puts "TESTING ERROR 2.2\n";exit}
55 "UP"
56}
57expect {
58 timeout {puts "TESTING ERROR 3\n";exit}
59 "eth0.102"
60}
61expect {
62 timeout {puts "TESTING ERROR 3.1\n";exit}
63 "UP"
64}
65expect {
66 timeout {puts "TESTING ERROR 4\n";exit}
67 "eth0.103"
68}
69expect {
70 timeout {puts "TESTING ERROR 4.1\n";exit}
71 "UP"
72}
73sleep 1
74send -- "exit\r"
75sleep 1
76
77send -- "firejail --noprofile --interface=eth0.104\r"
78expect {
79 timeout {puts "TESTING ERROR 5\n";exit}
80 "eth0.104"
81}
82expect {
83 timeout {puts "TESTING ERROR 5.1\n";exit}
84 "UP"
85}
86
87puts "all done\n"
88
diff --git a/test/4bridges_arp.exp b/test/network/4bridges_arp.exp
index 6a3e6db2a..6383aad5e 100755
--- a/test/4bridges_arp.exp
+++ b/test/network/4bridges_arp.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -26,9 +29,9 @@ expect {
26 timeout {puts "TESTING ERROR 0.4\n";exit} 29 timeout {puts "TESTING ERROR 0.4\n";exit}
27 "Child process initialized" 30 "Child process initialized"
28} 31}
29sleep 2 32sleep 1
30send -- "exit\r" 33send -- "exit\r"
31sleep 2 34sleep 1
32 35
33# check eth1 36# check eth1
34send -- "firejail --net=br0 --net=br1 --net=br2 --net=br3\r" 37send -- "firejail --net=br0 --net=br1 --net=br2 --net=br3\r"
@@ -52,9 +55,9 @@ expect {
52 timeout {puts "TESTING ERROR 1.4\n";exit} 55 timeout {puts "TESTING ERROR 1.4\n";exit}
53 "Child process initialized" 56 "Child process initialized"
54} 57}
55sleep 2 58sleep 1
56send -- "exit\r" 59send -- "exit\r"
57sleep 2 60sleep 1
58 61
59 62
60# check eth2 63# check eth2
@@ -79,9 +82,9 @@ expect {
79 timeout {puts "TESTING ERROR 2.4\n";exit} 82 timeout {puts "TESTING ERROR 2.4\n";exit}
80 "Child process initialized" 83 "Child process initialized"
81} 84}
82sleep 2 85sleep 1
83send -- "exit\r" 86send -- "exit\r"
84sleep 2 87sleep 1
85 88
86 89
87 90
@@ -107,9 +110,9 @@ expect {
107 timeout {puts "TESTING ERROR 4\n";exit} 110 timeout {puts "TESTING ERROR 4\n";exit}
108 "Child process initialized" 111 "Child process initialized"
109} 112}
110sleep 2 113sleep 1
111send -- "exit\r" 114send -- "exit\r"
112sleep 2 115sleep 1
113 116
114 117
115 118
@@ -164,7 +167,8 @@ expect {
164 timeout {puts "TESTING ERROR 10.2\n";exit} 167 timeout {puts "TESTING ERROR 10.2\n";exit}
165 "10.10.50.0/24 dev eth3 proto kernel scope link" 168 "10.10.50.0/24 dev eth3 proto kernel scope link"
166} 169}
167sleep 1 170send -- "exit\r"
171after 100
168 172
169puts "\nall done\n" 173puts "\nall done\n"
170 174
diff --git a/test/4bridges_ip.exp b/test/network/4bridges_ip.exp
index 8068aeebb..e762ac285 100755
--- a/test/4bridges_ip.exp
+++ b/test/network/4bridges_ip.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -26,9 +29,9 @@ expect {
26 timeout {puts "TESTING ERROR 0.4\n";exit} 29 timeout {puts "TESTING ERROR 0.4\n";exit}
27 "Child process initialized" 30 "Child process initialized"
28} 31}
29sleep 2 32sleep 1
30send -- "exit\r" 33send -- "exit\r"
31sleep 2 34sleep 1
32 35
33# check eth1 36# check eth1
34send -- "firejail --net=br0 --net=br1 --ip=10.10.30.50 --net=br2 --ip=10.10.40.100 --net=br3\r" 37send -- "firejail --net=br0 --net=br1 --ip=10.10.30.50 --net=br2 --ip=10.10.40.100 --net=br3\r"
@@ -52,9 +55,9 @@ expect {
52 timeout {puts "TESTING ERROR 1.4\n";exit} 55 timeout {puts "TESTING ERROR 1.4\n";exit}
53 "Child process initialized" 56 "Child process initialized"
54} 57}
55sleep 2 58sleep 1
56send -- "exit\r" 59send -- "exit\r"
57sleep 2 60sleep 1
58 61
59 62
60# check eth2 63# check eth2
@@ -79,9 +82,9 @@ expect {
79 timeout {puts "TESTING ERROR 2.4\n";exit} 82 timeout {puts "TESTING ERROR 2.4\n";exit}
80 "Child process initialized" 83 "Child process initialized"
81} 84}
82sleep 2 85sleep 1
83send -- "exit\r" 86send -- "exit\r"
84sleep 2 87sleep 1
85 88
86 89
87 90
@@ -107,9 +110,9 @@ expect {
107 timeout {puts "TESTING ERROR 4\n";exit} 110 timeout {puts "TESTING ERROR 4\n";exit}
108 "Child process initialized" 111 "Child process initialized"
109} 112}
110sleep 2 113sleep 1
111send -- "exit\r" 114send -- "exit\r"
112sleep 2 115sleep 1
113 116
114 117
115 118
@@ -168,7 +171,8 @@ expect {
168 "10.10.50.0/24 dev eth3 proto kernel scope link" 171 "10.10.50.0/24 dev eth3 proto kernel scope link"
169} 172}
170 173
171sleep 1 174send -- "exit\r"
175after 100
172 176
173puts "\nall done\n" 177puts "\nall done\n"
174 178
diff --git a/test/network/README b/test/network/README
new file mode 100644
index 000000000..4404c53b0
--- /dev/null
+++ b/test/network/README
@@ -0,0 +1,14 @@
1Warning: this test requires root access to configure a number of bridge, mac
2and vlan devices. Please take a look at configure file. By the time you are
3finished testing, you'll probably have to reboot the computer to get your
4networking subsytem back to normal.
5
6Limitations - to be investigated and fixed:
7 - the test is assuming an eth0 wired interface to be present
8 - using netstat and ifconfig - this needs to be moved to iproute2
9 - configure script inserts an entry in system netfilter configuration
10 - the test will probably not work on grsecurity settings
11 - macvlan interfaces don't seem to work correctly under VirtualBox
12
13Run the test:
14 $ ./network.sh | grep TESTING
diff --git a/test/bandwidth.exp b/test/network/bandwidth.exp
index 33b351296..8a2e46e04 100755
--- a/test/bandwidth.exp
+++ b/test/network/bandwidth.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -9,13 +12,13 @@ expect {
9 timeout {puts "TESTING ERROR 0\n";exit} 12 timeout {puts "TESTING ERROR 0\n";exit}
10 "Child process initialized" 13 "Child process initialized"
11} 14}
12sleep 2 15sleep 1
13 16
14spawn $env(SHELL) 17spawn $env(SHELL)
15send -- "firejail --bandwidth=test status\r" 18send -- "firejail --bandwidth=test status\r"
16expect { 19expect {
17 timeout {puts "TESTING ERROR 1\n";exit} 20 timeout {puts "TESTING ERROR 1\n";exit}
18 "qdisc noqueue 0: dev eth0" 21 "qdisc * 0: dev eth0"
19} 22}
20sleep 1 23sleep 1
21 24
@@ -51,12 +54,12 @@ expect {
51} 54}
52sleep 1 55sleep 1
53 56
54send -- "firejail --bandwidth=test status; pwd\r" 57send -- "firejail --bandwidth=test status; echo done\r"
55expect { 58expect {
56 timeout {puts "TESTING ERROR 8\n";exit} 59 timeout {puts "TESTING ERROR 8\n";exit}
57 "rate 80Kbit burst 10Kb" {puts "TESTING ERROR 9\n";exit} 60 "rate 80Kbit burst 10Kb" {puts "TESTING ERROR 9\n";exit}
58 "home" {puts "ok\n"} 61 "done"
59} 62}
60sleep 1 63after 100
61 64
62puts "\nall done\n" 65puts "\nall done\n"
diff --git a/test/network/configure b/test/network/configure
new file mode 100755
index 000000000..35d938340
--- /dev/null
+++ b/test/network/configure
@@ -0,0 +1,27 @@
1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6brctl addbr br0
7ifconfig br0 10.10.20.1/29 up
8# NAT masquerade
9iptables -t nat -A POSTROUTING -o eth0 -s 10.10.20.0/29 -j MASQUERADE
10# port forwarding
11# iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to 10.10.20.2:80
12
13brctl addbr br1
14ifconfig br1 10.10.30.1/24 up
15brctl addbr br2
16ifconfig br2 10.10.40.1/24 up
17brctl addbr br3
18ifconfig br3 10.10.50.1/24 up
19brctl addbr br4
20ifconfig br4 10.10.60.1/24 up
21ip link add link eth0 name eth0.5 type vlan id 5
22/sbin/ifconfig eth0.5 10.10.205.10/24 up
23ip link add link eth0 name eth0.6 type vlan id 6
24/sbin/ifconfig eth0.6 10.10.206.10/24 up
25ip link add link eth0 name eth0.7 type vlan id 7
26/sbin/ifconfig eth0.7 10.10.207.10/24 up
27
diff --git a/test/network/firemon-arp.exp b/test/network/firemon-arp.exp
new file mode 100755
index 000000000..71fa1660f
--- /dev/null
+++ b/test/network/firemon-arp.exp
@@ -0,0 +1,50 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7#send -- "ping -c 3 192.168.1.1\r"
8#expect {
9# timeout {puts "TESTING ERROR 0\n";exit}
10# "3 packets transmitted"
11#}
12#sleep 1
13
14send -- "firejail --name=test1\r"
15expect {
16 timeout {puts "TESTING ERROR 1\n";exit}
17 "Child process initialized"
18}
19sleep 1
20
21spawn $env(SHELL)
22send -- "firejail --name=test2\r"
23expect {
24 timeout {puts "TESTING ERROR 2\n";exit}
25 "Child process initialized"
26}
27sleep 1
28
29spawn $env(SHELL)
30send -- "firemon --arp\r"
31expect {
32 timeout {puts "TESTING ERROR 3\n";exit}
33 "name=test1"
34}
35expect {
36 timeout {puts "TESTING ERROR 4\n";exit}
37 "192.168.1.1 dev eth0 lladdr" {puts "Debian testing\n";}
38 "192.168.1.1 dev enp0s3 lladdr" {puts "Centos 7 testing\n";}
39}
40expect {
41 timeout {puts "TESTING ERROR 5\n";exit}
42 "REACHABLE"
43}
44expect {
45 timeout {puts "TESTING ERROR 6\n";exit}
46 "name=test2"
47}
48after 100
49
50puts "\nall done\n"
diff --git a/test/network/firemon-interfaces.exp b/test/network/firemon-interfaces.exp
new file mode 100755
index 000000000..deb8594af
--- /dev/null
+++ b/test/network/firemon-interfaces.exp
@@ -0,0 +1,67 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --net=eth0 --name=test1\r"
11expect {
12 timeout {puts "TESTING ERROR 9\n";exit}
13 "Child process initialized"
14}
15sleep 1
16
17spawn $env(SHELL)
18send -- "firejail --net=eth0 --name=test2\r"
19expect {
20 timeout {puts "TESTING ERROR 9\n";exit}
21 "Child process initialized"
22}
23sleep 1
24
25spawn $env(SHELL)
26send -- "firemon --interface\r"
27expect {
28 timeout {puts "TESTING ERROR 9\n";exit}
29 "Link status"
30}
31expect {
32 timeout {puts "TESTING ERROR 9\n";exit}
33 "lo UP"
34}
35expect {
36 timeout {puts "TESTING ERROR 9\n";exit}
37 "eth0-"
38}
39expect {
40 timeout {puts "TESTING ERROR 9\n";exit}
41 "IPv4 status"
42}
43expect {
44 timeout {puts "TESTING ERROR 9\n";exit}
45 "lo UP"
46}
47expect {
48 timeout {puts "TESTING ERROR 9\n";exit}
49 "eth0-"
50}
51expect {
52 timeout {puts "TESTING ERROR 9\n";exit}
53 "IPv6 status"
54}
55expect {
56 timeout {puts "TESTING ERROR 9\n";exit}
57 "lo UP"
58}
59expect {
60 timeout {puts "TESTING ERROR 9\n";exit}
61 "eth0-"
62}
63
64after 100
65
66puts "\n"
67
diff --git a/test/firemon-route.exp b/test/network/firemon-route.exp
index a48116675..19a705778 100755
--- a/test/firemon-route.exp
+++ b/test/network/firemon-route.exp
@@ -4,7 +4,7 @@ set timeout 10
4spawn $env(SHELL) 4spawn $env(SHELL)
5match_max 100000 5match_max 100000
6 6
7send -- "firejail\r" 7send -- "firejail --name=test1\r"
8expect { 8expect {
9 timeout {puts "TESTING ERROR 0\n";exit} 9 timeout {puts "TESTING ERROR 0\n";exit}
10 "Child process initialized" 10 "Child process initialized"
@@ -12,22 +12,38 @@ expect {
12sleep 1 12sleep 1
13 13
14spawn $env(SHELL) 14spawn $env(SHELL)
15send -- "firemon --route\r" 15send -- "firejail --name=test2\r"
16expect { 16expect {
17 timeout {puts "TESTING ERROR 1\n";exit} 17 timeout {puts "TESTING ERROR 1\n";exit}
18 "Child process initialized"
19}
20sleep 1
21
22spawn $env(SHELL)
23send -- "firemon --route\r"
24expect {
25 timeout {puts "TESTING ERROR 2\n";exit}
26 "name=test1"
27}
28expect {
29 timeout {puts "TESTING ERROR 3\n";exit}
18 "0.0.0.0/0 via 192.168.1.1, dev eth0, metric 0" {puts "Debian testing\n";} 30 "0.0.0.0/0 via 192.168.1.1, dev eth0, metric 0" {puts "Debian testing\n";}
19 "0.0.0.0/0 via 192.168.1.1, dev enp0s3, metric 1024" {puts "Centos 7 testing\n";} 31 "0.0.0.0/0 via 192.168.1.1, dev enp0s3, metric 1024" {puts "Centos 7 testing\n";}
20 "0.0.0.0/0 via 192.168.1.1, dev enp0s3, metric 0" {puts "OpenSUSE testing\n";} 32 "0.0.0.0/0 via 192.168.1.1, dev enp0s3, metric 0" {puts "OpenSUSE testing\n";}
21 "0.0.0.0/0 via 192.168.1.1, dev enp0s3, metric 100" {puts "Arch testing\n";} 33 "0.0.0.0/0 via 192.168.1.1, dev enp0s3, metric 100" {puts "Arch testing\n";}
22} 34}
23expect { 35expect {
24 timeout {puts "TESTING ERROR 2\n";exit} 36 timeout {puts "TESTING ERROR 4\n";exit}
25 "10.10.30.0/24, dev br1, scope link src 10.10.30.1" 37 "10.10.30.0/24, dev br1, scope link src 10.10.30.1"
26} 38}
27expect { 39expect {
28 timeout {puts "TESTING ERROR 3\n";exit} 40 timeout {puts "TESTING ERROR 5\n";exit}
29 "10.10.50.0/24, dev br3, scope link src 10.10.50.1" 41 "10.10.50.0/24, dev br3, scope link src 10.10.50.1"
30} 42}
31sleep 1 43expect {
44 timeout {puts "TESTING ERROR 6\n";exit}
45 "name=test2"
46}
47after 100
32 48
33puts "\n" 49puts "\nalldone\n"
diff --git a/test/hostname.exp b/test/network/hostname.exp
index 4e5c7e073..73d06725f 100755
--- a/test/hostname.exp
+++ b/test/network/hostname.exp
@@ -1,25 +1,29 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
5match_max 100000 8match_max 100000
6 9
7send -- "firejail --hostname=baluba --noprofile\r" 10send -- "firejail --hostname=bingo --noprofile\r"
8expect { 11expect {
9 timeout {puts "TESTING ERROR 1\n";exit} 12 timeout {puts "TESTING ERROR 1\n";exit}
10 "Child process initialized" 13 "Child process initialized"
11} 14}
12sleep 1 15sleep 1
13 16
14send -- "ping -c 3 baluba;pwd\r" 17send -- "ping -c 3 bingo; echo done\r"
15expect { 18expect {
16 timeout {puts "TESTING ERROR 2\n";exit} 19 timeout {puts "TESTING ERROR 2\n";exit}
17 "3 packets transmitted, 3 received" 20 "3 packets transmitted, 3 received"
18} 21}
19expect { 22expect {
20 timeout {puts "TESTING ERROR 3\n";exit} 23 timeout {puts "TESTING ERROR 3\n";exit}
21 "home" 24 "done"
22} 25}
23sleep 1 26send -- "exit\r"
27after 100
24 28
25puts "all done\n" 29puts "all done\n"
diff --git a/test/network/interface.exp b/test/network/interface.exp
new file mode 100755
index 000000000..bd8777c33
--- /dev/null
+++ b/test/network/interface.exp
@@ -0,0 +1,66 @@
1#!/usr/bin/expect -f
2#
3# interface
4#
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9set overlay [lindex $argv 0]
10set chroot [lindex $argv 1]
11
12#
13# N
14#
15# todo: seems to be unable to find interface eth0.7
16#send -- "firejail --noprofile --interface=eth0.5 --interface=eth0.6 --interface=eth0.7\r"
17send -- "firejail --noprofile --interface=eth0.5 --interface=eth0.6\r"
18expect {
19 timeout {puts "TESTING ERROR 0\n";exit}
20 "Child process initialized"
21}
22sleep 1
23
24send -- "/sbin/ifconfig\r"
25expect {
26 timeout {puts "TESTING ERROR 1\n";exit}
27 "eth0.5"
28}
29expect {
30 timeout {puts "TESTING ERROR 2n";exit}
31 "Link"
32}
33expect {
34 timeout {puts "TESTING ERROR 3\n";exit}
35 "10.10.205.10"
36}
37expect {
38 timeout {puts "TESTING ERROR 4\n";exit}
39 "UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1"
40}
41after 100
42
43send -- "/sbin/ifconfig\r"
44expect {
45 timeout {puts "TESTING ERROR 5\n";exit}
46 "eth0.6"
47}
48expect {
49 timeout {puts "TESTING ERROR 6\n";exit}
50 "Link"
51}
52expect {
53 timeout {puts "TESTING ERROR 7\n";exit}
54 "10.10.206.10"
55}
56expect {
57 timeout {puts "TESTING ERROR 8\n";exit}
58 "UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1"
59}
60after 100
61
62send -- "exit\r"
63sleep 1
64
65
66puts "\nall done\n"
diff --git a/test/ip6.exp b/test/network/ip6.exp
index fba47d095..f0fcebcf8 100755
--- a/test/ip6.exp
+++ b/test/network/ip6.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -15,6 +18,7 @@ expect {
15} 18}
16expect { 19expect {
17 timeout {puts "TESTING ERROR 2\n";exit} 20 timeout {puts "TESTING ERROR 2\n";exit}
21 "unable to initialize table 'filter'" {puts "\nTESTING SKIP 2: no IPv6 support\n"; exit}
18 "2001:db8:1f0a:3ec::2" 22 "2001:db8:1f0a:3ec::2"
19} 23}
20expect { 24expect {
@@ -38,6 +42,8 @@ expect {
38 "scopeid 0x0<global>" { puts "Arch\n"} 42 "scopeid 0x0<global>" { puts "Arch\n"}
39} 43}
40 44
45send -- "exit\r"
46after 100
41 47
42puts "\nall done\n" 48puts "\nall done\n"
43 49
diff --git a/test/ipv6.net b/test/network/ipv6.net
index cc8f22943..cc8f22943 100644
--- a/test/ipv6.net
+++ b/test/network/ipv6.net
diff --git a/test/network/net-profile.profile b/test/network/net-profile.profile
new file mode 100644
index 000000000..05052b6dc
--- /dev/null
+++ b/test/network/net-profile.profile
@@ -0,0 +1,10 @@
1net br0
2mac 00:11:22:33:44:55
3mtu 1000
4net br1
5ip 10.10.30.50
6net br2
7ip 10.10.40.100
8net br3
9defaultgw 10.10.20.2
10
diff --git a/test/net_arp.exp b/test/network/net_arp.exp
index 9e07744f3..fdd30f218 100755
--- a/test/net_arp.exp
+++ b/test/network/net_arp.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -66,6 +69,6 @@ expect {
66 "sleep 20" 69 "sleep 20"
67} 70}
68 71
69# wait for snadboxes to be shutdown 72# wait for sandboxes to be shutdown
70sleep 30 73sleep 30
71puts "\n" 74puts "\n"
diff --git a/test/net_badip.exp b/test/network/net_badip.exp
index 71b69e104..d13a6144e 100755
--- a/test/net_badip.exp
+++ b/test/network/net_badip.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -10,7 +13,7 @@ expect {
10 timeout {puts "TESTING ERROR 0.0\n";exit} 13 timeout {puts "TESTING ERROR 0.0\n";exit}
11 "the IP address is not" 14 "the IP address is not"
12} 15}
13sleep 1 16after 100
14 17
15puts "\n" 18puts "\n"
16 19
diff --git a/test/net_defaultgw.exp b/test/network/net_defaultgw.exp
index 840f2ccac..6291ae5ba 100755
--- a/test/net_defaultgw.exp
+++ b/test/network/net_defaultgw.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -40,7 +43,8 @@ expect {
40 timeout {puts "TESTING ERROR 10.2\n";exit} 43 timeout {puts "TESTING ERROR 10.2\n";exit}
41 "10.10.20.0/29 dev eth0 proto kernel scope link" 44 "10.10.20.0/29 dev eth0 proto kernel scope link"
42} 45}
43sleep 1 46send -- "exit\r"
47after 100
44 48
45puts "\nall done\n" 49puts "\nall done\n"
46 50
diff --git a/test/net_defaultgw2.exp b/test/network/net_defaultgw2.exp
index db14e17cb..7620e4899 100755
--- a/test/net_defaultgw2.exp
+++ b/test/network/net_defaultgw2.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -34,7 +37,8 @@ expect {
34 timeout {puts "TESTING ERROR 10.3\n";exit} 37 timeout {puts "TESTING ERROR 10.3\n";exit}
35 "10.10.30.0/24 dev eth1 proto kernel scope link" 38 "10.10.30.0/24 dev eth1 proto kernel scope link"
36} 39}
37sleep 1 40send -- "exit\r"
41after 100
38 42
39puts "\nall done\n" 43puts "\nall done\n"
40 44
diff --git a/test/net_defaultgw3.exp b/test/network/net_defaultgw3.exp
index 64da9dfca..a47324adc 100755
--- a/test/net_defaultgw3.exp
+++ b/test/network/net_defaultgw3.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -11,7 +14,8 @@ expect {
11 "default gateway 10.10.95.89 is not in the range of any network" 14 "default gateway 10.10.95.89 is not in the range of any network"
12} 15}
13 16
14sleep 1 17after 100
18
15 19
16puts "\n" 20puts "\n"
17 21
diff --git a/test/net_ip.exp b/test/network/net_ip.exp
index f5d487ecc..0fa84243a 100755
--- a/test/net_ip.exp
+++ b/test/network/net_ip.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -26,9 +29,9 @@ expect {
26 timeout {puts "TESTING ERROR 4\n";exit} 29 timeout {puts "TESTING ERROR 4\n";exit}
27 "Child process initialized" 30 "Child process initialized"
28} 31}
29sleep 2 32sleep 1
30send -- "exit\r" 33send -- "exit\r"
31sleep 2 34sleep 1
32 35
33# check loopback 36# check loopback
34send -- "firejail --net=br0 --ip=10.10.20.5 --protocol=unix,inet,netlink\r" 37send -- "firejail --net=br0 --ip=10.10.20.5 --protocol=unix,inet,netlink\r"
@@ -66,7 +69,8 @@ expect {
66 timeout {puts "TESTING ERROR 10\n";exit} 69 timeout {puts "TESTING ERROR 10\n";exit}
67 "10.10.20.0/29 dev eth0 proto kernel scope link" 70 "10.10.20.0/29 dev eth0 proto kernel scope link"
68} 71}
69sleep 1 72send -- "exit\r"
73after 100
70 74
71puts "\n" 75puts "\n"
72 76
diff --git a/test/net_local.exp b/test/network/net_local.exp
index 642213658..d58135785 100755
--- a/test/net_local.exp
+++ b/test/network/net_local.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -14,9 +17,9 @@ expect {
14 timeout {puts "TESTING ERROR 4\n";exit} 17 timeout {puts "TESTING ERROR 4\n";exit}
15 "Child process initialized" 18 "Child process initialized"
16} 19}
17sleep 2 20sleep 1
18send -- "exit\r" 21send -- "exit\r"
19sleep 2 22sleep 1
20 23
21# check loopback 24# check loopback
22send -- "firejail --noprofile\r" 25send -- "firejail --noprofile\r"
@@ -40,6 +43,8 @@ expect {
40 timeout {puts "TESTING ERROR 7\n";exit} 43 timeout {puts "TESTING ERROR 7\n";exit}
41 "255.0.0.0" 44 "255.0.0.0"
42} 45}
46send -- "exit\r"
47after 100
43 48
44puts "all done\n" 49puts "all done\n"
45 50
diff --git a/test/net_mac.exp b/test/network/net_mac.exp
index 076634730..d3cd8163f 100755
--- a/test/net_mac.exp
+++ b/test/network/net_mac.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -30,7 +33,8 @@ expect {
30 timeout {puts "TESTING ERROR 4\n";exit} 33 timeout {puts "TESTING ERROR 4\n";exit}
31 "Child process initialized" 34 "Child process initialized"
32} 35}
33sleep 1 36send -- "exit\r"
37after 100
34 38
35puts "\nall done\n" 39puts "\nall done\n"
36 40
diff --git a/test/net_macvlan.exp b/test/network/net_macvlan.exp
index 20d022de9..f457ea98f 100755
--- a/test/net_macvlan.exp
+++ b/test/network/net_macvlan.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -83,6 +86,8 @@ while { $i <= $MAXi } {
83 after 100 86 after 100
84# sleep 1 87# sleep 1
85} 88}
89send -- "exit\r"
90after 100
86 91
87puts "\n" 92puts "\n"
88 93
diff --git a/test/net_mtu.exp b/test/network/net_mtu.exp
index 7943b2866..eb9c5d08c 100755
--- a/test/net_mtu.exp
+++ b/test/network/net_mtu.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -25,6 +28,8 @@ expect {
25 timeout {puts "TESTING ERROR 4\n";exit} 28 timeout {puts "TESTING ERROR 4\n";exit}
26 "state UP" 29 "state UP"
27} 30}
31send -- "exit\r"
32after 100
28 33
29puts "\nall done\n" 34puts "\nall done\n"
30 35
diff --git a/test/net_netfilter.exp b/test/network/net_netfilter.exp
index 989fcc407..737485d07 100755
--- a/test/net_netfilter.exp
+++ b/test/network/net_netfilter.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -26,7 +29,7 @@ expect {
26 timeout {puts "TESTING ERROR 4\n";exit} 29 timeout {puts "TESTING ERROR 4\n";exit}
27 "Child process initialized" 30 "Child process initialized"
28} 31}
29sleep 2 32sleep 1
30send -- "exit\r" 33send -- "exit\r"
31sleep 1 34sleep 1
32 35
@@ -40,7 +43,7 @@ expect {
40 "ACCEPT icmp -- any any anywhere" {puts "TESTING ERROR 5.1\n";exit} 43 "ACCEPT icmp -- any any anywhere" {puts "TESTING ERROR 5.1\n";exit}
41 "Child process initialized" 44 "Child process initialized"
42} 45}
43sleep 2 46sleep 1
44send -- "exit\r" 47send -- "exit\r"
45sleep 1 48sleep 1
46 49
@@ -54,7 +57,7 @@ expect {
54 timeout {puts "TESTING ERROR 6.1\n";exit} 57 timeout {puts "TESTING ERROR 6.1\n";exit}
55 "Child process initialized" 58 "Child process initialized"
56} 59}
57sleep 2 60sleep 1
58send -- "ping -c 1 -w 3 10.10.20.1\r" 61send -- "ping -c 1 -w 3 10.10.20.1\r"
59expect { 62expect {
60 timeout {puts "TESTING ERROR 6.2\n";exit} 63 timeout {puts "TESTING ERROR 6.2\n";exit}
diff --git a/test/net_noip.exp b/test/network/net_noip.exp
index 8d28adb39..b557d116c 100755
--- a/test/net_noip.exp
+++ b/test/network/net_noip.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -16,25 +19,26 @@ send -- "bash\r"
16sleep 1 19sleep 1
17 20
18# no default gateway configured 21# no default gateway configured
19send -- "netstat -rn;pwd\r" 22send -- "netstat -rn;echo done\r"
20expect { 23expect {
21 timeout {puts "TESTING ERROR 2\n";exit} 24 timeout {puts "TESTING ERROR 2\n";exit}
22 "0.0.0.0" {puts "TESTING ERROR 3\n";exit} 25 "0.0.0.0" {puts "TESTING ERROR 3\n";exit}
23 "eth0" {puts "TESTING ERROR 4\n";exit} 26 "eth0" {puts "TESTING ERROR 4\n";exit}
24 "home" 27 "done"
25} 28}
26sleep 1 29sleep 1
27 30
28# eth0 configured 31# eth0 configured
29send -- "/sbin/ifconfig;pwd\r" 32send -- "/sbin/ifconfig;echo done\r"
30expect { 33expect {
31 timeout {puts "TESTING ERROR 5\n";exit} 34 timeout {puts "TESTING ERROR 5\n";exit}
32 "eth0" 35 "eth0"
33} 36}
34expect { 37expect {
35 timeout {puts "TESTING ERROR 6\n";exit} 38 timeout {puts "TESTING ERROR 6\n";exit}
36 "home" 39 "done"
37} 40}
41send -- "exit\r"
38after 100 42after 100
39 43
40puts "all done\n" 44puts "all done\n"
diff --git a/test/net_noip2.exp b/test/network/net_noip2.exp
index 58f90422b..c86ea4900 100755
--- a/test/net_noip2.exp
+++ b/test/network/net_noip2.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -16,25 +19,26 @@ send -- "bash\r"
16sleep 1 19sleep 1
17 20
18# no default gateway configured 21# no default gateway configured
19send -- "netstat -rn;pwd\r" 22send -- "netstat -rn;echo done\r"
20expect { 23expect {
21 timeout {puts "TESTING ERROR 2\n";exit} 24 timeout {puts "TESTING ERROR 2\n";exit}
22 "0.0.0.0" {puts "TESTING ERROR 3\n";exit} 25 "0.0.0.0" {puts "TESTING ERROR 3\n";exit}
23 "eth0" {puts "TESTING ERROR 4\n";exit} 26 "eth0" {puts "TESTING ERROR 4\n";exit}
24 "home" 27 "done"
25} 28}
26sleep 1 29sleep 1
27 30
28# eth0 configured 31# eth0 configured
29send -- "/sbin/ifconfig;pwd\r" 32send -- "/sbin/ifconfig;echo done\r"
30expect { 33expect {
31 timeout {puts "TESTING ERROR 5\n";exit} 34 timeout {puts "TESTING ERROR 5\n";exit}
32 "eth0" 35 "eth0"
33} 36}
34expect { 37expect {
35 timeout {puts "TESTING ERROR 6\n";exit} 38 timeout {puts "TESTING ERROR 6\n";exit}
36 "home" 39 "done"
37} 40}
41send -- "exit\r"
38after 100 42after 100
39 43
40puts "all done\n" 44puts "all done\n"
diff --git a/test/net_none.exp b/test/network/net_none.exp
index 54b6cb946..1761eb423 100755
--- a/test/net_none.exp
+++ b/test/network/net_none.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -16,20 +19,20 @@ sleep 1
16# test default gw 19# test default gw
17send -- "bash\r" 20send -- "bash\r"
18sleep 1 21sleep 1
19send -- "netstat -rn; pwd\r" 22send -- "netstat -rn; echo done\r"
20expect { 23expect {
21 timeout {puts "TESTING ERROR 1\n";exit} 24 timeout {puts "TESTING ERROR 1\n";exit}
22 "0.0.0.0" {puts "TESTING ERROR 1.1\n";exit} 25 "0.0.0.0" {puts "TESTING ERROR 1.1\n";exit}
23 "home" 26 "done"
24} 27}
25sleep 1 28sleep 1
26 29
27# check again devices 30# check again devices
28send -- "cat /proc/1/net/dev;pwd\r" 31send -- "cat /proc/1/net/dev;echo done\r"
29expect { 32expect {
30 timeout {puts "TESTING ERROR 2\n";exit} 33 timeout {puts "TESTING ERROR 2\n";exit}
31 "eth0" {puts "TESTING ERROR 2.1\n";exit} 34 "eth0" {puts "TESTING ERROR 2.1\n";exit}
32 "home" 35 "done"
33} 36}
34send -- "exit\r" 37send -- "exit\r"
35sleep 1 38sleep 1
@@ -48,21 +51,22 @@ sleep 1
48# test default gw 51# test default gw
49send -- "bash\r" 52send -- "bash\r"
50sleep 1 53sleep 1
51send -- "netstat -rn; pwd\r" 54send -- "netstat -rn; echo done\r"
52expect { 55expect {
53 timeout {puts "TESTING ERROR 4\n";exit} 56 timeout {puts "TESTING ERROR 4\n";exit}
54 "0.0.0.0" {puts "TESTING ERROR 4.1\n";exit} 57 "0.0.0.0" {puts "TESTING ERROR 4.1\n";exit}
55 "home" 58 "done"
56} 59}
57sleep 1 60sleep 1
58 61
59# check again devices 62# check again devices
60send -- "cat /proc/1/net/dev;pwd\r" 63send -- "cat /proc/1/net/dev;echo done\r"
61expect { 64expect {
62 timeout {puts "TESTING ERROR 5\n";exit} 65 timeout {puts "TESTING ERROR 5\n";exit}
63 "eth0" {puts "TESTING ERROR 5.1\n";exit} 66 "eth0" {puts "TESTING ERROR 5.1\n";exit}
64 "home" 67 "done"
65} 68}
66sleep 1 69send -- "exit\r"
70after 100
67 71
68puts "\n" 72puts "\nall done\n"
diff --git a/test/net_none.profile b/test/network/net_none.profile
index 079c08ea8..079c08ea8 100644
--- a/test/net_none.profile
+++ b/test/network/net_none.profile
diff --git a/test/network/net_profile.exp b/test/network/net_profile.exp
new file mode 100755
index 000000000..29008d811
--- /dev/null
+++ b/test/network/net_profile.exp
@@ -0,0 +1,77 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10# check eth0
11send -- "firejail --profile=net-profile.profile\r"
12expect {
13 timeout {puts "TESTING ERROR 0.0\n";exit}
14 "eth0"
15}
16expect {
17 timeout {puts "TESTING ERROR 0.1\n";exit}
18 "00:11:22:33:44:55"
19}
20expect {
21 timeout {puts "TESTING ERROR 0.1\n";exit}
22 "10.10.20"
23}
24expect {
25 timeout {puts "TESTING ERROR 0.2\n";exit}
26 "255.255.255.248"
27}
28expect {
29 timeout {puts "TESTING ERROR 0.3\n";exit}
30 "UP"
31}
32expect {
33 timeout {puts "TESTING ERROR 0.4\n";exit}
34 "Child process initialized"
35}
36sleep 1
37
38send -- "ip route show\r"
39expect {
40 timeout {puts "TESTING ERROR 1\n";exit}
41 "10.10.30.0/24 dev eth1 proto kernel scope link src 10.10.30.50"
42}
43
44send -- "ip route show\r"
45expect {
46 timeout {puts "TESTING ERROR 2\n";exit}
47 "10.10.40.0/24 dev eth2 proto kernel scope link src 10.10.40.100"
48}
49
50
51# check default gw
52send -- "ip route show\r"
53expect {
54 timeout {puts "TESTING ERROR 3\n";exit}
55 "default via 10.10.20.2 dev eth0"
56}
57
58# check mtu
59send -- "ip link show\r"
60expect {
61 timeout {puts "TESTING ERROR 4\n";exit}
62 "eth0"
63}
64expect {
65 timeout {puts "TESTING ERROR 5\n";exit}
66 "mtu 1000"
67}
68expect {
69 timeout {puts "TESTING ERROR 6\n";exit}
70 "state UP"
71}
72
73send -- "exit\r"
74after 100
75
76puts "\nall done\n"
77
diff --git a/test/network/net_scan.exp b/test/network/net_scan.exp
new file mode 100755
index 000000000..5afbbeea6
--- /dev/null
+++ b/test/network/net_scan.exp
@@ -0,0 +1,75 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10#
11send -- "firejail --net=br1 --ip=10.10.30.50\r"
12expect {
13 timeout {puts "TESTING ERROR 0\n";exit}
14 "eth0"
15}
16expect {
17 timeout {puts "TESTING ERROR 1\n";exit}
18 "10.10.30.50"
19}
20expect {
21 timeout {puts "TESTING ERROR 2\n";exit}
22 "255.255.255.0"
23}
24expect {
25 timeout {puts "TESTING ERROR 3\n";exit}
26 "Child process initialized"
27}
28sleep 1
29
30spawn $env(SHELL)
31send -- "firejail --net=br1 --ip=10.10.30.51\r"
32expect {
33 timeout {puts "TESTING ERROR 4\n";exit}
34 "eth0"
35}
36expect {
37 timeout {puts "TESTING ERROR 5\n";exit}
38 "10.10.30.51"
39}
40expect {
41 timeout {puts "TESTING ERROR 6\n";exit}
42 "255.255.255.0"
43}
44expect {
45 timeout {puts "TESTING ERROR 7\n";exit}
46 "Child process initialized"
47}
48sleep 1
49
50spawn $env(SHELL)
51send -- "firejail --net=br1 --scan\r"
52expect {
53 timeout {puts "TESTING ERROR 8\n";exit}
54 "eth0"
55}
56expect {
57 timeout {puts "TESTING ERROR 9\n";exit}
58 "10.10.30.50"
59}
60expect {
61 timeout {puts "TESTING ERROR 10\n";exit}
62 "10.10.30.51"
63}
64expect {
65 timeout {puts "TESTING ERROR 11\n";exit}
66 "Child process initialized"
67}
68sleep 1
69
70
71
72after 100
73
74puts "\nall done\n"
75
diff --git a/test/network/net_veth.exp b/test/network/net_veth.exp
new file mode 100755
index 000000000..89dedcb24
--- /dev/null
+++ b/test/network/net_veth.exp
@@ -0,0 +1,130 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --net=eth0\r"
11expect {
12 timeout {puts "TESTING ERROR 1\n";exit}
13 "lo"
14}
15expect {
16 timeout {puts "TESTING ERROR 2\n";exit}
17 "127.0.0.1"
18}
19expect {
20 timeout {puts "TESTING ERROR 3\n";exit}
21 "255.0.0.0"
22}
23expect {
24 timeout {puts "TESTING ERROR 4\n";exit}
25 "UP"
26}
27expect {
28 timeout {puts "TESTING ERROR 5\n";exit}
29 "eth0-"
30}
31expect {
32 timeout {puts "TESTING ERROR 6\n";exit}
33 "255.255.255.0"
34}
35expect {
36 timeout {puts "TESTING ERROR 7\n";exit}
37 "UP"
38}
39expect {
40 timeout {puts "TESTING ERROR 8\n";exit}
41 "Default gateway"
42}
43expect {
44 timeout {puts "TESTING ERROR 9\n";exit}
45 "Child process initialized"
46}
47sleep 1
48send -- "exit\r"
49sleep 1
50
51send -- "firejail --net=eth0 --net=eth0 --net=eth0 --net=eth0\r"
52expect {
53 timeout {puts "TESTING ERROR 11\n";exit}
54 "lo"
55}
56expect {
57 timeout {puts "TESTING ERROR 12\n";exit}
58 "127.0.0.1"
59}
60expect {
61 timeout {puts "TESTING ERROR 13\n";exit}
62 "255.0.0.0"
63}
64expect {
65 timeout {puts "TESTING ERROR 14\n";exit}
66 "UP"
67}
68expect {
69 timeout {puts "TESTING ERROR 15\n";exit}
70 "eth0-"
71}
72expect {
73 timeout {puts "TESTING ERROR 16\n";exit}
74 "255.255.255.0"
75}
76expect {
77 timeout {puts "TESTING ERROR 17\n";exit}
78 "UP"
79}
80expect {
81 timeout {puts "TESTING ERROR 18\n";exit}
82 "eth1-"
83}
84expect {
85 timeout {puts "TESTING ERROR 19\n";exit}
86 "255.255.255.0"
87}
88expect {
89 timeout {puts "TESTING ERROR 20\n";exit}
90 "UP"
91}
92expect {
93 timeout {puts "TESTING ERROR 5\n";exit}
94 "eth2-"
95}
96expect {
97 timeout {puts "TESTING ERROR 21\n";exit}
98 "255.255.255.0"
99}
100expect {
101 timeout {puts "TESTING ERROR 22\n";exit}
102 "UP"
103}
104expect {
105 timeout {puts "TESTING ERROR 23\n";exit}
106 "eth3-"
107}
108expect {
109 timeout {puts "TESTING ERROR 24\n";exit}
110 "255.255.255.0"
111}
112expect {
113 timeout {puts "TESTING ERROR 25\n";exit}
114 "UP"
115}
116expect {
117 timeout {puts "TESTING ERROR 26\n";exit}
118 "Default gateway"
119}
120expect {
121 timeout {puts "TESTING ERROR 27\n";exit}
122 "Child process initialized"
123}
124sleep 1
125send -- "exit\r"
126
127after 100
128
129puts "\n"
130
diff --git a/test/netfilter.filter b/test/network/netfilter.filter
index 3e232065c..3e232065c 100644
--- a/test/netfilter.filter
+++ b/test/network/netfilter.filter
diff --git a/test/netfilter.profile b/test/network/netfilter.profile
index 824c6cd0f..824c6cd0f 100644
--- a/test/netfilter.profile
+++ b/test/network/netfilter.profile
diff --git a/test/network/netstats.exp b/test/network/netstats.exp
new file mode 100755
index 000000000..41232061d
--- /dev/null
+++ b/test/network/netstats.exp
@@ -0,0 +1,39 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --net=eth0 --name=test1\r"
11expect {
12 timeout {puts "TESTING ERROR 9\n";exit}
13 "Child process initialized"
14}
15sleep 1
16
17spawn $env(SHELL)
18send -- "firejail --net=eth0 --name=test2\r"
19expect {
20 timeout {puts "TESTING ERROR 9\n";exit}
21 "Child process initialized"
22}
23sleep 1
24
25spawn $env(SHELL)
26send -- "firejail --netstats\r"
27sleep 4
28expect {
29 timeout {puts "TESTING ERROR 9\n";exit}
30 "name=test1"
31}
32expect {
33 timeout {puts "TESTING ERROR 9\n";exit}
34 "name=test2"
35}
36after 100
37
38puts "\n"
39
diff --git a/test/network/network.sh b/test/network/network.sh
new file mode 100755
index 000000000..e1646d64a
--- /dev/null
+++ b/test/network/network.sh
@@ -0,0 +1,85 @@
1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6export MALLOC_CHECK_=3
7export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
8
9sudo ./configure
10
11echo "TESTING: firemon interface (firemon-interfaces.exp)"
12sudo ./firemon-interfaces.exp
13
14echo "TESTING: firemon arp (firemon-arp.exp)"
15./firemon-arp.exp
16
17echo "TESTING: firemon netstats (netstats.exp)"
18./netstats.exp
19
20echo "TESTING: firemon route (firemon-route.exp)"
21./firemon-route.exp
22
23echo "TESTING: network profile (net_profile.exp)"
24./net_profile.exp
25
26echo "TESTING: bandwidth (bandwidth.exp)"
27./bandwidth.exp
28
29echo "TESTING: IPv6 support (ip6.exp)"
30./ip6.exp
31
32echo "TESTING: local network (net_local.exp)"
33./net_local.exp
34
35echo "TESTING: no network (net_none.exp)"
36./net_none.exp
37
38echo "TESTING: network IP (net_ip.exp)"
39./net_ip.exp
40
41echo "TESTING: network MAC (net_mac.exp)"
42sleep 2
43./net_mac.exp
44
45echo "TESTING: network MTU (net_mtu.exp)"
46./net_mtu.exp
47
48echo "TESTING: network hostname (hostname.exp)"
49./hostname.exp
50
51echo "TESTING: network bad IP (net_badip.exp)"
52./net_badip.exp
53
54echo "TESTING: network no IP test 1 (net_noip.exp)"
55./net_noip.exp
56
57echo "TESTING: network no IP test 2 (net_noip2.exp)"
58./net_noip2.exp
59
60echo "TESTING: network default gateway test 1 (net_defaultgw.exp)"
61./net_defaultgw.exp
62
63echo "TESTING: network default gateway test 2 (net_defaultgw2.exp)"
64./net_defaultgw2.exp
65
66echo "TESTING: network default gateway test 3 (net_defaultgw3.exp)"
67./net_defaultgw3.exp
68
69echo "TESTING: scan (net_scan.exp)"
70./net_scan.exp
71
72echo "TESTING: interface (interface.exp)"
73./interface.exp
74
75echo "TESTING: veth (net_veth.exp)"
76./net_veth.exp
77
78echo "TESTING: netfilter (net_netfilter.exp)"
79./net_netfilter.exp
80
81echo "TESTING: 4 bridges ARP (4bridges_arp.exp)"
82./4bridges_arp.exp
83
84echo "TESTING: 4 bridges IP (4bridges_ip.exp)"
85./4bridges_ip.exp
diff --git a/test/noroot.exp b/test/noroot.exp
deleted file mode 100755
index 37d55fe78..000000000
--- a/test/noroot.exp
+++ /dev/null
@@ -1,117 +0,0 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "firejail --debug --noprofile --noroot --caps.drop=all --seccomp --cpu=0,1 --name=noroot-sandbox\r"
8expect {
9 timeout {puts "TESTING ERROR 0.1\n";exit}
10 "Child process initialized"
11}
12sleep 1
13
14send -- "cat /proc/self/status\r"
15expect {
16 timeout {puts "TESTING ERROR 1\n";exit}
17 "CapBnd:"
18}
19expect {
20 timeout {puts "TESTING ERROR 1.1\n";exit}
21 "0000000000000000"
22}
23
24send -- "cat /proc/self/status\r"
25expect {
26 timeout {puts "TESTING ERROR 2\n";exit}
27 "Cpus_allowed:"
28}
29expect {
30 timeout {puts "TESTING ERROR 2.1\n";exit}
31 "3"
32}
33expect {
34 timeout {puts "TESTING ERROR 2.2\n";exit}
35 "Cpus_allowed_list:"
36}
37puts "\n"
38
39send -- "cat /proc/self/status\r"
40expect {
41 timeout {puts "TESTING ERROR 2\n";exit}
42 "Seccomp:"
43}
44expect {
45 timeout {puts "TESTING ERROR 2.1\n";exit}
46 "2"
47}
48expect {
49 timeout {puts "TESTING ERROR 2.2\n";exit}
50 "Cpus_allowed:"
51}
52puts "\n"
53
54send -- "ping 0\r"
55expect {
56 timeout {puts "TESTING ERROR 4\n";exit}
57 "Operation not permitted"
58}
59puts "\n"
60
61send -- "whoami\r"
62expect {
63 timeout {puts "TESTING ERROR 55\\n";exit}
64 "netblue"
65}
66puts "\n"
67send -- "exit\r"
68sleep 2
69
70
71send -- "firejail --noroot --noprofile\r"
72expect {
73 timeout {puts "TESTING ERROR 6\n";exit}
74 "Child process initialized"
75}
76sleep 1
77send -- "whoami\r"
78expect {
79 timeout {puts "TESTING ERROR 7\n";exit}
80 "netblue"
81}
82send -- "sudo -s\r"
83expect {
84 timeout {puts "TESTING ERROR 8\n";exit}
85 "effective uid is not 0, is sudo installed setuid root?" { puts "OK\n";}
86 "sudo must be owned by uid 0 and have the setuid bit set" { puts "OK\n";}
87}
88puts "\n"
89send -- "exit\r"
90sleep 2
91
92send -- "firejail --name=test --noroot --noprofile\r"
93expect {
94 timeout {puts "TESTING ERROR 9\n";exit}
95 "Child process initialized"
96}
97sleep 1
98
99spawn $env(SHELL)
100send -- "firejail --debug --join=test\r"
101expect {
102 timeout {puts "TESTING ERROR 9\n";exit}
103 "User namespace detected"
104}
105expect {
106 timeout {puts "TESTING ERROR 9\n";exit}
107 "Joining user namespace"
108}
109sleep 1
110
111send -- "sudo -s\r"
112expect {
113 timeout {puts "TESTING ERROR 8\n";exit}
114 "effective uid is not 0, is sudo installed setuid root?" { puts "OK\n";}
115 "sudo must be owned by uid 0 and have the setuid bit set" { puts "OK\n";}
116}
117puts "all done\n"
diff --git a/test/notes b/test/notes
deleted file mode 100644
index 864cd5519..000000000
--- a/test/notes
+++ /dev/null
@@ -1,13 +0,0 @@
1Testing --nosound
2
3Get a list of active PulseAudio clients:
4$ pacmd info | grep application.process.binary
5 application.process.binary = "lxpanel"
6 application.process.binary = "plugin-container"
7 application.process.binary = "plugin-container"
8
9Find active PulseAudio socket:
10$ netstat -l | grep pulse
11unix 2 [ ACC ] STREAM LISTENING 10669 /tmp/pulse-WwG6ohxIJmGO/cli
12unix 2 [ ACC ] STREAM LISTENING 12584 /tmp/pulse-WwG6ohxIJmGO/dbus-socket
13unix 2 [ ACC ] STREAM LISTENING 12581 /tmp/pulse-WwG6ohxIJmGO/native
diff --git a/test/option-join2.exp b/test/option-join2.exp
deleted file mode 100755
index 630b62d9e..000000000
--- a/test/option-join2.exp
+++ /dev/null
@@ -1,39 +0,0 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "firejail --name=\"svn testing\"\r"
8expect {
9 timeout {puts "TESTING ERROR 0\n";exit}
10 "Child process initialized"
11}
12sleep 3
13
14spawn $env(SHELL)
15send -- "firejail --join=\"svn testing\";pwd\r"
16expect {
17 timeout {puts "TESTING ERROR 1\n";exit}
18 "Switching to pid"
19}
20sleep 1
21
22
23spawn $env(SHELL)
24send -- "firejail --shutdown=\"svn testing\";pwd\r"
25expect {
26 timeout {puts "TESTING ERROR 3\n";exit}
27 "home"
28}
29sleep 1
30
31send -- "firejail --list;pwd\r"
32expect {
33 timeout {puts "TESTING ERROR 4\n";exit}
34 "svn testing" {puts "TESTING ERROR 5\n";exit}
35 "home"
36}
37sleep 1
38
39puts "\nall done\n"
diff --git a/test/option-join3.exp b/test/option-join3.exp
deleted file mode 100755
index aa8a445df..000000000
--- a/test/option-join3.exp
+++ /dev/null
@@ -1,39 +0,0 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "firejail --name=svn\\ testing\r"
8expect {
9 timeout {puts "TESTING ERROR 0\n";exit}
10 "Child process initialized"
11}
12sleep 3
13
14spawn $env(SHELL)
15send -- "firejail --join=svn\\ testing;pwd\r"
16expect {
17 timeout {puts "TESTING ERROR 1\n";exit}
18 "Switching to pid"
19}
20sleep 1
21
22
23spawn $env(SHELL)
24send -- "firejail --shutdown=svn\\ testing;pwd\r"
25expect {
26 timeout {puts "TESTING ERROR 3\n";exit}
27 "home"
28}
29sleep 1
30
31send -- "firejail --list;pwd\r"
32expect {
33 timeout {puts "TESTING ERROR 4\n";exit}
34 "svn testing" {puts "TESTING ERROR 5\n";exit}
35 "home"
36}
37sleep 1
38
39puts "\nall done\n"
diff --git a/test/option-trace.exp b/test/option-trace.exp
deleted file mode 100755
index 38038b58e..000000000
--- a/test/option-trace.exp
+++ /dev/null
@@ -1,25 +0,0 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "firejail --trace\r"
8expect {
9 timeout {puts "TESTING ERROR 0\n";exit}
10 "Child process initialized"
11}
12expect {
13 timeout {puts "TESTING ERROR 1\n";exit}
14 "bash:open /dev/tty" {puts "64bit\n"}
15 "bash:open64 /dev/tty" {puts "32bit\n"}
16}
17expect {
18 timeout {puts "TESTING ERROR 3\n";exit}
19 "bash:access /etc/terminfo/x/xterm" {puts "debian\n"}
20 "bash:access /usr/share/terminfo/x/xterm" {puts "arch\n"}
21}
22
23sleep 1
24
25puts "\nall done\n"
diff --git a/test/overlay/firefox-x11-xorg.exp b/test/overlay/firefox-x11-xorg.exp
new file mode 100755
index 000000000..76c0e55fc
--- /dev/null
+++ b/test/overlay/firefox-x11-xorg.exp
@@ -0,0 +1,90 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --overlay --name=test --x11=xorg firefox -no-remote www.gentoo.org\r"
11sleep 10
12
13spawn $env(SHELL)
14send -- "firejail --list\r"
15expect {
16 timeout {puts "TESTING ERROR 3\n";exit}
17 ":firejail"
18}
19expect {
20 timeout {puts "TESTING ERROR 3.1\n";exit}
21 "firefox" {puts "firefox detected\n";}
22 "iceweasel" {puts "iceweasel detected\n";}
23}
24expect {
25 timeout {puts "TESTING ERROR 3.2\n";exit}
26 "no-remote"
27}
28sleep 1
29# grsecurity exit
30send -- "file /proc/sys/kernel/grsecurity\r"
31expect {
32 timeout {puts "TESTING ERROR - grsecurity detection\n";exit}
33 "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit}
34 "cannot open" {puts "grsecurity not present\n"}
35}
36send -- "firejail --overlay --name=blablabla\r"
37expect {
38 timeout {puts "TESTING ERROR 4\n";exit}
39 "Child process initialized"
40}
41sleep 2
42
43spawn $env(SHELL)
44send -- "firemon --seccomp\r"
45expect {
46 timeout {puts "TESTING ERROR 5\n";exit}
47 " firefox" {puts "firefox detected\n";}
48 " iceweasel" {puts "iceweasel detected\n";}
49}
50expect {
51 timeout {puts "TESTING ERROR 5.0\n";exit}
52 "no-remote"
53}
54expect {
55 timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit}
56 "Seccomp: 2"
57}
58expect {
59 timeout {puts "TESTING ERROR 5.1\n";exit}
60 "name=blablabla"
61}
62sleep 1
63send -- "firemon --caps\r"
64expect {
65 timeout {puts "TESTING ERROR 6\n";exit}
66 " firefox" {puts "firefox detected\n";}
67 " iceweasel" {puts "iceweasel detected\n";}
68}
69expect {
70 timeout {puts "TESTING ERROR 6.0\n";exit}
71 "no-remote"
72}
73expect {
74 timeout {puts "TESTING ERROR 6.1\n";exit}
75 "CapBnd:"
76}
77expect {
78 timeout {puts "TESTING ERROR 6.2\n";exit}
79 "0000000000000000"
80}
81expect {
82 timeout {puts "TESTING ERROR 6.3\n";exit}
83 "name=blablabla"
84}
85sleep 1
86send -- "firejail --shutdown=test\r"
87sleep 3
88
89puts "\nall done\n"
90
diff --git a/test/firefox-x11.exp b/test/overlay/firefox-x11.exp
index 7e30437db..aa248f328 100755
--- a/test/firefox-x11.exp
+++ b/test/overlay/firefox-x11.exp
@@ -1,10 +1,13 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
5match_max 100000 8match_max 100000
6 9
7send -- "firejail --name=test --x11 --net=br0 firefox -no-remote www.gentoo.org\r" 10send -- "firejail --overlay --name=test --x11 firefox -no-remote www.gentoo.org\r"
8sleep 10 11sleep 10
9 12
10spawn $env(SHELL) 13spawn $env(SHELL)
@@ -30,7 +33,7 @@ expect {
30 "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit} 33 "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit}
31 "cannot open" {puts "grsecurity not present\n"} 34 "cannot open" {puts "grsecurity not present\n"}
32} 35}
33send -- "firejail --name=blablabla\r" 36send -- "firejail --name=blablabla --overlay\r"
34expect { 37expect {
35 timeout {puts "TESTING ERROR 4\n";exit} 38 timeout {puts "TESTING ERROR 4\n";exit}
36 "Child process initialized" 39 "Child process initialized"
diff --git a/test/overlay/firefox.exp b/test/overlay/firefox.exp
new file mode 100755
index 000000000..6ef23558d
--- /dev/null
+++ b/test/overlay/firefox.exp
@@ -0,0 +1,99 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --overlay firefox -no-remote www.gentoo.org\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Reading profile /etc/firejail/firefox.profile"
14}
15expect {
16 timeout {puts "TESTING ERROR 1\n";exit}
17 "Child process initialized"
18}
19sleep 10
20
21spawn $env(SHELL)
22send -- "firejail --list\r"
23expect {
24 timeout {puts "TESTING ERROR 3\n";exit}
25 ":firejail"
26}
27expect {
28 timeout {puts "TESTING ERROR 3.1\n";exit}
29 "firefox" {puts "firefox detected\n";}
30 "iceweasel" {puts "iceweasel detected\n";}
31}
32expect {
33 timeout {puts "TESTING ERROR 3.2\n";exit}
34 "no-remote"
35}
36after 100
37
38# grsecurity exit
39send -- "file /proc/sys/kernel/grsecurity\r"
40expect {
41 timeout {puts "TESTING ERROR - grsecurity detection\n";exit}
42 "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit}
43 "cannot open" {puts "grsecurity not present\n"}
44}
45
46
47send -- "firejail --name=blablabla --overlay\r"
48expect {
49 timeout {puts "TESTING ERROR 4\n";exit}
50 "Child process initialized"
51}
52sleep 2
53
54spawn $env(SHELL)
55send -- "firemon --seccomp\r"
56expect {
57 timeout {puts "TESTING ERROR 5\n";exit}
58 " firefox" {puts "firefox detected\n";}
59 " iceweasel" {puts "iceweasel detected\n";}
60}
61expect {
62 timeout {puts "TESTING ERROR 5.0\n";exit}
63 "no-remote"
64}
65expect {
66 timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit}
67 "Seccomp: 2"
68}
69expect {
70 timeout {puts "TESTING ERROR 5.1\n";exit}
71 "name=blablabla"
72}
73after 100
74send -- "firemon --caps\r"
75expect {
76 timeout {puts "TESTING ERROR 6\n";exit}
77 " firefox" {puts "firefox detected\n";}
78 " iceweasel" {puts "iceweasel detected\n";}
79}
80expect {
81 timeout {puts "TESTING ERROR 6.0\n";exit}
82 "no-remote"
83}
84expect {
85 timeout {puts "TESTING ERROR 6.1\n";exit}
86 "CapBnd:"
87}
88expect {
89 timeout {puts "TESTING ERROR 6.2\n";exit}
90 "0000000000000000"
91}
92expect {
93 timeout {puts "TESTING ERROR 6.3\n";exit}
94 "name=blablabla"
95}
96after 100
97
98puts "\nall done\n"
99
diff --git a/test/overlay/fs-named.exp b/test/overlay/fs-named.exp
new file mode 100755
index 000000000..2ccb22bb1
--- /dev/null
+++ b/test/overlay/fs-named.exp
@@ -0,0 +1,66 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "firejail --overlay-named=firejail-test\r"
8expect {
9 timeout {puts "TESTING ERROR 2\n";exit}
10 "not available for kernels older than 3.18" {puts "\nTESTING: overlayfs not available\n"; exit}
11 "Error: --overlay option is not available on Grsecurity systems" {puts "\nTESTING: overlayfs not available\n"; exit}
12 "Child process initialized" {puts "found\n"}
13}
14sleep 1
15
16send -- "echo xyzxyzxyz > ~/_firejail_test_file; echo done\r"
17expect {
18 timeout {puts "TESTING ERROR 3\n";exit}
19 "done"
20}
21after 100
22
23send -- "cat ~/_firejail_test_file; echo done\r"
24expect {
25 timeout {puts "TESTING ERROR 4\n";exit}
26 "xyzxyzxyz"
27}
28expect {
29 timeout {puts "TESTING ERROR 4.1\n";exit}
30 "done"
31}
32after 100
33
34send -- "exit\r"
35sleep 2
36
37send -- "cat ~/_firejail_test_file; echo done\r"
38expect {
39 timeout {puts "TESTING ERROR 5\n";exit}
40 "xyzxyzxyz" {puts "TESTING ERROR 5.1\n";exit}
41 "done"
42}
43after 100
44
45send -- "firejail --overlay-named=firejail-test\r"
46expect {
47 timeout {puts "TESTING ERROR 2\n";exit}
48 "not available for kernels older than 3.18" {puts "\nTESTING: overlayfs not available\n"; exit}
49 "Error: --overlay option is not available on Grsecurity systems" {puts "\nTESTING: overlayfs not available\n"; exit}
50 "Child process initialized" {puts "found\n"}
51}
52sleep 1
53
54send -- "cat ~/_firejail_test_file; echo done\r"
55expect {
56 timeout {puts "TESTING ERROR 4\n";exit}
57 "xyzxyzxyz"
58}
59expect {
60 timeout {puts "TESTING ERROR 4.1\n";exit}
61 "done"
62}
63after 100
64
65puts "\nall done\n"
66
diff --git a/test/fs_overlay.exp b/test/overlay/fs-tmpfs.exp
index b7eeba80f..658d16779 100755
--- a/test/fs_overlay.exp
+++ b/test/overlay/fs-tmpfs.exp
@@ -4,63 +4,59 @@ set timeout 10
4spawn $env(SHELL) 4spawn $env(SHELL)
5match_max 100000 5match_max 100000
6 6
7send -- "rm -f /tmp/firejail-overlay-test;pwd\r" 7send -- "firejail --overlay-clean\r"
8after 100
9send -- "file ~/.firejail\r"
8expect { 10expect {
9 timeout {puts "TESTING ERROR 0\n";exit} 11 timeout {puts "TESTING ERROR 0\n";exit}
10 "home" 12 "cannot open"
11} 13}
14after 100
12 15
13send -- "ls > /tmp/firejail-overlay-test;pwd\r" 16send -- "firejail --overlay-tmpfs\r"
14expect { 17expect {
15 timeout {puts "TESTING ERROR 1\n";exit} 18 timeout {puts "TESTING ERROR 1\n";exit}
16 "home"
17}
18
19send -- "firejail --noprofile --overlay\r"
20expect {
21 timeout {puts "TESTING ERROR 2\n";exit}
22 "not available for kernels older than 3.18" {puts "\nTESTING: overlayfs not available\n"; exit} 19 "not available for kernels older than 3.18" {puts "\nTESTING: overlayfs not available\n"; exit}
23 "Error: --overlay option is not available on Grsecurity systems" {puts "\nTESTING: overlayfs not available\n"; exit} 20 "Error: --overlay option is not available on Grsecurity systems" {puts "\nTESTING: overlayfs not available\n"; exit}
24 "Child process initialized" {puts "found\n"} 21 "Child process initialized" {puts "found\n"}
25} 22}
26sleep 1 23sleep 1
27 24
28send -- "echo xyzxyzxyz > /tmp/firejail-overlay-test;pwd\r" 25send -- "echo xyzxyzxyz > ~/_firejail_test_file; echo done\r"
29expect { 26expect {
30 timeout {puts "TESTING ERROR 3\n";exit} 27 timeout {puts "TESTING ERROR 2\n";exit}
31 "home" 28 "done"
32} 29}
33sleep 1 30after 100
34 31
35send -- "cat /tmp/firejail-overlay-test;pwd\r" 32send -- "cat ~/_firejail_test_file; echo done\r"
36expect { 33expect {
37 timeout {puts "TESTING ERROR 4\n";exit} 34 timeout {puts "TESTING ERROR 3\n";exit}
38 "xyzxyzxyz" 35 "xyzxyzxyz"
39} 36}
40expect { 37expect {
41 timeout {puts "TESTING ERROR 4.1\n";exit} 38 timeout {puts "TESTING ERROR 4\n";exit}
42 "home" 39 "done"
43} 40}
44sleep 1 41after 100
45 42
46send -- "exit\r" 43send -- "exit\r"
47sleep 2 44sleep 1
48 45
49send -- "cat /tmp/firejail-overlay-test;pwd\r" 46send -- "cat ~/_firejail_test_file; echo done\r"
50expect { 47expect {
51 timeout {puts "TESTING ERROR 5\n";exit} 48 timeout {puts "TESTING ERROR 5\n";exit}
52 "xyzxyzxyz" {puts "TESTING ERROR 5.1\n";exit} 49 "xyzxyzxyz" {puts "TESTING ERROR 6\n";exit}
53 "home" 50 "done"
54} 51}
52after 100
55 53
56sleep 1 54send -- "file ~/.firejail\r"
57send -- "rm -f /tmp/firejail-overlay-test;pwd\r"
58expect { 55expect {
59 timeout {puts "TESTING ERROR 0\n";exit} 56 timeout {puts "TESTING ERROR 7\n";exit}
60 "home" 57 "cannot open"
61} 58}
59after 100
62 60
63 61puts "\nall done\n"
64sleep 1
65puts "all done \n"
66 62
diff --git a/test/overlay/fs.exp b/test/overlay/fs.exp
new file mode 100755
index 000000000..15ada9203
--- /dev/null
+++ b/test/overlay/fs.exp
@@ -0,0 +1,46 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "firejail --overlay\r"
8expect {
9 timeout {puts "TESTING ERROR 2\n";exit}
10 "not available for kernels older than 3.18" {puts "\nTESTING: overlayfs not available\n"; exit}
11 "Error: --overlay option is not available on Grsecurity systems" {puts "\nTESTING: overlayfs not available\n"; exit}
12 "Child process initialized" {puts "found\n"}
13}
14sleep 1
15
16send -- "echo xyzxyzxyz > ~/_firejail_test_file; echo done\r"
17expect {
18 timeout {puts "TESTING ERROR 3\n";exit}
19 "done"
20}
21after 100
22
23send -- "cat ~/_firejail_test_file; echo done\r"
24expect {
25 timeout {puts "TESTING ERROR 4\n";exit}
26 "xyzxyzxyz"
27}
28expect {
29 timeout {puts "TESTING ERROR 4.1\n";exit}
30 "done"
31}
32after 100
33
34send -- "exit\r"
35sleep 2
36
37send -- "cat ~/_firejail_test_file; echo done\r"
38expect {
39 timeout {puts "TESTING ERROR 5\n";exit}
40 "xyzxyzxyz" {puts "TESTING ERROR 5.1\n";exit}
41 "done"
42}
43
44after 100
45puts "\nall done\n"
46
diff --git a/test/overlay/overlay.sh b/test/overlay/overlay.sh
new file mode 100755
index 000000000..4c9ebe5b0
--- /dev/null
+++ b/test/overlay/overlay.sh
@@ -0,0 +1,67 @@
1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6export MALLOC_CHECK_=3
7export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
8
9echo "TESTING: overlay fs (test/overlay/fs.exp)"
10rm -fr ~/_firejail_test_*
11./fs.exp
12rm -fr ~/_firejail_test_*
13
14echo "TESTING: overlay named fs (test/overlay/fs-named.exp)"
15rm -fr ~/_firejail_test_*
16./fs-named.exp
17rm -fr ~/_firejail_test_*
18
19echo "TESTING: overlay tmpfs fs (test/overlay/fs-tmpfs.exp)"
20rm -fr ~/_firejail_test_*
21./fs-tmpfs.exp
22rm -fr ~/_firejail_test_*
23
24which firefox
25if [ "$?" -eq 0 ];
26then
27 echo "TESTING: overlay firefox"
28 ./firefox.exp
29else
30 echo "TESTING SKIP: firefox not found"
31fi
32
33which firefox
34if [ "$?" -eq 0 ];
35then
36 echo "TESTING: overlay firefox x11 xorg"
37 ./firefox.exp
38else
39 echo "TESTING SKIP: firefox not found"
40fi
41
42
43# check xpra/xephyr
44which xpra
45if [ "$?" -eq 0 ];
46then
47 echo "xpra found"
48else
49 echo "xpra not found"
50 which Xephyr
51 if [ "$?" -eq 0 ];
52 then
53 echo "Xephyr found"
54 else
55 echo "TESTING SKIP: xpra and/or Xephyr not found"
56 exit
57 fi
58fi
59
60which firefox
61if [ "$?" -eq 0 ];
62then
63 echo "TESTING: overlay firefox x11"
64 ./firefox-x11.exp
65else
66 echo "TESTING SKIP: firefox not found"
67fi
diff --git a/test/private.exp b/test/private.exp
deleted file mode 100755
index a5920c37b..000000000
--- a/test/private.exp
+++ /dev/null
@@ -1,97 +0,0 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7if { $argc != 1 } {
8 puts "TESTING ERROR: argument missing"
9 puts "Usage: private.exp username"
10 puts "where username is the name of the current user"
11 exit
12}
13
14# testing profile and private
15send -- "firejail --private --profile=/etc/firejail/generic.profile\r"
16expect {
17 timeout {puts "TESTING ERROR 0\n";exit}
18 "Child process initialized"
19}
20sleep 1
21send -- "exit\r"
22sleep 1
23
24send -- "firejail --private --noprofile\r"
25expect {
26 timeout {puts "TESTING ERROR 0\n";exit}
27 "Child process initialized"
28}
29
30sleep 1
31send -- "ls -al; pwd\r"
32expect {
33 timeout {puts "TESTING ERROR 0.1\n";exit}
34 ".bashrc"
35}
36expect {
37 timeout {puts "TESTING ERROR 0.2\n";exit}
38 [lindex $argv 0]
39}
40send -- "ls -al; pwd\r"
41expect {
42 timeout {
43 # OpenSUSE doesn't use .Xauthority from user home directory
44 send -- "env | grep XAUTHORITY\r"
45
46 expect {
47 timeout {puts "TESTING ERROR 0.3\n";exit}
48 "/run/lightdm/netblue/xauthority"
49 }
50 }
51 ".Xauthority"
52}
53expect {
54 timeout {puts "TESTING ERROR 0.4\n";exit}
55 [lindex $argv 0]
56}
57
58
59# testing private only
60send -- "bash\r"
61sleep 1
62# owner /home/netblue
63send -- "ls -l /home;pwd\r"
64expect {
65 timeout {puts "TESTING ERROR 1\n";exit}
66 [lindex $argv 0]
67}
68expect {
69 timeout {puts "TESTING ERROR 1.1\n";exit}
70 [lindex $argv 0]
71}
72expect {
73 timeout {puts "TESTING ERROR 1.2\n";exit}
74 [lindex $argv 0]
75}
76expect {
77 timeout {puts "TESTING ERROR 1.3\n";exit}
78 "home"
79}
80sleep 1
81
82# owner /tmp
83send -- "stat -c %U%a /tmp;pwd\r"
84expect {
85 timeout {puts "TESTING ERROR 2\n";exit}
86 "root777" {puts "version 1\n";}
87 "root1777" {puts "version 2\n";}
88 "nobody777" {puts "version 3\n";}
89 "nobody1777" {puts "version 4\n";}
90}
91expect {
92 timeout {puts "TESTING ERROR 2.1\n";exit}
93 "home"
94}
95sleep 1
96
97puts "all done\n"
diff --git a/test/private_dir.exp b/test/private_dir.exp
index 9dfb2ea9f..a4beeba27 100755
--- a/test/private_dir.exp
+++ b/test/private_dir.exp
@@ -42,7 +42,7 @@ expect {
42send -- "ls -al | wc -l;pwd\r" 42send -- "ls -al | wc -l;pwd\r"
43expect { 43expect {
44 timeout {puts "TESTING ERROR 1\n";exit} 44 timeout {puts "TESTING ERROR 1\n";exit}
45 "7" {puts "normal system\n";} 45 "6" {puts "normal system\n";}
46 "5" {puts "OpenSUSE\n";} 46 "5" {puts "OpenSUSE\n";}
47} 47}
48expect { 48expect {
diff --git a/test/private_dir_profile.exp b/test/private_dir_profile.exp
index 5b38ad0bb..8d1c74444 100755
--- a/test/private_dir_profile.exp
+++ b/test/private_dir_profile.exp
@@ -42,7 +42,7 @@ expect {
42send -- "ls -al | wc -l;pwd\r" 42send -- "ls -al | wc -l;pwd\r"
43expect { 43expect {
44 timeout {puts "TESTING ERROR 1\n";exit} 44 timeout {puts "TESTING ERROR 1\n";exit}
45 "7" {puts "normal system\n";} 45 "6" {puts "normal system\n";}
46 "5" {puts "OpenSUSE\n";} 46 "5" {puts "OpenSUSE\n";}
47} 47}
48expect { 48expect {
diff --git a/test/profile_tmpfs.exp b/test/profile_tmpfs.exp
deleted file mode 100755
index a2faa32f7..000000000
--- a/test/profile_tmpfs.exp
+++ /dev/null
@@ -1,37 +0,0 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "mkdir /tmp/firejailtestdir\r"
8sleep 1
9send -- "ls > /tmp/firejailtestdir/tmpfile\r"
10sleep 1
11
12send -- "firejail --profile=tmpfs.profile\r"
13expect {
14 timeout {puts "TESTING ERROR 0\n";exit}
15 "Child process initialized"
16}
17
18# testing private only
19send -- "bash\r"
20sleep 1
21
22send -- "ls -l /tmp/firejailtestdir;pwd\r"
23expect {
24 timeout {puts "TESTING ERROR 1.1\n";exit}
25 "tmpfile" {puts "TESTING ERROR 1\n";exit}
26 "home"
27}
28sleep 1
29send -- "exit\r"
30sleep 1
31send -- "exit\r"
32sleep 1
33send -- "rm -fr /tmp/firejailtestdir\r"
34
35sleep 1
36
37puts "\n"
diff --git a/test/ignore.exp b/test/profiles/ignore.exp
index c5ea25684..0c5691e9a 100755
--- a/test/ignore.exp
+++ b/test/profiles/ignore.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -43,5 +46,5 @@ expect {
43 "Child process initialized" 46 "Child process initialized"
44} 47}
45 48
46 49after 100
47puts "\nall done\n" 50puts "\nall done\n"
diff --git a/test/ignore.profile b/test/profiles/ignore.profile
index aec231ad2..aec231ad2 100644
--- a/test/ignore.profile
+++ b/test/profiles/ignore.profile
diff --git a/test/ignore2.profile b/test/profiles/ignore2.profile
index 49fcd8324..49fcd8324 100644
--- a/test/ignore2.profile
+++ b/test/profiles/ignore2.profile
diff --git a/test/profile_followlnk.exp b/test/profiles/profile_followlnk.exp
index e2ede2865..eb3d04852 100755
--- a/test/profile_followlnk.exp
+++ b/test/profiles/profile_followlnk.exp
@@ -5,34 +5,22 @@ spawn $env(SHELL)
5match_max 100000 5match_max 100000
6 6
7send -- "mkdir /tmp/firejailtestdir\r" 7send -- "mkdir /tmp/firejailtestdir\r"
8sleep 1
9send -- "ln -s /tmp/firejailtestdir /tmp/firejailtestdirlnk\r" 8send -- "ln -s /tmp/firejailtestdir /tmp/firejailtestdirlnk\r"
10sleep 1
11send -- "touch /tmp/firejailtestfile\r" 9send -- "touch /tmp/firejailtestfile\r"
12sleep 1
13send -- "ln -s /tmp/firejailtestfile /tmp/firejailtestfilelnk\r" 10send -- "ln -s /tmp/firejailtestfile /tmp/firejailtestfilelnk\r"
14sleep 1 11sleep 1
15 12
16send -- "firejail --profile=readonly-lnk.profile --debug\r" 13send -- "firejail --profile=readonly-lnk.profile\r"
17expect { 14expect {
18 timeout {puts "TESTING ERROR 0\n";exit} 15 timeout {puts "TESTING ERROR 0\n";exit}
19 "Child process initialized" 16 "Child process initialized"
20} 17}
21 18
22# testing private only 19send -- "ls > /tmp/firejailtestdirlnk/ttt\r"
23send -- "bash\r"
24sleep 1
25
26
27send -- "ls > /tmp/firejailtestdirlnk/ttt;pwd\r"
28expect { 20expect {
29 timeout {puts "TESTING ERROR 1\n";exit} 21 timeout {puts "TESTING ERROR 1\n";exit}
30 "Read-only file system" 22 "Read-only file system"
31} 23}
32expect {
33 timeout {puts "TESTING ERROR 1.1\n";exit}
34 "home"
35}
36sleep 1 24sleep 1
37 25
38send -- "ls > /tmp/firejailtestfilelnk;pwd\r" 26send -- "ls > /tmp/firejailtestfilelnk;pwd\r"
@@ -40,29 +28,11 @@ expect {
40 timeout {puts "TESTING ERROR 2\n";exit} 28 timeout {puts "TESTING ERROR 2\n";exit}
41 "Read-only file system" 29 "Read-only file system"
42} 30}
43expect {
44 timeout {puts "TESTING ERROR 2.1\n";exit}
45 "home"
46}
47sleep 1 31sleep 1
48 32
49send -- "exit\r" 33send -- "exit\r"
50sleep 1 34after 100
51send -- "pwd\r"
52expect {
53 timeout {puts "TESTING ERROR 3\n";exit}
54 "home"
55}
56sleep 1
57send -- "exit\r"
58sleep 1
59send -- "pwd\r"
60expect {
61 timeout {puts "TESTING ERROR 4\n";exit}
62 "home"
63}
64sleep 2
65send -- "rm -fr /tmp/firejailtest*\r" 35send -- "rm -fr /tmp/firejailtest*\r"
66sleep 1 36after 100
67 37
68puts "\n" 38puts "\nall done\n"
diff --git a/test/profile_noperm.exp b/test/profiles/profile_noperm.exp
index b3ed558bc..b3b031cb2 100755
--- a/test/profile_noperm.exp
+++ b/test/profiles/profile_noperm.exp
@@ -9,5 +9,5 @@ expect {
9 timeout {puts "TESTING ERROR 0\n";exit} 9 timeout {puts "TESTING ERROR 0\n";exit}
10 "cannot access profile" 10 "cannot access profile"
11} 11}
12sleep 1 12after 100
13puts "\n" 13puts "\nall done\n"
diff --git a/test/profile_readonly.exp b/test/profiles/profile_readonly.exp
index 046b0d738..c1c9544a6 100755
--- a/test/profile_readonly.exp
+++ b/test/profiles/profile_readonly.exp
@@ -5,7 +5,6 @@ spawn $env(SHELL)
5match_max 100000 5match_max 100000
6 6
7send -- "mkdir /tmp/firejailtestdir\r" 7send -- "mkdir /tmp/firejailtestdir\r"
8sleep 1
9send -- "touch /tmp/firejailtestfile\r" 8send -- "touch /tmp/firejailtestfile\r"
10sleep 1 9sleep 1
11 10
@@ -14,51 +13,24 @@ expect {
14 timeout {puts "TESTING ERROR 0\n";exit} 13 timeout {puts "TESTING ERROR 0\n";exit}
15 "Child process initialized" 14 "Child process initialized"
16} 15}
16sleep 2
17 17
18# testing private only 18send -- "ls > /tmp/firejailtestdir/ttt\r"
19send -- "bash\r"
20sleep 1
21
22
23send -- "ls > /tmp/firejailtestdir/ttt;pwd\r"
24expect { 19expect {
25 timeout {puts "TESTING ERROR 1\n";exit} 20 timeout {puts "TESTING ERROR 1\n";exit}
26 "Read-only file system" 21 "Read-only file system"
27} 22}
28expect {
29 timeout {puts "TESTING ERROR 1.1\n";exit}
30 "home"
31}
32sleep 1 23sleep 1
33 24
34send -- "ls > /tmp/firejailtestfile;pwd\r" 25send -- "ls > /tmp/firejailtestfile\r"
35expect { 26expect {
36 timeout {puts "TESTING ERROR 2\n";exit} 27 timeout {puts "TESTING ERROR 2\n";exit}
37 "Read-only file system" 28 "Read-only file system"
38} 29}
39expect {
40 timeout {puts "TESTING ERROR 2.1\n";exit}
41 "home"
42}
43sleep 1
44
45send -- "exit\r"
46sleep 1
47send -- "pwd\r"
48expect {
49 timeout {puts "TESTING ERROR 3\n";exit}
50 "home"
51}
52sleep 1
53send -- "exit\r" 30send -- "exit\r"
54sleep 1 31after 100
55send -- "pwd\r" 32
56expect {
57 timeout {puts "TESTING ERROR 4\n";exit}
58 "home"
59}
60sleep 2
61send -- "rm -fr /tmp/firejailtest*\r" 33send -- "rm -fr /tmp/firejailtest*\r"
62sleep 1 34after 100
63 35
64puts "\n" 36puts "\nall done\n"
diff --git a/test/profile_syntax.exp b/test/profiles/profile_syntax.exp
index 559947276..d1be2074a 100755
--- a/test/profile_syntax.exp
+++ b/test/profiles/profile_syntax.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -22,42 +25,30 @@ sleep 1
22send -- "ls -l /etc/shadow\r" 25send -- "ls -l /etc/shadow\r"
23expect { 26expect {
24 timeout {puts "TESTING ERROR 3\n";exit} 27 timeout {puts "TESTING ERROR 3\n";exit}
25 "root root 0" 28 "root root"
26} 29}
27 30
28sleep 1 31sleep 1
29send -- "rmdir;pwd\r" 32send -- "rmdir\r"
30expect { 33expect {
31 timeout {puts "TESTING ERROR 4\n";exit} 34 timeout {puts "TESTING ERROR 4\n";exit}
32 "Permission denied" 35 "Permission denied"
33} 36}
34expect {
35 timeout {puts "TESTING ERROR 5\n";exit}
36 "home"
37}
38 37
39sleep 1 38sleep 1
40send -- "mount;pwd\r" 39send -- "mount\r"
41expect { 40expect {
42 timeout {puts "TESTING ERROR 6\n";exit} 41 timeout {puts "TESTING ERROR 6\n";exit}
43 "Permission denied" 42 "Permission denied"
44} 43}
45expect {
46 timeout {puts "TESTING ERROR 7\n";exit}
47 "home"
48}
49 44
50sleep 1 45sleep 1
51send -- "umount;pwd\r" 46send -- "umount\r"
52expect { 47expect {
53 timeout {puts "TESTING ERROR 8\n";exit} 48 timeout {puts "TESTING ERROR 8\n";exit}
54 "Permission denied" 49 "Permission denied"
55} 50}
56expect {
57 timeout {puts "TESTING ERROR 9\n";exit}
58 "home"
59}
60send -- "exit\r" 51send -- "exit\r"
61 52
62sleep 1 53after 100
63puts "\n" 54puts "\nall done\n"
diff --git a/test/profile_syntax2.exp b/test/profiles/profile_syntax2.exp
index 96e85ba93..9dca35ca2 100755
--- a/test/profile_syntax2.exp
+++ b/test/profiles/profile_syntax2.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -42,6 +45,6 @@ expect {
42 timeout {puts "TESTING ERROR 8\n";exit} 45 timeout {puts "TESTING ERROR 8\n";exit}
43 "Child process initialized" 46 "Child process initialized"
44} 47}
45 48send -- "exit\r"
46sleep 1 49after 100
47puts "\nall done\n" 50puts "\nall done\n"
diff --git a/test/profiles/profiles.sh b/test/profiles/profiles.sh
new file mode 100755
index 000000000..ca0b9fb29
--- /dev/null
+++ b/test/profiles/profiles.sh
@@ -0,0 +1,34 @@
1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6export MALLOC_CHECK_=3
7export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
8
9echo "TESTING: default profiles installed in /etc"
10PROFILES=`ls /etc/firejail/*.profile`
11for PROFILE in $PROFILES
12do
13 echo "TESTING: $PROFILE"
14 ./test-profile.exp $PROFILE
15done
16
17echo "TESTING: profile syntax (test/profiles/profile_syntax.exp)"
18./profile_syntax.exp
19
20echo "TESTING: profile syntax 2 (test/profiles/profile_syntax2.exp)"
21./profile_syntax2.exp
22
23echo "TESTING: ignore command (test/profiles/ignore.exp)"
24./ignore.exp
25
26echo "TESTING: profile read-only (test/profiles/profile_readonly.exp)"
27./profile_readonly.exp
28
29echo "TESTING: profile read-only links (test/profiles/profile_readonly.exp)"
30./profile_followlnk.exp
31
32echo "TESTING: profile no permissions (test/profiles/profile_noperm.exp)"
33./profile_noperm.exp
34
diff --git a/test/readonly-lnk.profile b/test/profiles/readonly-lnk.profile
index 71ffb1a26..71ffb1a26 100644
--- a/test/readonly-lnk.profile
+++ b/test/profiles/readonly-lnk.profile
diff --git a/test/readonly.profile b/test/profiles/readonly.profile
index 55d89e3d7..55d89e3d7 100644
--- a/test/readonly.profile
+++ b/test/profiles/readonly.profile
diff --git a/test/test-profile.exp b/test/profiles/test-profile.exp
index a03e8db31..a6b4a5aad 100755
--- a/test/test-profile.exp
+++ b/test/profiles/test-profile.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -10,10 +13,10 @@ if { $argc != 1 } {
10 exit 13 exit
11} 14}
12 15
13send -- "firejail --profile=$argv /bin/bash\r" 16send -- "firejail --profile=$argv echo done\r"
14expect { 17expect {
15 timeout {puts "TESTING ERROR 0\n";exit} 18 timeout {puts "TESTING ERROR 0\n";exit}
16 "Child process initialized" 19 "done"
17} 20}
18send -- "exit\r" 21send -- "exit\r"
19after 100 22after 100
diff --git a/test/test.profile b/test/profiles/test.profile
index 1d69cc960..1d69cc960 100644
--- a/test/test.profile
+++ b/test/profiles/test.profile
diff --git a/test/test2.profile b/test/profiles/test2.profile
index d7e1a1f21..d7e1a1f21 100644
--- a/test/test2.profile
+++ b/test/profiles/test2.profile
diff --git a/test/quiet.exp b/test/quiet.exp
deleted file mode 100755
index fa46aebf2..000000000
--- a/test/quiet.exp
+++ /dev/null
@@ -1,17 +0,0 @@
1#!/usr/bin/expect -f
2
3set timeout 4
4spawn $env(SHELL)
5match_max 100000
6
7# check ip address
8send -- "firejail --net=br0 --quiet\r"
9expect {
10 "Child process initialized" {puts "TESTING ERROR 1\n";exit}
11 "Interface" {puts "TESTING ERROR 1\n";exit}
12}
13sleep 1
14send -- "\r"
15
16puts "\nall done\n"
17
diff --git a/test/profile_rlimit.exp b/test/rlimit/rlimit-profile.exp
index 7d2637444..a9e54a405 100755
--- a/test/profile_rlimit.exp
+++ b/test/rlimit/rlimit-profile.exp
@@ -1,6 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2 2
3set timeout 10 3set timeout 10
4#cd /home
4spawn $env(SHELL) 5spawn $env(SHELL)
5match_max 100000 6match_max 100000
6 7
@@ -11,7 +12,7 @@ expect {
11} 12}
12sleep 1 13sleep 1
13 14
14send -- "cat /proc/self/limits; pwd\r" 15send -- "cat /proc/self/limits\r"
15expect { 16expect {
16 timeout {puts "TESTING ERROR 1.1\n";exit} 17 timeout {puts "TESTING ERROR 1.1\n";exit}
17 "Max file size 1024 1024" 18 "Max file size 1024 1024"
@@ -28,9 +29,5 @@ expect {
28 timeout {puts "TESTING ERROR 1.4\n";exit} 29 timeout {puts "TESTING ERROR 1.4\n";exit}
29 "Max pending signals 200 200" 30 "Max pending signals 200 200"
30} 31}
31expect { 32after 100
32 timeout {puts "TESTING ERROR 1.5\n";exit} 33puts "\nall done\n"
33 "home"
34}
35sleep 1
36puts "\n"
diff --git a/test/option_rlimit.exp b/test/rlimit/rlimit.exp
index 17d2bd9d1..611f69821 100755
--- a/test/option_rlimit.exp
+++ b/test/rlimit/rlimit.exp
@@ -1,6 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2 2
3set timeout 10 3set timeout 10
4cd /home
4spawn $env(SHELL) 5spawn $env(SHELL)
5match_max 100000 6match_max 100000
6 7
@@ -32,5 +33,5 @@ expect {
32 timeout {puts "TESTING ERROR 1.5\n";exit} 33 timeout {puts "TESTING ERROR 1.5\n";exit}
33 "home" 34 "home"
34} 35}
35sleep 1 36after 100
36puts "\n" 37puts "\n"
diff --git a/test/rlimit.profile b/test/rlimit/rlimit.profile
index 271891c03..271891c03 100644
--- a/test/rlimit.profile
+++ b/test/rlimit/rlimit.profile
diff --git a/test/rlimit/rlimit.sh b/test/rlimit/rlimit.sh
new file mode 100755
index 000000000..d85497176
--- /dev/null
+++ b/test/rlimit/rlimit.sh
@@ -0,0 +1,14 @@
1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6export MALLOC_CHECK_=3
7export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
8
9echo "TESTING: rlimit (test/rlimit/rlimit.exp)"
10./rlimit.exp
11
12echo "TESTING: rlimit profile (test/rlimit/rlimit-profile.exp)"
13./rlimit-profile.exp
14
diff --git a/test/servers3.exp b/test/root/apache2.exp
index eccdaa1d9..0b102bad5 100755
--- a/test/servers3.exp
+++ b/test/root/apache2.exp
@@ -4,16 +4,6 @@ set timeout 5
4spawn $env(SHELL) 4spawn $env(SHELL)
5match_max 100000 5match_max 100000
6 6
7send -- "sudo ls; sudo whoami; sudo pwd\r"
8expect {
9 timeout {puts "TESTING ERROR: you need to root run this test as root\n";exit}
10 "root"
11}
12
13send -- "pkill apache\r"
14sleep 2
15
16
17send -- "firejail --name=apache /etc/init.d/apache2 start\r" 7send -- "firejail --name=apache /etc/init.d/apache2 start\r"
18expect { 8expect {
19 timeout {puts "TESTING ERROR 0\n";exit} 9 timeout {puts "TESTING ERROR 0\n";exit}
diff --git a/test/root/firecfg.exp b/test/root/firecfg.exp
new file mode 100755
index 000000000..b4864988d
--- /dev/null
+++ b/test/root/firecfg.exp
@@ -0,0 +1,46 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firecfg\r"
11sleep 1
12
13send -- "firecfg --clean\r"
14expect {
15 timeout {puts "TESTING ERROR 0\n";exit}
16 "/usr/local/bin/firefox removed"
17}
18after 100
19send -- "file /usr/local/bin/firefox; echo done\r"
20expect {
21 timeout {puts "TESTING ERROR 1\n";exit}
22 "symbolic link to /usr/bin/firejail" {puts "TESTING ERROR 2\n";exit}
23 "done"
24}
25after 100
26
27send -- "firecfg\r"
28expect {
29 timeout {puts "TESTING ERROR 3\n";exit}
30 "/usr/local/bin/firefox created"
31}
32after 100
33send -- "file /usr/local/bin/firefox\r"
34expect {
35 timeout {puts "TESTING ERROR 4\n";exit}
36 "symbolic link to /usr/bin/firejail"
37}
38after 100
39
40send -- "firecfg --list\r"
41expect {
42 timeout {puts "TESTING ERROR 5\n";exit}
43 "/usr/local/bin/firefox"
44}
45after 100
46puts "\nall done\n"
diff --git a/test/root/firejail.config b/test/root/firejail.config
new file mode 100644
index 000000000..71ff2f4e9
--- /dev/null
+++ b/test/root/firejail.config
@@ -0,0 +1,20 @@
1bind yes
2chroot yes
3chroot-desktop yes
4file-transfer yes
5force-nonewprivs no
6network yes
7overlayfs yes
8private-bin-no-local no
9private-home yes
10quiet-by-default no
11remount-proc-sys yes
12restricted-network no
13# netfilter-default /etc/iptables.iptables.rules
14seccomp yes
15userns yes
16whitelist yes
17x11 yes
18xephyr-screen 800x600
19xephyr-window-title yes
20xephyr-extra-params -grayscale
diff --git a/test/root/firemon-events.exp b/test/root/firemon-events.exp
new file mode 100755
index 000000000..4f305e51d
--- /dev/null
+++ b/test/root/firemon-events.exp
@@ -0,0 +1,72 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7# start firemon
8set firemon_id $spawn_id
9send -- "firemon\r"
10sleep 1
11
12# start firejail
13spawn $env(SHELL)
14set firejail_id $spawn_id
15send -- "firejail\r"
16expect {
17 timeout {puts "TESTING ERROR 0\n";exit}
18 "Child process initialized"
19}
20
21# get messages on firemon
22set spawn_id $firemon_id
23expect {
24 timeout {puts "TESTING ERROR 1\n";exit}
25 "exec"
26}
27expect {
28 timeout {puts "TESTING ERROR 2\n";exit}
29 "/bin/bash -c /bin/bash"
30}
31expect {
32 timeout {puts "TESTING ERROR 3\n";exit}
33 "exec"
34}
35expect {
36 timeout {puts "TESTING ERROR 4\n";exit}
37 "/bin/bash"
38}
39expect {
40 timeout {puts "TESTING ERROR 5\n";exit}
41 "fork"
42}
43expect {
44 timeout {puts "TESTING ERROR 6\n";exit}
45 "child"
46}
47expect {
48 timeout {puts "TESTING ERROR 7\n";exit}
49 "/bin/bash"
50}
51after 100
52
53# exit firejail
54set spawn_id $firejail_id
55send -- "exit\r"
56sleep 1
57
58# get messages on firemon
59set spawn_id $firemon_id
60expect {
61 timeout {puts "TESTING ERROR 8\n";exit}
62 "exit"
63}
64
65expect {
66 timeout {puts "TESTING ERROR 9\n";exit}
67 "EXIT SANDBOX"
68}
69
70
71puts "\nall done\n"
72
diff --git a/test/servers4.exp b/test/root/isc-dhcp.exp
index 86500707a..5d9597e7c 100755
--- a/test/servers4.exp
+++ b/test/root/isc-dhcp.exp
@@ -4,15 +4,6 @@ set timeout 5
4spawn $env(SHELL) 4spawn $env(SHELL)
5match_max 100000 5match_max 100000
6 6
7send -- "sudo ls; sudo whoami; sudo pwd\r"
8expect {
9 timeout {puts "TESTING ERROR: you need to root run this test as root\n";exit}
10 "root"
11}
12
13send -- "pkill dhcpd\r"
14sleep 2
15
16send -- "firejail --name=dhcpd /etc/init.d/isc-dhcp-server start\r" 7send -- "firejail --name=dhcpd /etc/init.d/isc-dhcp-server start\r"
17expect { 8expect {
18 timeout {puts "TESTING ERROR 0\n";exit} 9 timeout {puts "TESTING ERROR 0\n";exit}
diff --git a/test/servers6.exp b/test/root/nginx.exp
index 9ef4ea514..82ebe0ee7 100755
--- a/test/servers6.exp
+++ b/test/root/nginx.exp
@@ -4,16 +4,6 @@ set timeout 5
4spawn $env(SHELL) 4spawn $env(SHELL)
5match_max 100000 5match_max 100000
6 6
7send -- "sudo ls; sudo whoami; sudo pwd\r"
8expect {
9 timeout {puts "TESTING ERROR: you need to root run this test as root\n";exit}
10 "root"
11}
12
13send -- "pkill nginx\r"
14sleep 2
15
16
17send -- "firejail --name=nginx /etc/init.d/nginx start\r" 7send -- "firejail --name=nginx /etc/init.d/nginx start\r"
18expect { 8expect {
19 timeout {puts "TESTING ERROR 0\n";exit} 9 timeout {puts "TESTING ERROR 0\n";exit}
diff --git a/test/option_bind_directory.exp b/test/root/option_bind_directory.exp
index 3233c68de..3233c68de 100755
--- a/test/option_bind_directory.exp
+++ b/test/root/option_bind_directory.exp
diff --git a/test/option_bind_file.exp b/test/root/option_bind_file.exp
index 8926e0391..8926e0391 100755
--- a/test/option_bind_file.exp
+++ b/test/root/option_bind_file.exp
diff --git a/test/option_tmpfs.exp b/test/root/option_tmpfs.exp
index 6522ef2d3..3d492dfdb 100755
--- a/test/option_tmpfs.exp
+++ b/test/root/option_tmpfs.exp
@@ -16,13 +16,9 @@ expect {
16 timeout {puts "TESTING ERROR 1\n";exit} 16 timeout {puts "TESTING ERROR 1\n";exit}
17 "total 0" 17 "total 0"
18} 18}
19expect { 19after 100
20 timeout {puts "TESTING ERROR 2\n";exit}
21 "/root"
22}
23sleep 1
24send -- "exit\r" 20send -- "exit\r"
25sleep 2 21sleep 1
26 22
27send -- "firejail --debug-check-filename --tmpfs=\"bla&&bla\"\r" 23send -- "firejail --debug-check-filename --tmpfs=\"bla&&bla\"\r"
28expect { 24expect {
@@ -40,5 +36,5 @@ expect {
40after 100 36after 100
41 37
42 38
43puts "\nalldone\n" 39puts "\nall done\n"
44 40
diff --git a/test/root/private.exp b/test/root/private.exp
new file mode 100755
index 000000000..4040081ee
--- /dev/null
+++ b/test/root/private.exp
@@ -0,0 +1,33 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --private\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Child process initialized"
14}
15sleep 2
16
17send -- "ls -l /home\r"
18expect {
19 timeout {puts "TESTING ERROR 1\n";exit}
20 "total 0"
21}
22after 100
23
24send -- "ls -l /root\r"
25expect {
26 timeout {puts "TESTING ERROR 2\n";exit}
27 "total 0"
28}
29after 100
30
31send -- "exit\r"
32after 100
33puts "\nall done\n"
diff --git a/test/root/profile_tmpfs.exp b/test/root/profile_tmpfs.exp
new file mode 100755
index 000000000..25f73b50b
--- /dev/null
+++ b/test/root/profile_tmpfs.exp
@@ -0,0 +1,40 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "firejail --profile=tmpfs.profile\r"
8expect {
9 timeout {puts "TESTING ERROR 0\n";exit}
10 "Child process initialized"
11}
12sleep 1
13
14send -- "ls -l /var;pwd\r"
15expect {
16 timeout {puts "TESTING ERROR 1\n";exit}
17 "total 0"
18}
19after 100
20send -- "exit\r"
21sleep 1
22
23send -- "firejail --debug-check-filename --profile=tmpfs-bad.profile\r"
24expect {
25 timeout {puts "TESTING ERROR 13.1\n";exit}
26 "Checking filename bla&&bla"
27}
28expect {
29 timeout {puts "TESTING ERROR 13.2\n";exit}
30 "Error:"
31}
32expect {
33 timeout {puts "TESTING ERROR 13.3\n";exit}
34 "is an invalid filename"
35}
36after 100
37
38
39puts "\nall done\n"
40
diff --git a/test/root/root.sh b/test/root/root.sh
new file mode 100755
index 000000000..494bd4fe7
--- /dev/null
+++ b/test/root/root.sh
@@ -0,0 +1,105 @@
1#!/bin/bash
2
3# set a new firejail config file
4cp firejail.config /etc/firejail/firejail.config
5
6#********************************
7# servers
8#********************************
9if [ -f /etc/init.d/snmpd ]
10then
11 echo "TESTING: snmpd (test/root/snmpd.exp)"
12 ./snmpd.exp
13else
14 echo "TESTING SKIP: snmpd not found"
15fi
16
17
18if [ -f /etc/init.d/apache2 ]
19then
20 echo "TESTING: apache2 (test/root/apache2.exp)"
21 ./apache2.exp
22else
23 echo "TESTING SKIP: apache2 not found"
24fi
25
26if [ -f /etc/init.d/isc-dhcp-server ]
27then
28 echo "TESTING: isc dhcp server (test/root/isc-dhscp.exp)"
29 ./isc-dhcp.exp
30else
31 echo "TESTING SKIP: isc dhcp server not found"
32fi
33
34if [ -f /etc/init.d/unbound ]
35then
36 echo "TESTING: unbound (test/root/unbound.exp)"
37 ./unbound.exp
38else
39 echo "TESTING SKIP: unbound not found"
40fi
41
42if [ -f /etc/init.d/nginx ]
43then
44 echo "TESTING: nginx (test/root/nginx.exp)"
45 ./nginx.exp
46else
47 echo "TESTING SKIP: nginx not found"
48fi
49
50#********************************
51# filesystem
52#********************************
53echo "TESTING: fs private (test/root/private.exp)"
54./private.exp
55
56#********************************
57# seccomp
58#********************************
59echo "TESTING: seccomp umount (test/root/seccomp-umount.exp)"
60./seccomp-umount.exp
61
62echo "TESTING: seccomp chmod (test/root/seccomp-chmod.exp)"
63./seccomp-chmod.exp
64
65echo "TESTING: seccomp chown (test/root/seccomp-chown.exp)"
66./seccomp-chown.exp
67
68#********************************
69# command line options
70#********************************
71echo "TESTING: tmpfs (test/root/option_tmpfs.exp)"
72./option_tmpfs.exp
73
74echo "TESTING: profile tmpfs (test/root/profile_tmpfs)"
75./profile_tmpfs.exp
76
77echo "TESTING: bind directory (test/root/option_bind_directory.exp)"
78./option_bind_directory.exp
79
80echo "TESTING: bind file (test/root/option_bind_file.exp)"
81echo hello > tmpfile
82./option_bind_file.exp
83rm -f tmpfile
84
85#********************************
86# firemon
87#********************************
88echo "TESTING: firemon events (test/root/firemon-events.exp)"
89./firemon-events.exp
90
91#********************************
92# firecfg
93#********************************
94which firefox
95if [ "$?" -eq 0 ];
96then
97 echo "TESTING: firecfg (test/root/firecfg.exp)"
98 ./firecfg.exp
99else
100 echo "TESTING SKIP: firecfg, firefox not found"
101fi
102
103# restore the default config file
104cp ../../etc/firejail.config /etc/firejail/firejail.config
105
diff --git a/test/root/seccomp-chmod.exp b/test/root/seccomp-chmod.exp
new file mode 100755
index 000000000..b17990e3a
--- /dev/null
+++ b/test/root/seccomp-chmod.exp
@@ -0,0 +1,51 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --seccomp=chmod,fchmod,fchmodat --private\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Child process initialized"
14}
15sleep 2
16
17send -- "cd ~; echo done\r"
18expect {
19 timeout {puts "TESTING ERROR 1\n";exit}
20 "done"
21}
22
23send -- "touch testfile; echo done\r"
24expect {
25 timeout {puts "TESTING ERROR 2\n";exit}
26 "done"
27}
28
29send -- "ls -l testfile; echo done\r"
30expect {
31 timeout {puts "TESTING ERROR 3\n";exit}
32 "testfile"
33}
34expect {
35 timeout {puts "TESTING ERROR 4\n";exit}
36 "done"
37}
38
39send -- "chmod +x testfile; echo done\r"
40expect {
41 timeout {puts "TESTING ERROR 5\n";exit}
42 "Bad system call"
43}
44expect {
45 timeout {puts "TESTING ERROR 6\n";exit}
46 "done"
47}
48
49send -- "exit\r"
50after 100
51puts "\nall done\n"
diff --git a/test/seccomp-chmod-profile.exp b/test/root/seccomp-chown.exp
index 098328cea..a54d279f1 100755
--- a/test/seccomp-chmod-profile.exp
+++ b/test/root/seccomp-chown.exp
@@ -1,10 +1,13 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
5match_max 100000 8match_max 100000
6 9
7send -- "firejail --profile=seccomp.profile --private\r" 10send -- "firejail --seccomp=chown,fchown,fchownat,lchown --private\r"
8expect { 11expect {
9 timeout {puts "TESTING ERROR 0\n";exit} 12 timeout {puts "TESTING ERROR 0\n";exit}
10 "Child process initialized" 13 "Child process initialized"
@@ -29,7 +32,7 @@ expect {
29 "/home" 32 "/home"
30} 33}
31 34
32send -- "chmod +x testfile;pwd\r" 35send -- "chown netblue:netblue testfile;pwd\r"
33expect { 36expect {
34 timeout {puts "TESTING ERROR 2\n";exit} 37 timeout {puts "TESTING ERROR 2\n";exit}
35 "Bad system call" 38 "Bad system call"
@@ -42,5 +45,5 @@ expect {
42 45
43 46
44send -- "exit\r" 47send -- "exit\r"
45sleep 1 48after 100
46puts "\n" 49puts "\nall done\n"
diff --git a/test/seccomp-umount.exp b/test/root/seccomp-umount.exp
index c0107a084..c441c5fc4 100755
--- a/test/seccomp-umount.exp
+++ b/test/root/seccomp-umount.exp
@@ -1,16 +1,13 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
5match_max 100000 8match_max 100000
6 9
7send -- "sudo ls; sudo whoami; sudo pwd\r" 10send -- "firejail --seccomp --noprofile\r"
8expect {
9 timeout {puts "TESTING ERROR: you need to root run this test as root\n";exit}
10 "root"
11}
12
13send -- "firejail --net=br0 --ip=10.10.20.5 --seccomp --noprofile\r"
14expect { 11expect {
15 timeout {puts "TESTING ERROR 0\n";exit} 12 timeout {puts "TESTING ERROR 0\n";exit}
16 "Child process initialized" 13 "Child process initialized"
@@ -24,5 +21,5 @@ expect {
24} 21}
25 22
26send -- "exit\r" 23send -- "exit\r"
27sleep 1 24after 100
28puts "\n" 25puts "\n"
diff --git a/test/servers2.exp b/test/root/snmpd.exp
index 90e34470f..610fdb13a 100755
--- a/test/servers2.exp
+++ b/test/root/snmpd.exp
@@ -4,16 +4,6 @@ set timeout 5
4spawn $env(SHELL) 4spawn $env(SHELL)
5match_max 100000 5match_max 100000
6 6
7send -- "sudo ls; sudo whoami; sudo pwd\r"
8expect {
9 timeout {puts "TESTING ERROR: you need to root run this test as root\n";exit}
10 "root"
11}
12
13send -- "pkill snmpd\r"
14sleep 2
15
16
17send -- "firejail --name=snmpd /etc/init.d/snmpd start\r" 7send -- "firejail --name=snmpd /etc/init.d/snmpd start\r"
18expect { 8expect {
19 timeout {puts "TESTING ERROR 0\n";exit} 9 timeout {puts "TESTING ERROR 0\n";exit}
diff --git a/test/root/tmpfs-bad.profile b/test/root/tmpfs-bad.profile
new file mode 100644
index 000000000..7264e18ff
--- /dev/null
+++ b/test/root/tmpfs-bad.profile
@@ -0,0 +1 @@
tmpfs bla&&bla
diff --git a/test/root/tmpfs.profile b/test/root/tmpfs.profile
new file mode 100644
index 000000000..55a6f7ebc
--- /dev/null
+++ b/test/root/tmpfs.profile
@@ -0,0 +1 @@
tmpfs /var
diff --git a/test/servers5.exp b/test/root/unbound.exp
index 193e662ff..9c496306a 100755
--- a/test/servers5.exp
+++ b/test/root/unbound.exp
@@ -4,15 +4,6 @@ set timeout 5
4spawn $env(SHELL) 4spawn $env(SHELL)
5match_max 100000 5match_max 100000
6 6
7send -- "sudo ls; sudo whoami; sudo pwd\r"
8expect {
9 timeout {puts "TESTING ERROR: you need to root run this test as root\n";exit}
10 "root"
11}
12
13send -- "pkill unbound\r"
14sleep 2
15
16send -- "firejail --name=unbound unbound\r" 7send -- "firejail --name=unbound unbound\r"
17expect { 8expect {
18 timeout {puts "TESTING ERROR 0\n";exit} 9 timeout {puts "TESTING ERROR 0\n";exit}
diff --git a/test/seccomp-errno.exp b/test/seccomp-errno.exp
deleted file mode 100755
index e6678ab8f..000000000
--- a/test/seccomp-errno.exp
+++ /dev/null
@@ -1,87 +0,0 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "touch seccomp-test-file\r"
8sleep 1
9
10send -- "firejail --seccomp.enoent=unlinkat rm seccomp-test-file\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "No such file or directory"
14}
15sleep 1
16
17send -- "firejail --seccomp.enoent=unlinkat --debug rm seccomp-test-file\r"
18expect {
19 timeout {puts "TESTING ERROR 1\n";exit}
20 "unlinkat 2 ENOENT"
21}
22sleep 1
23
24send -- "firejail --seccomp.enoent=unlinkat,mkdir\r"
25expect {
26 timeout {puts "TESTING ERROR 2\n";exit}
27 "Child process initialized"
28}
29sleep 1
30send -- "rm seccomp-test-file\r"
31expect {
32 timeout {puts "TESTING ERROR 3\n";exit}
33 "No such file or directory"
34}
35after 100
36puts "\n"
37
38send -- "mkdir seccomp-test-dir\r"
39expect {
40 timeout {puts "TESTING ERROR 4\n";exit}
41 "No such file or directory"
42}
43after 100
44puts "\n"
45
46send -- "exit\r"
47sleep 1
48
49
50send -- "firejail --seccomp.enoent=unlinkat --seccomp.enoent=mkdir\r"
51expect {
52 timeout {puts "TESTING ERROR 5\n";exit}
53 "errno enoent already configured"
54}
55sleep 1
56
57send -- "firejail --seccomp.enoent=unlinkat --seccomp.eperm=mkdir\r"
58expect {
59 timeout {puts "TESTING ERROR 6\n";exit}
60 "Child process initialized"
61}
62sleep 1
63send -- "rm seccomp-test-file\r"
64expect {
65 timeout {puts "TESTING ERROR 7\n";exit}
66 "No such file or directory"
67}
68after 100
69puts "\n"
70
71send -- "mkdir seccomp-test-dir\r"
72expect {
73 timeout {puts "TESTING ERROR 8\n";exit}
74 "Operation not permitted"
75}
76after 100
77puts "\n"
78
79send -- "exit\r"
80sleep 1
81
82
83
84
85send -- "rm seccomp-test-file\r"
86sleep 1
87puts "all done\n"
diff --git a/test/sysrq-trigger.exp b/test/sysrq-trigger.exp
deleted file mode 100755
index 18fb4a01a..000000000
--- a/test/sysrq-trigger.exp
+++ /dev/null
@@ -1,21 +0,0 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "firejail\r"
8expect {
9 timeout {puts "TESTING ERROR 0\n";exit}
10 "Child process initialized"
11}
12sleep 1
13
14send -- "echo b > /proc/sysrq-trigger\r"
15expect {
16 timeout {puts "TESTING ERROR 1\n";exit}
17 "Read-only file system"
18}
19sleep 1
20
21puts "\n"
diff --git a/test/sysutils/cpio.exp b/test/sysutils/cpio.exp
new file mode 100755
index 000000000..9755d8737
--- /dev/null
+++ b/test/sysutils/cpio.exp
@@ -0,0 +1,26 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "find /usr/share/doc/firejail | /bin/cpio -ov > firejail_t1\r"
11sleep 1
12
13send -- "find /usr/share/doc/firejail | firejail /bin/cpio -ov > firejail_t2\r"
14sleep 1
15
16send -- "diff -s firejail_t1 firejail_t2\r"
17expect {
18 timeout {puts "TESTING ERROR 1\n";exit}
19 "firejail_t1 and firejail_t2 are identical"
20}
21
22send -- "rm firejail_t*\r"
23sleep 1
24
25
26puts "\nall done\n"
diff --git a/test/sysutils/file.exp b/test/sysutils/file.exp
new file mode 100755
index 000000000..a8ad84d12
--- /dev/null
+++ b/test/sysutils/file.exp
@@ -0,0 +1,18 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "echo 'test string for firejail test' > /tmp/firejail_test.txt; firejail file /tmp/firejail_test.txt\r"
11expect {
12 timeout {puts "TESTING ERROR 1\n";exit}
13 "ASCII text"
14}
15send -- "rm /tmp/firejail_test.txt\r"
16sleep 1
17
18puts "\nall done\n"
diff --git a/test/sysutils/gzip.exp b/test/sysutils/gzip.exp
new file mode 100755
index 000000000..ab0e727de
--- /dev/null
+++ b/test/sysutils/gzip.exp
@@ -0,0 +1,26 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "/bin/gzip -c /usr/bin/firejail > firejail_t1\r"
11sleep 1
12
13send -- "firejail /bin/gzip -c /usr/bin/firejail > firejail_t2\r"
14sleep 1
15
16send -- "diff -s firejail_t1 firejail_t2\r"
17expect {
18 timeout {puts "TESTING ERROR 1\n";exit}
19 "firejail_t1 and firejail_t2 are identical"
20}
21
22send -- "rm firejail_t*\r"
23sleep 1
24
25
26puts "\nall done\n"
diff --git a/test/sysutils/less.exp b/test/sysutils/less.exp
new file mode 100755
index 000000000..720830304
--- /dev/null
+++ b/test/sysutils/less.exp
@@ -0,0 +1,20 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail less ../../Makefile.in\r"
11expect {
12 timeout {puts "TESTING ERROR 1\n";exit}
13 "MYLIBS"
14}
15expect {
16 timeout {puts "TESTING ERROR 2\n";exit}
17 "APPS"
18}
19
20puts "\nall done\n"
diff --git a/test/sysutils/strings.exp b/test/sysutils/strings.exp
new file mode 100755
index 000000000..1fd0f5dc0
--- /dev/null
+++ b/test/sysutils/strings.exp
@@ -0,0 +1,26 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "/usr/bin/strings /usr/bin/firejail > firejail_t1\r"
11sleep 1
12
13send -- "firejail /usr/bin/strings /usr/bin/firejail > firejail_t2\r"
14sleep 1
15
16send -- "diff -s firejail_t1 firejail_t2\r"
17expect {
18 timeout {puts "TESTING ERROR 1\n";exit}
19 "firejail_t1 and firejail_t2 are identical"
20}
21
22send -- "rm firejail_t*\r"
23sleep 1
24
25
26puts "\nall done\n"
diff --git a/test/sysutils/sysutils.sh b/test/sysutils/sysutils.sh
new file mode 100755
index 000000000..99939133d
--- /dev/null
+++ b/test/sysutils/sysutils.sh
@@ -0,0 +1,80 @@
1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6export MALLOC_CHECK_=3
7export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
8
9which cpio
10if [ "$?" -eq 0 ];
11then
12 echo "TESTING: cpio"
13 ./cpio.exp
14else
15 echo "TESTING SKIP: cpio not found"
16fi
17
18#which strings
19#if [ "$?" -eq 0 ];
20#then
21# echo "TESTING: strings"
22# ./strings.exp
23#else
24# echo "TESTING SKIP: strings not found"
25#fi
26
27which gzip
28if [ "$?" -eq 0 ];
29then
30 echo "TESTING: gzip"
31 ./gzip.exp
32else
33 echo "TESTING SKIP: gzip not found"
34fi
35
36which xzdec
37if [ "$?" -eq 0 ];
38then
39 echo "TESTING: xzdec"
40 ./xzdec.exp
41else
42 echo "TESTING SKIP: xzdec not found"
43fi
44
45which xz
46if [ "$?" -eq 0 ];
47then
48 echo "TESTING: xz"
49 ./xz.exp
50else
51 echo "TESTING SKIP: xz not found"
52fi
53
54which less
55if [ "$?" -eq 0 ];
56then
57 echo "TESTING: less"
58 ./less.exp
59else
60 echo "TESTING SKIP: less not found"
61fi
62
63which file
64if [ "$?" -eq 0 ];
65then
66 echo "TESTING: file"
67 ./file.exp
68else
69 echo "TESTING SKIP: file not found"
70fi
71
72which tar
73if [ "$?" -eq 0 ];
74then
75 echo "TESTING: tar"
76 ./tar.exp
77else
78 echo "TESTING SKIP: tar not found"
79fi
80
diff --git a/test/sysutils/tar.exp b/test/sysutils/tar.exp
new file mode 100755
index 000000000..f41d67d6f
--- /dev/null
+++ b/test/sysutils/tar.exp
@@ -0,0 +1,46 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail /bin/tar -cjvf firejail_t2 /usr/share/doc/firejail\r"
11expect {
12 timeout {puts "TESTING ERROR 1.1\n";exit}
13 "Error" {puts "TESTING ERROR 1.2\n";exit}
14 "/usr/share/doc/firejail/README"
15}
16after 100
17
18send -- "stat -c '|%s|' firejail_t2; uname -s\r"
19expect {
20 timeout {puts "TESTING ERROR 2.1\n";exit}
21 "|0|" {puts "TESTING ERROR 2.2\n";exit}
22 "Linux"
23}
24sleep 1
25
26send -- "firejail /bin/tar --compare --file=firejail_t2 -C / | wc\r"
27expect {
28 timeout {puts "TESTING ERROR 3.1\n";exit}
29 "This does not look like a tar archive" {puts "TESTING ERROR 3.2\n"; exit}
30 " 0 0 0"
31}
32sleep 1
33send -- "/bin/tar --compare --file=firejail_t2 -C / | wc\r"
34expect {
35 timeout {puts "TESTING ERROR 4.1\n";exit}
36 "This does not look like a tar archive" {puts "TESTING ERROR 4.2\n"; exit}
37 " 0 0 0"
38}
39sleep 1
40
41
42send -- "rm firejail_t*\r"
43sleep 1
44
45
46puts "\nall done\n"
diff --git a/test/sysutils/xz.exp b/test/sysutils/xz.exp
new file mode 100755
index 000000000..11d0e560c
--- /dev/null
+++ b/test/sysutils/xz.exp
@@ -0,0 +1,26 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "/usr/bin/xz -c /usr/bin/firejail > firejail_t1\r"
11sleep 1
12
13send -- "firejail /usr/bin/xz -c /usr/bin/firejail > firejail_t2\r"
14sleep 1
15
16send -- "diff -s firejail_t1 firejail_t2\r"
17expect {
18 timeout {puts "TESTING ERROR 1\n";exit}
19 "firejail_t1 and firejail_t2 are identical"
20}
21
22send -- "rm firejail_t*\r"
23sleep 1
24
25
26puts "\nall done\n"
diff --git a/test/sysutils/xzdec.exp b/test/sysutils/xzdec.exp
new file mode 100755
index 000000000..0ea6f5fb0
--- /dev/null
+++ b/test/sysutils/xzdec.exp
@@ -0,0 +1,29 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "/usr/bin/xz -c /usr/bin/firejail > firejail_t3\r"
11sleep 1
12
13send -- "/usr/bin/xzdec -c firejail_t3 > firejail_t1\r"
14sleep 1
15
16send -- "firejail /usr/bin/xzdec -c firejail_t3 > firejail_t2\r"
17sleep 1
18
19send -- "diff -s firejail_t1 firejail_t2\r"
20expect {
21 timeout {puts "TESTING ERROR 1\n";exit}
22 "firejail_t1 and firejail_t2 are identical"
23}
24
25send -- "rm firejail_t*\r"
26sleep 1
27
28
29puts "\nall done\n"
diff --git a/test/test-apps-x11.sh b/test/test-apps-x11.sh
deleted file mode 100755
index 6521fa2b0..000000000
--- a/test/test-apps-x11.sh
+++ /dev/null
@@ -1,29 +0,0 @@
1#!/bin/bash
2
3which firefox
4if [ "$?" -eq 0 ];
5then
6 echo "TESTING: firefox x11"
7 ./firefox-x11.exp
8else
9 echo "TESTING: firefox not found"
10fi
11
12which chromium
13if [ "$?" -eq 0 ];
14then
15 echo "TESTING: chromium x11"
16 ./chromium-x11.exp
17else
18 echo "TESTING: chromium not found"
19fi
20
21which transmission-gtk
22if [ "$?" -eq 0 ];
23then
24 echo "TESTING: transmission-gtk x11"
25 ./transmission-gtk.exp
26else
27 echo "TESTING: transmission-gtk not found"
28fi
29
diff --git a/test/test-nonet.sh b/test/test-nonet.sh
deleted file mode 100755
index 3df8b2d4e..000000000
--- a/test/test-nonet.sh
+++ /dev/null
@@ -1,44 +0,0 @@
1#!/bin/bash
2
3echo "TESTING: version"
4./option_version.exp
5
6echo "TESTING: help"
7./option_help.exp
8
9echo "TESTING: man"
10./option_man.exp
11
12echo "TESTING: list"
13./option_list.exp
14
15echo "TESTING: PID"
16./pid.exp
17
18echo "TESTING: profile no permissions"
19./profile_noperm.exp
20
21echo "TESTING: profile syntax"
22./profile_syntax.exp
23
24echo "TESTING: profile read-only"
25./profile_readonly.exp
26
27echo "TESTING: profile tmpfs"
28./profile_tmpfs.exp
29
30echo "TESTING: private"
31./private.exp `whoami`
32
33echo "TESTING: read/write /var/tmp"
34./fs_var_tmp.exp
35
36echo "TESTING: read/write /var/run"
37./fs_var_run.exp
38
39echo "TESTING: read/write /var/lock"
40./fs_var_lock.exp
41
42echo "TESTING: read/write /dev/shm"
43./fs_dev_shm.exp
44
diff --git a/test/test-profiles.sh b/test/test-profiles.sh
deleted file mode 100755
index d9142885b..000000000
--- a/test/test-profiles.sh
+++ /dev/null
@@ -1,10 +0,0 @@
1#!/bin/bash
2
3echo "TESTING: default profiles installed in /etc"
4PROFILES=`ls /etc/firejail/*.profile`
5for PROFILE in $PROFILES
6do
7 echo "TESTING: $PROFILE"
8 ./test-profile.exp $PROFILE
9done
10
diff --git a/test/test-root.sh b/test/test-root.sh
deleted file mode 100755
index 7e1a0b968..000000000
--- a/test/test-root.sh
+++ /dev/null
@@ -1,82 +0,0 @@
1#!/bin/bash
2
3./chk_config.exp
4
5echo "TESTING: tmpfs (option_tmpfs.exp)"
6./option_tmpfs.exp
7
8echo "TESTING: profile tmpfs (profile_tmpfs)"
9./profile_tmpfs.exp
10
11echo "TESTING: network interfaces (net_interface.exp)"
12./net_interface.exp
13
14echo "TESTING: chroot (fs_chroot_asroot.exp)"
15./fs_chroot_asroot.exp
16
17if [ -f /etc/init.d/snmpd ]
18then
19 echo "TESTING: servers snmpd, private-dev (servers2.exp)"
20 ./servers2.exp
21fi
22
23if [ -f /etc/init.d/apache2 ]
24then
25 echo "TESTING: servers apache2, private-dev, private-tmp (servers3.exp)"
26 ./servers3.exp
27fi
28
29if [ -f /etc/init.d/isc-dhcp-server ]
30then
31 echo "TESTING: servers isc dhcp server, private-dev (servers4.exp)"
32 ./servers4.exp
33fi
34
35if [ -f /etc/init.d/unbound ]
36then
37 echo "TESTING: servers unbound, private-dev, private-tmp (servers5.exp)"
38 ./servers5.exp
39fi
40
41if [ -f /etc/init.d/nginx ]
42then
43 echo "TESTING: servers nginx, private-dev, private-tmp (servers6.exp)"
44 ./servers6.exp
45fi
46
47echo "TESTING: /proc/sysrq-trigger reset disabled (sysrq-trigger.exp)"
48./sysrq-trigger.exp
49
50echo "TESTING: seccomp umount (seccomp-umount.exp)"
51./seccomp-umount.exp
52
53echo "TESTING: seccomp chmod (seccomp-chmod.exp)"
54./seccomp-chmod.exp
55
56echo "TESTING: seccomp chown (seccomp-chown.exp)"
57./seccomp-chown.exp
58
59echo "TESTING: bind directory (option_bind_directory.exp)"
60./option_bind_directory.exp
61
62echo "TESTING: bind file (option_bind_file.exp)"
63echo hello > tmpfile
64./option_bind_file.exp
65rm -f tmpfile
66
67echo "TESTING: firemon --interface (firemon-interface.exp)"
68./firemon-interface.exp
69
70if [ -f /sys/fs/cgroup/g1/tasks ]
71then
72 echo "TESTING: firemon --cgroup (firemon-cgroup.exp)"
73 ./firemon-cgroup.exp
74fi
75
76echo "TESTING: chroot resolv.conf (chroot-resolvconf.exp)"
77rm -f tmpfile
78touch tmpfile
79rm -f /tmp/chroot/etc/resolv.conf
80ln -s tmp /tmp/chroot/etc/resolv.conf
81./chroot-resolvconf.exp
82rm -f tmpfile
diff --git a/test/test.sh b/test/test.sh
index c6fe4f299..4b7d5bb6d 100755
--- a/test/test.sh
+++ b/test/test.sh
@@ -1,70 +1,15 @@
1#!/bin/bash 1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3./chk_config.exp 6./chk_config.exp
4 7
5./test-profiles.sh
6
7./fscheck.sh 8./fscheck.sh
8 9
9echo "TESTING: cpu.print (cpu-print.exp)"
10echo "TESTING: failing under VirtualBox where there is only one CPU"
11./cpu-print.exp
12
13echo "TESTING: bandwidth (bandwidth.exp)"
14./bandwidth.exp
15
16echo "TESTING: file transfer (ls.exp)"
17./ls.exp
18
19echo "TESTING: fs.print (fs-print.exp)"
20./fs-print.exp
21
22echo "TESTING: dns.print (dns-print.exp)"
23./dns-print.exp
24
25echo "TESTING: caps.print (caps-print.exp)"
26./caps-print.exp
27
28echo "TESTING: seccomp.print (seccomp-print.exp)"
29./seccomp-print.exp
30
31echo "TESTING: protocol.print (protocol-print.exp)"
32./protocol-print.exp
33
34echo "TESTING: sound (sound.exp)"
35./sound.exp
36
37echo "TESTING: nice (nice.exp)"
38./nice.exp
39
40echo "TESTING: tty (tty.exp)" 10echo "TESTING: tty (tty.exp)"
41./tty.exp 11./tty.exp
42 12
43echo "TESTING: protocol (protocol.exp)"
44./protocol.exp
45
46echo "TESTING: invalid filename (invalid_filename.exp)"
47./invalid_filename.exp
48
49echo "TESTING: environment variables (env.exp)"
50./env.exp
51
52echo "TESTING: whitelist empty (whitelist-empty.exp)"
53./whitelist-empty.exp
54
55echo "TESTING: ignore command (ignore.exp)"
56./ignore.exp
57
58echo "TESTING: private-etc (private-etc.exp)"
59./private-etc.exp
60
61echo "TESTING: private-bin (private-bin.exp)"
62./private-bin.exp
63
64echo "TESTING: private whitelist (private-whitelist.exp)"
65echo "TESTING: failing on OpenSUSE"
66./private-whitelist.exp
67
68sleep 1 13sleep 1
69rm -fr dir\ with\ space 14rm -fr dir\ with\ space
70mkdir dir\ with\ space 15mkdir dir\ with\ space
@@ -82,102 +27,9 @@ rm -fr auto2
82rm -fr auto3 27rm -fr auto3
83rm -fr auto4 28rm -fr auto4
84 29
85
86echo "TESTING: version (option_version.exp)"
87./option_version.exp
88
89echo "TESTING: help (option_help.exp)"
90./option_help.exp
91
92echo "TESTING: man (option_man.exp)"
93./option_man.exp
94
95echo "TESTING: list (option_list.exp)"
96./option_list.exp
97
98echo "TESTING: tree (option_tree.exp)"
99./option_tree.exp
100
101if [ -f /proc/self/uid_map ];
102then
103 echo "TESTING: noroot (noroot.exp)"
104 ./noroot.exp
105else
106 echo "TESTING: user namespaces not available"
107fi
108
109echo "TESTING: doubledash"
110mkdir -- -testdir
111touch -- -testdir/ttt
112cp -- /bin/bash -testdir/.
113./doubledash.exp
114rm -fr -- -testdir
115
116echo "TESTING: trace1 (option-trace.exp)"
117./option-trace.exp
118
119echo "TESTING: trace2 (trace.exp)"
120rm -f index.html*
121./trace.exp
122rm -f index.html*
123
124echo "TESTING: extract command (extract_command.exp)"
125./extract_command.exp
126
127echo "TESTING: kmsg access (kmsg.exp)"
128./kmsg.exp
129
130echo "TESTING: rlimit (option_rlimit.exp)"
131./option_rlimit.exp
132
133echo "TESTING: shutdown (option_shutdown.exp)"
134./option-shutdown.exp
135
136echo "TESTING: shutdown2 (option_shutdown2.exp)"
137./option-shutdown2.exp
138
139echo "TESTING: shutdown3 (option_shutdown3.exp)"
140./option-shutdown3.exp
141
142echo "TESTING: shutdown4 (option_shutdown4.exp)"
143./option-shutdown4.exp
144
145echo "TESTING: join (option-join.exp)"
146./option-join.exp
147
148echo "TESTING: join2 (option-join2.exp)"
149./option-join2.exp
150
151echo "TESTING: join3 (option-join3.exp)"
152./option-join3.exp
153
154echo "TESTING: join profile (option-join-profile.exp)"
155./option-join-profile.exp
156
157echo "TESTING: firejail in firejail - single sandbox (firejail-in-firejail.exp)"
158./firejail-in-firejail.exp
159
160echo "TESTING: firejail in firejail - force new sandbox (firejail-in-firejail2.exp)"
161./firejail-in-firejail2.exp
162
163echo "TESTING: chroot overlay (option_chroot_overlay.exp)" 30echo "TESTING: chroot overlay (option_chroot_overlay.exp)"
164./option_chroot_overlay.exp 31./option_chroot_overlay.exp
165 32
166echo "TESTING: blacklist directory (option_blacklist.exp)"
167./option_blacklist.exp
168
169echo "TESTING: blacklist file (opiton_blacklist_file.exp)"
170./option_blacklist_file.exp
171
172echo "TESTING: bind as user (option_bind_user.exp)"
173./option_bind_user.exp
174
175if [ -d /home/bingo ];
176then
177 echo "TESTING: home sanitize (opiton_version.exp)"
178 ./option_version.exp
179fi
180
181echo "TESTING: chroot as user (fs_chroot.exp)" 33echo "TESTING: chroot as user (fs_chroot.exp)"
182./fs_chroot.exp 34./fs_chroot.exp
183 35
@@ -190,47 +42,7 @@ ls -al > tmpreadonly
190sleep 5 42sleep 5
191rm -f tmpreadonly 43rm -f tmpreadonly
192 44
193echo "TESTING: zsh (shell_zsh.exp)"
194./shell_zsh.exp
195
196echo "TESTING: csh (shell_csh.exp)"
197./shell_csh.exp
198
199which dash
200if [ "$?" -eq 0 ];
201then
202 echo "TESTING: dash (shell_dash.exp)"
203 ./shell_dash.exp
204else
205 echo "TESTING: dash not found"
206fi
207
208./test-apps.sh
209./test-apps-x11.sh
210
211echo "TESTING: PID (pid.exp)"
212./pid.exp
213
214echo "TESTING: output (output.exp)"
215./output.exp
216
217echo "TESTING: profile no permissions (profile_noperm.exp)"
218./profile_noperm.exp
219
220echo "TESTING: profile syntax (profile_syntax.exp)"
221./profile_syntax.exp
222
223echo "TESTING: profile syntax 2 (profile_syntax2.exp)"
224./profile_syntax2.exp
225
226echo "TESTING: profile rlimit (profile_rlimit.exp)"
227./profile_rlimit.exp
228 45
229echo "TESTING: profile read-only (profile_readonly.exp)"
230./profile_readonly.exp
231
232echo "TESTING: private (private.exp)"
233./private.exp `whoami`
234 46
235echo "TESTING: private directory (private_dir.exp)" 47echo "TESTING: private directory (private_dir.exp)"
236rm -fr dirprivate 48rm -fr dirprivate
@@ -247,113 +59,13 @@ rm -fr dirprivate
247echo "TESTING: overlayfs (fs_overlay.exp)" 59echo "TESTING: overlayfs (fs_overlay.exp)"
248./fs_overlay.exp 60./fs_overlay.exp
249 61
250echo "TESTING: seccomp debug (seccomp-debug.exp)"
251./seccomp-debug.exp
252
253echo "TESTING: seccomp errno (seccomp-errno.exp)"
254./seccomp-errno.exp
255
256echo "TESTING: seccomp su (seccomp-su.exp)"
257./seccomp-su.exp
258
259echo "TESTING: seccomp ptrace (seccomp-ptrace.exp)"
260./seccomp-ptrace.exp
261
262echo "TESTING: seccomp chmod - seccomp lists (seccomp-chmod.exp)"
263./seccomp-chmod.exp
264
265echo "TESTING: seccomp chmod profile - seccomp lists (seccomp-chmod-profile.exp)"
266./seccomp-chmod-profile.exp
267
268echo "TESTING: seccomp empty (seccomp-empty.exp)"
269./seccomp-empty.exp
270
271echo "TESTING: seccomp bad empty (seccomp-bad-empty.exp)"
272./seccomp-bad-empty.exp
273
274echo "TESTING: seccomp dual filter (seccomp-dualfilter.exp)"
275./seccomp-dualfilter.exp
276
277echo "TESTING: read/write /var/tmp (fs_var_tmp.exp)"
278./fs_var_tmp.exp
279
280echo "TESTING: read/write /var/lock (fs_var_lock.exp)"
281./fs_var_lock.exp
282
283echo "TESTING: read/write /dev/shm (fs_dev_shm.exp)"
284./fs_dev_shm.exp
285
286echo "TESTING: quiet (quiet.exp)"
287./quiet.exp
288
289echo "TESTING: IPv6 support (ip6.exp)"
290echo "TESTING: broken on Centos - todo"
291./ip6.exp
292
293echo "TESTING: local network (net_local.exp)"
294./net_local.exp
295
296echo "TESTING: no network (net_none.exp)"
297./net_none.exp
298
299echo "TESTING: network IP (net_ip.exp)"
300./net_ip.exp
301
302echo "TESTING: network MAC (net_mac.exp)"
303sleep 2
304./net_mac.exp
305
306echo "TESTING: network MTU (net_mtu.exp)"
307./net_mtu.exp
308
309echo "TESTING: network hostname (hostname.exp)"
310./hostname.exp
311
312echo "TESTING: network bad IP (net_badip.exp)"
313./net_badip.exp
314
315echo "TESTING: network no IP test 1 (net_noip.exp)"
316./net_noip.exp
317
318echo "TESTING: network no IP test 2 (net_noip2.exp)"
319./net_noip2.exp
320
321echo "TESTING: network default gateway test 1 (net_defaultgw.exp)"
322./net_defaultgw.exp
323
324echo "TESTING: network default gateway test 2 (net_defaultgw2.exp)"
325./net_defaultgw2.exp
326
327echo "TESTING: network default gateway test 3 (net_defaultgw3.exp)"
328./net_defaultgw3.exp
329
330echo "TESTING: netfilter (net_netfilter.exp)"
331./net_netfilter.exp
332
333echo "TESTING: 4 bridges ARP (4bridges_arp.exp)"
334./4bridges_arp.exp
335
336echo "TESTING: 4 bridges IP (4bridges_ip.exp)"
337./4bridges_ip.exp
338
339echo "TESTING: login SSH (login_ssh.exp)" 62echo "TESTING: login SSH (login_ssh.exp)"
340./login_ssh.exp 63./login_ssh.exp
341 64
342echo "TESTING: ARP (net_arp.exp)"
343./net_arp.exp
344
345echo "TESTING: DNS (dns.exp)"
346./dns.exp
347
348echo "TESTING: firemon --arp (firemon-arp.exp)" 65echo "TESTING: firemon --arp (firemon-arp.exp)"
349./firemon-arp.exp 66./firemon-arp.exp
350 67
351echo "TESTING: firemon --route (firemon-route.exp)" 68echo "TESTING: firemon --route (firemon-route.exp)"
352./firemon-route.exp 69./firemon-route.exp
353 70
354echo "TESTING: firemon --seccomp (firemon-seccomp.exp)"
355./firemon-seccomp.exp
356
357echo "TESTING: firemon --caps (firemon-caps.exp)"
358./firemon-caps.exp
359 71
diff --git a/test/tmpfs.profile b/test/tmpfs.profile
deleted file mode 100644
index 0680f4d69..000000000
--- a/test/tmpfs.profile
+++ /dev/null
@@ -1 +0,0 @@
1tmpfs /tmp/firejailtestdir \ No newline at end of file
diff --git a/test/caps-print.exp b/test/utils/caps-print.exp
index 39e5ec50a..fa5239da2 100755
--- a/test/caps-print.exp
+++ b/test/utils/caps-print.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -25,5 +28,5 @@ expect {
25 timeout {puts "TESTING ERROR 3\n";exit} 28 timeout {puts "TESTING ERROR 3\n";exit}
26 "net_raw - disabled" 29 "net_raw - disabled"
27} 30}
28sleep 1 31after 100
29puts "\nall done\n" 32puts "\nall done\n"
diff --git a/test/caps1.profile b/test/utils/caps1.profile
index e14655b2e..e14655b2e 100644
--- a/test/caps1.profile
+++ b/test/utils/caps1.profile
diff --git a/test/caps2.profile b/test/utils/caps2.profile
index cb2258c52..cb2258c52 100644
--- a/test/caps2.profile
+++ b/test/utils/caps2.profile
diff --git a/test/catchsignal-master.sh b/test/utils/catchsignal-master.sh
index 62a1801cc..62a1801cc 100755
--- a/test/catchsignal-master.sh
+++ b/test/utils/catchsignal-master.sh
diff --git a/test/catchsignal.sh b/test/utils/catchsignal.sh
index 87a1d0adf..87a1d0adf 100755
--- a/test/catchsignal.sh
+++ b/test/utils/catchsignal.sh
diff --git a/test/catchsignal2.sh b/test/utils/catchsignal2.sh
index 424350397..424350397 100755
--- a/test/catchsignal2.sh
+++ b/test/utils/catchsignal2.sh
diff --git a/test/cpu-print.exp b/test/utils/cpu-print.exp
index d8e3fbb04..ca2e57313 100755
--- a/test/cpu-print.exp
+++ b/test/utils/cpu-print.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -17,5 +20,5 @@ expect {
17 timeout {puts "TESTING ERROR 1\n";exit} 20 timeout {puts "TESTING ERROR 1\n";exit}
18 "Cpus_allowed_list: 1-2" 21 "Cpus_allowed_list: 1-2"
19} 22}
20sleep 1 23after 100
21puts "\nall done\n" 24puts "\nall done\n"
diff --git a/test/dns-print.exp b/test/utils/dns-print.exp
index ee7b08e5e..406ab5149 100755
--- a/test/dns-print.exp
+++ b/test/utils/dns-print.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -17,5 +20,5 @@ expect {
17 timeout {puts "TESTING ERROR 1\n";exit} 20 timeout {puts "TESTING ERROR 1\n";exit}
18 "nameserver 1.2.3.4" 21 "nameserver 1.2.3.4"
19} 22}
20sleep 1 23after 100
21puts "\nall done\n" 24puts "\nall done\n"
diff --git a/test/firemon-caps.exp b/test/utils/firemon-caps.exp
index 3dd6384db..76aa13725 100755
--- a/test/firemon-caps.exp
+++ b/test/utils/firemon-caps.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -63,6 +66,7 @@ spawn $env(SHELL)
63send -- "firemon --caps\r" 66send -- "firemon --caps\r"
64expect { 67expect {
65 timeout {puts "TESTING ERROR 8.1\n";exit} 68 timeout {puts "TESTING ERROR 8.1\n";exit}
69 "need to be root" {puts "TESTING SKIP: /proc mounted as hidepid\n"; exit}
66 "bingo1" 70 "bingo1"
67} 71}
68expect { 72expect {
diff --git a/test/utils/firemon-cgroup.exp b/test/utils/firemon-cgroup.exp
new file mode 100755
index 000000000..b1ab083ae
--- /dev/null
+++ b/test/utils/firemon-cgroup.exp
@@ -0,0 +1,41 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --name=test1\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Child process initialized"
14}
15sleep 1
16
17spawn $env(SHELL)
18send -- "firejail --name=test2\r"
19expect {
20 timeout {puts "TESTING ERROR 1\n";exit}
21 "Child process initialized"
22}
23sleep 1
24
25spawn $env(SHELL)
26send -- "firemon --cgroup\r"
27sleep 4
28expect {
29 timeout {puts "TESTING ERROR 2\n";exit}
30 "need to be root" {puts "TESTING SKIP: /proc mounted as hidepid\n"; exit}
31 "name=test1"
32}
33expect {
34 timeout {puts "TESTING ERROR 3\n";exit}
35 "name=test2"
36}
37
38after 100
39
40puts "\nall done\n"
41
diff --git a/test/seccomp-dualfilter.exp b/test/utils/firemon-cpu.exp
index afdf8a53a..f2ecd4a5c 100755
--- a/test/seccomp-dualfilter.exp
+++ b/test/utils/firemon-cpu.exp
@@ -1,38 +1,45 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
5match_max 100000 8match_max 100000
6 9
7send -- "firejail ../src/tools/syscall_test mount\r" 10send -- "firejail --name=test1\r"
8expect { 11expect {
9 timeout {puts "TESTING ERROR 0\n";exit} 12 timeout {puts "TESTING ERROR 0\n";exit}
10 "Child process initialized" 13 "Child process initialized"
11} 14}
15sleep 1
16
17spawn $env(SHELL)
18send -- "firejail --name=test2\r"
12expect { 19expect {
13 timeout {puts "TESTING ERROR 1\n";exit} 20 timeout {puts "TESTING ERROR 1\n";exit}
14 "before mount" 21 "Child process initialized"
15} 22}
23sleep 1
24
25spawn $env(SHELL)
26send -- "firemon --cpu\r"
27sleep 4
16expect { 28expect {
17 timeout {puts "TESTING ERROR 2\n";exit} 29 timeout {puts "TESTING ERROR 2\n";exit}
18 "after mount" {puts "TESTING ERROR 2.1\n";exit} 30 "need to be root" {puts "TESTING SKIP: /proc mounted as hidepid\n"; exit}
19 "Parent is shutting down" 31 "name=test1"
20} 32}
21sleep 1
22
23send -- "firejail ../src/tools/syscall_test32 mount\r"
24expect { 33expect {
25 timeout {puts "TESTING ERROR 3\n";exit} 34 timeout {puts "TESTING ERROR 3\n";exit}
26 "Child process initialized" 35 "Cpus_allowed_list"
27} 36}
28expect { 37expect {
29 timeout {puts "TESTING ERROR 4\n";exit} 38 timeout {puts "TESTING ERROR 4\n";exit}
30 "before mount" 39 "name=test2"
31}
32expect {
33 timeout {puts "TESTING ERROR 5\n";exit}
34 "after mount" {puts "TESTING ERROR 5.1\n";exit}
35 "Parent is shutting down"
36} 40}
37 41
42after 100
43
38puts "\nall done\n" 44puts "\nall done\n"
45
diff --git a/test/firemon-seccomp.exp b/test/utils/firemon-seccomp.exp
index 55817faf3..26c478344 100755
--- a/test/firemon-seccomp.exp
+++ b/test/utils/firemon-seccomp.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -26,6 +29,7 @@ spawn $env(SHELL)
26send -- "firemon --seccomp\r" 29send -- "firemon --seccomp\r"
27expect { 30expect {
28 timeout {puts "TESTING ERROR 1\n";exit} 31 timeout {puts "TESTING ERROR 1\n";exit}
32 "need to be root" {puts "TESTING SKIP: /proc mounted as hidepid\n"; exit}
29 "bingo1" 33 "bingo1"
30} 34}
31expect { 35expect {
@@ -37,7 +41,7 @@ expect {
37 "bingo2" 41 "bingo2"
38} 42}
39expect { 43expect {
40 timeout {puts "TESTING ERROR 3\n";exit} 44 timeout {puts "TESTING ERROR 4\n";exit}
41 "Seccomp: 0" 45 "Seccomp: 0"
42} 46}
43after 100 47after 100
diff --git a/test/fs-print.exp b/test/utils/fs-print.exp
index 48056a3bf..4d4ceb718 100755
--- a/test/fs-print.exp
+++ b/test/utils/fs-print.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -25,5 +28,5 @@ expect {
25 timeout {puts "TESTING ERROR 3\n";exit} 28 timeout {puts "TESTING ERROR 3\n";exit}
26 "blacklist /proc/kmsg" 29 "blacklist /proc/kmsg"
27} 30}
28sleep 1 31after 100
29puts "\nall done\n" 32puts "\nall done\n"
diff --git a/test/option_help.exp b/test/utils/help.exp
index f4518219c..5b9864578 100755
--- a/test/option_help.exp
+++ b/test/utils/help.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
diff --git a/test/firemon-interface.exp b/test/utils/join-profile.exp
index 6a82ae41e..a2078c2f6 100755
--- a/test/firemon-interface.exp
+++ b/test/utils/join-profile.exp
@@ -4,31 +4,32 @@ set timeout 10
4spawn $env(SHELL) 4spawn $env(SHELL)
5match_max 100000 5match_max 100000
6 6
7send -- "firejail\r" 7
8send -- "firejail --profile=name.profile\r"
8expect { 9expect {
9 timeout {puts "TESTING ERROR 0\n";exit} 10 timeout {puts "TESTING ERROR 0\n";exit}
10 "Child process initialized" 11 "Child process initialized"
11} 12}
12sleep 1 13sleep 2
13 14
14spawn $env(SHELL) 15spawn $env(SHELL)
15send -- "firemon --interface\r" 16send -- "firejail --join=jointesting\r"
16expect { 17expect {
17 timeout {puts "TESTING ERROR 1\n";exit} 18 timeout {puts "TESTING ERROR 1\n";exit}
18 "lo UP" 19 "Switching to pid"
19} 20}
21sleep 1
22send -- "ps aux\r"
20expect { 23expect {
21 timeout {puts "TESTING ERROR 2\n";exit} 24 timeout {puts "TESTING ERROR 2\n";exit}
22 "10.10.20.1/29" 25 "/bin/bash"
23}
24expect {
25 timeout {puts "TESTING ERROR 3\n";exit}
26 "10.10.50.1/24"
27} 26}
28expect { 27expect {
29 timeout {puts "TESTING ERROR 3\n";exit} 28 timeout {puts "TESTING ERROR 3\n";exit}
30 "br3" 29 "/bin/bash"
31} 30}
32sleep 1
33 31
34puts "\n" 32send -- "exit"
33after 100
34
35puts "\nall done\n"
diff --git a/test/utils/join.exp b/test/utils/join.exp
new file mode 100755
index 000000000..fc30bc6a4
--- /dev/null
+++ b/test/utils/join.exp
@@ -0,0 +1,38 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7cd /home
8spawn $env(SHELL)
9match_max 100000
10
11send -- "firejail --name=jointesting --cpu=0 --nice=2\r"
12expect {
13 timeout {puts "TESTING ERROR 0\n";exit}
14 "Child process initialized"
15}
16sleep 2
17
18spawn $env(SHELL)
19send -- "firejail --join=jointesting\r"
20expect {
21 timeout {puts "TESTING ERROR 1\n";exit}
22 "Switching to pid"
23}
24sleep 1
25send -- "ps aux\r"
26expect {
27 timeout {puts "TESTING ERROR 2\n";exit}
28 "/bin/bash"
29}
30expect {
31 timeout {puts "TESTING ERROR 3\n";exit}
32 "/bin/bash"
33}
34
35send -- "exit"
36after 100
37
38puts "\nall done\n"
diff --git a/test/option-join-profile.exp b/test/utils/join2.exp
index 9200980a1..5895eb730 100755
--- a/test/option-join-profile.exp
+++ b/test/utils/join2.exp
@@ -1,39 +1,38 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
7cd /home
4spawn $env(SHELL) 8spawn $env(SHELL)
5match_max 100000 9match_max 100000
6 10
7send -- "firejail --profile=name.profile\r" 11send -- "firejail --name=\"join testing\"\r"
8expect { 12expect {
9 timeout {puts "TESTING ERROR 0\n";exit} 13 timeout {puts "TESTING ERROR 0\n";exit}
10 "Child process initialized" 14 "Child process initialized"
11} 15}
12sleep 3 16sleep 2
13 17
14spawn $env(SHELL) 18spawn $env(SHELL)
15send -- "firejail --join=jointesting;pwd\r" 19send -- "firejail --join=\"join testing\"\r"
16expect { 20expect {
17 timeout {puts "TESTING ERROR 1\n";exit} 21 timeout {puts "TESTING ERROR 1\n";exit}
18 "Switching to pid" 22 "Switching to pid"
19} 23}
20sleep 3 24sleep 1
21 25send -- "ps aux\r"
22
23spawn $env(SHELL)
24send -- "firejail --shutdown=jointesting;pwd\r"
25expect { 26expect {
26 timeout {puts "TESTING ERROR 3\n";exit} 27 timeout {puts "TESTING ERROR 2\n";exit}
27 "home" 28 "/bin/bash"
28} 29}
29sleep 5
30
31send -- "firejail --list;pwd\r"
32expect { 30expect {
33 timeout {puts "TESTING ERROR 4\n";exit} 31 timeout {puts "TESTING ERROR 3\n";exit}
34 "jointesting" {puts "TESTING ERROR 5\n";exit} 32 "/bin/bash"
35 "home"
36} 33}
37sleep 1 34
35send -- "exit"
36after 100
38 37
39puts "\nall done\n" 38puts "\nall done\n"
diff --git a/test/option-join.exp b/test/utils/join3.exp
index 6250e87a2..3ccc47bf9 100755
--- a/test/option-join.exp
+++ b/test/utils/join3.exp
@@ -1,39 +1,38 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
7cd /home
4spawn $env(SHELL) 8spawn $env(SHELL)
5match_max 100000 9match_max 100000
6 10
7send -- "firejail --name=svntesting\r" 11send -- "firejail --name=join\\ testing\r"
8expect { 12expect {
9 timeout {puts "TESTING ERROR 0\n";exit} 13 timeout {puts "TESTING ERROR 0\n";exit}
10 "Child process initialized" 14 "Child process initialized"
11} 15}
12sleep 3 16sleep 2
13 17
14spawn $env(SHELL) 18spawn $env(SHELL)
15send -- "firejail --join=svntesting;pwd\r" 19send -- "firejail --join=join\\ testing\r"
16expect { 20expect {
17 timeout {puts "TESTING ERROR 1\n";exit} 21 timeout {puts "TESTING ERROR 1\n";exit}
18 "Switching to pid" 22 "Switching to pid"
19} 23}
20sleep 1 24sleep 1
21 25send -- "ps aux\r"
22
23spawn $env(SHELL)
24send -- "firejail --shutdown=svntesting;pwd\r"
25expect { 26expect {
26 timeout {puts "TESTING ERROR 3\n";exit} 27 timeout {puts "TESTING ERROR 2\n";exit}
27 "home" 28 "/bin/bash"
28} 29}
29sleep 1
30
31send -- "firejail --list;pwd\r"
32expect { 30expect {
33 timeout {puts "TESTING ERROR 4\n";exit} 31 timeout {puts "TESTING ERROR 3\n";exit}
34 "svntesting" {puts "TESTING ERROR 5\n";exit} 32 "/bin/bash"
35 "home"
36} 33}
37sleep 1 34
35send -- "exit"
36after 100
38 37
39puts "\nall done\n" 38puts "\nall done\n"
diff --git a/test/firemon-arp.exp b/test/utils/join4.exp
index 3fc8c2aee..c367dd770 100755
--- a/test/firemon-arp.exp
+++ b/test/utils/join4.exp
@@ -1,34 +1,38 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
7cd /home
4spawn $env(SHELL) 8spawn $env(SHELL)
5match_max 100000 9match_max 100000
6 10
7send -- "ping -c 3 192.168.1.1\r" 11send -- "firejail --name=123test\r"
8expect { 12expect {
9 timeout {puts "TESTING ERROR 0\n";exit} 13 timeout {puts "TESTING ERROR 0\n";exit}
10 "3 packets transmitted" 14 "Child process initialized"
11} 15}
12sleep 1 16sleep 2
13 17
14send -- "firejail\r" 18spawn $env(SHELL)
19send -- "firejail --join=123test\r"
15expect { 20expect {
16 timeout {puts "TESTING ERROR 1\n";exit} 21 timeout {puts "TESTING ERROR 1\n";exit}
17 "Child process initialized" 22 "Switching to pid"
18} 23}
19sleep 1 24sleep 1
20 25send -- "ps aux\r"
21spawn $env(SHELL)
22send -- "firemon --arp\r"
23expect { 26expect {
24 timeout {puts "TESTING ERROR 2\n";exit} 27 timeout {puts "TESTING ERROR 2\n";exit}
25 "192.168.1.1 dev eth0 lladdr" {puts "Debian testing\n";} 28 "/bin/bash"
26 "192.168.1.1 dev enp0s3 lladdr" {puts "Centos 7 testing\n";}
27} 29}
28expect { 30expect {
29 timeout {puts "TESTING ERROR 3\n";exit} 31 timeout {puts "TESTING ERROR 3\n";exit}
30 "REACHABLE" 32 "/bin/bash"
31} 33}
32sleep 1
33 34
34puts "\n" 35send -- "exit"
36after 100
37
38puts "\nall done\n"
diff --git a/test/option_list.exp b/test/utils/list.exp
index b9c73e52b..69db1f568 100755
--- a/test/option_list.exp
+++ b/test/utils/list.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
diff --git a/test/ls.exp b/test/utils/ls.exp
index 5fe6d79c6..ff6867c51 100755
--- a/test/ls.exp
+++ b/test/utils/ls.exp
@@ -3,6 +3,8 @@
3set timeout 10 3set timeout 10
4spawn $env(SHELL) 4spawn $env(SHELL)
5match_max 100000 5match_max 100000
6set firstspawn $spawn_id
7
6 8
7send -- "rm -f lstesting\r" 9send -- "rm -f lstesting\r"
8sleep 1 10sleep 1
@@ -11,11 +13,11 @@ expect {
11 timeout {puts "TESTING ERROR 0\n";exit} 13 timeout {puts "TESTING ERROR 0\n";exit}
12 "Child process initialized" 14 "Child process initialized"
13} 15}
14sleep 2 16sleep 1
15send -- "echo my_testing > lstesting\r" 17send -- "echo my_testing > ~/lstesting\r"
16sleep 2 18after 100
17
18 19
20# ls
19spawn $env(SHELL) 21spawn $env(SHELL)
20send -- "firejail --ls=test ~/.\r" 22send -- "firejail --ls=test ~/.\r"
21expect { 23expect {
@@ -23,19 +25,45 @@ expect {
23 "lstesting" 25 "lstesting"
24} 26}
25sleep 1 27sleep 1
28
29# get
26send -- "firejail --get=test ~/lstesting\r" 30send -- "firejail --get=test ~/lstesting\r"
27expect {
28 timeout {puts "TESTING ERROR 1\n";exit}
29 "lstesting"
30}
31sleep 1 31sleep 1
32send -- "cat lstesting\r" 32send -- "cat lstesting\r"
33expect { 33expect {
34 timeout {puts "TESTING ERROR 1\n";exit} 34 timeout {puts "TESTING ERROR 2n";exit}
35 "my_testing" 35 "my_testing"
36} 36}
37after 100
38
39# put
40send -- "echo put_test > ~/lstesting\r"
41after 100
42send -- "firejail --put=test ~/lstesting ~/lstesting_2\r"
37sleep 1 43sleep 1
38send -- "rm -f lstesting\r"
39 44
45set spawn_id $firstspawn
46send -- "ls -al ~\r"
47expect {
48 timeout {puts "TESTING ERROR 3\n";exit}
49 "lstesting_2"
50}
51
52after 100
53send -- "cat ~/lstesting_2\r"
54expect {
55 timeout {puts "TESTING ERROR 4\n";exit}
56 "put_test"
57}
58after 100
59send -- "exit\r"
40sleep 1 60sleep 1
61
62
63
64
65
66send -- "rm -f lstesting\r"
67
68after 100
41puts "\nall done\n" 69puts "\nall done\n"
diff --git a/test/option_man.exp b/test/utils/man.exp
index d941a2432..d29f760b0 100755
--- a/test/option_man.exp
+++ b/test/utils/man.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
diff --git a/test/name.profile b/test/utils/name.profile
index 1aa9f2d64..1aa9f2d64 100644
--- a/test/name.profile
+++ b/test/utils/name.profile
diff --git a/test/protocol-print.exp b/test/utils/protocol-print.exp
index 4d1ae34d6..b4b94ea93 100755
--- a/test/protocol-print.exp
+++ b/test/utils/protocol-print.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -17,5 +20,5 @@ expect {
17 timeout {puts "TESTING ERROR 1\n";exit} 20 timeout {puts "TESTING ERROR 1\n";exit}
18 "unix,inet,inet6" 21 "unix,inet,inet6"
19} 22}
20sleep 1 23after 100
21puts "\nall done\n" 24puts "\nall done\n"
diff --git a/test/seccomp-print.exp b/test/utils/seccomp-print.exp
index b4e6ed35e..f6ff1e721 100755
--- a/test/seccomp-print.exp
+++ b/test/utils/seccomp-print.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -29,5 +32,5 @@ expect {
29 timeout {puts "TESTING ERROR 4\n";exit} 32 timeout {puts "TESTING ERROR 4\n";exit}
30 "RETURN_ALLOW" 33 "RETURN_ALLOW"
31} 34}
32sleep 1 35after 100
33puts "\nall done\n" 36puts "\nall done\n"
diff --git a/test/option-shutdown.exp b/test/utils/shutdown.exp
index e869f7611..15a9a62c8 100755
--- a/test/option-shutdown.exp
+++ b/test/utils/shutdown.exp
@@ -1,6 +1,10 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
7cd /home
4spawn $env(SHELL) 8spawn $env(SHELL)
5match_max 100000 9match_max 100000
6 10
@@ -9,22 +13,23 @@ expect {
9 timeout {puts "TESTING ERROR 0\n";exit} 13 timeout {puts "TESTING ERROR 0\n";exit}
10 "Child process initialized" 14 "Child process initialized"
11} 15}
12sleep 3 16sleep 2
13 17
14spawn $env(SHELL) 18spawn $env(SHELL)
15send -- "firejail --shutdown=shutdowntesting;pwd\r" 19send -- "firejail --shutdown=shutdowntesting; echo done\r"
16expect { 20expect {
17 timeout {puts "TESTING ERROR 4\n";exit} 21 timeout {puts "TESTING ERROR 4\n";exit}
18 "home" 22 "done"
19} 23}
20sleep 1 24sleep 5
21 25
22send -- "firejail --list;pwd\r" 26spawn $env(SHELL)
27send -- "firejail --list;echo done\r"
23expect { 28expect {
24 timeout {puts "TESTING ERROR 5\n";exit} 29 timeout {puts "TESTING ERROR 5\n";exit}
25 "shutdowntesting" {puts "TESTING ERROR 6\n";exit} 30 "shutdowntesting" {puts "TESTING ERROR 6\n";exit}
26 "home" 31 "done"
27} 32}
28sleep 1 33sleep 1
29 34
30puts "\nalldone\n" 35puts "\nall done\n"
diff --git a/test/option-shutdown2.exp b/test/utils/shutdown2.exp
index 403bc30be..777a73ec9 100755
--- a/test/option-shutdown2.exp
+++ b/test/utils/shutdown2.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -37,6 +40,6 @@ expect {
37 timeout {puts "TESTING ERROR 5\n";exit} 40 timeout {puts "TESTING ERROR 5\n";exit}
38 "5" 41 "5"
39} 42}
40sleep 1 43after 100
41 44
42puts "\nalldone\n" 45puts "\nalldone\n"
diff --git a/test/option-shutdown3.exp b/test/utils/shutdown3.exp
index 0ef371cd8..a74fb3386 100755
--- a/test/option-shutdown3.exp
+++ b/test/utils/shutdown3.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -57,6 +60,6 @@ expect {
57 timeout {puts "TESTING ERROR 10\n";exit} 60 timeout {puts "TESTING ERROR 10\n";exit}
58 "5" 61 "5"
59} 62}
60sleep 1 63after 100
61 64
62puts "\nalldone\n" 65puts "\nalldone\n"
diff --git a/test/option-shutdown4.exp b/test/utils/shutdown4.exp
index f188ec66d..2942ba3d5 100755
--- a/test/option-shutdown4.exp
+++ b/test/utils/shutdown4.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -57,10 +60,6 @@ expect {
57 timeout {puts "TESTING ERROR 50\n";exit} 60 timeout {puts "TESTING ERROR 50\n";exit}
58 "50" 61 "50"
59} 62}
60expect { 63after 100
61 timeout {puts "TESTING ERROR 60\n";exit}
62 "Killed"
63}
64sleep 1
65 64
66puts "\nalldone\n" 65puts "\nalldone\n"
diff --git a/test/utils/top.exp b/test/utils/top.exp
new file mode 100755
index 000000000..d530e5a85
--- /dev/null
+++ b/test/utils/top.exp
@@ -0,0 +1,40 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --name=test1\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Child process initialized"
14}
15sleep 1
16
17spawn $env(SHELL)
18send -- "firejail --name=test2\r"
19expect {
20 timeout {puts "TESTING ERROR 1\n";exit}
21 "Child process initialized"
22}
23sleep 1
24
25spawn $env(SHELL)
26send -- "firejail --top\r"
27sleep 4
28expect {
29 timeout {puts "TESTING ERROR 2\n";exit}
30 "name=test1"
31}
32expect {
33 timeout {puts "TESTING ERROR 2\n";exit}
34 "name=test2"
35}
36
37after 100
38
39puts "\nall done\n"
40
diff --git a/test/trace.exp b/test/utils/trace.exp
index 21dd6a559..78a04b273 100755
--- a/test/trace.exp
+++ b/test/utils/trace.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 30 6set timeout 30
4spawn $env(SHELL) 7spawn $env(SHELL)
@@ -76,6 +79,7 @@ expect {
76 timeout {puts "TESTING ERROR 8.6\n";exit} 79 timeout {puts "TESTING ERROR 8.6\n";exit}
77 "wget:fopen64 index.html" {puts "OK\n";} 80 "wget:fopen64 index.html" {puts "OK\n";}
78 "wget:fopen index.html" {puts "OK\n";} 81 "wget:fopen index.html" {puts "OK\n";}
82 "Parent is shutting down" {puts "OK\n";}
79} 83}
80sleep 1 84sleep 1
81 85
@@ -86,9 +90,26 @@ expect {
86} 90}
87expect { 91expect {
88 timeout {puts "TESTING ERROR 10\n";exit} 92 timeout {puts "TESTING ERROR 10\n";exit}
89 "rm:unlinkat index.html" 93 "rm:unlinkat index.html" {puts "OK\n";}
94 "Parent is shutting down" {puts "OK\n";}
90} 95}
91sleep 1 96sleep 1
92 97
98send -- "firejail --trace\r"
99expect {
100 timeout {puts "TESTING ERROR 11\n";exit}
101 "Child process initialized"
102}
103expect {
104 timeout {puts "TESTING ERROR 12\n";exit}
105 "bash:open /dev/tty" {puts "64bit\n"}
106 "bash:open64 /dev/tty" {puts "32bit\n"}
107}
108expect {
109 timeout {puts "TESTING ERROR 13\n";exit}
110 "bash:access /etc/terminfo/" {puts "debian\n"}
111 "bash:access /usr/share/terminfo/" {puts "arch\n"}
112}
113after 100
93 114
94puts "\nall done\n" 115puts "\nall done\n"
diff --git a/test/option_tree.exp b/test/utils/tree.exp
index 1841907d1..a8ef763f1 100755
--- a/test/option_tree.exp
+++ b/test/utils/tree.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
diff --git a/test/utils/utils.sh b/test/utils/utils.sh
new file mode 100755
index 000000000..bd91110f7
--- /dev/null
+++ b/test/utils/utils.sh
@@ -0,0 +1,102 @@
1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6export MALLOC_CHECK_=3
7export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
8
9echo "TESTING: version (test/utils/version.exp)"
10./version.exp
11
12echo "TESTING: help (test/utils/help.exp)"
13./help.exp
14
15which man
16if [ "$?" -eq 0 ];
17then
18 echo "TESTING: man (test/utils/man.exp)"
19 ./man.exp
20else
21 echo "TESTING SKIP: man not found"
22fi
23
24echo "TESTING: list (test/utils/list.exp)"
25./list.exp
26
27echo "TESTING: tree (test/utils/tree.exp)"
28./tree.exp
29
30if [ $(grep -c ^processor /proc/cpuinfo) -gt 1 ];
31then
32 echo "TESTING: cpu.print (test/utils/cpu-print.exp)"
33 ./cpu-print.exp
34else
35 echo "TESTING SKIP: cpu.print, not enough CPUs"
36fi
37
38echo "TESTING: fs.print (test/utils/fs-print.exp)"
39./fs-print.exp
40
41echo "TESTING: dns.print (test/utils/dns-print.exp)"
42./dns-print.exp
43
44echo "TESTING: caps.print (test/utils/caps-print.exp)"
45./caps-print.exp
46
47echo "TESTING: seccomp.print (test/utils/seccomp-print.exp)"
48./seccomp-print.exp
49
50echo "TESTING: protocol.print (test/utils/protocol-print.exp)"
51./protocol-print.exp
52
53echo "TESTING: shutdown (test/utils/shutdown.exp)"
54./shutdown.exp
55
56echo "TESTING: shutdown2 (test/utils/shutdown2.exp)"
57./shutdown2.exp
58
59echo "TESTING: shutdown3 (test/utils/shutdown3.exp)"
60./shutdown3.exp
61
62echo "TESTING: shutdown4 (test/utils/shutdown4.exp)"
63./shutdown4.exp
64
65echo "TESTING: join (test/utils/join.exp)"
66./join.exp
67
68echo "TESTING: join2 (test/utils/join2.exp)"
69./join2.exp
70
71echo "TESTING: join3 (test/utils/join3.exp)"
72./join3.exp
73
74echo "TESTING: join3 (test/utils/join4.exp)"
75./join4.exp
76
77echo "TESTING: join profile (test/utils/join-profile.exp)"
78./join-profile.exp
79
80echo "TESTING: trace (test/utils/trace.exp)"
81rm -f index.html*
82./trace.exp
83rm -f index.html*
84
85echo "TESTING: top (test/utils/top.exp)"
86./top.exp
87
88echo "TESTING: file transfer (test/utils/ls.exp)"
89./ls.exp
90
91echo "TESTING: firemon seccomp (test/utils/firemon-seccomp.exp)"
92./firemon-seccomp.exp
93
94echo "TESTING: firemon caps (test/utils/firemon-caps.exp)"
95./firemon-caps.exp
96
97echo "TESTING: firemon cpu (test/utils/firemon-cpu.exp)"
98./firemon-cpu.exp
99
100echo "TESTING: firemon cgroup (test/utils/firemon-cgroup.exp)"
101./firemon-cgroup.exp
102
diff --git a/test/option_version.exp b/test/utils/version.exp
index 44c0c217f..2ce6f1680 100755
--- a/test/option_version.exp
+++ b/test/utils/version.exp
@@ -1,4 +1,7 @@
1#!/usr/bin/expect -f 1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
2 5
3set timeout 10 6set timeout 10
4spawn $env(SHELL) 7spawn $env(SHELL)
diff --git a/todo b/todo
index da732be9f..6bc73313f 100644
--- a/todo
+++ b/todo
@@ -74,11 +74,217 @@ CapEff: 0000000000000000
74CapBnd: 0000003fffffffff 74CapBnd: 0000003fffffffff
75CapAmb: 0000000000000000 75CapAmb: 0000000000000000
76 76
7711. cleanup thunderbird profile - disable-common was commented out 7711. check seccomp on Docker: https://docs.docker.com/engine/security/seccomp/
78
7912. check seccomp on Docker: https://docs.docker.com/engine/security/seccomp/
80Seccomp lists: 78Seccomp lists:
81https://github.com/torvalds/linux/blob/1e75a9f34a5ed5902707fb74b468356c55142b71/arch/x86/entry/syscalls/syscall_64.tbl 79https://github.com/torvalds/linux/blob/1e75a9f34a5ed5902707fb74b468356c55142b71/arch/x86/entry/syscalls/syscall_64.tbl
82https://github.com/torvalds/linux/blob/1e75a9f34a5ed5902707fb74b468356c55142b71/arch/x86/entry/syscalls/syscall_32.tbl 80https://github.com/torvalds/linux/blob/1e75a9f34a5ed5902707fb74b468356c55142b71/arch/x86/entry/syscalls/syscall_32.tbl
83 81
8413. check for --chroot why .config/pulse dir is not created 8212. check for --chroot why .config/pulse dir is not created
83
8413. print error line number for profile files in profile_check_line()
85
8614. make rpms problems
87$ firejail --version
88firejail version 0.9.40
89User namespace support is disabled.
90
91$ rpmlint firejail-0.9.40-1.x86_64.rpm
92firejail.x86_64: E: no-changelogname-tag
93firejail.x86_64: W: unstripped-binary-or-object /usr/lib64/firejail/libtracelog.so
94firejail.x86_64: W: unstripped-binary-or-object /usr/lib64/firejail/libtrace.so
95firejail.x86_64: E: missing-call-to-setgroups /usr/lib64/firejail/libtrace.so
96firejail.x86_64: W: conffile-without-noreplace-flag /etc/firejail/google-play-music-desktop-player.profile
97firejail.x86_64: W: conffile-without-noreplace-flag /etc/firejail/rtorrent.profi
98
99$ rpmlint firejail-0.9.40-1.src.rpm
100firejail.src: E: no-changelogname-tag
101firejail.src: W: invalid-url Source0: https://github.com/netblue30/firejail/archive/0.9.40.tar.gz#/firejail-0.9.40.tar.gz HTTP Error 404: Not Found
1021 packages and 0 specfiles checked; 1 errors, 1 warnings.
103
10415. bug: capabiliteis declared on the command line take precedence over caps declared in profiles
105
106$ firejail --caps.keep=chown,net_bind_service src/faudit/faudit
107Reading profile /etc/firejail/default.profile
108Reading profile /etc/firejail/disable-common.inc
109Reading profile /etc/firejail/disable-programs.inc
110Reading profile /etc/firejail/disable-passwdmgr.inc
111
112** Note: you can use --noprofile to disable default.profile **
113
114Parent pid 6872, child pid 6873
115
116Child process initialized
117
118----- Firejail Audit: the Good, the Bad and the Ugly -----
119
120GOOD: Process PID 2, running in a PID namespace
121Container/sandbox: firejail
122GOOD: all capabilities are disabled
123
124
125Parent is shutting down, bye...
126
12716. Sound devices:
128/dev/snd
129
130
131 /dev/snd/pcmC0D0 -> /dev/audio0 (/dev/audio) -> minor 4
132 /dev/snd/pcmC0D0 -> /dev/dsp0 (/dev/dsp) -> minor 3
133 /dev/snd/pcmC0D1 -> /dev/adsp0 (/dev/adsp) -> minor 12
134 /dev/snd/pcmC1D0 -> /dev/audio1 -> minor 4+16 = 20
135 /dev/snd/pcmC1D0 -> /dev/dsp1 -> minor 3+16 = 19
136 /dev/snd/pcmC1D1 -> /dev/adsp1 -> minor 12+16 = 28
137 /dev/snd/pcmC2D0 -> /dev/audio2 -> minor 4+32 = 36
138 /dev/snd/pcmC2D0 -> /dev/dsp2 -> minor 3+32 = 35
139 /dev/snd/pcmC2D1 -> /dev/adsp2 -> minor 12+32 = 44
140
141
14217. test 3d acceleration
143
144$ lspci -nn | grep VGA
145
146# apt-get install mesa-utils
147
148$ glxinfo | grep rendering
149
150The output should be:
151
152direct rendering: Yes
153
154$ glxinfo | grep "renderer string"
155
156OpenGL renderer string: Gallium 0.4 on AMD KAVERI
157
158
159glxgears stuck to 60fps may be due to VSync signal synchronization.
160To disable Vsync
161
162$ vblank_mode=0 glxgears
163
16419. testing snaps
165
166Install firejail from official repository
167sudo apt-get install firejail
168
169Check firejail version
170firejail --version
171
172Above command outputs: firejail version 0.9.38
173
174Search the snap 'ubuntu clock' application
175sudo snap find ubuntu-clock-app
176
177Install 'ubuntu clock' application using snap
178sudo snap install ubuntu-clock-app
179
180Ubuntu snap packages are installed in /snap/// directory and can be executed from /snap/bin/
181cd /snap/bin/
182ls -l
183
184Note: We see application name is: ubuntu-clock-app.clock
185
186Run application
187/snap/bin/ubuntu-clock-app.clock
188
189Note: Application starts-up without a problem and clock is displayed.
190
191Close application using mouse.
192
193Now try to firejail the application.
194firejail /snap/bin/ubuntu-clock-app.clock
195
196-------- Error message --------
197Reading profile /etc/firejail/generic.profile
198Reading profile /etc/firejail/disable-mgmt.inc
199Reading profile /etc/firejail/disable-secret.inc
200Reading profile /etc/firejail/disable-common.inc
201
202** Note: you can use --noprofile to disable generic.profile **
203
204Parent pid 3770, child pid 3771
205
206Child process initialized
207need to run as root or suid
208
209parent is shutting down, bye...
210-------- End of Error message --------
211
212Try running as root as message instructs.
213sudo firejail /snap/bin/ubuntu-clock-app.clock
214
215extract env for process
216ps e -p <pid> | sed 's/ /\n/g'
217
218
21920. check default disable - from grsecurity
220
221GRKERNSEC_HIDESYM
222/proc/kallsyms and other files
223
224GRKERNSEC_PROC_USER
225If you say Y here, non-root users will only be able to view their own
226processes, and restricts them from viewing network-related information,
227and viewing kernel symbol and module information.
228
229GRKERNSEC_PROC_ADD
230If you say Y here, additional restrictions will be placed on
231/proc that keep normal users from viewing device information and
232slabinfo information that could be useful for exploits.
233
23421. Core Infrastructure Initiative (CII) Best Practices
235
236Proposal
237
238Someone closely involved with the project could go thought the criteria and keep them up-to-date.
239References
240
241 https://bestpractices.coreinfrastructure.org
242 https://twit.tv/shows/floss-weekly/episodes/389
243
24422. add support for read-write and noexec to Firetools
245
24623. AppArmor
247
248$ sudo apt-get install apparmor apparmor-profiles apparmor-utils apparmor-notify
249$ sudo apt-get install libapparmor-dev
250
251$ sudo perl -pi -e 's,GRUB_CMDLINE_LINUX="(.*)"$,GRUB_CMDLINE_LINUX="$1 apparmor=1 security=apparmor",' /etc/default/grub
252$ sudo update-grub
253$ sudo reboot
254
255If you are using auditd, start aa-notify to get notification whenever a program causes a DENIED message.
256$ sudo aa-notify -p -f /var/log/audit/audit.log
257
258$ sudo cat /sys/kernel/security/apparmor/profiles | grep firejail
259firejail-default (enforce)
260
26124. check monitor proc behaviour for sandboxes with --blacklist=/proc
262also check --apparmor in this case
263
26425. fix firemon and firetools on systems with hidepid=2
265
266sudo mount -o remount,rw,hidepid=2 /proc
267
26826. mupdf profile
269
27027. LUKS
271
272dm-crypt+LUKS – dm-crypt is a transparent disk encryption subsystem in
273Linux kernel v2.6+ and later and DragonFly BSD. It can encrypt whole disks,
274removable media, partitions, software RAID volumes, logical volumes, and files.
275
27628. Merge --dbus=none from https://github.com/Sidnioulz/firejail
277
278 // block dbus session bus the hard way if necessary
279 if (cfg.dbus == 0) {
280 char *dbus_path;
281 if (asprintf(&dbus_path, "/run/user/%d/bus", getuid()) == -1)
282 errExit("asprintf");
283 fs_blacklist_file(dbus_path);
284 free(dbus_path);
285}
286
28729. grsecurity - move test after "firejail --name=blablabla" in /test/apps*
288
28930. /* coverity[toctou] */
290