aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar curiosity-seeker <seeker@posteo.org>2016-12-15 12:58:32 +0100
committerLibravatar GitHub <noreply@github.com>2016-12-15 12:58:32 +0100
commitd8ee390a6ca56fde4baad57dea7572c39d595809 (patch)
tree255252b15232086e6f65203cda676859ab4117a0
parentUpdate quiterss.profile (diff)
parentadded a 1 second delay after xpra server is started (diff)
downloadfirejail-d8ee390a6ca56fde4baad57dea7572c39d595809.tar.gz
firejail-d8ee390a6ca56fde4baad57dea7572c39d595809.tar.zst
firejail-d8ee390a6ca56fde4baad57dea7572c39d595809.zip
Merge pull request #1 from netblue30/master
Bring fork up-to-date
-rw-r--r--.gitignore12
-rw-r--r--Makefile.in315
-rw-r--r--README225
-rw-r--r--README.md263
-rw-r--r--RELNOTES115
-rwxr-xr-xconfigure569
-rw-r--r--configure.ac83
-rw-r--r--etc/0ad.profile29
-rw-r--r--etc/7z.profile9
-rw-r--r--etc/Cryptocat.profile20
-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.profile17
-rw-r--r--etc/amarok.profile19
-rw-r--r--etc/ark.profile23
-rw-r--r--etc/atom-beta.profile20
-rw-r--r--etc/atom.profile20
-rw-r--r--etc/atool.profile24
-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/bleachbit.profile21
-rw-r--r--etc/bless.profile20
-rw-r--r--etc/brasero.profile23
-rw-r--r--etc/brave.profile17
-rw-r--r--etc/cherrytree.profile20
-rw-r--r--etc/chromium.profile5
-rw-r--r--etc/claws-mail.profile23
-rw-r--r--etc/clementine.profile5
-rw-r--r--etc/cmus.profile5
-rw-r--r--etc/conkeror.profile5
-rw-r--r--etc/corebird.profile11
-rw-r--r--etc/cpio.profile21
-rw-r--r--etc/cryptocat.profile1
-rw-r--r--etc/cyberfox.profile49
-rw-r--r--etc/deadbeef.profile5
-rw-r--r--etc/default.profile24
-rw-r--r--etc/deluge.profile13
-rw-r--r--etc/dillo.profile11
-rw-r--r--etc/disable-common.inc102
-rw-r--r--etc/disable-devel.inc38
-rw-r--r--etc/disable-passwdmgr.inc4
-rw-r--r--etc/disable-programs.inc377
-rw-r--r--etc/display.profile23
-rw-r--r--etc/dnscrypt-proxy.profile2
-rw-r--r--etc/dnsmasq.profile8
-rw-r--r--etc/dolphin.profile27
-rw-r--r--etc/dosbox.profile21
-rw-r--r--etc/dragon.profile22
-rw-r--r--etc/dropbox.profile16
-rw-r--r--etc/elinks.profile24
-rw-r--r--etc/emacs.profile16
-rw-r--r--etc/empathy.profile7
-rw-r--r--etc/enchant.profile23
-rw-r--r--etc/eog.profile22
-rw-r--r--etc/eom.profile21
-rw-r--r--etc/epiphany.profile11
-rw-r--r--etc/evince.profile18
-rw-r--r--etc/evolution.profile25
-rw-r--r--etc/exiftool.profile28
-rw-r--r--etc/fbreader.profile10
-rw-r--r--etc/feh.profile21
-rw-r--r--etc/file-roller.profile21
-rw-r--r--etc/file.profile26
-rw-r--r--etc/filezilla.profile12
-rw-r--r--etc/firefox-esr.profile2
-rw-r--r--etc/firefox.profile29
-rw-r--r--etc/firejail-default154
-rw-r--r--etc/firejail.config50
-rw-r--r--etc/flashpeak-slimjet.profile7
-rw-r--r--etc/flowblade.profile13
-rw-r--r--etc/franz.profile24
-rw-r--r--etc/gajim.profile38
-rw-r--r--etc/gedit.profile26
-rw-r--r--etc/gimp.profile20
-rw-r--r--etc/git.profile26
-rw-r--r--etc/gitter.profile20
-rw-r--r--etc/gjs.profile28
-rw-r--r--etc/gnome-2048.profile25
-rw-r--r--etc/gnome-books.profile26
-rw-r--r--etc/gnome-calculator.profile19
-rw-r--r--etc/gnome-chess.profile22
-rw-r--r--etc/gnome-clocks.profile21
-rw-r--r--etc/gnome-contacts.profile19
-rw-r--r--etc/gnome-documents.profile24
-rw-r--r--etc/gnome-maps.profile24
-rw-r--r--etc/gnome-mplayer.profile11
-rw-r--r--etc/gnome-music.profile22
-rw-r--r--etc/gnome-photos.profile26
-rw-r--r--etc/gnome-weather.profile26
-rw-r--r--etc/goobox.profile20
-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/gpa.profile23
-rw-r--r--etc/gpg-agent.profile23
-rw-r--r--etc/gpg.profile24
-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/highlight.profile24
-rw-r--r--etc/icecat.profile50
-rw-r--r--etc/icedove.profile4
-rw-r--r--etc/img2txt.profile24
-rw-r--r--etc/inkscape.profile20
-rw-r--r--etc/inox.profile24
-rw-r--r--etc/jd-gui.profile19
-rw-r--r--etc/jitsi.profile17
-rw-r--r--etc/k3b.profile21
-rw-r--r--etc/kate.profile28
-rw-r--r--etc/keepass.profile21
-rw-r--r--etc/keepass2.profile5
-rw-r--r--etc/keepassx.profile22
-rw-r--r--etc/kmail.profile9
-rw-r--r--etc/konversation.profile14
-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/lollypop.profile20
-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.profile5
-rw-r--r--etc/lynx.profile22
-rw-r--r--etc/mcabber.profile21
-rw-r--r--etc/mediainfo.profile26
-rw-r--r--etc/midori.profile6
-rw-r--r--etc/mpv.profile18
-rw-r--r--etc/multimc5.profile27
-rw-r--r--etc/mumble.profile26
-rw-r--r--etc/mupdf.profile30
-rw-r--r--etc/mupen64plus.profile8
-rw-r--r--etc/mutt.profile40
-rw-r--r--etc/nautilus.profile26
-rw-r--r--etc/netsurf.profile29
-rw-r--r--etc/nolocal.net3
-rw-r--r--etc/odt2txt.profile24
-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/pdfsam.profile17
-rw-r--r--etc/pdftotext.profile22
-rw-r--r--etc/pidgin.profile16
-rw-r--r--etc/pithos.profile19
-rw-r--r--etc/pix.profile22
-rw-r--r--etc/pluma.profile21
-rw-r--r--etc/polari.profile12
-rw-r--r--etc/psi-plus.profile22
-rw-r--r--etc/qbittorrent.profile11
-rw-r--r--etc/qemu-launcher.profile19
-rw-r--r--etc/qemu-system-x86_64.profile17
-rw-r--r--etc/qpdfview.profile22
-rw-r--r--etc/qtox.profile14
-rw-r--r--etc/quassel.profile5
-rw-r--r--etc/qutebrowser.profile11
-rw-r--r--etc/ranger.profile24
-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/simple-scan.profile23
-rw-r--r--etc/skanlite.profile21
-rw-r--r--etc/skype.profile3
-rw-r--r--etc/skypeforlinux.profile11
-rw-r--r--etc/slack.profile31
-rw-r--r--etc/snap.profile12
-rw-r--r--etc/soffice.profile5
-rw-r--r--etc/spotify.profile33
-rw-r--r--etc/ssh-agent.profile16
-rw-r--r--etc/ssh.profile8
-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/tracker.profile24
-rw-r--r--etc/transmission-cli.profile23
-rw-r--r--etc/transmission-gtk.profile14
-rw-r--r--etc/transmission-qt.profile14
-rw-r--r--etc/transmission-show.profile24
-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.profile12
-rw-r--r--etc/vivaldi.profile2
-rw-r--r--etc/vlc.profile13
-rw-r--r--etc/w3m.profile23
-rw-r--r--etc/warzone2100.profile26
-rw-r--r--etc/weechat.profile10
-rw-r--r--etc/wesnoth.profile12
-rw-r--r--etc/wget.profile22
-rw-r--r--etc/whitelist-common.inc12
-rw-r--r--etc/wine.profile1
-rw-r--r--etc/wire.profile23
-rw-r--r--etc/wireshark.profile22
-rw-r--r--etc/xchat.profile7
-rw-r--r--etc/xed.profile21
-rw-r--r--etc/xfburn.profile23
-rw-r--r--etc/xiphos.profile30
-rw-r--r--etc/xonotic-glx.profile5
-rw-r--r--etc/xonotic-sdl.profile5
-rw-r--r--etc/xonotic.profile25
-rw-r--r--etc/xpdf.profile (renamed from etc/generic.profile)15
-rw-r--r--etc/xplayer.profile22
-rw-r--r--etc/xpra.profile21
-rw-r--r--etc/xreader.profile23
-rw-r--r--etc/xviewer.profile21
-rw-r--r--etc/xz.profile3
-rw-r--r--etc/xzdec.profile14
-rw-r--r--etc/zathura.profile26
-rw-r--r--etc/zoom.profile22
-rwxr-xr-xgcov.sh94
-rwxr-xr-xmkasc.sh1
-rwxr-xr-xmkdeb.sh4
-rwxr-xr-xmketc.sh32
-rwxr-xr-xmkuid.sh20
-rw-r--r--platform/debian/conffiles292
-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.c99
-rw-r--r--src/faudit/seccomp.c101
-rw-r--r--src/faudit/syscall.c102
-rw-r--r--src/faudit/x11.c63
-rw-r--r--src/fcopy/Makefile.in45
-rw-r--r--src/fcopy/main.c340
-rw-r--r--src/firecfg/Makefile.in8
-rw-r--r--src/firecfg/firecfg.config201
-rw-r--r--src/firecfg/main.c195
-rw-r--r--src/firejail/Makefile.in16
-rw-r--r--src/firejail/appimage.c184
-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.c106
-rw-r--r--src/firejail/cgroup.c3
-rw-r--r--src/firejail/checkcfg.c251
-rw-r--r--src/firejail/cmdline.c159
-rw-r--r--src/firejail/cpu.c20
-rw-r--r--src/firejail/env.c93
-rw-r--r--src/firejail/firejail.h277
-rw-r--r--src/firejail/fs.c940
-rw-r--r--src/firejail/fs_bin.c219
-rw-r--r--src/firejail/fs_dev.c181
-rw-r--r--src/firejail/fs_etc.c209
-rw-r--r--src/firejail/fs_home.c251
-rw-r--r--src/firejail/fs_hostname.c52
-rw-r--r--src/firejail/fs_logger.c22
-rw-r--r--src/firejail/fs_mkdir.c102
-rw-r--r--src/firejail/fs_trace.c25
-rw-r--r--src/firejail/fs_var.c85
-rw-r--r--src/firejail/fs_whitelist.c316
-rw-r--r--src/firejail/join.c160
-rw-r--r--src/firejail/list.c81
-rw-r--r--src/firejail/ls.c269
-rw-r--r--src/firejail/main.c1408
-rw-r--r--src/firejail/netfilter.c233
-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.c160
-rw-r--r--src/firejail/output.c2
-rw-r--r--src/firejail/preproc.c91
-rw-r--r--src/firejail/profile.c457
-rw-r--r--src/firejail/protocol.c278
-rw-r--r--src/firejail/pulseaudio.c53
-rw-r--r--src/firejail/restrict_users.c37
-rw-r--r--src/firejail/restricted_shell.c47
-rw-r--r--src/firejail/rlimit.c12
-rw-r--r--src/firejail/run_symlink.c11
-rw-r--r--src/firejail/sandbox.c642
-rw-r--r--src/firejail/sbox.c221
-rw-r--r--src/firejail/seccomp.c868
-rw-r--r--src/firejail/shutdown.c16
-rw-r--r--src/firejail/usage.c409
-rw-r--r--src/firejail/user.c115
-rw-r--r--src/firejail/util.c266
-rw-r--r--src/firejail/x11.c528
-rw-r--r--src/firemon/Makefile.in11
-rw-r--r--src/firemon/arp.c10
-rw-r--r--src/firemon/caps.c9
-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.c10
-rw-r--r--src/firemon/procevent.c15
-rw-r--r--src/firemon/route.c10
-rw-r--r--src/firemon/seccomp.c12
-rw-r--r--src/firemon/top.c6
-rw-r--r--src/firemon/tree.c5
-rw-r--r--src/firemon/x11.c30
-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.c93
-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.c122
-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.c36
-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.c106
-rw-r--r--src/lib/libnetlink.c50
-rw-r--r--src/lib/pid.c51
-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.c81
-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.txt202
-rw-r--r--src/man/firejail.txt479
-rw-r--r--src/man/firemon.txt1
-rwxr-xr-xsrc/tools/mkcoverit.sh6
-rwxr-xr-xsrc/tools/unchrootbin9720 -> 0 bytes
-rw-r--r--src/tools/unchroot.c125
-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.sh16
-rwxr-xr-xtest/appimage/filename.exp35
-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/chroot-resolvconf.exp14
-rwxr-xr-xtest/chroot/chroot.sh21
-rwxr-xr-xtest/chroot/configure46
-rwxr-xr-xtest/chroot/fs_chroot.exp (renamed from test/fs_chroot.exp)26
-rwxr-xr-xtest/chroot/unchroot-as-root.exp27
-rw-r--r--test/chroot/unchroot.c40
-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.exp76
-rw-r--r--test/environment/dns.profile3
-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.sh113
-rwxr-xr-xtest/environment/extract_command.exp (renamed from test/extract_command.exp)4
-rwxr-xr-xtest/environment/firejail-in-firejail.exp49
-rwxr-xr-xtest/environment/firejail-in-firejail2.exp51
-rwxr-xr-xtest/environment/ibus.exp (renamed from test/sysrq-trigger.exp)17
-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/rlimit-bad-profile.exp35
-rwxr-xr-xtest/environment/rlimit-bad.exp34
-rw-r--r--test/environment/rlimit-bad1.profile1
-rw-r--r--test/environment/rlimit-bad2.profile1
-rw-r--r--test/environment/rlimit-bad3.profile1
-rw-r--r--test/environment/rlimit-bad4.profile1
-rwxr-xr-xtest/environment/rlimit-profile.exp (renamed from test/profile_rlimit.exp)11
-rwxr-xr-xtest/environment/rlimit.exp (renamed from test/option_rlimit.exp)3
-rw-r--r--test/environment/rlimit.profile (renamed from test/rlimit.profile)0
-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/fcopy/cmdline.exp46
-rwxr-xr-xtest/fcopy/dircopy.exp106
-rwxr-xr-xtest/fcopy/fcopy.sh23
-rwxr-xr-xtest/fcopy/filecopy.exp54
-rwxr-xr-xtest/fcopy/linkcopy.exp54
-rw-r--r--test/fcopy/src/a/b/file411
-rw-r--r--test/fcopy/src/a/file30
l---------test/fcopy/src/dircopy.exp1
-rwxr-xr-xtest/fcopy/src/file10
-rw-r--r--test/fcopy/src/file20
-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-print.exp103
-rwxr-xr-xtest/filters/caps.exp139
-rw-r--r--test/filters/caps1.profile1
-rw-r--r--test/filters/caps2.profile1
-rw-r--r--test/filters/caps3.profile1
-rwxr-xr-xtest/filters/filters.sh71
-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/ip6.exp)36
-rwxr-xr-xtest/filters/seccomp-chmod.exp (renamed from test/pid.exp)36
-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/firejail-in-firejail.exp21
-rwxr-xr-xtest/firejail-in-firejail2.exp21
-rwxr-xr-xtest/fs/fs.sh116
-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/fscheck-bindnoroot.exp (renamed from test/fscheck-bindnoroot.exp)5
-rwxr-xr-xtest/fs/fscheck-private.exp50
-rwxr-xr-xtest/fs/fscheck-readonly.exp (renamed from test/fscheck-readonly.exp)3
-rwxr-xr-xtest/fs/fscheck-tmpfs.exp (renamed from test/fscheck-tmpfs.exp)2
-rwxr-xr-xtest/fs/invalid_filename.exp (renamed from test/invalid_filename.exp)39
-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)24
-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.exp73
-rwxr-xr-xtest/fs/private-home-dir.exp70
-rwxr-xr-xtest/fs/private-home.exp103
-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.exp35
-rwxr-xr-xtest/fs/sys_fs.exp44
-rw-r--r--test/fs/testdir1/.directory/file0
-rw-r--r--test/fs/testdir1/.file0
-rw-r--r--test/fs/testfile10
-rw-r--r--test/fs/user-dirs.dirs15
-rwxr-xr-xtest/fs/whitelist-dev.exp47
-rwxr-xr-xtest/fs/whitelist-double.exp42
-rwxr-xr-xtest/fs/whitelist-downloads.exp49
-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/fscheck-private.exp70
-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/dns-print.exp31
-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.exp89
-rw-r--r--test/network/ip6.profile3
-rwxr-xr-xtest/network/iprange.exp103
-rw-r--r--test/network/iprange.profile2
-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_macvlan2.exp43
-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.exp142
-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.sh100
-rwxr-xr-xtest/network/veth-name.exp77
-rw-r--r--test/network/veth-name.profile3
-rwxr-xr-xtest/noroot.exp117
-rw-r--r--test/notes13
-rwxr-xr-xtest/option-join-profile.exp39
-rwxr-xr-xtest/option-join.exp39
-rwxr-xr-xtest/option-join2.exp39
-rwxr-xr-xtest/option-join3.exp39
-rwxr-xr-xtest/option-shutdown.exp30
-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-etc.exp42
-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/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/join.exp52
-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.exp90
-rwxr-xr-xtest/root/profile_tmpfs.exp40
-rwxr-xr-xtest/root/root.sh114
-rwxr-xr-xtest/root/seccomp-chmod.exp51
-rwxr-xr-xtest/root/seccomp-chown.exp (renamed from test/seccomp-chmod.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/root/whitelist.exp118
-rwxr-xr-xtest/seccomp-chmod-profile.exp46
-rwxr-xr-xtest/seccomp-errno.exp87
-rwxr-xr-xtest/stress/net_macvlan.exp (renamed from test/net_macvlan.exp)7
-rwxr-xr-xtest/stress/stress.sh11
-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/audit.exp79
-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)34
-rwxr-xr-xtest/utils/firemon-interface.exp18
-rwxr-xr-xtest/utils/firemon-name.exp28
-rwxr-xr-xtest/utils/firemon-seccomp.exp (renamed from test/firemon-seccomp.exp)6
-rwxr-xr-xtest/utils/firemon-version.exp18
-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.exp51
-rwxr-xr-xtest/utils/join2.exp38
-rwxr-xr-xtest/utils/join3.exp38
-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.exp49
-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.sh114
-rwxr-xr-xtest/utils/version.exp (renamed from test/option_version.exp)3
-rw-r--r--todo227
702 files changed, 25550 insertions, 9158 deletions
diff --git a/.gitignore b/.gitignore
index 85e317827..89bf3c4fa 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,13 @@ 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
25src/fcopy/fcopy
26uids.h
27seccomp
28seccomp.debug
29seccomp.i386
30seccomp.amd64
31
diff --git a/Makefile.in b/Makefile.in
index 16f8e8717..8251f9882 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,6 +1,8 @@
1all: apps firejail.1 firemon.1 firecfg.1 firejail-profile.5 firejail-login.5 firejail-config.5 1all: apps man filters
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 src/fcopy
4MANPAGES = firejail.1 firemon.1 firecfg.1 firejail-profile.5 firejail-login.5
5SECCOMP_FILTERS = seccomp seccomp.i386 seccomp.amd64
4 6
5prefix=@prefix@ 7prefix=@prefix@
6exec_prefix=@exec_prefix@ 8exec_prefix=@exec_prefix@
@@ -14,47 +16,55 @@ VERSION=@PACKAGE_VERSION@
14NAME=@PACKAGE_NAME@ 16NAME=@PACKAGE_NAME@
15PACKAGE_TARNAME=@PACKAGE_TARNAME@ 17PACKAGE_TARNAME=@PACKAGE_TARNAME@
16DOCDIR=@docdir@ 18DOCDIR=@docdir@
19HAVE_APPARMOR=@HAVE_APPARMOR@
20BUSYBOX_WORKAROUND=@BUSYBOX_WORKAROUND@
21
22uids.h:; ./mkuid.sh
17 23
18.PHONY: mylibs $(MYLIBS) 24.PHONY: mylibs $(MYLIBS)
19mylibs: $(MYLIBS) 25mylibs: $(MYLIBS) uids.h
20$(MYLIBS): 26$(MYLIBS):
21 $(MAKE) -C $@ 27 $(MAKE) -C $@
22 28
23.PHONY: apps $(APPS) 29.PHONY: apps $(APPS)
24apps: $(APPS) 30apps: $(APPS)
25$(APPS): $(MYLIBS) 31$(APPS): $(MYLIBS) uids.h
26 $(MAKE) -C $@ 32 $(MAKE) -C $@
27 33
28firemon.1: src/man/firemon.txt 34$(MANPAGES): $(wildcard src/man/*.txt)
29 ./mkman.sh $(VERSION) src/man/firemon.txt firemon.1 35 ./mkman.sh $(VERSION) src/man/$(basename $@).txt $@
30firejail.1: src/man/firejail.txt 36
31 ./mkman.sh $(VERSION) src/man/firejail.txt firejail.1 37man: $(MANPAGES)
32firecfg.1: src/man/firecfg.txt 38
33 ./mkman.sh $(VERSION) src/man/firecfg.txt firecfg.1 39filters: src/fseccomp
34firejail-profile.5: src/man/firejail-profile.txt 40 src/fseccomp/fseccomp default seccomp
35 ./mkman.sh $(VERSION) src/man/firejail-profile.txt firejail-profile.5 41 src/fseccomp/fseccomp default seccomp.debug allow-debuggers
36firejail-login.5: src/man/firejail-login.txt 42 src/fseccomp/fseccomp secondary 32 seccomp.i386
37 ./mkman.sh $(VERSION) src/man/firejail-login.txt firejail-login.5 43 src/fseccomp/fseccomp secondary 64 seccomp.amd64
38firejail-config.5: src/man/firejail-config.txt
39 ./mkman.sh $(VERSION) src/man/firejail-config.txt firejail-config.5
40 44
41clean: 45clean:
42 for dir in $(APPS); do \ 46 for dir in $(APPS) $(MYLIBS); do \
43 $(MAKE) -C $$dir clean; \
44 done
45 for dir in $(MYLIBS); do \
46 $(MAKE) -C $$dir clean; \ 47 $(MAKE) -C $$dir clean; \
47 done 48 done
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 49 rm -f $(MANPAGES) $(MANPAGES:%=%.gz) firejail*.rpm
50 rm -f seccomp seccomp.debug seccomp.i386 seccomp.amd64
51 rm -f test/utils/index.html*
52 rm -f test/utils/wget-log
53 rm -f test/utils/lstesting
54 rm -f test/environment/index.html*
55 rm -f test/environment/wget-log*
56 rm -fr test/environment/-testdir
57 rm -f test/environment/logfile*
58 rm -f test/environment/index.html
59 rm -f test/environment/wget-log
60 rm -f test/sysutils/firejail_t*
61 cd test/compile; ./compile.sh --clean; cd ../..
49 62
50distclean: clean 63distclean: clean
51 for dir in $(APPS); do \ 64 for dir in $(APPS) $(MYLIBS); do \
52 $(MAKE) -C $$dir distclean; \ 65 $(MAKE) -C $$dir distclean; \
53 done 66 done
54 for dir in $(MYLIBS); do \ 67 rm -fr Makefile autom4te.cache config.log config.status config.h uids.h
55 $(MAKE) -C $$dir distclean; \
56 done
57 rm -fr Makefile autom4te.cache config.log config.status config.h
58 68
59realinstall: 69realinstall:
60 # firejail executable 70 # firejail executable
@@ -69,133 +79,54 @@ realinstall:
69 install -m 0755 -d $(DESTDIR)/$(libdir)/firejail 79 install -m 0755 -d $(DESTDIR)/$(libdir)/firejail
70 install -c -m 0644 src/libtrace/libtrace.so $(DESTDIR)/$(libdir)/firejail/. 80 install -c -m 0644 src/libtrace/libtrace.so $(DESTDIR)/$(libdir)/firejail/.
71 install -c -m 0644 src/libtracelog/libtracelog.so $(DESTDIR)/$(libdir)/firejail/. 81 install -c -m 0644 src/libtracelog/libtracelog.so $(DESTDIR)/$(libdir)/firejail/.
82 install -c -m 0644 src/libconnect/libconnect.so $(DESTDIR)/$(libdir)/firejail/.
72 install -c -m 0755 src/ftee/ftee $(DESTDIR)/$(libdir)/firejail/. 83 install -c -m 0755 src/ftee/ftee $(DESTDIR)/$(libdir)/firejail/.
73 install -c -m 0755 src/fshaper/fshaper.sh $(DESTDIR)/$(libdir)/firejail/. 84 install -c -m 0755 src/fshaper/fshaper.sh $(DESTDIR)/$(libdir)/firejail/.
74 install -c -m 0644 src/firecfg/firecfg.config $(DESTDIR)/$(libdir)/firejail/. 85 install -c -m 0644 src/firecfg/firecfg.config $(DESTDIR)/$(libdir)/firejail/.
86 install -c -m 0755 src/faudit/faudit $(DESTDIR)/$(libdir)/firejail/.
87 install -c -m 0755 src/fnet/fnet $(DESTDIR)/$(libdir)/firejail/.
88 install -c -m 0755 src/fseccomp/fseccomp $(DESTDIR)/$(libdir)/firejail/.
89 install -c -m 0755 src/fcopy/fcopy $(DESTDIR)/$(libdir)/firejail/.
90 install -c -m 0644 seccomp $(DESTDIR)/$(libdir)/firejail/.
91 install -c -m 0644 seccomp.debug $(DESTDIR)/$(libdir)/firejail/.
92 install -c -m 0644 seccomp.i386 $(DESTDIR)/$(libdir)/firejail/.
93 install -c -m 0644 seccomp.amd64 $(DESTDIR)/$(libdir)/firejail/.
75 # documents 94 # documents
76 install -m 0755 -d $(DESTDIR)/$(DOCDIR) 95 install -m 0755 -d $(DESTDIR)/$(DOCDIR)
77 install -c -m 0644 COPYING $(DESTDIR)/$(DOCDIR)/. 96 install -c -m 0644 COPYING $(DESTDIR)/$(DOCDIR)/.
78 install -c -m 0644 README $(DESTDIR)/$(DOCDIR)/. 97 install -c -m 0644 README $(DESTDIR)/$(DOCDIR)/.
79 install -c -m 0644 RELNOTES $(DESTDIR)/$(DOCDIR)/. 98 install -c -m 0644 RELNOTES $(DESTDIR)/$(DOCDIR)/.
80 # etc files 99 # etc files
81 ./mketc.sh $(sysconfdir) 100 ./mketc.sh $(sysconfdir) $(BUSYBOX_WORKAROUND)
82 install -m 0755 -d $(DESTDIR)/$(sysconfdir)/firejail 101 install -m 0755 -d $(DESTDIR)/$(sysconfdir)/firejail
83 install -c -m 0644 .etc/audacious.profile $(DESTDIR)/$(sysconfdir)/firejail/. 102 for file in .etc/* etc/firejail.config; do \
84 install -c -m 0644 .etc/clementine.profile $(DESTDIR)/$(sysconfdir)/firejail/. 103 install -c -m 0644 $$file $(DESTDIR)/$(sysconfdir)/firejail; \
85 install -c -m 0644 .etc/epiphany.profile $(DESTDIR)/$(sysconfdir)/firejail/. 104 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;" 105 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 106 rm -fr .etc
107ifeq ($(HAVE_APPARMOR),-DHAVE_APPARMOR)
108 # install apparmor profile
109 sh -c "if [ ! -d $(DESTDIR)/$(sysconfdir)/apparmor.d ]; then install -d -m 755 $(DESTDIR)/$(sysconfdir)/apparmor.d; fi;"
110 install -c -m 0644 etc/firejail-default $(DESTDIR)/$(sysconfdir)/apparmor.d/.
111endif
170 # man pages 112 # 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 113 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 114 install -m 0755 -d $(DESTDIR)/$(mandir)/man5
188 install -c -m 0644 firejail-profile.5.gz $(DESTDIR)/$(mandir)/man5/. 115 for man in $(MANPAGES); do \
189 install -c -m 0644 firejail-login.5.gz $(DESTDIR)/$(mandir)/man5/. 116 rm -f $$man.gz; \
190 install -c -m 0644 firejail-config.5.gz $(DESTDIR)/$(mandir)/man5/. 117 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 118 case "$$man" in \
119 *.1) install -c -m 0644 $$man.gz $(DESTDIR)/$(mandir)/man1/; ;; \
120 *.5) install -c -m 0644 $$man.gz $(DESTDIR)/$(mandir)/man5/; ;; \
121 esac; \
122 done
123 rm -f $(MANPAGES) $(MANPAGES:%=%.gz)
192 # bash completion 124 # bash completion
193 install -m 0755 -d $(DESTDIR)/$(datarootdir)/bash-completion/completions 125 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 126 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 127 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 128 install -c -m 0644 src/bash_completion/firecfg.bash_completion $(DESTDIR)/$(datarootdir)/bash-completion/completions/firecfg
197 129
198
199install: all 130install: all
200 $(MAKE) realinstall 131 $(MAKE) realinstall
201 132
@@ -205,7 +136,12 @@ install-strip: all
205 strip src/firecfg/firecfg 136 strip src/firecfg/firecfg
206 strip src/libtrace/libtrace.so 137 strip src/libtrace/libtrace.so
207 strip src/libtracelog/libtracelog.so 138 strip src/libtracelog/libtracelog.so
139 strip src/libconnect/libconnect.so
208 strip src/ftee/ftee 140 strip src/ftee/ftee
141 strip src/faudit/faudit
142 strip src/fnet/fnet
143 strip src/fseccomp/fseccomp
144 strip src/fcopy/fcopy
209 $(MAKE) realinstall 145 $(MAKE) realinstall
210 146
211uninstall: 147uninstall:
@@ -214,30 +150,44 @@ uninstall:
214 rm -f $(DESTDIR)/$(bindir)/firecfg 150 rm -f $(DESTDIR)/$(bindir)/firecfg
215 rm -fr $(DESTDIR)/$(libdir)/firejail 151 rm -fr $(DESTDIR)/$(libdir)/firejail
216 rm -fr $(DESTDIR)/$(datarootdir)/doc/firejail 152 rm -fr $(DESTDIR)/$(datarootdir)/doc/firejail
217 rm -f $(DESTDIR)/$(mandir)/man1/firejail.1* 153 for man in $(MANPAGES); do \
218 rm -f $(DESTDIR)/$(mandir)/man1/firemon.1* 154 rm -f $(DESTDIR)/$(mandir)/man5/$$man*; \
219 rm -f $(DESTDIR)/$(mandir)/man1/firecfg.1* 155 rm -f $(DESTDIR)/$(mandir)/man1/$$man*; \
220 rm -f $(DESTDIR)/$(mandir)/man5/firejail-profile.5* 156 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 157 rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firejail
224 rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firemon 158 rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firemon
225 rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firecfg 159 rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firecfg
226 160
161DISTFILES = "src etc platform configure configure.ac Makefile.in install.sh mkman.sh mketc.sh mkdeb.sh mkuid.sh COPYING README RELNOTES"
162DISTFILES_TEST = "test/apps test/apps-x11 test/apps-x11-xorg test/root test/fcopy test/environment test/profiles test/utils test/compile test/filters test/network test/arguments test/fs test/sysutils"
163
227dist: 164dist:
165 mv config.status config.status.old
228 make distclean 166 make distclean
229 rm -fr $(NAME)-$(VERSION) $(NAME)-$(VERSION).tar.bz2 167 mv config.status.old config.status
230 mkdir $(NAME)-$(VERSION) 168 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 .. 169 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 .. 170 cp -a "$(DISTFILES)" $(NAME)-$(VERSION)
233 cd $(NAME)-$(VERSION); cp -a ../COPYING .; cp -a ../README .; cp -a ../RELNOTES .; cd .. 171 cp -a "$(DISTFILES_TEST)" $(NAME)-$(VERSION)/test
234 cd $(NAME)-$(VERSION); rm -fr `find . -name .svn`; rm -fr $(NAME)-$(VERSION); cd .. 172 rm -rf $(NAME)-$(VERSION)/src/tools
235 tar -cjvf $(NAME)-$(VERSION).tar.bz2 $(NAME)-$(VERSION) 173 find $(NAME)-$(VERSION) -name .svn -delete
174 tar -cJvf $(NAME)-$(VERSION).tar.xz $(NAME)-$(VERSION)
236 rm -fr $(NAME)-$(VERSION) 175 rm -fr $(NAME)-$(VERSION)
237 176
177asc:; ./mkasc.sh $(VERSION)
178
238deb: dist 179deb: dist
239 ./mkdeb.sh $(NAME) $(VERSION) 180 ./mkdeb.sh $(NAME) $(VERSION)
240 181
182snap: all
183 cd platform/snap; ./snap.sh
184
185install-snap: snap
186 sudo snap remove faudit; sudo snap install faudit*.snap
187
188test-compile: dist
189 cd test/compile; ./compile.sh $(NAME)-$(VERSION)
190
241.PHONY: rpms 191.PHONY: rpms
242rpms: 192rpms:
243 ./platform/rpm/mkrpm.sh $(NAME) $(VERSION) 193 ./platform/rpm/mkrpm.sh $(NAME) $(VERSION)
@@ -250,5 +200,78 @@ cppcheck: clean
250 200
251scan-build: clean 201scan-build: clean
252 scan-build make 202 scan-build make
253asc:; ./mkasc.sh $(VERSION)
254 203
204
205#
206# make test
207#
208
209
210test-profiles:
211 cd test/profiles; ./profiles.sh | grep TESTING
212
213test-apps:
214 cd test/apps; ./apps.sh | grep TESTING
215
216test-apps-x11:
217 cd test/apps-x11; ./apps-x11.sh | grep TESTING
218
219test-apps-x11-xorg:
220 cd test/apps-x11-xorg; ./apps-x11-xorg.sh | grep TESTING
221
222test-sysutils:
223 cd test/sysutils; ./sysutils.sh | grep TESTING
224
225test-utils:
226 cd test/utils; ./utils.sh | grep TESTING
227
228test-environment:
229 cd test/environment; ./environment.sh | grep TESTING
230
231test-filters:
232 cd test/filters; ./filters.sh | grep TESTING
233
234test-arguments:
235 cd test/arguments; ./arguments.sh | grep TESTING
236
237test-fs:
238 cd test/fs; ./fs.sh | grep TESTING
239
240test-fcopy:
241 cd test/fcopy; ./fcopy.sh | grep TESTING
242
243test: test-profiles test-fcopy test-fs test-utils test-environment test-apps test-apps-x11 test-apps-x11-xorg test-filters test-arguments
244 echo "TEST COMPLETE"
245
246##########################################
247# Individual tests, some of them require root access
248# The tests are very intrussive, by the time you are done
249# with them you will need to restart your computer.
250##########################################
251
252# requires root access
253test-chroot:
254 cd test/chroot; ./chroot.sh | grep testing
255
256# Huge appimage files, not included in "make dist" archive
257test-appimage:
258 cd test/appimage; ./appimage.sh | grep TESTING
259
260# Root access, network devices are created before the test
261# restart your computer to get rid of these devices
262test-network:
263 cd test/network; ./network.sh | grep TESTING
264
265# Tesets running a root user
266test-root:
267 cd test/root; su -c ./root.sh | grep TESTING
268
269# OverlayFS is not available on all platforms
270test-overlay:
271 cd test/overlay; ./overlay.sh | grep TESTING
272
273# For testing hidepid system, the command to set it up is "mount -o remount,rw,hidepid=2 /proc"
274
275test-all: test-root test-chroot test-network test-appimage test-overlay
276 echo "TEST COMPLETE"
277 \ No newline at end of file
diff --git a/README b/README
index 81481f512..d20503974 100644
--- a/README
+++ b/README
@@ -18,18 +18,194 @@ 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
83 - added xed and pluma profiles
84 - added Cryptocat profile
85 - added wireshark profile
86valoq (https://github.com/valoq)
87 - lots of profile fixes
88 - added support for /srv in --whitelist feature
89 - Eye of GNOME, Evolution, display (imagemagik) and Wire profiles
90 - blacklist suid binaries in disable-common.inc
91 - fix man pages
92 - added keypass2, qemu profiles
93 - added amarok, ark, atool, bleachbit, brasero, dolphin, dragon, elinks, enchant, exiftool profiles
94 - added file-roller, gedit, gjs,gnome-books, gnome-documents, gnome-maps, gnome-music profiles
95 - added gnome-photos, gnome-weather, goobox, gpa, gpg, gpg-agent, highlight profiles
96 - added img2txt, k3b, kate, lynx, mediainfo, nautilus, odt2txt, pdftotext, simple-scan profiles
97 - added skanlite, ssh-agent, transmission-cli, tracker, transmission-show, w3m, xfburn, xpra profiles
98 - added wget profile
99 - disable gnupg and systemd directories under /run/user
100Lari Rauno (https://github.com/tuutti)
101 - qutebrowser profile fixes
102SpotComms (https://github.com/SpotComms)
103 - added Bless, Gnome 2048, Gnome Calculator, Gnome Contacts, JD-GUI, Lollypop, MultiMC5 profiles
104 - added PDFSam, Pithos, and Xonotic profiles
105Vasya Novikov (https://github.com/vn971)
106 - Wesnoth profile
107 - Hedegewars profile
108 - manpage fixes
109 - fixed firecfg clean/clear issue
110 - found the ugliest bug so far
111 - seccomp debug description in man page
112curiosity-seeker (https://github.com/curiosity-seeker)
113 - tightening unbound and dnscrypt-proxy profiles
114 - correct and tighten QuiteRss profile
115 - dnsmasq profile
116 - okular and gwenview profiles
117 - cherrytree profile fixes
118 - added quiterss profile
119 - added guayadeque profile
120Simon Peter (https://github.com/probonopd)
121 - set $APPIMAGE and $APPDIR environment variables
122 - AppImage version detection
123 - Leafppad type v1 and v2 appimage packages in test/appimage
124BogDan Vatra (https://github.com/bog-dan-ro)
125 - zoom profile
126Impyy (https://github.com/Impyy)
127 - added mumble profile
128Vadim A. Misbakh-Soloviov (https://github.com/msva)
129 - profile fixes
130Rafael Cavalcanti (https://github.com/rccavalcanti)
131 - chromium profile fixes for Arch Linux
132Deelvesh Bunjun (https://github.com/DeelveshBunjun)
133 - added xpdf profile
134Dara Adib (https://github.com/daradib)
135 - ssh profile fix
136 - evince profile fix
137vismir2 (https://github.com/vismir2)
138 - feh, ranger, 7z, keepass, keepassx and zathura profiles
139 - claws-mail, mutt, git, emacs, vim profiles
140 - lots of profile fixes
141 - support for truecrypt and zuluCrypt
142graywolf (https://github.com/graywolf)
143 - spelling fix
144Tomasz Jan Góralczyk (https://github.com/tjg)
145 - fixed Steam profile
146pwnage-pineapple (https://github.com/pwnage-pineapple)
147 - update Okular profile
148Sergey Alirzaev (https://github.com/l29ah)
149 - firejail.h enum fix
150greigdp (https://github.com/greigdp)
151 - Gajim IM client profile
152 - fix Slack profile
153Icaro Perseo (https://github.com/icaroperseo)
154 - Icecat profile
155 - several profile fixes
156hamzadis (https://github.com/hamzadis)
157 - added --overlay-named=name and --overlay-path=path
158Gaman Gabriel (https://github.com/stelariusinfinitek)
159 - inox profile
160greigdp (https://github.com/greigdp)
161 - fixed spotify profile
162 - added Slack profile
163Laurent Declercq (https://github.com/nuxwin)
164 - fixed test for shell interpreter in chroots
165Franco (nextime) Lanza (https://github.com/nextime)
166 - added --private-template/--private-home
167xee5ch (https://github.com/xee5ch)
168 - skypeforlinux profile
169Peter Hogg (https://github.com/pigmonkey)
170 - WeeChat profile
171 - rtorrent profile
172 - bitlbee profile fixes
173 - mutt profile fixes
174Thomas Jarosch (https://github.com/thomasjfox)
175 - disable keepassx in disable-passwdmgr.inc
176 - added uudeview profile
177 - added tar (gtar), unzip and unrar profile
178 - added file profile
179 - improved profile list
180 - fixed small variable glitch in stat64() / lstat64() (libtracelog)
181 - added lstat() / lstat64() support to libtrace
182 - include mkuid.sh in make dist
183Niklas Haas (https://github.com/haasn)
184 - blacklisting for keybase.io's client
185Jaykishan Mutkawoa (https://github.com/jmutkawoa)
186 - cpio profile
187Paupiah Yash (https://github.com/CaffeinatedStud)
188 - gzip profile
189Akhil Hans Maulloo (https://github.com/kouul)
190 - xz profile
191Rahul Golam (https://github.com/technoLord)
192 - strings profile
193geg2048 (https://github.com/geg2048)
194 - kwallet profile fixes
195maces (https://github.com/maces)
196 - Franz messenger profile
197KellerFuchs (https://github.com/KellerFuchs)
198 - nonewpriv support, extended profiles for this feature
199 - make `restricted-network` prevent use of netfilter
200 - disable-common.inc additions
201ValdikSS (https://github.com/ValdikSS)
202 - Psi+, Corebird, Konversation profiles
203 - various profile fixes
28avoidr (https://github.com/avoidr) 204avoidr (https://github.com/avoidr)
29 - whitelist fix 205 - whitelist fix
30 - recently-used.xbel fix 206 - recently-used.xbel fix
31 - added parole profile 207 - added parole profile
32 - blacklist ncat, manpage fixes, 208 - blacklist ncat
33 - hostname support in profile file 209 - hostname support in profile file
34 - Google Chrome profile rework 210 - Google Chrome profile rework
35 - added cmus profile 211 - added cmus profile
@@ -37,6 +213,17 @@ avoidr (https://github.com/avoidr)
37 - add net iface support in profile files 213 - add net iface support in profile files
38 - paths fix 214 - paths fix
39 - lots of profile fixes 215 - lots of profile fixes
216 - added mcabber profile
217 - fixed mpv profile
218 - various other fixes
219Ruan (https://github.com/ruany)
220 - fixed hexchat profile
221Matthew Gyurgyik (https://github.com/pyther)
222 - rpm spec and several fixes
223Joan Figueras (https://github.com/figue)
224 - added abrowser profile
225 - added Google-Play-Music-Desktop-Player
226 - added cyberfox profile
40Petter Reinholdtsen (pere@hungry.com) 227Petter Reinholdtsen (pere@hungry.com)
41 - Opera profile patch 228 - Opera profile patch
42n1trux (https://github.com/n1trux) 229n1trux (https://github.com/n1trux)
@@ -52,12 +239,9 @@ dshmgh (https://github.com/dshmgh)
52yumkam (https://github.com/yumkam) 239yumkam (https://github.com/yumkam)
53 - add compile-time option to restrict --net= to root only 240 - add compile-time option to restrict --net= to root only
54 - man page fixes 241 - man page fixes
55Vasya Novikov (https://github.com/vn971)
56 - Wesnoth profile
57 - Hedegewars profile
58 - manpage fixes
59mahdi1234 (https://github.com/mahdi1234) 242mahdi1234 (https://github.com/mahdi1234)
60 - cherrytree profile 243 - cherrytree profile
244 - Seamonkey profiles
61jrabe (https://github.com/jrabe) 245jrabe (https://github.com/jrabe)
62 - disallow access to kdbx files 246 - disallow access to kdbx files
63 - Epiphany profile 247 - Epiphany profile
@@ -71,19 +255,14 @@ Tom Mellor (https://github.com/kalegrill)
71Martin Carpenter (https://github.com/mcarpenter) 255Martin Carpenter (https://github.com/mcarpenter)
72 - security audit and bug fixes 256 - security audit and bug fixes
73 - Centos 6.x support 257 - 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) 258pszxzsd (https://github.com/pszxzsd)
79 -uGet profile 259 -uGet profile
80Rahiel Kasim (https://github.com/rahiel) 260Rahiel Kasim (https://github.com/rahiel)
81 - Mathematica profile 261 - Mathematica profile
262 - whitelisted Dropbox profile
263 - whitelisted keysnail config for firefox
82creideiki (https://github.com/creideiki) 264creideiki (https://github.com/creideiki)
83 - make the sandbox process reap all children 265 - 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) 266sinkuu (https://github.com/sinkuu)
88 - blacklisting kwalletd 267 - blacklisting kwalletd
89 - fix symlink invocation for programs placing symlinks in $PATH 268 - fix symlink invocation for programs placing symlinks in $PATH
@@ -93,8 +272,7 @@ Holger Heinz (https://github.com/hheinz)
93 - manpage work 272 - manpage work
94Andrey Alekseenko (https://github.com/al42and) 273Andrey Alekseenko (https://github.com/al42and)
95 - fixing lintian warnings 274 - fixing lintian warnings
96mahdi1234 (https://github.com/mahdi1234) 275 - fixed Skype profile
97 - Seamonkey profiles
98Ivan Kozik (https://github.com/ivan) 276Ivan Kozik (https://github.com/ivan)
99 - speed up sandbox exit 277 - speed up sandbox exit
100Christian Stadelmann (https://github.com/genodeftest) 278Christian Stadelmann (https://github.com/genodeftest)
@@ -105,11 +283,6 @@ Kaan Genç (https://github.com/SeriousBug)
105 - dynamic allocation of noblacklist buffer 283 - dynamic allocation of noblacklist buffer
106Veeti Paananen (https://github.com/veeti) 284Veeti Paananen (https://github.com/veeti)
107 - fixed Spotify profile 285 - 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) 286rogshdo (https://github.com/rogshdo)
114 - BitlBee profile 287 - BitlBee profile
115Bruno Nova (https://github.com/brunonova) 288Bruno Nova (https://github.com/brunonova)
@@ -117,8 +290,6 @@ Bruno Nova (https://github.com/brunonova)
117 - bash arguments fix 290 - bash arguments fix
118Matt Parnell (https://github.com/ilikenwf) 291Matt Parnell (https://github.com/ilikenwf)
119 - whitelisting for core firefox related functionality 292 - whitelisting for core firefox related functionality
120Andrey Alekseenko (https://github.com/al42and)
121 - fixed Skype profile
122Ondra Nekola (https://github.com/satai) 293Ondra Nekola (https://github.com/satai)
123 - allow firefox theming with non-global themes 294 - allow firefox theming with non-global themes
124emacsomancer (https://github.com/emacsomancer) 295emacsomancer (https://github.com/emacsomancer)
@@ -132,8 +303,6 @@ andrew160 (https://github.com/andrew160)
132 - profile and man pages fixes 303 - profile and man pages fixes
133Loïc Damien (https://github.com/dzamlo) 304Loïc Damien (https://github.com/dzamlo)
134 - small fixes 305 - small fixes
135Matthew Gyurgyik (https://github.com/pyther)
136 - rpm spec and several fixes
137greigdp (https://github.com/greigdp) 306greigdp (https://github.com/greigdp)
138 - add Spotify profile 307 - add Spotify profile
139Mattias Wadman (https://github.com/wader) 308Mattias Wadman (https://github.com/wader)
@@ -150,12 +319,6 @@ sarneaud (https://github.com/sarneaud)
150 - various enhancements and bug fixes 319 - various enhancements and bug fixes
151Patrick Toomey (http://sourceforge.net/u/ptoomey/profile/) 320Patrick Toomey (http://sourceforge.net/u/ptoomey/profile/)
152 - user namespace implementation 321 - 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/) 322sshirokov (http://sourceforge.net/u/yshirokov/profile/)
160 - Patch to output "Reading profile" to stderr instead of stdout 323 - Patch to output "Reading profile" to stderr instead of stdout
161G4JC (http://sourceforge.net/u/gaming4jc/profile/) 324G4JC (http://sourceforge.net/u/gaming4jc/profile/)
diff --git a/README.md b/README.md
index 7f6f573b4..609533a91 100644
--- a/README.md
+++ b/README.md
@@ -31,255 +31,62 @@ 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
36`````
37# Current development version: 0.9.40-rc2
38Version 0.9.40-rc1 released!
39
40## X11 sandboxing support
41
42X11 support is built around Xpra (http://xpra.org/) or Xephyr.
43`````
44 --x11 Start a new X11 server using Xpra or Xephyr and attach the sand‐
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 34
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
110 --ls=pid dir_or_filename
111 List container files. The container is specified by process ID.
112 Full path is needed for dir_or_filename.
113
114 Examples:
115
116 $ firejail --name=mybrowser --private firefox
117
118 $ firejail --ls=mybrowser ~/Downloads
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````` 35`````
127 36
128## Firecfg
129````` 37`````
130NAME 38## User submitted profile repositories
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 39
142 The symbolic links are placed in /usr/local/bin. For more information, 40If you keep your Firejail profiles in a public repository, please give us a link:
143 see DESKTOP INTEGRATION section in man 1 firejail.
144 41
145OPTIONS 42* https://github.com/chiraag-nataraj/firejail-profiles
146 --clear
147 Clear all firejail symbolic links
148 43
149 -?, --help 44* https://github.com/triceratops1/fe
150 Print options end exit.
151 45
152 --list List all firejail symbolic links 46Use this issue to request new profiles: https://github.com/netblue30/firejail/issues/825
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````` 47`````
172 48
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````` 49`````
187 bind Enable or disable bind support, default enabled. 50# Current development version: 0.9.45
188
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````` 51`````
220 52
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````` 53`````
229 *filter 54## AppImage type 2 support
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````` 55`````
246 56
247The filter is loaded by default for Firefox if a network namespace is configured:
248`````
249$ firejail --net=eth0 firefox
250````` 57`````
251 58## New command line options
252## Set sandbox nice value
253````` 59`````
254 --nice=value 60 --private-opt=file,directory
255 Set nice value for all processes running inside the sandbox. 61 Build a new /opt in a temporary filesystem, and copy the files
62 and directories in the list. If no listed file is found, /opt
63 directory will be empty. All modifications are discarded when
64 the sandbox is closed.
256 65
257 Example: 66 Example:
258 $ firejail --nice=-5 firefox 67 $ firejail --private-opt=firefox /opt/firefox/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 68
272 mkdir ~/.mozilla 69 --private-srv=file,directory
273 whitelist ~/.mozilla 70 Build a new /srv in a temporary filesystem, and copy the files
274 mkdir ~/.cache 71 and directories in the list. If no listed file is found, /srv
275 mkdir ~/.cache/mozilla 72 directory will be empty. All modifications are discarded when
276 mkdir ~/.cache/mozilla/firefox 73 the sandbox is closed.
277 whitelist ~/.cache/mozilla/firefox
278 74
279[...] 75 Example:
280````` 76 # firejail --private-srv=www /etc/init.d/apache2 start
281 77
282## New security profiles 78 --machine-id
283lxterminal, Epiphany, cherrytree, Polari, Vivaldi, Atril, qutebrowser, SlimJet, Battle for Wesnoth, Hedgewars, qTox, 79 Preserve id number in /etc/machine-id file. By default a new
284OpenSSH client, OpenBox window manager, Dillo, cmus, dnsmasq, PaleMoon, Icedove, abrowser, 0ad 80 random id is generated inside the sandbox.
285 81
82 Example:
83 $ firejail --machine-id
84`````
85## New Profiles
86xiphos, Tor Browser Bundle, display (imagemagik), Wire, mumble, zoom, Guayadeque, qemu, keypass2,
87amarok, ark, atool, bleachbit, brasero, dolphin, dragon, elinks, enchant, exiftool, file-roller, gedit,
88gjs, gnome-books, gnome-clocks, gnome-documents, gnome-maps, gnome-music, gnome-photos, gnome-weather,
89goobox, gpa, gpg, gpg-agent, highlight, img2txt, k3b, kate, lynx, mediainfo, nautilus, odt2txt, pdftotext,
90simple-scan, skanlite, ssh-agent, tracker, transmission-cli, transmission-show, w3m, xfburn, xpra, wget,
91xed, pluma, Cryptocat, Bless, Gnome 2048, Gnome Calculator, Gnome Contacts, JD-GUI, Lollypop, MultiMC5,
92PDFSam, Pithos, Xonotic, wireshark
diff --git a/RELNOTES b/RELNOTES
index fbd620408..064553f98 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -1,12 +1,113 @@
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 * security: split file copying in private option in a separate executable
9 * feature: disable gnupg and systemd directories under /run/user
10 * feature: allow root user access to /dev/shm (--noblacklist=/dev/shm)
11 * feature: AppImage type 2 support
12 * feature: test coverage (gcov) support
13 * feature: private /opt directory (--private-opt, profile support)
14 * feature: private /srv directory (--private-srv, profile support)
15 * feature: spoof machine-id
16 * feature: config support for firejail prompt in terminal
17 * new profiles: xiphos, Tor Browser Bundle, display (imagemagik), Wire,
18 * new profiles: mumble, zoom, Guayadeque, qemu, keypass2, xed, pluma,
19 * new profiles: Cryptocat, Bless, Gnome 2048, Gnome Calculator,
20 * new profiles: Gnome Contacts, JD-GUI, Lollypop, MultiMC5, PDFSam, Pithos,
21 * new profies: Xonotic, wireshark
22 * bugfixes
23 -- netblue30 <netblue30@yahoo.com> Sun, 23 Oct 2016 08:00:00 -0500
24
25firejail (0.9.44) baseline; urgency=low
26 * CVE-2016-7545 submitted by Aleksey Manevich
27 * modifs: removed man firejail-config
28 * modifs: --private-tmp whitelists /tmp/.X11-unix directory
29 * modifs: Nvidia drivers added to --private-dev
30 * modifs: /srv supported by --whitelist
31 * feature: allow user access to /sys/fs (--noblacklist=/sys/fs)
32 * feature: support starting/joining sandbox is a single command
33 (--join-or-start)
34 * feature: X11 detection support for --audit
35 * feature: assign a name to the interface connected to the bridge
36 (--veth-name)
37 * feature: all user home directories are visible (--allusers)
38 * feature: add files to sandbox container (--put)
39 * feature: blocking x11 (--x11=block)
40 * feature: X11 security extension (--x11=xorg)
41 * feature: disable 3D hardware acceleration (--no3d)
42 * feature: x11 xpra, x11 xephyr, x11 block, allusers, no3d profile commands
43 * feature: move files in sandbox (--put)
44 * feature: accept wildcard patterns in user name field of restricted
45 shell login feature
46 * new profiles: qpdfview, mupdf, Luminance HDR, Synfig Studio, Gimp, Inkscape
47 * new profiles: feh, ranger, zathura, 7z, keepass, keepassx,
48 * new profiles: claws-mail, mutt, git, emacs, vim, xpdf, VirtualBox, OpenShot
49 * new profiles: Flowblade, Eye of GNOME (eog), Evolution
50 * bugfixes
51 -- netblue30 <netblue30@yahoo.com> Fri, 21 Oct 2016 08:00:00 -0500
52
53firejail (0.9.42) baseline; urgency=low
54 * security: --whitelist deleted files, submitted by Vasya Novikov
55 * security: disable x32 ABI in seccomp, submitted by Jann Horn
56 * security: tighten --chroot, submitted by Jann Horn
57 * security: terminal sandbox escape, submitted by Stephan Sokolow
58 * security: several TOCTOU fixes submitted by Aleksey Manevich
59 * modifs: bringing back --private-home option
60 * modifs: deprecated --user option, please use "sudo -u username firejail"
61 * modifs: allow symlinks in home directory for --whitelist option
62 * modifs: Firejail prompt is enabled by env variable FIREJAIL_PROMPT="yes"
63 * modifs: recursive mkdir
64 * modifs: include /dev/snd in --private-dev
65 * modifs: seccomp filter update
66 * modifs: release archives moved to .xz format
67 * feature: AppImage support (--appimage)
68 * feature: AppArmor support (--apparmor)
69 * feature: Ubuntu snap support (/etc/firejail/snap.profile)
70 * feature: Sandbox auditing support (--audit)
71 * feature: remove environment variable (--rmenv)
72 * feature: noexec support (--noexec)
73 * feature: clean local overlay storage directory (--overlay-clean)
74 * feature: store and reuse overlay (--overlay-named)
75 * feature: allow debugging inside the sandbox with gdb and strace
76 (--allow-debuggers)
77 * feature: mkfile profile command
78 * feature: quiet profile command
79 * feature: x11 profile command
80 * feature: option to fix desktop files (firecfg --fix)
81 * compile time: Busybox support (--enable-busybox-workaround)
82 * compile time: disable overlayfs (--disable-overlayfs)
83 * compile time: disable whitlisting (--disable-whitelist)
84 * compile time: disable global config (--disable-globalcfg)
85 * run time: enable/disable overlayfs (overlayfs yes/no)
86 * run time: enable/disable quiet as default (quiet-by-default yes/no)
87 * run time: user-defined network filter (netfilter-default)
88 * run time: enable/disable whitelisting (whitelist yes/no)
89 * run time: enable/disable remounting of /proc and /sys
90 (remount-proc-sys yes/no)
91 * run time: enable/disable chroot desktop features (chroot-desktop yes/no)
92 * profiles: Gitter, gThumb, mpv, Franz messenger, LibreOffice
93 * profiles: pix, audacity, xz, xzdec, gzip, cpio, less
94 * profiles: Atom Beta, Atom, jitsi, eom, uudeview
95 * profiles: tar (gtar), unzip, unrar, file, skypeforlinux,
96 * profiles: inox, Slack, gnome-chess. Gajim IM client, DOSBox
97 * bugfixes
98 -- netblue30 <netblue30@yahoo.com> Thu, 8 Sept 2016 08:00:00 -0500
99
100firejail (0.9.40) baseline; urgency=low
2 * added --nice option 101 * added --nice option
3 * added --x11 option 102 * added --x11 option
4 * added --x11=xpra option 103 * added --x11=xpra option
5 * added --x11=xephyr option 104 * added --x11=xephyr option
6 * added --cpu.print option 105 * added --cpu.print option
7 * added filetransfer options --ls and --get 106 * added filetransfer options --ls and --get
107 * added --writable-etc and --writable-var options
108 * added --read-only option
8 * added mkdir, ipc-namespace, and nosound profile commands 109 * added mkdir, ipc-namespace, and nosound profile commands
9 * added net iface, and iprange profile commands 110 * added net, ip, defaultgw, ip6, mac, mtu and iprange profile commands
10 * --version also prints compile options 111 * --version also prints compile options
11 * --output option also redirects stderr 112 * --output option also redirects stderr
12 * added compile-time option to restrict --net= to root only 113 * added compile-time option to restrict --net= to root only
@@ -18,10 +119,16 @@ firejail (0.9.40-rc1) baseline; urgency=low
18 * new profiles: lxterminal, Epiphany, cherrytree, Polari, Vivaldi, Atril 119 * new profiles: lxterminal, Epiphany, cherrytree, Polari, Vivaldi, Atril
19 * new profiles: qutebrowser, SlimJet, Battle for Wesnoth, Hedgewars 120 * new profiles: qutebrowser, SlimJet, Battle for Wesnoth, Hedgewars
20 * new profiles: qTox, OpenSSH client, OpenBox, Dillo, cmus, dnsmasq 121 * new profiles: qTox, OpenSSH client, OpenBox, Dillo, cmus, dnsmasq
21 * new profiles: PaleMoon, Icedove, abrowser, 0ad 122 * new profiles: PaleMoon, Icedove, abrowser, 0ad, netsurf, Warzone2100
123 * new profiles: okular, gwenview, Google-Play-Music-Desktop-Player
124 * new profiles: Aweather, Stellarium, gpredict, quiterss, cyberfox
125 * new profiles: generic Ubuntu snap application profile, xplayer
126 * new profiles: xreader, xviewer, mcabber, Psi+, Corebird, Konversation
127 * new profiles: Brave, Gitter
128 * generic.profile renamed default.profile
22 * build rpm packages using "make rpms" 129 * build rpm packages using "make rpms"
23 * bugfixes 130 * bugfixes
24 -- netblue30 <netblue30@yahoo.com> Sun, 3 Apr 2016 08:00:00 -0500 131 -- netblue30 <netblue30@yahoo.com> Sun, 29 May 2016 08:00:00 -0500
25 132
26firejail (0.9.38) baseline; urgency=low 133firejail (0.9.38) baseline; urgency=low
27 * IPv6 support (--ip6 and --netfilter6) 134 * IPv6 support (--ip6 and --netfilter6)
diff --git a/configure b/configure
index 73a5c89e6..9efba1b1d 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/fcopy/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,17 @@ 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/fcopy/Makefile") CONFIG_FILES="$CONFIG_FILES src/fcopy/Makefile" ;;
4492 "src/fnet/Makefile") CONFIG_FILES="$CONFIG_FILES src/fnet/Makefile" ;;
4354 "src/firejail/Makefile") CONFIG_FILES="$CONFIG_FILES src/firejail/Makefile" ;; 4493 "src/firejail/Makefile") CONFIG_FILES="$CONFIG_FILES src/firejail/Makefile" ;;
4355 "src/firemon/Makefile") CONFIG_FILES="$CONFIG_FILES src/firemon/Makefile" ;; 4494 "src/firemon/Makefile") CONFIG_FILES="$CONFIG_FILES src/firemon/Makefile" ;;
4356 "src/libtrace/Makefile") CONFIG_FILES="$CONFIG_FILES src/libtrace/Makefile" ;; 4495 "src/libtrace/Makefile") CONFIG_FILES="$CONFIG_FILES src/libtrace/Makefile" ;;
4357 "src/libtracelog/Makefile") CONFIG_FILES="$CONFIG_FILES src/libtracelog/Makefile" ;; 4496 "src/libtracelog/Makefile") CONFIG_FILES="$CONFIG_FILES src/libtracelog/Makefile" ;;
4358 "src/firecfg/Makefile") CONFIG_FILES="$CONFIG_FILES src/firecfg/Makefile" ;; 4497 "src/firecfg/Makefile") CONFIG_FILES="$CONFIG_FILES src/firecfg/Makefile" ;;
4359 "src/ftee/Makefile") CONFIG_FILES="$CONFIG_FILES src/ftee/Makefile" ;; 4498 "src/ftee/Makefile") CONFIG_FILES="$CONFIG_FILES src/ftee/Makefile" ;;
4499 "src/faudit/Makefile") CONFIG_FILES="$CONFIG_FILES src/faudit/Makefile" ;;
4500 "src/libconnect/Makefile") CONFIG_FILES="$CONFIG_FILES src/libconnect/Makefile" ;;
4501 "src/fseccomp/Makefile") CONFIG_FILES="$CONFIG_FILES src/fseccomp/Makefile" ;;
4360 4502
4361 *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; 4503 *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
4362 esac 4504 esac
@@ -4818,13 +4960,22 @@ echo " prefix: $prefix"
4818echo " sysconfdir: $sysconfdir" 4960echo " sysconfdir: $sysconfdir"
4819echo " seccomp: $HAVE_SECCOMP" 4961echo " seccomp: $HAVE_SECCOMP"
4820echo " <linux/seccomp.h>: $HAVE_SECCOMP_H" 4962echo " <linux/seccomp.h>: $HAVE_SECCOMP_H"
4963echo " apparmor: $HAVE_APPARMOR"
4964echo " global config: $HAVE_GLOBALCFG"
4821echo " chroot: $HAVE_CHROOT" 4965echo " chroot: $HAVE_CHROOT"
4822echo " bind: $HAVE_BIND" 4966echo " bind: $HAVE_BIND"
4823echo " network: $HAVE_NETWORK" 4967echo " network: $HAVE_NETWORK"
4824echo " user namespace: $HAVE_USERNS" 4968echo " user namespace: $HAVE_USERNS"
4825echo " X11 sandboxing support: $HAVE_X11" 4969echo " X11 sandboxing support: $HAVE_X11"
4970echo " whitelisting: $HAVE_WHITELIST"
4971echo " private home support: $HAVE_PRIVATE_HOME"
4826echo " file transfer support: $HAVE_FILE_TRANSFER" 4972echo " file transfer support: $HAVE_FILE_TRANSFER"
4973echo " overlayfs support: $HAVE_OVERLAYFS"
4974echo " busybox workaround: $BUSYBOX_WORKAROUND"
4975echo " EXTRA_LDFLAGS: $EXTRA_LDFLAGS"
4827echo " fatal warnings: $HAVE_FATAL_WARNINGS" 4976echo " fatal warnings: $HAVE_FATAL_WARNINGS"
4977echo " Gcov instrumentation: $HAVE_GCOV"
4828echo 4978echo
4829 4979
4830 4980
4981
diff --git a/configure.ac b/configure.ac
index a4486b3ff..f3076f2f8 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,9 @@ 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/fcopy/Makefile src/fnet/Makefile src/firejail/Makefile \
162src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile \
163src/ftee/Makefile src/faudit/Makefile src/libconnect/Makefile src/fseccomp/Makefile)
94 164
95echo 165echo
96echo "Configuration options:" 166echo "Configuration options:"
@@ -98,13 +168,22 @@ echo " prefix: $prefix"
98echo " sysconfdir: $sysconfdir" 168echo " sysconfdir: $sysconfdir"
99echo " seccomp: $HAVE_SECCOMP" 169echo " seccomp: $HAVE_SECCOMP"
100echo " <linux/seccomp.h>: $HAVE_SECCOMP_H" 170echo " <linux/seccomp.h>: $HAVE_SECCOMP_H"
171echo " apparmor: $HAVE_APPARMOR"
172echo " global config: $HAVE_GLOBALCFG"
101echo " chroot: $HAVE_CHROOT" 173echo " chroot: $HAVE_CHROOT"
102echo " bind: $HAVE_BIND" 174echo " bind: $HAVE_BIND"
103echo " network: $HAVE_NETWORK" 175echo " network: $HAVE_NETWORK"
104echo " user namespace: $HAVE_USERNS" 176echo " user namespace: $HAVE_USERNS"
105echo " X11 sandboxing support: $HAVE_X11" 177echo " X11 sandboxing support: $HAVE_X11"
178echo " whitelisting: $HAVE_WHITELIST"
179echo " private home support: $HAVE_PRIVATE_HOME"
106echo " file transfer support: $HAVE_FILE_TRANSFER" 180echo " file transfer support: $HAVE_FILE_TRANSFER"
181echo " overlayfs support: $HAVE_OVERLAYFS"
182echo " busybox workaround: $BUSYBOX_WORKAROUND"
183echo " EXTRA_LDFLAGS: $EXTRA_LDFLAGS"
107echo " fatal warnings: $HAVE_FATAL_WARNINGS" 184echo " fatal warnings: $HAVE_FATAL_WARNINGS"
185echo " Gcov instrumentation: $HAVE_GCOV"
108echo 186echo
109 187
110 188
189
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/Cryptocat.profile b/etc/Cryptocat.profile
new file mode 100644
index 000000000..3db34c03c
--- /dev/null
+++ b/etc/Cryptocat.profile
@@ -0,0 +1,20 @@
1# Firejail profile for
2noblacklist ${HOME}/.config/Cryptocat
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
14nosound
15protocol unix,inet,inet6,netlink
16seccomp
17shell none
18
19private-dev
20private-tmp
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..481301420 100644
--- a/etc/abrowser.profile
+++ b/etc/abrowser.profile
@@ -1,5 +1,4 @@
1# Firejail profile for Abrowser 1# Firejail profile for Abrowser
2
3noblacklist ~/.mozilla 2noblacklist ~/.mozilla
4noblacklist ~/.cache/mozilla 3noblacklist ~/.cache/mozilla
5include /etc/firejail/disable-common.inc 4include /etc/firejail/disable-common.inc
@@ -7,17 +6,16 @@ include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-devel.inc 6include /etc/firejail/disable-devel.inc
8 7
9caps.drop all 8caps.drop all
10seccomp
11protocol unix,inet,inet6,netlink
12netfilter 9netfilter
13tracelog 10nonewprivs
14noroot 11noroot
12protocol unix,inet,inet6,netlink
13seccomp
14tracelog
15 15
16whitelist ${DOWNLOADS} 16whitelist ${DOWNLOADS}
17mkdir ~/.mozilla 17mkdir ~/.mozilla
18whitelist ~/.mozilla 18whitelist ~/.mozilla
19mkdir ~/.cache
20mkdir ~/.cache/mozilla
21mkdir ~/.cache/mozilla/abrowser 19mkdir ~/.cache/mozilla/abrowser
22whitelist ~/.cache/mozilla/abrowser 20whitelist ~/.cache/mozilla/abrowser
23whitelist ~/dwhelper 21whitelist ~/dwhelper
@@ -40,13 +38,12 @@ whitelist ~/.config/lastpass
40 38
41 39
42#silverlight 40#silverlight
43whitelist ~/.wine-pipelight 41whitelist ~/.wine-pipelight
44whitelist ~/.wine-pipelight64 42whitelist ~/.wine-pipelight64
45whitelist ~/.config/pipelight-widevine 43whitelist ~/.config/pipelight-widevine
46whitelist ~/.config/pipelight-silverlight5.1 44whitelist ~/.config/pipelight-silverlight5.1
47 45
48include /etc/firejail/whitelist-common.inc 46include /etc/firejail/whitelist-common.inc
49 47
50# experimental features 48# 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 49#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/amarok.profile b/etc/amarok.profile
new file mode 100644
index 000000000..8d5b35d47
--- /dev/null
+++ b/etc/amarok.profile
@@ -0,0 +1,19 @@
1# amarok 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
9nogroups
10nonewprivs
11noroot
12shell none
13#seccomp
14protocol unix,inet,inet6
15
16#private-bin amarok
17private-dev
18private-tmp
19#private-etc none
diff --git a/etc/ark.profile b/etc/ark.profile
new file mode 100644
index 000000000..61b4c6f60
--- /dev/null
+++ b/etc/ark.profile
@@ -0,0 +1,23 @@
1# ark profile
2noblacklist ~/.config/arkrc
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
14nosound
15shell none
16seccomp
17protocol unix
18
19# private-bin
20private-dev
21private-tmp
22# private-etc
23
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/atool.profile b/etc/atool.profile
new file mode 100644
index 000000000..3fbfb9fc7
--- /dev/null
+++ b/etc/atool.profile
@@ -0,0 +1,24 @@
1# atool profile
2include /etc/firejail/disable-common.inc
3include /etc/firejail/disable-programs.inc
4# include /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# private-bin atool
20private-tmp
21private-dev
22private-etc none
23
24
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/bleachbit.profile b/etc/bleachbit.profile
new file mode 100644
index 000000000..0a71db9f0
--- /dev/null
+++ b/etc/bleachbit.profile
@@ -0,0 +1,21 @@
1# bleachbit profile
2include /etc/firejail/disable-common.inc
3# include /etc/firejail/disable-programs.inc
4include /etc/firejail/disable-devel.inc
5include /etc/firejail/disable-passwdmgr.inc
6
7caps.drop all
8netfilter
9nogroups
10nonewprivs
11noroot
12nosound
13shell none
14seccomp
15protocol unix
16
17# private-bin
18# private-dev
19# private-tmp
20# private-etc
21
diff --git a/etc/bless.profile b/etc/bless.profile
new file mode 100644
index 000000000..752edadf7
--- /dev/null
+++ b/etc/bless.profile
@@ -0,0 +1,20 @@
1#
2#Profile for bless
3#
4
5#No Blacklist Paths
6noblacklist ${HOME}/.config/bless
7
8#Blacklist Paths
9include /etc/firejail/disable-common.inc
10include /etc/firejail/disable-programs.inc
11include /etc/firejail/disable-passwdmgr.inc
12include /etc/firejail/disable-devel.inc
13
14#Options
15caps.drop all
16netfilter
17nonewprivs
18noroot
19protocol unix,inet,inet6
20seccomp
diff --git a/etc/brasero.profile b/etc/brasero.profile
new file mode 100644
index 000000000..66de6fa50
--- /dev/null
+++ b/etc/brasero.profile
@@ -0,0 +1,23 @@
1# brasero profile
2noblacklist ~/.config/brasero
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
16netfilter
17shell none
18tracelog
19
20# private-bin brasero
21# private-tmp
22# private-dev
23# private-etc fonts
diff --git a/etc/brave.profile b/etc/brave.profile
new file mode 100644
index 000000000..21ea7f908
--- /dev/null
+++ b/etc/brave.profile
@@ -0,0 +1,17 @@
1# Profile for Brave browser
2noblacklist ~/.config/brave
3include /etc/firejail/disable-common.inc
4include /etc/firejail/disable-programs.inc
5include /etc/firejail/disable-devel.inc
6
7caps.drop all
8netfilter
9nonewprivs
10noroot
11protocol unix,inet,inet6,netlink
12seccomp
13
14whitelist ${DOWNLOADS}
15
16mkdir ~/.config/brave
17whitelist ~/.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..8921bb25e
--- /dev/null
+++ b/etc/claws-mail.profile
@@ -0,0 +1,23 @@
1# claws-mail profile
2noblacklist ~/.claws-mail
3noblacklist ~/.signature
4noblacklist ~/.gnupg
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
14noroot
15nogroups
16nosound
17protocol unix,inet,inet6
18seccomp
19shell none
20
21private-dev
22private-tmp
23
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..6fb8219e8
--- /dev/null
+++ b/etc/corebird.profile
@@ -0,0 +1,11 @@
1# Firejail corebird 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
9noroot
10protocol unix,inet,inet6
11seccomp
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/cryptocat.profile b/etc/cryptocat.profile
new file mode 100644
index 000000000..0d392b272
--- /dev/null
+++ b/etc/cryptocat.profile
@@ -0,0 +1 @@
include /etc/Cryptocat.profile
diff --git a/etc/cyberfox.profile b/etc/cyberfox.profile
new file mode 100644
index 000000000..84021dab3
--- /dev/null
+++ b/etc/cyberfox.profile
@@ -0,0 +1,49 @@
1# Firejail profile for Cyberfox (based on Mozilla Firefox)
2noblacklist ~/.8pecxstudios
3noblacklist ~/.cache/8pecxstudios
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
14tracelog
15
16whitelist ${DOWNLOADS}
17mkdir ~/.8pecxstudios
18whitelist ~/.8pecxstudios
19mkdir ~/.cache/8pecxstudios
20whitelist ~/.cache/8pecxstudios
21whitelist ~/dwhelper
22whitelist ~/.zotero
23whitelist ~/.vimperatorrc
24whitelist ~/.vimperator
25whitelist ~/.pentadactylrc
26whitelist ~/.pentadactyl
27whitelist ~/.keysnail.js
28whitelist ~/.config/gnome-mplayer
29whitelist ~/.cache/gnome-mplayer/plugin
30whitelist ~/.pki
31
32# lastpass, keepassx
33whitelist ~/.keepassx
34whitelist ~/.config/keepassx
35whitelist ~/keepassx.kdbx
36whitelist ~/.lastpass
37whitelist ~/.config/lastpass
38
39
40#silverlight
41whitelist ~/.wine-pipelight
42whitelist ~/.wine-pipelight64
43whitelist ~/.config/pipelight-widevine
44whitelist ~/.config/pipelight-silverlight5.1
45
46include /etc/firejail/whitelist-common.inc
47
48# experimental features
49#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/default.profile b/etc/default.profile
new file mode 100644
index 000000000..603321316
--- /dev/null
+++ b/etc/default.profile
@@ -0,0 +1,24 @@
1################################
2# Generic GUI application profile
3################################
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
13seccomp
14
15#
16# depending on you usage, you can enable some of the commands below:
17#
18# nogroups
19# shell none
20# private-bin program
21# private-etc none
22# private-dev
23# private-tmp
24
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..108787920 100644
--- a/etc/dillo.profile
+++ b/etc/dillo.profile
@@ -1,5 +1,4 @@
1# Firejail profile for Dillo web browser 1# Firejail profile for Dillo web browser
2
3noblacklist ~/.dillo 2noblacklist ~/.dillo
4include /etc/firejail/disable-common.inc 3include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc 4include /etc/firejail/disable-programs.inc
@@ -7,11 +6,12 @@ include /etc/firejail/disable-devel.inc
7include /etc/firejail/disable-passwdmgr.inc 6include /etc/firejail/disable-passwdmgr.inc
8 7
9caps.drop all 8caps.drop all
10seccomp
11protocol unix,inet,inet6
12netfilter 9netfilter
13tracelog 10nonewprivs
14noroot 11noroot
12protocol unix,inet,inet6
13seccomp
14tracelog
15 15
16whitelist ${DOWNLOADS} 16whitelist ${DOWNLOADS}
17mkdir ~/.dillo 17mkdir ~/.dillo
@@ -20,6 +20,3 @@ mkdir ~/.fltk
20whitelist ~/.fltk 20whitelist ~/.fltk
21 21
22include /etc/firejail/whitelist-common.inc 22include /etc/firejail/whitelist-common.inc
23
24
25
diff --git a/etc/disable-common.inc b/etc/disable-common.inc
index b1133f28f..b86c6f998 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,48 @@ 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/
27# blacklist ${HOME}/.xpra - this will kill --x11=xpra cmdline option for all programs
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
42# TrueCrypt
43blacklist ${PATH}/truecrypt
44blacklist ${PATH}/truecrypt-uninstall.sh
45blacklist /usr/share/truecrypt
46blacklist /usr/share/applications/truecrypt.*
47blacklist /usr/share/pixmaps/truecrypt.*
48blacklist ${HOME}/.TrueCrypt
49
50# zuluCrypt
51blacklist ${HOME}/.zuluCrypt
52blacklist ${HOME}/.zuluCrypt-socket
53blacklist ${PATH}/zuluCrypt-cli
54blacklist ${PATH}/zuluMount-cli
55
29# var 56# var
30blacklist /var/spool/cron 57blacklist /var/spool/cron
31blacklist /var/spool/anacron 58blacklist /var/spool/anacron
59blacklist /var/mail
32blacklist /var/run/acpid.socket 60blacklist /var/run/acpid.socket
33blacklist /var/run/minissdpd.sock 61blacklist /var/run/minissdpd.sock
34blacklist /var/run/rpcbind.sock 62blacklist /var/run/rpcbind.sock
@@ -39,7 +67,7 @@ blacklist /var/lib/mysql/mysql.sock
39blacklist /var/run/docker.sock 67blacklist /var/run/docker.sock
40 68
41# etc 69# etc
42blacklist /etc/cron.* 70blacklist /etc/cron*
43blacklist /etc/profile.d 71blacklist /etc/profile.d
44blacklist /etc/rc.local 72blacklist /etc/rc.local
45blacklist /etc/anacrontab 73blacklist /etc/anacrontab
@@ -50,11 +78,15 @@ read-only ${HOME}/.xserverrc
50read-only ${HOME}/.profile 78read-only ${HOME}/.profile
51 79
52# Shell startup files 80# Shell startup files
81read-only ${HOME}/.antigen
53read-only ${HOME}/.bash_login 82read-only ${HOME}/.bash_login
54read-only ${HOME}/.bashrc 83read-only ${HOME}/.bashrc
55read-only ${HOME}/.bash_profile 84read-only ${HOME}/.bash_profile
56read-only ${HOME}/.bash_logout 85read-only ${HOME}/.bash_logout
86read-only ${HOME}/.zsh.d
87read-only ${HOME}/.zshenv
57read-only ${HOME}/.zshrc 88read-only ${HOME}/.zshrc
89read-only ${HOME}/.zshrc.local
58read-only ${HOME}/.zlogin 90read-only ${HOME}/.zlogin
59read-only ${HOME}/.zprofile 91read-only ${HOME}/.zprofile
60read-only ${HOME}/.zlogout 92read-only ${HOME}/.zlogout
@@ -62,8 +94,12 @@ read-only ${HOME}/.zsh_files
62read-only ${HOME}/.tcshrc 94read-only ${HOME}/.tcshrc
63read-only ${HOME}/.cshrc 95read-only ${HOME}/.cshrc
64read-only ${HOME}/.csh_files 96read-only ${HOME}/.csh_files
97read-only ${HOME}/.profile
65 98
66# Initialization files that allow arbitrary command execution 99# Initialization files that allow arbitrary command execution
100read-only ${HOME}/.caffrc
101read-only ${HOME}/.dotfiles
102read-only ${HOME}/dotfiles
67read-only ${HOME}/.mailcap 103read-only ${HOME}/.mailcap
68read-only ${HOME}/.exrc 104read-only ${HOME}/.exrc
69read-only ${HOME}/_exrc 105read-only ${HOME}/_exrc
@@ -73,10 +109,11 @@ read-only ${HOME}/.gvimrc
73read-only ${HOME}/_gvimrc 109read-only ${HOME}/_gvimrc
74read-only ${HOME}/.vim 110read-only ${HOME}/.vim
75read-only ${HOME}/.emacs 111read-only ${HOME}/.emacs
112read-only ${HOME}/.emacs.d
113read-only ${HOME}/.nano
76read-only ${HOME}/.tmux.conf 114read-only ${HOME}/.tmux.conf
77read-only ${HOME}/.iscreenrc 115read-only ${HOME}/.iscreenrc
78read-only ${HOME}/.muttrc 116read-only ${HOME}/.reportbugrc
79read-only ${HOME}/.mutt/muttrc
80read-only ${HOME}/.xmonad 117read-only ${HOME}/.xmonad
81read-only ${HOME}/.xscreensaver 118read-only ${HOME}/.xscreensaver
82 119
@@ -84,16 +121,25 @@ read-only ${HOME}/.xscreensaver
84read-only ${HOME}/bin 121read-only ${HOME}/bin
85 122
86# top secret 123# top secret
124blacklist ${HOME}/.ecryptfs
125blacklist ${HOME}/.Private
87blacklist ${HOME}/.ssh 126blacklist ${HOME}/.ssh
127blacklist ${HOME}/.cert
88blacklist ${HOME}/.gnome2/keyrings 128blacklist ${HOME}/.gnome2/keyrings
89blacklist ${HOME}/kde4/share/apps/kwallet 129blacklist ${HOME}/.kde4/share/apps/kwallet
90blacklist ${HOME}/kde/share/apps/kwallet 130blacklist ${HOME}/.kde/share/apps/kwallet
91blacklist ${HOME}/.local/share/kwalletd 131blacklist ${HOME}/.local/share/kwalletd
132blacklist ${HOME}/.config/keybase
92blacklist ${HOME}/.netrc 133blacklist ${HOME}/.netrc
93blacklist ${HOME}/.gnupg 134blacklist ${HOME}/.gnupg
135blacklist ${HOME}/.caff
136blacklist ${HOME}/.smbcredentials
94blacklist ${HOME}/*.kdbx 137blacklist ${HOME}/*.kdbx
95blacklist ${HOME}/*.kdb 138blacklist ${HOME}/*.kdb
96blacklist ${HOME}/*.key 139blacklist ${HOME}/*.key
140blacklist ${HOME}/.muttrc
141blacklist ${HOME}/.mutt/muttrc
142blacklist ${HOME}/.msmtprc
97blacklist /etc/shadow 143blacklist /etc/shadow
98blacklist /etc/gshadow 144blacklist /etc/gshadow
99blacklist /etc/passwd- 145blacklist /etc/passwd-
@@ -106,11 +152,19 @@ blacklist /etc/shadow+
106blacklist /etc/gshadow+ 152blacklist /etc/gshadow+
107blacklist /etc/ssh 153blacklist /etc/ssh
108blacklist /var/backup 154blacklist /var/backup
155blacklist /home/.ecryptfs
156
157# system directories
158blacklist /sbin
159blacklist /usr/sbin
160blacklist /usr/local/sbin
109 161
110# system management 162# system management
111blacklist ${PATH}/umount 163blacklist ${PATH}/umount
112blacklist ${PATH}/mount 164blacklist ${PATH}/mount
113blacklist ${PATH}/fusermount 165blacklist ${PATH}/fusermount
166blacklist ${PATH}/ntfs-3g
167blacklist ${PATH}/at
114blacklist ${PATH}/su 168blacklist ${PATH}/su
115blacklist ${PATH}/sudo 169blacklist ${PATH}/sudo
116blacklist ${PATH}/xinput 170blacklist ${PATH}/xinput
@@ -119,17 +173,45 @@ blacklist ${PATH}/xev
119blacklist ${PATH}/strace 173blacklist ${PATH}/strace
120blacklist ${PATH}/nc 174blacklist ${PATH}/nc
121blacklist ${PATH}/ncat 175blacklist ${PATH}/ncat
176blacklist ${PATH}/gpasswd
177blacklist ${PATH}/newgidmap
178blacklist ${PATH}/newgrp
179blacklist ${PATH}/newuidmap
180blacklist ${PATH}/pkexec
181blacklist ${PATH}/sg
182blacklist ${PATH}/crontab
183blacklist ${PATH}/ksu
184blacklist ${PATH}/chsh
185blacklist ${PATH}/chfn
186blacklist ${PATH}/chage
187blacklist ${PATH}/expiry
188blacklist ${PATH}/unix_chkpwd
189blacklist ${PATH}/procmail
190blacklist ${PATH}/mount.ecryptfs_private
122 191
123# system directories 192# other SUID binaries
124blacklist /sbin 193blacklist /usr/lib/virtualbox
125blacklist /usr/sbin
126blacklist /usr/local/sbin
127 194
128# prevent lxterminal connecting to an existing lxterminal session 195# prevent lxterminal connecting to an existing lxterminal session
129blacklist /tmp/.lxterminal-socket* 196blacklist /tmp/.lxterminal-socket*
130 197
131# disable terminals running as server 198# disable terminals running as server resulting in sandbox escape
132blacklist ${PATH}/gnome-terminal 199blacklist ${PATH}/gnome-terminal
133blacklist ${PATH}/gnome-terminal.wrapper 200blacklist ${PATH}/gnome-terminal.wrapper
134blacklist ${PATH}/xfce4-terminal 201blacklist ${PATH}/xfce4-terminal
135blacklist ${PATH}/xfce4-terminal.wrapper 202blacklist ${PATH}/xfce4-terminal.wrapper
203blacklist ${PATH}/mate-terminal
204blacklist ${PATH}/mate-terminal.wrapper
205blacklist ${PATH}/lilyterm
206blacklist ${PATH}/pantheon-terminal
207blacklist ${PATH}/roxterm
208blacklist ${PATH}/roxterm-config
209blacklist ${PATH}/terminix
210blacklist ${PATH}/urxvtc
211blacklist ${PATH}/urxvtcd
212#konsole doesn't seem to have this problem - last tested on Ubuntu 16.04
213#blacklist ${PATH}/konsole
214
215# kernel files
216blacklist /vmlinuz*
217blacklist /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..045b4d92b 100644
--- a/etc/disable-passwdmgr.inc
+++ b/etc/disable-passwdmgr.inc
@@ -1,6 +1,10 @@
1blacklist ${HOME}/.pki/nssdb 1blacklist ${HOME}/.pki/nssdb
2blacklist ${HOME}/.lastpass 2blacklist ${HOME}/.lastpass
3blacklist ${HOME}/.keepassx 3blacklist ${HOME}/.keepassx
4blacklist ${HOME}/.keepass
4blacklist ${HOME}/.password-store 5blacklist ${HOME}/.password-store
5blacklist ${HOME}/keepassx.kdbx 6blacklist ${HOME}/keepassx.kdbx
7blacklist ${HOME}/.config/keepassx
8blacklist ${HOME}/.config/keepass
9blacklist ${HOME}/.config/KeePass
6 10
diff --git a/etc/disable-programs.inc b/etc/disable-programs.inc
index f4e66dc66..a9ca487c5 100644
--- a/etc/disable-programs.inc
+++ b/etc/disable-programs.inc
@@ -1,168 +1,269 @@
1# various programs 1blacklist ${HOME}/.*coin
2blacklist ${HOME}/.8pecxstudios
2blacklist ${HOME}/.Atom 3blacklist ${HOME}/.Atom
3blacklist ${HOME}/.remmina
4blacklist ${HOME}/.tconn
5blacklist ${HOME}/.FBReader 4blacklist ${HOME}/.FBReader
6blacklist ${HOME}/.wine 5blacklist ${HOME}/.LuminanceHDR
7blacklist ${HOME}/.Mathematica 6blacklist ${HOME}/.Mathematica
7blacklist ${HOME}/.Natron
8blacklist ${HOME}/.Skype
9blacklist ${HOME}/.TelegramDesktop
10blacklist ${HOME}/.VirtualBox
8blacklist ${HOME}/.Wolfram Research 11blacklist ${HOME}/.Wolfram Research
9blacklist ${HOME}/.stellarium 12blacklist ${HOME}/.arduino15
10blacklist ${HOME}/.sword 13blacklist ${HOME}/.atom
11blacklist ${HOME}/.xiphos 14blacklist ${HOME}/.audacity-data
15blacklist ${HOME}/.bcast5
16blacklist ${HOME}/.cache/0ad
17blacklist ${HOME}/.cache/8pecxstudios
18blacklist ${HOME}/.cache/Franz
19blacklist ${HOME}/.cache/INRIA
20blacklist ${HOME}/.cache/QuiteRss
21blacklist ${HOME}/.cache/champlain
22blacklist ${HOME}/.cache/chromium
23blacklist ${HOME}/.cache/chromium-dev
24blacklist ${HOME}/.cache/darktable
25blacklist ${HOME}/.cache/epiphany
26blacklist ${HOME}/.cache/evolution
27blacklist ${HOME}/.cache/gajim
28blacklist ${HOME}/.cache/google-chrome
29blacklist ${HOME}/.cache/google-chrome-beta
30blacklist ${HOME}/.cache/google-chrome-unstable
31blacklist ${HOME}/.cache/icedove
32blacklist ${HOME}/.cache/inox
33blacklist ${HOME}/.cache/libgweather
34blacklist ${HOME}/.cache/midori
35blacklist ${HOME}/.cache/mozilla
36blacklist ${HOME}/.cache/mutt
37blacklist ${HOME}/.cache/netsurf
38blacklist ${HOME}/.cache/opera
39blacklist ${HOME}/.cache/opera-beta
40blacklist ${HOME}/.cache/org.gnome.Books
41blacklist ${HOME}/.cache/qutebrowser
42blacklist ${HOME}/.cache/simple-scan
43blacklist ${HOME}/.cache/slimjet
44blacklist ${HOME}/.cache/spotify
45blacklist ${HOME}/.cache/telepathy
46blacklist ${HOME}/.cache/thunderbird
47blacklist ${HOME}/.cache/torbrowser
48blacklist ${HOME}/.cache/transmission
49blacklist ${HOME}/.cache/vivaldi
50blacklist ${HOME}/.cache/wesnoth
51blacklist ${HOME}/.cache/xreader
52blacklist ${HOME}/.claws-mail
53blacklist ${HOME}/.config/0ad
12blacklist ${HOME}/.config/Atom 54blacklist ${HOME}/.config/Atom
13blacklist ${HOME}/.config/gthumb 55blacklist ${HOME}/.config/Brackets
14blacklist ${HOME}/.config/mupen64plus 56blacklist ${HOME}/.config/Cryptocat
15blacklist ${HOME}/.config/transmission 57blacklist ${HOME}/.config/Franz
16blacklist ${HOME}/.config/uGet 58blacklist ${HOME}/.config/Gitter
59blacklist ${HOME}/.config/Google
17blacklist ${HOME}/.config/Gpredict 60blacklist ${HOME}/.config/Gpredict
18blacklist ${HOME}/.config/aweather 61blacklist ${HOME}/.config/INRIA
19blacklist ${HOME}/.config/stellarium
20blacklist ${HOME}/.config/atril
21blacklist ${HOME}/.config/xreader
22blacklist ${HOME}/.config/xviewer
23blacklist ${HOME}/.config/libreoffice
24blacklist ${HOME}/.config/pix
25blacklist ${HOME}/.config/mate/eom
26blacklist ${HOME}/.kde/share/apps/okular
27blacklist ${HOME}/.kde/share/config/okularrc
28blacklist ${HOME}/.kde/share/config/okularpartrc
29blacklist ${HOME}/.kde/share/apps/gwenview
30blacklist ${HOME}/.kde/share/config/gwenviewrc
31blacklist ${HOME}/.config/qpdfview
32blacklist ${HOME}/.config/Luminance 62blacklist ${HOME}/.config/Luminance
33blacklist ${HOME}/.config/synfig 63blacklist ${HOME}/.config/Meltytech
34blacklist ${HOME}/.synfig 64blacklist ${HOME}/.config/Mumble
35blacklist ${HOME}/.inkscape 65blacklist ${HOME}/.config/QuiteRss
36blacklist ${HOME}/.gimp* 66blacklist ${HOME}/.config/QuiteRssrc
37blacklist ${HOME}/.config/zathura 67blacklist ${HOME}/.config/Slack
68blacklist ${HOME}/.config/VirtualBox
69blacklist ${HOME}/.config/Wire
70blacklist ${HOME}/.config/ardour4
71blacklist ${HOME}/.config/ardour5
72blacklist ${HOME}/.config/arkrc
73blacklist ${HOME}/.config/atril
74blacklist ${HOME}/.config/autostart
75blacklist ${HOME}/.config/autostart/dropbox.desktop
76blacklist ${HOME}/.config/aweather
77blacklist ${HOME}/.config/blender
78blacklist ${HOME}/.config/bless
79blacklist ${HOME}/.config/brasero
80blacklist ${HOME}/.config/brave
38blacklist ${HOME}/.config/cherrytree 81blacklist ${HOME}/.config/cherrytree
39blacklist ${HOME}/.xpdfrc 82blacklist ${HOME}/.config/chromium
40blacklist ${HOME}/.openshot 83blacklist ${HOME}/.config/chromium-dev
41blacklist ${HOME}/.openshot_qt 84blacklist ${HOME}/.config/chromium-flags.conf
42blacklist ${HOME}/.flowblade
43blacklist ${HOME}/.config/flowblade
44blacklist ${HOME}/.config/eog
45
46
47# Media players
48blacklist ${HOME}/.config/cmus 85blacklist ${HOME}/.config/cmus
86blacklist ${HOME}/.config/darktable
49blacklist ${HOME}/.config/deadbeef 87blacklist ${HOME}/.config/deadbeef
50blacklist ${HOME}/.config/spotify 88blacklist ${HOME}/.config/dolphinrc
51blacklist ${HOME}/.config/vlc 89blacklist ${HOME}/.config/dragonplayerrc
52blacklist ${HOME}/.config/mpv 90blacklist ${HOME}/.config/enchant
53blacklist ${HOME}/.config/totem 91blacklist ${HOME}/.config/eog
54blacklist ${HOME}/.config/xplayer 92blacklist ${HOME}/.config/epiphany
55blacklist ${HOME}/.audacity-data 93blacklist ${HOME}/.config/evince
56blacklist ${HOME}/.guayadeque 94blacklist ${HOME}/.config/evolution
57 95blacklist ${HOME}/.config/filezilla
58# HTTP / FTP / Mail 96blacklist ${HOME}/.config/flowblade
59blacklist ${HOME}/.icedove 97blacklist ${HOME}/.config/gajim
60blacklist ${HOME}/.thunderbird 98blacklist ${HOME}/.config/gedit
61blacklist ${HOME}/.sylpheed-2.0
62blacklist ${HOME}/.config/midori
63blacklist ${HOME}/.mozilla
64blacklist ${HOME}/.config/chromium
65blacklist ${HOME}/.config/google-chrome 99blacklist ${HOME}/.config/google-chrome
66blacklist ${HOME}/.config/google-chrome-beta 100blacklist ${HOME}/.config/google-chrome-beta
67blacklist ${HOME}/.config/google-chrome-unstable 101blacklist ${HOME}/.config/google-chrome-unstable
102blacklist ${HOME}/.config/gthumb
103blacklist ${HOME}/.config/hexchat
104blacklist ${HOME}/.config/inox
105blacklist ${HOME}/.config/jd-gui.cfg
106blacklist ${HOME}/.config/katepartrc
107blacklist ${HOME}/.config/katerc
108blacklist ${HOME}/.config/kateschemarc
109blacklist ${HOME}/.config/katesyntaxhighlightingrc
110blacklist ${HOME}/.config/katevirc
111blacklist ${HOME}/.config/libreoffice
112blacklist ${HOME}/.config/mate/eom
113blacklist ${HOME}/.config/midori
114blacklist ${HOME}/.config/mpv
115blacklist ${HOME}/.config/mupen64plus
116blacklist ${HOME}/.config/nautilus
117blacklist ${HOME}/.config/netsurf
68blacklist ${HOME}/.config/opera 118blacklist ${HOME}/.config/opera
69blacklist ${HOME}/.config/opera-beta 119blacklist ${HOME}/.config/opera-beta
70blacklist ${HOME}/.opera 120blacklist ${HOME}/.config/pix
71blacklist ${HOME}/.config/vivaldi 121blacklist ${HOME}/.config/pluma
72blacklist ${HOME}/.filezilla
73blacklist ${HOME}/.config/filezilla
74blacklist ${HOME}/.dillo
75blacklist ${HOME}/.conkeror.mozdev.org
76blacklist ${HOME}/.config/epiphany
77blacklist ${HOME}/.config/slimjet
78blacklist ${HOME}/.config/qutebrowser
79blacklist ${HOME}/.8pecxstudios
80blacklist ${HOME}/.config/brave
81blacklist ${HOME}/.config/inox
82blacklist ${HOME}/.muttrc
83blacklist ${HOME}/.mutt
84blacklist ${HOME}/.mutt/muttrc
85blacklist ${HOME}/.msmtprc
86blacklist ${HOME}/.config/evolution
87blacklist ${HOME}/.local/share/evolution
88blacklist ${HOME}/.cache/evolution
89
90# Instant Messaging
91blacklist ${HOME}/.config/hexchat
92blacklist ${HOME}/.mcabber
93blacklist ${HOME}/.mcabberrc
94blacklist ${HOME}/.purple
95blacklist ${HOME}/.config/psi+ 122blacklist ${HOME}/.config/psi+
96blacklist ${HOME}/.retroshare 123blacklist ${HOME}/.config/qpdfview
97blacklist ${HOME}/.weechat 124blacklist ${HOME}/.config/qutebrowser
98blacklist ${HOME}/.config/xchat 125blacklist ${HOME}/.config/ranger
99blacklist ${HOME}/.Skype 126blacklist ${HOME}/.config/redshift.conf
100blacklist ${HOME}/.config/skypeforlinux 127blacklist ${HOME}/.config/skypeforlinux
128blacklist ${HOME}/.config/slimjet
129blacklist ${HOME}/.config/spotify
130blacklist ${HOME}/.config/stellarium
131blacklist ${HOME}/.config/synfig
132blacklist ${HOME}/.config/telepathy-account-widgets
133blacklist ${HOME}/.config/torbrowser
134blacklist ${HOME}/.config/totem
101blacklist ${HOME}/.config/tox 135blacklist ${HOME}/.config/tox
102blacklist ${HOME}/.TelegramDesktop 136blacklist ${HOME}/.config/transmission
103blacklist ${HOME}/.config/Gitter 137blacklist ${HOME}/.config/uGet
104blacklist ${HOME}/.config/Franz 138blacklist ${HOME}/.config/vivaldi
105blacklist ${HOME}/.jitsi 139blacklist ${HOME}/.config/vlc
106blacklist ${HOME}/.config/Slack
107blacklist ${HOME}/.cache/gajim
108blacklist ${HOME}/.local/share/gajim
109blacklist ${HOME}/.config/gajim
110blacklist ${HOME}/.config/Wire
111
112# Games
113blacklist ${HOME}/.hedgewars
114blacklist ${HOME}/.steam
115blacklist ${HOME}/.config/wesnoth 140blacklist ${HOME}/.config/wesnoth
116blacklist ${HOME}/.config/0ad 141blacklist ${HOME}/.config/wire
117blacklist ${HOME}/.warzone2100-3.1 142blacklist ${HOME}/.config/wireshark
143blacklist ${HOME}/.config/xchat
144blacklist ${HOME}/.config/xed
145blacklist ${HOME}/.config/xfburn
146blacklist ${HOME}/.config/xplayer
147blacklist ${HOME}/.config/xreader
148blacklist ${HOME}/.config/xviewer
149blacklist ${HOME}/.config/zathura
150blacklist ${HOME}/.config/zoomus.conf
151blacklist ${HOME}/.conkeror.mozdev.org
152blacklist ${HOME}/.dillo
118blacklist ${HOME}/.dosbox 153blacklist ${HOME}/.dosbox
119 154blacklist ${HOME}/.dropbox-dist
120# Cryptocoins
121blacklist ${HOME}/.*coin
122blacklist ${HOME}/.electrum* 155blacklist ${HOME}/.electrum*
123blacklist ${HOME}/wallet.dat 156blacklist ${HOME}/.elinks
124 157blacklist ${HOME}/.emacs
125# git, subversion 158blacklist ${HOME}/.emacs.d
126blacklist ${HOME}/.subversion 159blacklist ${HOME}/.filezilla
127blacklist ${HOME}/.gitconfig 160blacklist ${HOME}/.flowblade
161blacklist ${HOME}/.fltk
162blacklist ${HOME}/.gimp*
128blacklist ${HOME}/.git-credential-cache 163blacklist ${HOME}/.git-credential-cache
129 164blacklist ${HOME}/.gitconfig
130# cache 165blacklist ${HOME}/.googleearth/Cache/
131blacklist ${HOME}/.cache/mozilla 166blacklist ${HOME}/.googleearth/Temp/
132blacklist ${HOME}/.cache/chromium 167blacklist ${HOME}/.googleearth/myplaces.backup.kml
133blacklist ${HOME}/.cache/google-chrome 168blacklist ${HOME}/.googleearth/myplaces.kml
134blacklist ${HOME}/.cache/google-chrome-beta 169blacklist ${HOME}/.guayadeque
135blacklist ${HOME}/.cache/google-chrome-unstable 170blacklist ${HOME}/.hedgewars
136blacklist ${HOME}/.cache/opera 171blacklist ${HOME}/.icedove
137blacklist ${HOME}/.cache/opera-beta 172blacklist ${HOME}/.inkscape
138blacklist ${HOME}/.cache/vivaldi 173blacklist ${HOME}/.jitsi
139blacklist ${HOME}/.cache/epiphany 174blacklist ${HOME}/.kde/share/apps/gwenview
140blacklist ${HOME}/.cache/slimjet 175blacklist ${HOME}/.kde/share/apps/okular
141blacklist ${HOME}/.cache/qutebrowser 176blacklist ${HOME}/.kde/share/config/gwenviewrc
142blacklist ${HOME}/.cache/spotify 177blacklist ${HOME}/.kde/share/config/okularpartrc
143blacklist ${HOME}/.cache/thunderbird 178blacklist ${HOME}/.kde/share/config/okularrc
144blacklist ${HOME}/.cache/icedove 179blacklist ${HOME}/.killingfloor
145blacklist ${HOME}/.cache/transmission 180blacklist ${HOME}/.linphone-history.db
146blacklist ${HOME}/.cache/wesnoth 181blacklist ${HOME}/.linphonerc
147blacklist ${HOME}/.cache/0ad 182blacklist ${HOME}/.lmmsrc.xml
148blacklist ${HOME}/.cache/8pecxstudios 183blacklist ${HOME}/.local/.share/maps-places.json
149blacklist ${HOME}/.cache/xreader 184blacklist ${HOME}/.local/lib/python2.7/site-packages
150blacklist ${HOME}/.cache/Franz 185blacklist ${HOME}/.local/share/0ad
151 186blacklist ${HOME}/.local/share/3909/PapersPlease
152# share 187blacklist ${HOME}/.local/share/Empathy
188blacklist ${HOME}/.local/share/Mumble
189blacklist ${HOME}/.local/share/QuiteRss
190blacklist ${HOME}/.local/share/Ricochet
191blacklist ${HOME}/.local/share/Steam
192blacklist ${HOME}/.local/share/SuperHexagon
193blacklist ${HOME}/.local/share/Terraria
194blacklist ${HOME}/.local/share/TpLogger
195blacklist ${HOME}/.local/share/aspyr-media
196blacklist ${HOME}/.local/share/cdprojektred
197blacklist ${HOME}/.local/share/data/Mumble
198blacklist ${HOME}/.local/share/dolphin
153blacklist ${HOME}/.local/share/epiphany 199blacklist ${HOME}/.local/share/epiphany
200blacklist ${HOME}/.local/share/evolution
201blacklist ${HOME}/.local/share/feral-interactive
202blacklist ${HOME}/.local/share/gajim
203blacklist ${HOME}/.local/share/gnome-2048
204blacklist ${HOME}/.local/share/gnome-chess
205blacklist ${HOME}/.local/share/gnome-music
206blacklist ${HOME}/.local/share/gnome-photos
207blacklist ${HOME}/.local/share/kate
208blacklist ${HOME}/.local/share/lollypop
209blacklist ${HOME}/.local/share/multimc5
154blacklist ${HOME}/.local/share/mupen64plus 210blacklist ${HOME}/.local/share/mupen64plus
211blacklist ${HOME}/.local/share/pix
212blacklist ${HOME}/.local/share/psi+
213blacklist ${HOME}/.local/share/qpdfview
155blacklist ${HOME}/.local/share/spotify 214blacklist ${HOME}/.local/share/spotify
156blacklist ${HOME}/.local/share/steam 215blacklist ${HOME}/.local/share/steam
216blacklist ${HOME}/.local/share/telepathy
217blacklist ${HOME}/.local/share/torbrowser
218blacklist ${HOME}/.local/share/totem
219blacklist ${HOME}/.local/share/vpltd
220blacklist ${HOME}/.local/share/vulkan
157blacklist ${HOME}/.local/share/wesnoth 221blacklist ${HOME}/.local/share/wesnoth
158blacklist ${HOME}/.local/share/0ad
159blacklist ${HOME}/.local/share/xplayer 222blacklist ${HOME}/.local/share/xplayer
160blacklist ${HOME}/.local/share/totem 223blacklist ${HOME}/.local/share/xreader
161blacklist ${HOME}/.local/share/psi+
162blacklist ${HOME}/.local/share/pix
163blacklist ${HOME}/.local/share/gnome-chess
164blacklist ${HOME}/.local/share/qpdfview
165blacklist ${HOME}/.local/share/zathura 224blacklist ${HOME}/.local/share/zathura
166 225blacklist ${HOME}/.lv2
167# ssh 226blacklist ${HOME}/.mcabber
227blacklist ${HOME}/.mcabberrc
228blacklist ${HOME}/.mozilla
229blacklist ${HOME}/.mozilla/seamonkey
230blacklist ${HOME}/.mpdconf
231blacklist ${HOME}/.msmtprc
232blacklist ${HOME}/.multimc5
233blacklist ${HOME}/.mutt
234blacklist ${HOME}/.mutt/muttrc
235blacklist ${HOME}/.muttrc
236blacklist ${HOME}/.nv
237blacklist ${HOME}/.openshot
238blacklist ${HOME}/.openshot_qt
239blacklist ${HOME}/.opera
240blacklist ${HOME}/.opera-beta
241blacklist ${HOME}/.pki
242blacklist ${HOME}/.purple
243blacklist ${HOME}/.qemu-launcher
244blacklist ${HOME}/.remmina
245blacklist ${HOME}/.retroshare
246blacklist ${HOME}/.scribus
247blacklist ${HOME}/.steam
248blacklist ${HOME}/.steampath
249blacklist ${HOME}/.steampid
250blacklist ${HOME}/.stellarium
251blacklist ${HOME}/.subversion
252blacklist ${HOME}/.sword
253blacklist ${HOME}/.sylpheed-2.0
254blacklist ${HOME}/.synfig
255blacklist ${HOME}/.tconn
256blacklist ${HOME}/.thunderbird
257blacklist ${HOME}/.ts3client
258blacklist ${HOME}/.vst
259blacklist ${HOME}/.w3m
260blacklist ${HOME}/.warzone2100-3.1
261blacklist ${HOME}/.weechat
262blacklist ${HOME}/.wine
263blacklist ${HOME}/.wine64
264blacklist ${HOME}/.xiphos
265blacklist ${HOME}/.xonotic
266blacklist ${HOME}/.xpdfrc
267blacklist ${HOME}/.zoom
268blacklist ${HOME}/wallet.dat
168blacklist /tmp/ssh-* 269blacklist /tmp/ssh-*
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/dolphin.profile b/etc/dolphin.profile
new file mode 100644
index 000000000..09a86f811
--- /dev/null
+++ b/etc/dolphin.profile
@@ -0,0 +1,27 @@
1# dolphin profile
2
3# warning: firejail is currently not effectively constraining dolphin since used services are started by kdeinit5
4
5noblacklist ~/.config/dolphinrc
6noblacklist ~/.local/share/dolphin
7
8include /etc/firejail/disable-common.inc
9# dolphin needs to be able to start arbitrary applications so we cannot blacklist their files
10#include /etc/firejail/disable-programs.inc
11include /etc/firejail/disable-devel.inc
12include /etc/firejail/disable-passwdmgr.inc
13
14caps.drop all
15netfilter
16nogroups
17nonewprivs
18noroot
19shell none
20seccomp
21protocol unix
22
23# private-bin
24# private-dev
25# private-tmp
26# private-etc
27
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/dragon.profile b/etc/dragon.profile
new file mode 100644
index 000000000..09cb73802
--- /dev/null
+++ b/etc/dragon.profile
@@ -0,0 +1,22 @@
1# dragon player profile
2noblacklist ~/.config/dragonplayerrc
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
14shell none
15seccomp
16protocol unix,inet,inet6
17
18private-bin dragon
19private-dev
20private-tmp
21# private-etc
22
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/elinks.profile b/etc/elinks.profile
new file mode 100644
index 000000000..df817ea56
--- /dev/null
+++ b/etc/elinks.profile
@@ -0,0 +1,24 @@
1# elinks profile
2noblacklist ~/.elinks
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,inet,inet6
15seccomp
16netfilter
17shell none
18tracelog
19
20# private-bin elinks
21private-tmp
22private-dev
23# private-etc none
24
diff --git a/etc/emacs.profile b/etc/emacs.profile
new file mode 100644
index 000000000..2b9c5805c
--- /dev/null
+++ b/etc/emacs.profile
@@ -0,0 +1,16 @@
1# emacs profile
2noblacklist ~/.emacs
3noblacklist ~/.emacs.d
4
5include /etc/firejail/disable-common.inc
6include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-passwdmgr.inc
8
9
10caps.drop all
11netfilter
12nonewprivs
13noroot
14nogroups
15protocol unix,inet,inet6
16seccomp
diff --git a/etc/empathy.profile b/etc/empathy.profile
index 789bdda08..2a0a6389c 100644
--- a/etc/empathy.profile
+++ b/etc/empathy.profile
@@ -4,6 +4,9 @@ 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
9nogroups
10noroot
11protocol unix,inet,inet6
12seccomp
diff --git a/etc/enchant.profile b/etc/enchant.profile
new file mode 100644
index 000000000..cf8288919
--- /dev/null
+++ b/etc/enchant.profile
@@ -0,0 +1,23 @@
1# enchant profile
2noblacklist ~/.config/enchant
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
16netfilter
17shell none
18tracelog
19
20# private-bin enchant
21# private-tmp
22# private-dev
23# private-etc fonts
diff --git a/etc/eog.profile b/etc/eog.profile
new file mode 100644
index 000000000..d463f3a97
--- /dev/null
+++ b/etc/eog.profile
@@ -0,0 +1,22 @@
1# eog (gnome image viewer) profile
2noblacklist ~/.config/eog
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
14nosound
15protocol unix
16seccomp
17shell none
18
19private-bin eog
20private-dev
21private-etc fonts
22private-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..1ec384947 100644
--- a/etc/evince.profile
+++ b/etc/evince.profile
@@ -1,11 +1,25 @@
1# evince pdf reader profile 1# evince pdf reader profile
2noblacklist ~/.config/evince
3
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 10netfilter
9protocol unix,inet,inet6 11#net none - creates some problems on some distributions
12nogroups
13nonewprivs
10noroot 14noroot
11nosound 15nosound
16protocol unix
17seccomp
18shell none
19tracelog
20
21private-bin evince,evince-previewer,evince-thumbnailer
22private-dev
23private-etc fonts
24# evince needs access to /tmp/mozilla* to work in firefox
25# private-tmp
diff --git a/etc/evolution.profile b/etc/evolution.profile
new file mode 100644
index 000000000..ab6dd7a4a
--- /dev/null
+++ b/etc/evolution.profile
@@ -0,0 +1,25 @@
1# evolution profile
2noblacklist ~/.config/evolution
3noblacklist ~/.local/share/evolution
4noblacklist ~/.cache/evolution
5noblacklist ~/.pki
6noblacklist ~/.pki/nssdb
7noblacklist ~/.gnupg
8
9include /etc/firejail/disable-common.inc
10include /etc/firejail/disable-programs.inc
11include /etc/firejail/disable-devel.inc
12include /etc/firejail/disable-passwdmgr.inc
13
14caps.drop all
15netfilter
16nogroups
17nonewprivs
18noroot
19nosound
20protocol unix,inet,inet6
21seccomp
22shell none
23
24private-dev
25private-tmp
diff --git a/etc/exiftool.profile b/etc/exiftool.profile
new file mode 100644
index 000000000..384695473
--- /dev/null
+++ b/etc/exiftool.profile
@@ -0,0 +1,28 @@
1# exiftool profile
2noblacklist /usr/bin/perl
3noblacklist /usr/share/perl*
4noblacklist /usr/lib/perl*
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
18netfilter
19net none
20shell none
21tracelog
22
23# private-bin exiftool,perl
24private-tmp
25private-dev
26private-etc none
27
28
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-roller.profile b/etc/file-roller.profile
new file mode 100644
index 000000000..6116389db
--- /dev/null
+++ b/etc/file-roller.profile
@@ -0,0 +1,21 @@
1# file-roller 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
15shell none
16tracelog
17
18# private-bin file-roller
19# private-tmp
20private-dev
21# private-etc fonts
diff --git a/etc/file.profile b/etc/file.profile
new file mode 100644
index 000000000..d145fe12a
--- /dev/null
+++ b/etc/file.profile
@@ -0,0 +1,26 @@
1# file profile
2quiet
3include /etc/firejail/disable-common.inc
4include /etc/firejail/disable-programs.inc
5include /etc/firejail/disable-passwdmgr.inc
6
7caps.drop all
8hostname file
9netfilter
10net none
11no3d
12nogroups
13nonewprivs
14#noroot
15nosound
16protocol unix
17seccomp
18shell none
19tracelog
20x11 none
21
22blacklist /tmp/.X11-unix
23
24private-dev
25private-bin file
26private-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..4f971f330 100644
--- a/etc/firefox.profile
+++ b/etc/firefox.profile
@@ -1,23 +1,24 @@
1# Firejail profile for Mozilla Firefox (Iceweasel in Debian) 1# Firejail profile for Mozilla Firefox (Iceweasel in Debian)
2
3noblacklist ~/.mozilla 2noblacklist ~/.mozilla
4noblacklist ~/.cache/mozilla 3noblacklist ~/.cache/mozilla
4noblacklist ~/.config/qpdfview
5noblacklist ~/.local/share/qpdfview
6noblacklist ~/.kde/share/apps/okular
5include /etc/firejail/disable-common.inc 7include /etc/firejail/disable-common.inc
6include /etc/firejail/disable-programs.inc 8include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-devel.inc 9include /etc/firejail/disable-devel.inc
8 10
9caps.drop all 11caps.drop all
10seccomp
11protocol unix,inet,inet6,netlink
12netfilter 12netfilter
13tracelog 13nonewprivs
14noroot 14noroot
15protocol unix,inet,inet6,netlink
16seccomp
17tracelog
15 18
16whitelist ${DOWNLOADS} 19whitelist ${DOWNLOADS}
17mkdir ~/.mozilla 20mkdir ~/.mozilla
18whitelist ~/.mozilla 21whitelist ~/.mozilla
19mkdir ~/.cache
20mkdir ~/.cache/mozilla
21mkdir ~/.cache/mozilla/firefox 22mkdir ~/.cache/mozilla/firefox
22whitelist ~/.cache/mozilla/firefox 23whitelist ~/.cache/mozilla/firefox
23whitelist ~/dwhelper 24whitelist ~/dwhelper
@@ -30,6 +31,9 @@ whitelist ~/.keysnail.js
30whitelist ~/.config/gnome-mplayer 31whitelist ~/.config/gnome-mplayer
31whitelist ~/.cache/gnome-mplayer/plugin 32whitelist ~/.cache/gnome-mplayer/plugin
32whitelist ~/.pki 33whitelist ~/.pki
34whitelist ~/.config/qpdfview
35whitelist ~/.local/share/qpdfview
36whitelist ~/.kde/share/apps/okular
33 37
34# lastpass, keepassx 38# lastpass, keepassx
35whitelist ~/.keepassx 39whitelist ~/.keepassx
@@ -40,14 +44,15 @@ whitelist ~/.config/lastpass
40 44
41 45
42#silverlight 46#silverlight
43whitelist ~/.wine-pipelight 47whitelist ~/.wine-pipelight
44whitelist ~/.wine-pipelight64 48whitelist ~/.wine-pipelight64
45whitelist ~/.config/pipelight-widevine 49whitelist ~/.config/pipelight-widevine
46whitelist ~/.config/pipelight-silverlight5.1 50whitelist ~/.config/pipelight-silverlight5.1
47 51
48include /etc/firejail/whitelist-common.inc 52include /etc/firejail/whitelist-common.inc
49 53
50# experimental features 54# 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 55#private-bin firefox,which,sh,dbus-launch,dbus-send,env
52 56#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 57private-dev
58private-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..824e3f503 100644
--- a/etc/firejail.config
+++ b/etc/firejail.config
@@ -9,24 +9,63 @@
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# Enable Firejail green prompt in terminal, default disabled
21# firejail-prompt no
22
23# Force use of nonewprivs. This mitigates the possibility of
24# a user abusing firejail's features to trick a privileged (suid
25# or file capabilities) process into loading code or configuration
26# that is partially under their control. Default disabled.
27# force-nonewprivs no
28
15# Enable or disable networking features, default enabled. 29# Enable or disable networking features, default enabled.
16# network yes 30# network yes
17 31
32# Enable or disable overlayfs features, default enabled.
33# overlayfs yes
34
35# Remove /usr/local directories from private-bin list, default disabled.
36# private-bin-no-local no
37
38# Enable or disable private-home feature, default enabled
39# private-home yes
40
41# Enable --quiet as default every time the sandbox is started. Default disabled.
42# quiet-by-default no
43
44# Remount /proc and /sys inside the sandbox, default enabled.
45# remount-proc-sys yes
46
18# Enable or disable restricted network support, default disabled. If enabled, 47# Enable or disable restricted network support, default disabled. If enabled,
19# networking features should also be enabled (network yes). 48# networking features should also be enabled (network yes).
20# Restricted networking grants access to --interface and --net=ethXXX 49# Restricted networking grants access to --interface, --net=ethXXX and
21# only to root user. Regular users are only allowed --net=none. 50# --netfilter only to root user. Regular users are only allowed --net=none.
22# restricted-network no 51# restricted-network no
23 52
53# Change default netfilter configuration. When using --netfilter option without
54# a file argument, the default filter is hardcoded (see man 1 firejail). This
55# configuration entry allows the user to change the default by specifying
56# a file containing the filter configuration. The filter file format is the
57# format of iptables-save and iptable-restore commands. Example:
58# netfilter-default /etc/iptables.iptables.rules
59
24# Enable or disable seccomp support, default enabled. 60# Enable or disable seccomp support, default enabled.
25# seccomp yes 61# seccomp yes
26 62
27# Enable or disable user namespace support, default enabled. 63# Enable or disable user namespace support, default enabled.
28# userns yes 64# userns yes
29 65
66# Enable or disable whitelisting support, default enabled.
67# whitelist yes
68
30# Enable or disable X11 sandboxing support, default enabled. 69# Enable or disable X11 sandboxing support, default enabled.
31# x11 yes 70# x11 yes
32 71
@@ -36,3 +75,10 @@
36# xephyr-screen 800x600 75# xephyr-screen 800x600
37# xephyr-screen 1024x768 76# xephyr-screen 1024x768
38# xephyr-screen 1280x1024 77# xephyr-screen 1280x1024
78
79# Firejail window title in Xephyr, default enabled.
80# xephyr-window-title yes
81
82# Xephyr command extra parameters. None by default, and the declaration is commented out.
83# xephyr-extra-params -keybd ephyr,,,xkbmodel=evdev
84# 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..eb60f858b
--- /dev/null
+++ b/etc/gajim.profile
@@ -0,0 +1,38 @@
1# Firejail profile for Gajim
2noblacklist ${HOME}/.cache/gajim
3noblacklist ${HOME}/.local/share/gajim
4noblacklist ${HOME}/.config/gajim
5
6mkdir ${HOME}/.cache/gajim
7mkdir ${HOME}/.local/share/gajim
8mkdir ${HOME}/.config/gajim
9mkdir ${HOME}/Downloads
10
11# Allow the local python 2.7 site packages, in case any plugins are using these
12mkdir ${HOME}/.local/lib/python2.7/site-packages/
13whitelist ${HOME}/.local/lib/python2.7/site-packages/
14read-only ${HOME}/.local/lib/python2.7/site-packages/
15
16whitelist ${HOME}/.cache/gajim
17whitelist ${HOME}/.local/share/gajim
18whitelist ${HOME}/.config/gajim
19whitelist ${HOME}/Downloads
20
21include /etc/firejail/disable-common.inc
22include /etc/firejail/disable-passwdmgr.inc
23include /etc/firejail/disable-programs.inc
24include /etc/firejail/disable-devel.inc
25
26caps.drop all
27netfilter
28nogroups
29nonewprivs
30noroot
31protocol unix,inet,inet6
32seccomp
33shell none
34
35#private-bin python2.7 gajim
36#private-etc fonts
37private-dev
38#private-tmp
diff --git a/etc/gedit.profile b/etc/gedit.profile
new file mode 100644
index 000000000..a25286bfa
--- /dev/null
+++ b/etc/gedit.profile
@@ -0,0 +1,26 @@
1# gedit profile
2
3# when gedit is started via gnome-shell, firejail is not applied because systemd will start it
4
5noblacklist ~/.config/gedit
6
7include /etc/firejail/disable-common.inc
8include /etc/firejail/disable-programs.inc
9#include /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
21tracelog
22
23# private-bin gedit
24private-tmp
25private-dev
26# private-etc fonts
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..d60e58c03
--- /dev/null
+++ b/etc/git.profile
@@ -0,0 +1,26 @@
1# git profile
2quiet
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
23seccomp
24shell none
25
26private-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/gjs.profile b/etc/gjs.profile
new file mode 100644
index 000000000..8d71728a2
--- /dev/null
+++ b/etc/gjs.profile
@@ -0,0 +1,28 @@
1# gjs (gnome javascript bindings) profile
2
3# when gjs apps are started via gnome-shell, firejail is not applied because systemd will start them
4
5noblacklist ~/.cache/org.gnome.Books
6noblacklist ~/.config/libreoffice
7noblacklist ~/.local/share/gnome-photos
8noblacklist ~/.cache/libgweather
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
16nogroups
17nonewprivs
18noroot
19protocol unix,inet,inet6
20seccomp
21netfilter
22shell none
23tracelog
24
25# private-bin gjs,gnome-books,gnome-documents,gnome-photos,gnome-maps,gnome-weather
26private-tmp
27private-dev
28# private-etc fonts
diff --git a/etc/gnome-2048.profile b/etc/gnome-2048.profile
new file mode 100644
index 000000000..f9982da61
--- /dev/null
+++ b/etc/gnome-2048.profile
@@ -0,0 +1,25 @@
1#
2#Profile for gnome-2048
3#
4
5#No Blacklist Paths
6noblacklist ${HOME}/.local/share/gnome-2048
7
8#Blacklist Paths
9include /etc/firejail/disable-common.inc
10include /etc/firejail/disable-programs.inc
11include /etc/firejail/disable-passwdmgr.inc
12include /etc/firejail/disable-devel.inc
13
14#Whitelist Paths
15mkdir ${HOME}/.local/share/gnome-2048
16whitelist ${HOME}/.local/share/gnome-2048
17include /etc/firejail/whitelist-common.inc
18
19#Options
20caps.drop all
21netfilter
22nonewprivs
23noroot
24protocol unix,inet,inet6
25seccomp
diff --git a/etc/gnome-books.profile b/etc/gnome-books.profile
new file mode 100644
index 000000000..10b06e173
--- /dev/null
+++ b/etc/gnome-books.profile
@@ -0,0 +1,26 @@
1# gnome-books profile
2
3# when gjs apps are started via gnome-shell, firejail is not applied because systemd will start them
4
5noblacklist ~/.cache/org.gnome.Books
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
21tracelog
22
23# private-bin gjs gnome-books
24private-tmp
25private-dev
26private-etc fonts
diff --git a/etc/gnome-calculator.profile b/etc/gnome-calculator.profile
new file mode 100644
index 000000000..49e068171
--- /dev/null
+++ b/etc/gnome-calculator.profile
@@ -0,0 +1,19 @@
1#
2#Profile for gnome-calculator
3#
4
5#Blacklist Paths
6include /etc/firejail/disable-common.inc
7include /etc/firejail/disable-programs.inc
8include /etc/firejail/disable-passwdmgr.inc
9include /etc/firejail/disable-devel.inc
10
11include /etc/firejail/whitelist-common.inc
12
13#Options
14caps.drop all
15netfilter
16nonewprivs
17noroot
18protocol unix,inet,inet6
19seccomp
diff --git a/etc/gnome-chess.profile b/etc/gnome-chess.profile
new file mode 100644
index 000000000..4db485ea7
--- /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-clocks.profile b/etc/gnome-clocks.profile
new file mode 100644
index 000000000..6cccf9d32
--- /dev/null
+++ b/etc/gnome-clocks.profile
@@ -0,0 +1,21 @@
1# gnome-clocks 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,inet,inet6
13seccomp
14netfilter
15shell none
16tracelog
17
18# private-bin gnome-clocks
19private-tmp
20private-dev
21# private-etc fonts
diff --git a/etc/gnome-contacts.profile b/etc/gnome-contacts.profile
new file mode 100644
index 000000000..9dc25b26c
--- /dev/null
+++ b/etc/gnome-contacts.profile
@@ -0,0 +1,19 @@
1#
2#Profile for gnome-contacts
3#
4
5#Blacklist Paths
6include /etc/firejail/disable-common.inc
7include /etc/firejail/disable-programs.inc
8include /etc/firejail/disable-passwdmgr.inc
9include /etc/firejail/disable-devel.inc
10
11include /etc/firejail/whitelist-common.inc
12
13#Options
14caps.drop all
15netfilter
16nonewprivs
17noroot
18protocol unix,inet,inet6
19seccomp
diff --git a/etc/gnome-documents.profile b/etc/gnome-documents.profile
new file mode 100644
index 000000000..c5def7aff
--- /dev/null
+++ b/etc/gnome-documents.profile
@@ -0,0 +1,24 @@
1# gnome-documents profile
2
3# when gjs apps are started via gnome-shell, firejail is not applied because systemd will start them
4
5noblacklist ~/.config/libreoffice
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
21tracelog
22
23private-tmp
24private-dev
diff --git a/etc/gnome-maps.profile b/etc/gnome-maps.profile
new file mode 100644
index 000000000..f1451506e
--- /dev/null
+++ b/etc/gnome-maps.profile
@@ -0,0 +1,24 @@
1# gnome-maps profile
2
3# when gjs apps are started via gnome-shell, firejail is not applied because systemd will start them
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,inet,inet6
16seccomp
17netfilter
18shell none
19tracelog
20
21# private-bin gjs gnome-maps
22private-tmp
23private-dev
24# private-etc fonts
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/gnome-music.profile b/etc/gnome-music.profile
new file mode 100644
index 000000000..4a8adeb22
--- /dev/null
+++ b/etc/gnome-music.profile
@@ -0,0 +1,22 @@
1# gnome-music profile
2noblacklist ~/.local/share/gnome-music
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
13protocol unix
14seccomp
15netfilter
16shell none
17tracelog
18
19# private-bin gnome-music,python3
20private-tmp
21private-dev
22# private-etc fonts
diff --git a/etc/gnome-photos.profile b/etc/gnome-photos.profile
new file mode 100644
index 000000000..8f9d60cb5
--- /dev/null
+++ b/etc/gnome-photos.profile
@@ -0,0 +1,26 @@
1# gnome-photos profile
2
3# when gjs apps are started via gnome-shell, firejail is not applied because systemd will start them
4
5noblacklist ~/.local/share/gnome-photos
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
21tracelog
22
23# private-bin gjs gnome-photos
24private-tmp
25private-dev
26# private-etc fonts
diff --git a/etc/gnome-weather.profile b/etc/gnome-weather.profile
new file mode 100644
index 000000000..9f93b8f15
--- /dev/null
+++ b/etc/gnome-weather.profile
@@ -0,0 +1,26 @@
1# gnome-weather profile
2
3# when gjs apps are started via gnome-shell, firejail is not applied because systemd will start them
4
5noblacklist ~/.cache/libgweather
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,inet,inet6
18seccomp
19netfilter
20shell none
21tracelog
22
23# private-bin gjs gnome-weather
24private-tmp
25private-dev
26# private-etc fonts
diff --git a/etc/goobox.profile b/etc/goobox.profile
new file mode 100644
index 000000000..8990943fc
--- /dev/null
+++ b/etc/goobox.profile
@@ -0,0 +1,20 @@
1# goobox 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
11protocol unix
12seccomp
13netfilter
14shell none
15tracelog
16
17# private-bin goobox
18# private-tmp
19# private-dev
20# private-etc fonts
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/gpa.profile b/etc/gpa.profile
new file mode 100644
index 000000000..7d7277190
--- /dev/null
+++ b/etc/gpa.profile
@@ -0,0 +1,23 @@
1# gpa profile
2noblacklist ~/.gnupg
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,inet,inet6
15seccomp
16netfilter
17shell none
18tracelog
19
20# private-bin gpa,gpg
21private-tmp
22private-dev
23# private-etc none
diff --git a/etc/gpg-agent.profile b/etc/gpg-agent.profile
new file mode 100644
index 000000000..b0ebdf43c
--- /dev/null
+++ b/etc/gpg-agent.profile
@@ -0,0 +1,23 @@
1# gpg-agent profile
2noblacklist ~/.gnupg
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
16netfilter
17shell none
18tracelog
19
20# private-bin gpg-agent,gpg
21private-tmp
22private-dev
23# private-etc none
diff --git a/etc/gpg.profile b/etc/gpg.profile
new file mode 100644
index 000000000..31372eb90
--- /dev/null
+++ b/etc/gpg.profile
@@ -0,0 +1,24 @@
1# gpg profile
2noblacklist ~/.gnupg
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
16netfilter
17net none
18shell none
19tracelog
20
21# private-bin gpg,gpg-agent
22private-tmp
23private-dev
24# private-etc none
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..feb27c150
--- /dev/null
+++ b/etc/gzip.profile
@@ -0,0 +1,14 @@
1# gzip profile
2quiet
3ignore noroot
4include /etc/firejail/default.profile
5
6blacklist /tmp/.X11-unix
7
8net none
9no3d
10nosound
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/highlight.profile b/etc/highlight.profile
new file mode 100644
index 000000000..f95f3924a
--- /dev/null
+++ b/etc/highlight.profile
@@ -0,0 +1,24 @@
1# highlight 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
19private-bin highlight
20private-tmp
21private-dev
22
23
24
diff --git a/etc/icecat.profile b/etc/icecat.profile
index 25d426ad2..0348076da 100644
--- a/etc/icecat.profile
+++ b/etc/icecat.profile
@@ -1,2 +1,50 @@
1# Firejail profile for GNU Icecat 1# Firejail profile for GNU Icecat
2include /etc/firejail/firefox.profile 2noblacklist ~/.mozilla
3noblacklist ~/.cache/mozilla
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
14tracelog
15
16whitelist ${DOWNLOADS}
17mkdir ~/.mozilla
18whitelist ~/.mozilla
19mkdir ~/.cache/mozilla/icecat
20whitelist ~/.cache/mozilla/icecat
21whitelist ~/dwhelper
22whitelist ~/.zotero
23whitelist ~/.vimperatorrc
24whitelist ~/.vimperator
25whitelist ~/.pentadactylrc
26whitelist ~/.pentadactyl
27whitelist ~/.keysnail.js
28whitelist ~/.config/gnome-mplayer
29whitelist ~/.cache/gnome-mplayer/plugin
30whitelist ~/.pki
31
32# lastpass, keepassx
33whitelist ~/.keepassx
34whitelist ~/.config/keepassx
35whitelist ~/keepassx.kdbx
36whitelist ~/.lastpass
37whitelist ~/.config/lastpass
38
39
40#silverlight
41whitelist ~/.wine-pipelight
42whitelist ~/.wine-pipelight64
43whitelist ~/.config/pipelight-widevine
44whitelist ~/.config/pipelight-silverlight5.1
45
46include /etc/firejail/whitelist-common.inc
47
48# experimental features
49#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
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/img2txt.profile b/etc/img2txt.profile
new file mode 100644
index 000000000..d55a31cd0
--- /dev/null
+++ b/etc/img2txt.profile
@@ -0,0 +1,24 @@
1# img2txt 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#private-bin img2txt
20private-tmp
21private-dev
22#private-etc none
23
24
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/jd-gui.profile b/etc/jd-gui.profile
new file mode 100644
index 000000000..1d6eb41f8
--- /dev/null
+++ b/etc/jd-gui.profile
@@ -0,0 +1,19 @@
1#
2#Profile for jd-gui
3#
4
5noblacklist ${HOME}/.config/jd-gui.cfg
6
7#Blacklist Paths
8include /etc/firejail/disable-common.inc
9include /etc/firejail/disable-programs.inc
10include /etc/firejail/disable-passwdmgr.inc
11include /etc/firejail/disable-devel.inc
12
13#Options
14caps.drop all
15netfilter
16nonewprivs
17noroot
18protocol unix,inet,inet6
19seccomp
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/k3b.profile b/etc/k3b.profile
new file mode 100644
index 000000000..8a5fff0c6
--- /dev/null
+++ b/etc/k3b.profile
@@ -0,0 +1,21 @@
1# k3b 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
9nogroups
10nonewprivs
11noroot
12nosound
13shell none
14seccomp
15protocol unix
16
17# private-bin
18# private-dev
19# private-tmp
20# private-etc
21
diff --git a/etc/kate.profile b/etc/kate.profile
new file mode 100644
index 000000000..4b07ea6cb
--- /dev/null
+++ b/etc/kate.profile
@@ -0,0 +1,28 @@
1# kate profile
2noblacklist ~/.local/share/kate
3noblacklist ~/.config/katerc
4noblacklist ~/.config/katepartrc
5noblacklist ~/.config/kateschemarc
6noblacklist ~/.config/katesyntaxhighlightingrc
7noblacklist ~/.config/katevirc
8
9include /etc/firejail/disable-common.inc
10include /etc/firejail/disable-programs.inc
11#include /etc/firejail/disable-devel.inc
12include /etc/firejail/disable-passwdmgr.inc
13
14caps.drop all
15nogroups
16nonewprivs
17noroot
18nosound
19protocol unix
20seccomp
21netfilter
22shell none
23tracelog
24
25# private-bin kate
26private-tmp
27private-dev
28# private-etc fonts
diff --git a/etc/keepass.profile b/etc/keepass.profile
new file mode 100644
index 000000000..18a5f4ebd
--- /dev/null
+++ b/etc/keepass.profile
@@ -0,0 +1,21 @@
1# keepass password manager profile
2noblacklist ${HOME}/.config/keepass
3noblacklist ${HOME}/.keepass
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,inet,inet6
16seccomp
17netfilter
18shell none
19
20private-tmp
21private-dev
diff --git a/etc/keepass2.profile b/etc/keepass2.profile
new file mode 100644
index 000000000..9daa014e3
--- /dev/null
+++ b/etc/keepass2.profile
@@ -0,0 +1,5 @@
1# keepass password manager profile
2#noblacklist ${HOME}/.config/KeePass
3#noblacklist ${HOME}/.keepass
4
5include /etc/firejail/keepass.profile
diff --git a/etc/keepassx.profile b/etc/keepassx.profile
new file mode 100644
index 000000000..d8621773f
--- /dev/null
+++ b/etc/keepassx.profile
@@ -0,0 +1,22 @@
1# keepassx password manager profile
2noblacklist ${HOME}/.config/keepassx
3noblacklist ${HOME}/.keepassx
4noblacklist ${HOME}/keepassx.kdbx
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
18netfilter
19shell none
20
21private-tmp
22private-dev
diff --git a/etc/kmail.profile b/etc/kmail.profile
index a7079661b..410ff36c6 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
19# private-tmp
diff --git a/etc/konversation.profile b/etc/konversation.profile
new file mode 100644
index 000000000..c00b91c18
--- /dev/null
+++ b/etc/konversation.profile
@@ -0,0 +1,14 @@
1# Firejail konversation 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
9nogroups
10noroot
11seccomp
12protocol unix,inet,inet6
13
14private-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/lollypop.profile b/etc/lollypop.profile
new file mode 100644
index 000000000..41a662bca
--- /dev/null
+++ b/etc/lollypop.profile
@@ -0,0 +1,20 @@
1#
2#Profile for lollypop
3#
4
5#No Blacklist Paths
6noblacklist ${HOME}/.local/share/lollypop
7
8#Blacklist Paths
9include /etc/firejail/disable-common.inc
10include /etc/firejail/disable-programs.inc
11include /etc/firejail/disable-passwdmgr.inc
12include /etc/firejail/disable-devel.inc
13
14#Options
15caps.drop all
16netfilter
17nonewprivs
18noroot
19protocol unix,inet,inet6
20seccomp
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..12765c299 100644
--- a/etc/lxterminal.profile
+++ b/etc/lxterminal.profile
@@ -1,11 +1,10 @@
1# lxterminal (LXDE) profile 1# lxterminal (LXDE) profile
2
3include /etc/firejail/disable-common.inc 2include /etc/firejail/disable-common.inc
4include /etc/firejail/disable-programs.inc 3include /etc/firejail/disable-programs.inc
5include /etc/firejail/disable-passwdmgr.inc 4include /etc/firejail/disable-passwdmgr.inc
6 5
7caps.drop all 6caps.drop all
8seccomp
9protocol unix,inet,inet6
10netfilter 7netfilter
8protocol unix,inet,inet6
9seccomp
11#noroot - somehow this breaks on Debian Jessie! 10#noroot - somehow this breaks on Debian Jessie!
diff --git a/etc/lynx.profile b/etc/lynx.profile
new file mode 100644
index 000000000..6e150f62e
--- /dev/null
+++ b/etc/lynx.profile
@@ -0,0 +1,22 @@
1# lynx 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,inet,inet6
13seccomp
14netfilter
15shell none
16tracelog
17
18# private-bin lynx
19private-tmp
20private-dev
21# private-etc none
22
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/mediainfo.profile b/etc/mediainfo.profile
new file mode 100644
index 000000000..c07a9a9e8
--- /dev/null
+++ b/etc/mediainfo.profile
@@ -0,0 +1,26 @@
1# mediainfo 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
19private-bin mediainfo
20private-tmp
21private-dev
22private-etc none
23
24
25
26
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/multimc5.profile b/etc/multimc5.profile
new file mode 100644
index 000000000..cc310f294
--- /dev/null
+++ b/etc/multimc5.profile
@@ -0,0 +1,27 @@
1#
2#Profile for multimc5
3#
4
5#No Blacklist Paths
6noblacklist ${HOME}/.local/share/multimc5
7noblacklist ${HOME}/.multimc5
8
9#Blacklist Paths
10include /etc/firejail/disable-common.inc
11include /etc/firejail/disable-programs.inc
12include /etc/firejail/disable-passwdmgr.inc
13include /etc/firejail/disable-devel.inc
14
15#Whitelist Paths
16mkdir ${HOME}/.local/share/multimc5
17whitelist ${HOME}/.local/share/multimc5
18mkdir ${HOME}/.multimc5
19whitelist ${HOME}/.multimc5
20include /etc/firejail/whitelist-common.inc
21
22#Options
23caps.drop all
24netfilter
25nonewprivs
26noroot
27protocol unix,inet,inet6
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..7f9261d8b
--- /dev/null
+++ b/etc/mupdf.profile
@@ -0,0 +1,30 @@
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
19private-tmp
20private-dev
21private-etc fonts
22
23# mupdf will never write anything
24read-only ${HOME}
25
26#
27# Experimental:
28#
29#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,mremap,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
30# private-bin mupdf,sh,tempfile,rm
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..2718421c5
--- /dev/null
+++ b/etc/mutt.profile
@@ -0,0 +1,40 @@
1# mutt email client profile
2noblacklist ~/.muttrc
3noblacklist ~/.mutt
4noblacklist ~/.mutt/muttrc
5noblacklist ~/.mailcap
6noblacklist ~/.gnupg
7noblacklist ~/.mail
8noblacklist ~/.Mail
9noblacklist ~/mail
10noblacklist ~/Mail
11noblacklist ~/sent
12noblacklist ~/postponed
13noblacklist ~/.cache/mutt
14noblacklist ~/.w3m
15noblacklist ~/.elinks
16noblacklist ~/.vim
17noblacklist ~/.vimrc
18noblacklist ~/.viminfo
19noblacklist ~/.emacs
20noblacklist ~/.emacs.d
21noblacklist ~/.signature
22noblacklist ~/.bogofilter
23noblacklist ~/.msmtprc
24
25include /etc/firejail/disable-common.inc
26include /etc/firejail/disable-programs.inc
27include /etc/firejail/disable-passwdmgr.inc
28include /etc/firejail/disable-devel.inc
29
30caps.drop all
31netfilter
32nogroups
33nonewprivs
34noroot
35nosound
36protocol unix,inet,inet6
37seccomp
38shell none
39
40private-dev
diff --git a/etc/nautilus.profile b/etc/nautilus.profile
new file mode 100644
index 000000000..264ee0b9d
--- /dev/null
+++ b/etc/nautilus.profile
@@ -0,0 +1,26 @@
1# nautilus profile
2
3# Nautilus is started by systemd on most systems. Therefore it is not firejailed by default. Since there is already a nautilus process running on gnome desktops firejail will have no effect.
4
5noblacklist ~/.config/nautilus
6
7include /etc/firejail/disable-common.inc
8# nautilus needs to be able to start arbitrary applications so we cannot blacklist their files
9#include /etc/firejail/disable-programs.inc
10include /etc/firejail/disable-devel.inc
11include /etc/firejail/disable-passwdmgr.inc
12
13caps.drop all
14nogroups
15nonewprivs
16noroot
17protocol unix
18seccomp
19netfilter
20shell none
21tracelog
22
23# private-bin nautilus
24# private-tmp
25# private-dev
26# private-etc fonts
diff --git a/etc/netsurf.profile b/etc/netsurf.profile
new file mode 100644
index 000000000..2071e5519
--- /dev/null
+++ b/etc/netsurf.profile
@@ -0,0 +1,29 @@
1# Firejail profile for Mozilla Firefox (Iceweasel in Debian)
2noblacklist ~/.config/netsurf
3noblacklist ~/.cache/netsurf
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
14tracelog
15
16whitelist ${DOWNLOADS}
17mkdir ~/.config/netsurf
18whitelist ~/.config/netsurf
19mkdir ~/.cache/netsurf
20whitelist ~/.cache/netsurf
21
22# lastpass, keepassx
23whitelist ~/.keepassx
24whitelist ~/.config/keepassx
25whitelist ~/keepassx.kdbx
26whitelist ~/.lastpass
27whitelist ~/.config/lastpass
28
29include /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/odt2txt.profile b/etc/odt2txt.profile
new file mode 100644
index 000000000..329275022
--- /dev/null
+++ b/etc/odt2txt.profile
@@ -0,0 +1,24 @@
1# odt2txt 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
19private-bin odt2txt
20private-tmp
21private-dev
22private-etc none
23
24read-only ${HOME}
diff --git a/etc/okular.profile b/etc/okular.profile
new file mode 100644
index 000000000..22e223cea
--- /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
12netfilter
13nonewprivs
14nogroups
15noroot
16nosound
17protocol unix
18seccomp
19shell none
20tracelog
21
22# private-bin okular,kbuildsycoca4,kbuildsycoca5
23# private-etc X11
24private-dev
25private-tmp
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/pdfsam.profile b/etc/pdfsam.profile
new file mode 100644
index 000000000..6e50f37cf
--- /dev/null
+++ b/etc/pdfsam.profile
@@ -0,0 +1,17 @@
1#
2#Profile for pdfsam
3#
4
5#Blacklist Paths
6include /etc/firejail/disable-common.inc
7include /etc/firejail/disable-programs.inc
8include /etc/firejail/disable-passwdmgr.inc
9include /etc/firejail/disable-devel.inc
10
11#Options
12caps.drop all
13netfilter
14nonewprivs
15noroot
16protocol unix,inet,inet6
17seccomp
diff --git a/etc/pdftotext.profile b/etc/pdftotext.profile
new file mode 100644
index 000000000..632c9d15e
--- /dev/null
+++ b/etc/pdftotext.profile
@@ -0,0 +1,22 @@
1# pdftotext 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
19private-bin pdftotext
20private-tmp
21private-dev
22private-etc 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/pithos.profile b/etc/pithos.profile
new file mode 100644
index 000000000..8270b8bee
--- /dev/null
+++ b/etc/pithos.profile
@@ -0,0 +1,19 @@
1#
2#Profile for pithos
3#
4
5#Blacklist Paths
6include /etc/firejail/disable-common.inc
7include /etc/firejail/disable-programs.inc
8include /etc/firejail/disable-passwdmgr.inc
9include /etc/firejail/disable-devel.inc
10
11include /etc/firejail/whitelist-common.inc
12
13#Options
14caps.drop all
15netfilter
16nonewprivs
17noroot
18protocol unix,inet,inet6
19seccomp
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/pluma.profile b/etc/pluma.profile
new file mode 100644
index 000000000..895cc2369
--- /dev/null
+++ b/etc/pluma.profile
@@ -0,0 +1,21 @@
1# Firejail profile for Xed
2noblacklist ${HOME}/.config/pluma
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
10net none
11nogroups
12nonewprivs
13noroot
14nosound
15seccomp
16shell none
17tracelog
18
19private-bin pluma
20private-dev
21private-tmp
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..e4e69b9f6
--- /dev/null
+++ b/etc/psi-plus.profile
@@ -0,0 +1,22 @@
1# Firejail profile for Psi+
2noblacklist ${HOME}/.config/psi+
3noblacklist ${HOME}/.local/share/psi+
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-passwdmgr.inc
7
8whitelist ${DOWNLOADS}
9mkdir ~/.config/psi+
10whitelist ~/.config/psi+
11mkdir ~/.local/share/psi+
12whitelist ~/.local/share/psi+
13mkdir ~/.cache/psi+
14whitelist ~/.cache/psi+
15
16caps.drop all
17netfilter
18noroot
19protocol unix,inet,inet6
20seccomp
21
22include /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/qemu-launcher.profile b/etc/qemu-launcher.profile
new file mode 100644
index 000000000..f9c8e6345
--- /dev/null
+++ b/etc/qemu-launcher.profile
@@ -0,0 +1,19 @@
1# qemu-launcher profile
2noblacklist ~/.qemu-launcher
3
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-passwdmgr.inc
7
8caps.drop all
9netfilter
10nogroups
11nonewprivs
12noroot
13protocol unix,inet,inet6
14seccomp
15shell none
16tracelog
17
18private-tmp
19
diff --git a/etc/qemu-system-x86_64.profile b/etc/qemu-system-x86_64.profile
new file mode 100644
index 000000000..65e1e44ea
--- /dev/null
+++ b/etc/qemu-system-x86_64.profile
@@ -0,0 +1,17 @@
1# qemu profile
2include /etc/firejail/disable-common.inc
3include /etc/firejail/disable-programs.inc
4include /etc/firejail/disable-passwdmgr.inc
5
6caps.drop all
7netfilter
8nogroups
9nonewprivs
10noroot
11protocol unix,inet,inet6
12seccomp
13shell none
14tracelog
15
16private-tmp
17
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/qutebrowser.profile b/etc/qutebrowser.profile
index 934a374de..dcacd4f29 100644
--- a/etc/qutebrowser.profile
+++ b/etc/qutebrowser.profile
@@ -1,5 +1,4 @@
1# Firejail profile for Qutebrowser (Qt5-Webkit+Python) browser 1# Firejail profile for Qutebrowser (Qt5-Webkit+Python) browser
2
3noblacklist ~/.config/qutebrowser 2noblacklist ~/.config/qutebrowser
4noblacklist ~/.cache/qutebrowser 3noblacklist ~/.cache/qutebrowser
5include /etc/firejail/disable-common.inc 4include /etc/firejail/disable-common.inc
@@ -7,16 +6,18 @@ include /etc/firejail/disable-programs.inc
7include /etc/firejail/disable-devel.inc 6include /etc/firejail/disable-devel.inc
8 7
9caps.drop all 8caps.drop all
10seccomp
11protocol unix,inet,inet6,netlink
12netfilter 9netfilter
13tracelog 10nonewprivs
14noroot 11noroot
12protocol unix,inet,inet6,netlink
13seccomp
14tracelog
15 15
16whitelist ${DOWNLOADS} 16whitelist ${DOWNLOADS}
17mkdir ~/.config/qutebrowser 17mkdir ~/.config/qutebrowser
18whitelist ~/.config/qutebrowser 18whitelist ~/.config/qutebrowser
19mkdir ~/.cache
20mkdir ~/.cache/qutebrowser 19mkdir ~/.cache/qutebrowser
21whitelist ~/.cache/qutebrowser 20whitelist ~/.cache/qutebrowser
21mkdir ~/.local/share/qutebrowser
22whitelist ~/.local/share/qutebrowser
22include /etc/firejail/whitelist-common.inc 23include /etc/firejail/whitelist-common.inc
diff --git a/etc/ranger.profile b/etc/ranger.profile
new file mode 100644
index 000000000..3538f3eb2
--- /dev/null
+++ b/etc/ranger.profile
@@ -0,0 +1,24 @@
1# ranger file manager profile
2noblacklist /usr/bin/perl
3#noblacklist /usr/bin/cpan*
4noblacklist /usr/share/perl*
5noblacklist /usr/lib/perl*
6noblacklist ~/.config/ranger
7
8include /etc/firejail/disable-common.inc
9include /etc/firejail/disable-programs.inc
10include /etc/firejail/disable-devel.inc
11include /etc/firejail/disable-passwdmgr.inc
12
13caps.drop all
14netfilter
15net none
16nogroups
17nonewprivs
18noroot
19protocol unix
20seccomp
21nosound
22
23private-tmp
24private-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/simple-scan.profile b/etc/simple-scan.profile
new file mode 100644
index 000000000..03089482b
--- /dev/null
+++ b/etc/simple-scan.profile
@@ -0,0 +1,23 @@
1# simple-scan profile
2noblacklist ~/.cache/simple-scan
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,inet,inet6
15#seccomp
16netfilter
17shell none
18tracelog
19
20# private-bin simple-scan
21# private-tmp
22# private-dev
23# private-etc fonts
diff --git a/etc/skanlite.profile b/etc/skanlite.profile
new file mode 100644
index 000000000..4dcfa64d9
--- /dev/null
+++ b/etc/skanlite.profile
@@ -0,0 +1,21 @@
1# skanlite 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
9nogroups
10nonewprivs
11noroot
12nosound
13shell none
14#seccomp
15protocol unix,inet,inet6
16
17private-bin skanlite
18# private-dev
19# private-tmp
20# private-etc
21
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..e2ada3a99
--- /dev/null
+++ b/etc/snap.profile
@@ -0,0 +1,12 @@
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
12
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-agent.profile b/etc/ssh-agent.profile
new file mode 100644
index 000000000..548ede37d
--- /dev/null
+++ b/etc/ssh-agent.profile
@@ -0,0 +1,16 @@
1# ssh-agent
2quiet
3noblacklist ~/.ssh
4noblacklist /tmp/ssh-*
5noblacklist /etc/ssh
6
7include /etc/firejail/disable-common.inc
8include /etc/firejail/disable-programs.inc
9include /etc/firejail/disable-passwdmgr.inc
10
11caps.drop all
12netfilter
13nonewprivs
14noroot
15protocol unix,inet,inet6
16seccomp
diff --git a/etc/ssh.profile b/etc/ssh.profile
index 7b282bde6..b7a8ed2b9 100644
--- a/etc/ssh.profile
+++ b/etc/ssh.profile
@@ -1,12 +1,16 @@
1# ssh client 1# ssh client
2quiet
2noblacklist ~/.ssh 3noblacklist ~/.ssh
4noblacklist /tmp/ssh-*
5noblacklist /etc/ssh
3 6
4include /etc/firejail/disable-common.inc 7include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc 8include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-passwdmgr.inc 9include /etc/firejail/disable-passwdmgr.inc
7 10
8caps.drop all 11caps.drop all
9seccomp
10protocol unix,inet,inet6
11netfilter 12netfilter
13nonewprivs
12noroot 14noroot
15protocol unix,inet,inet6
16seccomp
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..2b7724b11
--- /dev/null
+++ b/etc/strings.profile
@@ -0,0 +1,11 @@
1# strings profile
2quiet
3ignore noroot
4include /etc/firejail/default.profile
5
6net none
7nosound
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..3addb02fb
--- /dev/null
+++ b/etc/tar.profile
@@ -0,0 +1,18 @@
1# tar profile
2quiet
3ignore noroot
4include /etc/firejail/default.profile
5
6blacklist /tmp/.X11-unix
7
8hostname tar
9net none
10no3d
11nosound
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/tracker.profile b/etc/tracker.profile
new file mode 100644
index 000000000..217631216
--- /dev/null
+++ b/etc/tracker.profile
@@ -0,0 +1,24 @@
1# tracker profile
2
3# Tracker is started by systemd on most systems. Therefore it is not firejailed by default
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
17netfilter
18shell none
19tracelog
20
21# private-bin tracker
22# private-tmp
23# private-dev
24# private-etc fonts
diff --git a/etc/transmission-cli.profile b/etc/transmission-cli.profile
new file mode 100644
index 000000000..6cbc3415c
--- /dev/null
+++ b/etc/transmission-cli.profile
@@ -0,0 +1,23 @@
1# transmission-cli bittorrent profile
2noblacklist ${HOME}/.config/transmission
3noblacklist ${HOME}/.cache/transmission
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
14nosound
15protocol unix,inet,inet6
16seccomp
17shell none
18tracelog
19
20#private-bin transmission-cli
21private-tmp
22private-dev
23private-etc none
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/transmission-show.profile b/etc/transmission-show.profile
new file mode 100644
index 000000000..5e5284b34
--- /dev/null
+++ b/etc/transmission-show.profile
@@ -0,0 +1,24 @@
1# transmission-show profile
2noblacklist ${HOME}/.config/transmission
3noblacklist ${HOME}/.cache/transmission
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
12net none
13nonewprivs
14noroot
15nosound
16protocol unix
17seccomp
18shell none
19tracelog
20
21# private-bin
22private-tmp
23private-dev
24private-etc none
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..bde6f4e22
--- /dev/null
+++ b/etc/unrar.profile
@@ -0,0 +1,18 @@
1# unrar profile
2quiet
3ignore noroot
4include /etc/firejail/default.profile
5
6blacklist /tmp/.X11-unix
7
8hostname unrar
9net none
10no3d
11nosound
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..8c10d11a0
--- /dev/null
+++ b/etc/unzip.profile
@@ -0,0 +1,16 @@
1# unzip profile
2quiet
3ignore noroot
4include /etc/firejail/default.profile
5blacklist /tmp/.X11-unix
6
7hostname unzip
8net none
9no3d
10nosound
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..d5b750a13
--- /dev/null
+++ b/etc/uudeview.profile
@@ -0,0 +1,15 @@
1# uudeview profile
2quiet
3ignore noroot
4include /etc/firejail/default.profile
5
6blacklist /etc
7
8hostname uudeview
9net none
10nosound
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..36a1e0704
--- /dev/null
+++ b/etc/virtualbox.profile
@@ -0,0 +1,12 @@
1# VirtualBox profile
2noblacklist ${HOME}/.VirtualBox
3noblacklist ${HOME}/VirtualBox VMs
4noblacklist ${HOME}/.config/VirtualBox
5noblacklist /usr/bin/virtualbox
6include /etc/firejail/disable-common.inc
7include /etc/firejail/disable-programs.inc
8include /etc/firejail/disable-passwdmgr.inc
9
10caps.drop all
11
12
diff --git a/etc/vivaldi.profile b/etc/vivaldi.profile
index 449d9a168..08b046847 100644
--- a/etc/vivaldi.profile
+++ b/etc/vivaldi.profile
@@ -8,10 +8,8 @@ include /etc/firejail/disable-devel.inc
8netfilter 8netfilter
9 9
10whitelist ${DOWNLOADS} 10whitelist ${DOWNLOADS}
11mkdir ~/.config
12mkdir ~/.config/vivaldi 11mkdir ~/.config/vivaldi
13whitelist ~/.config/vivaldi 12whitelist ~/.config/vivaldi
14mkdir ~/.cache
15mkdir ~/.cache/vivaldi 13mkdir ~/.cache/vivaldi
16whitelist ~/.cache/vivaldi 14whitelist ~/.cache/vivaldi
17include /etc/firejail/whitelist-common.inc 15include /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/w3m.profile b/etc/w3m.profile
new file mode 100644
index 000000000..d765217cf
--- /dev/null
+++ b/etc/w3m.profile
@@ -0,0 +1,23 @@
1# w3m profile
2noblacklist ~/.w3m
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,inet,inet6
15seccomp
16netfilter
17shell none
18tracelog
19
20# private-bin w3m
21private-tmp
22private-dev
23private-etc none
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/wget.profile b/etc/wget.profile
new file mode 100644
index 000000000..d9bca2acc
--- /dev/null
+++ b/etc/wget.profile
@@ -0,0 +1,22 @@
1# wget profile
2quiet
3include /etc/firejail/disable-common.inc
4include /etc/firejail/disable-programs.inc
5include /etc/firejail/disable-passwdmgr.inc
6
7caps.drop all
8netfilter
9nonewprivs
10noroot
11nogroups
12nosound
13protocol unix,inet,inet6
14seccomp
15shell none
16
17
18# private-bin wget
19# private-etc resolv.conf
20private-dev
21private-tmp
22
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..ec8ed8771
--- /dev/null
+++ b/etc/wire.profile
@@ -0,0 +1,23 @@
1# wire messenger profile
2noblacklist ~/.config/Wire
3noblacklist ~/.config/wire
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
13nogroups
14noroot
15protocol unix,inet,inet6,netlink
16seccomp
17shell none
18
19private-tmp
20private-dev
21
22# Note: the current beta version of wire is located in /opt/Wire/wire and therefore not in PATH.
23# To use wire with firejail run "firejail /opt/Wire/wire"
diff --git a/etc/wireshark.profile b/etc/wireshark.profile
new file mode 100644
index 000000000..898fc787e
--- /dev/null
+++ b/etc/wireshark.profile
@@ -0,0 +1,22 @@
1# Firejail profile for
2noblacklist ${HOME}/.config/wireshark
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
14nosound
15protocol unix,inet,inet6,netlink
16seccomp
17shell none
18tracelog
19
20private-bin wireshark
21private-dev
22private-tmp
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/xed.profile b/etc/xed.profile
new file mode 100644
index 000000000..051710a70
--- /dev/null
+++ b/etc/xed.profile
@@ -0,0 +1,21 @@
1# Firejail profile for Xed
2noblacklist ${HOME}/.config/xed
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
10net none
11nogroups
12nonewprivs
13noroot
14nosound
15seccomp
16shell none
17tracelog
18
19private-bin xed
20private-dev
21private-tmp
diff --git a/etc/xfburn.profile b/etc/xfburn.profile
new file mode 100644
index 000000000..1dd24aa61
--- /dev/null
+++ b/etc/xfburn.profile
@@ -0,0 +1,23 @@
1# xfburn profile
2noblacklist ~/.config/xfburn
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
16netfilter
17shell none
18tracelog
19
20# private-bin xfburn
21# private-tmp
22# private-dev
23# private-etc fonts
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/xonotic-glx.profile b/etc/xonotic-glx.profile
new file mode 100644
index 000000000..b255ffdbb
--- /dev/null
+++ b/etc/xonotic-glx.profile
@@ -0,0 +1,5 @@
1#
2#Profile for xonotic:xonotic-glx
3#
4
5include /etc/firejail/xonotic.profile
diff --git a/etc/xonotic-sdl.profile b/etc/xonotic-sdl.profile
new file mode 100644
index 000000000..783667304
--- /dev/null
+++ b/etc/xonotic-sdl.profile
@@ -0,0 +1,5 @@
1#
2#Profile for xonotic:xonotic-sdl
3#
4
5include /etc/firejail/xonotic.profile
diff --git a/etc/xonotic.profile b/etc/xonotic.profile
new file mode 100644
index 000000000..75d649619
--- /dev/null
+++ b/etc/xonotic.profile
@@ -0,0 +1,25 @@
1#
2#Profile for xonotic
3#
4
5#No Blacklist Paths
6noblacklist ${HOME}/.xonotic
7
8#Blacklist Paths
9include /etc/firejail/disable-common.inc
10include /etc/firejail/disable-programs.inc
11include /etc/firejail/disable-passwdmgr.inc
12include /etc/firejail/disable-devel.inc
13
14#Whitelist Paths
15mkdir ${HOME}/.xonotic
16whitelist ${HOME}/.xonotic
17include /etc/firejail/whitelist-common.inc
18
19#Options
20caps.drop all
21netfilter
22nonewprivs
23noroot
24protocol unix,inet,inet6
25seccomp
diff --git a/etc/generic.profile b/etc/xpdf.profile
index f2c7d4114..7ea368bbe 100644
--- a/etc/generic.profile
+++ b/etc/xpdf.profile
@@ -1,15 +1,18 @@
1################################ 1################################
2# Generic GUI application profile 2# xpdf application profile
3################################ 3################################
4noblacklist ${HOME}/.xpdfrc
4include /etc/firejail/disable-common.inc 5include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc 6include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-passwdmgr.inc 7include /etc/firejail/disable-passwdmgr.inc
7 8
8#blacklist ${HOME}/.wine
9
10caps.drop all 9caps.drop all
11seccomp 10net none
12protocol unix,inet,inet6 11nonewprivs
13netfilter
14noroot 12noroot
13protocol unix
14shell none
15seccomp
15 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/xpra.profile b/etc/xpra.profile
new file mode 100644
index 000000000..8584e4e5b
--- /dev/null
+++ b/etc/xpra.profile
@@ -0,0 +1,21 @@
1# xpra 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
9nogroups
10nonewprivs
11noroot
12nosound
13shell none
14seccomp
15protocol unix,inet,inet6
16
17# private-bin
18private-dev
19private-tmp
20# private-etc
21
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..ca380b4c7
--- /dev/null
+++ b/etc/xviewer.profile
@@ -0,0 +1,21 @@
1# xviewer profile
2noblacklist ~/.config/xviewer
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-dev
20private-bin xviewer
21private-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..6164e3200
--- /dev/null
+++ b/etc/xzdec.profile
@@ -0,0 +1,14 @@
1# xzdec profile
2quiet
3ignore noroot
4include /etc/firejail/default.profile
5
6blacklist /tmp/.X11-unix
7
8net none
9no3d
10nosound
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..4c08868cf
--- /dev/null
+++ b/etc/zoom.profile
@@ -0,0 +1,22 @@
1# Firejail profile for zoom.us
2noblacklist ~/.config/zoomus.conf
3
4include /etc/firejail/disable-common.inc
5include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-devel.inc
7
8
9# Whitelists
10
11mkdir ~/.zoom
12whitelist ~/.zoom
13
14
15caps.drop all
16netfilter
17nonewprivs
18noroot
19protocol unix,inet,inet6
20seccomp
21
22private-tmp
diff --git a/gcov.sh b/gcov.sh
new file mode 100755
index 000000000..57190cad2
--- /dev/null
+++ b/gcov.sh
@@ -0,0 +1,94 @@
1#!/bin/bash
2
3gcov_init() {
4 USER=`whoami`
5 firejail --help > /dev/null
6 firemon --help > /dev/null
7 /usr/lib/firejail/fnet --help > /dev/null
8 /usr/lib/firejail/fseccomp --help > /dev/null
9 /usr/lib/firejail/ftee --help > /dev/null
10 /usr/lib/firejail/fcopy --help > /dev/null
11 firecfg --help > /dev/null
12 sudo chown $USER:$USER `find .`
13}
14
15generate() {
16 lcov -q --capture -d src/firejail -d src/firemon -d src/fcopy -d src/fseccomp -d src/fnet -d src/ftee -d src/lib -d src/firecfg --output-file gcov-file-new
17 lcov --add-tracefile gcov-file-old --add-tracefile gcov-file-new --output-file gcov-file
18 rm -fr gcov-dir
19 genhtml -q gcov-file --output-directory gcov-dir
20 sudo rm `find . -name *.gcda`
21 cp gcov-file gcov-file-old
22 gcov_init
23}
24
25
26gcov_init
27lcov -q --capture -d src/firejail -d src/firemon -d src/fcopy -d src/fseccomp -d src/fnet -d src/ftee -d src/lib -d src/firecfg --output-file gcov-file-old
28
29#make test-environment
30#generate
31#sleep 2
32#exit
33
34
35# running tests
36make test-root
37generate
38sleep 2
39
40make test-chroot
41generate
42sleep 2
43
44make test-network
45generate
46sleep 2
47
48make test-appimage
49generate
50sleep 2
51
52make test-overlay
53generate
54sleep 2
55
56make test-fcopy
57generate
58sleep 2
59
60make test-profiles
61generate
62sleep 2
63
64make test-fs
65generate
66sleep 2
67
68make test-utils
69generate
70sleep 2
71
72make test-environment
73generate
74sleep 2
75
76make test-apps
77generate
78sleep 2
79
80make test-apps-x11
81generate
82sleep 2
83
84make test-apps-x11-xorg
85generate
86sleep 2
87
88make test-filters
89generate
90sleep 2
91
92make test-arguments
93generate
94sleep 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..97e7cf884 100644
--- a/platform/debian/conffiles
+++ b/platform/debian/conffiles
@@ -1,85 +1,239 @@
1/etc/firejail/evince.profile 1/etc/firejail/0ad.profile
2/etc/firejail/chromium.profile 2/etc/firejail/7z.profile
3/etc/firejail/Cyberfox.profile
4/etc/firejail/Mathematica.profile
5/etc/firejail/Telegram.profile
6/etc/firejail/Wire.profile
7/etc/firejail/abrowser.profile
8/etc/firejail/amarok.profile
9/etc/firejail/ark.profile
10/etc/firejail/atom-beta.profile
11/etc/firejail/atom.profile
12/etc/firejail/atool.profile
13/etc/firejail/atril.profile
14/etc/firejail/audacious.profile
15/etc/firejail/audacity.profile
16/etc/firejail/aweather.profile
17/etc/firejail/bitlbee.profile
18/etc/firejail/bleachbit.profile
19/etc/firejail/brasero.profile
20/etc/firejail/brave.profile
21/etc/firejail/cherrytree.profile
3/etc/firejail/chromium-browser.profile 22/etc/firejail/chromium-browser.profile
4/etc/firejail/google-chrome.profile 23/etc/firejail/chromium.profile
5/etc/firejail/google-chrome-stable.profile 24/etc/firejail/claws-mail.profile
25/etc/firejail/clementine.profile
26/etc/firejail/cmus.profile
27/etc/firejail/conkeror.profile
28/etc/firejail/corebird.profile
29/etc/firejail/cpio.profile
30/etc/firejail/cryptocat.profile
31/etc/firejail/Cryptocat.profile
32/etc/firejail/cyberfox.profile
33/etc/firejail/deadbeef.profile
34/etc/firejail/default.profile
35/etc/firejail/deluge.profile
36/etc/firejail/dillo.profile
37/etc/firejail/disable-common.inc
38/etc/firejail/disable-devel.inc
39/etc/firejail/disable-passwdmgr.inc
40/etc/firejail/disable-programs.inc
41/etc/firejail/display.profile
42/etc/firejail/dnscrypt-proxy.profile
43/etc/firejail/dnsmasq.profile
44/etc/firejail/dolphin.profile
45/etc/firejail/dosbox.profile
46/etc/firejail/dragon.profile
47/etc/firejail/dropbox.profile
48/etc/firejail/elinks.profile
49/etc/firejail/emacs.profile
50/etc/firejail/empathy.profile
51/etc/firejail/enchant.profile
52/etc/firejail/eog.profile
53/etc/firejail/eom.profile
54/etc/firejail/epiphany.profile
55/etc/firejail/evince.profile
56/etc/firejail/evolution.profile
57/etc/firejail/exiftool.profile
58/etc/firejail/fbreader.profile
59/etc/firejail/feh.profile
60/etc/firejail/file-roller.profile
61/etc/firejail/file.profile
62/etc/firejail/filezilla.profile
63/etc/firejail/firefox-esr.profile
64/etc/firejail/firefox.profile
65/etc/firejail/firejail.config
66/etc/firejail/flashpeak-slimjet.profile
67/etc/firejail/flowblade.profile
68/etc/firejail/franz.profile
69/etc/firejail/gajim.profile
70/etc/firejail/gedit.profile
71/etc/firejail/gimp.profile
72/etc/firejail/git.profile
73/etc/firejail/gitter.profile
74/etc/firejail/gjs.profile
75/etc/firejail/gnome-books.profile
76/etc/firejail/gnome-chess.profile
77/etc/firejail/gnome-clocks.profile
78/etc/firejail/gnome-documents.profile
79/etc/firejail/gnome-maps.profile
80/etc/firejail/gnome-mplayer.profile
81/etc/firejail/gnome-music.profile
82/etc/firejail/gnome-photos.profile
83/etc/firejail/gnome-weather.profile
84/etc/firejail/goobox.profile
6/etc/firejail/google-chrome-beta.profile 85/etc/firejail/google-chrome-beta.profile
86/etc/firejail/google-chrome-stable.profile
7/etc/firejail/google-chrome-unstable.profile 87/etc/firejail/google-chrome-unstable.profile
8/etc/firejail/midori.profile 88/etc/firejail/google-chrome.profile
89/etc/firejail/google-play-music-desktop-player.profile
90/etc/firejail/gpa.profile
91/etc/firejail/gpg-agent.profile
92/etc/firejail/gpg.profile
93/etc/firejail/gpredict.profile
94/etc/firejail/gtar.profile
95/etc/firejail/gthumb.profile
96/etc/firejail/guayadeque.profile
97/etc/firejail/gwenview.profile
98/etc/firejail/gzip.profile
99/etc/firejail/hedgewars.profile
100/etc/firejail/hexchat.profile
101/etc/firejail/highlight.profile
102/etc/firejail/icecat.profile
9/etc/firejail/icedove.profile 103/etc/firejail/icedove.profile
10/etc/firejail/iceweasel.profile 104/etc/firejail/iceweasel.profile
11/etc/firejail/dropbox.profile 105/etc/firejail/img2txt.profile
106/etc/firejail/inkscape.profile
107/etc/firejail/inox.profile
108/etc/firejail/jitsi.profile
109/etc/firejail/k3b.profile
110/etc/firejail/kate.profile
111/etc/firejail/keepass.profile
112/etc/firejail/keepass2.profile
113/etc/firejail/keepassx.profile
114/etc/firejail/kmail.profile
115/etc/firejail/konversation.profile
116/etc/firejail/less.profile
117/etc/firejail/libreoffice.profile
118/etc/firejail/localc.profile
119/etc/firejail/lodraw.profile
120/etc/firejail/loffice.profile
121/etc/firejail/lofromtemplate.profile
12/etc/firejail/login.users 122/etc/firejail/login.users
13/etc/firejail/firefox.profile 123/etc/firejail/loimpress.profile
14/etc/firejail/opera.profile 124/etc/firejail/lomath.profile
125/etc/firejail/loweb.profile
126/etc/firejail/lowriter.profile
127/etc/firejail/luminance-hdr.profile
128/etc/firejail/lxterminal.profile
129/etc/firejail/lynx.profile
130/etc/firejail/mathematica.profile
131/etc/firejail/mcabber.profile
132/etc/firejail/mediainfo.profile
133/etc/firejail/midori.profile
134/etc/firejail/mpv.profile
135/etc/firejail/mumble.profile
136/etc/firejail/mupdf.profile
137/etc/firejail/mupen64plus.profile
138/etc/firejail/mutt.profile
139/etc/firejail/nautilus.profile
140/etc/firejail/netsurf.profile
141/etc/firejail/nolocal.net
142/etc/firejail/odt2txt.profile
143/etc/firejail/okular.profile
144/etc/firejail/openbox.profile
145/etc/firejail/openshot.profile
15/etc/firejail/opera-beta.profile 146/etc/firejail/opera-beta.profile
16/etc/firejail/thunderbird.profile 147/etc/firejail/opera.profile
17/etc/firejail/transmission-gtk.profile 148/etc/firejail/palemoon.profile
18/etc/firejail/transmission-qt.profile 149/etc/firejail/parole.profile
19/etc/firejail/vlc.profile 150/etc/firejail/pdftotext.profile
20/etc/firejail/audacious.profile 151/etc/firejail/pidgin.profile
21/etc/firejail/clementine.profile 152/etc/firejail/pix.profile
22/etc/firejail/epiphany.profile 153/etc/firejail/pluma.profile
23/etc/firejail/qtox.profile
24/etc/firejail/polari.profile 154/etc/firejail/polari.profile
25/etc/firejail/gnome-mplayer.profile 155/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 156/etc/firejail/qbittorrent.profile
30/etc/firejail/generic.profile 157/etc/firejail/qemu-launcher.profile
31/etc/firejail/xchat.profile 158/etc/firejail/qemu-system-x86_64.profile
32/etc/firejail/server.profile 159/etc/firejail/qpdfview.profile
160/etc/firejail/qtox.profile
33/etc/firejail/quassel.profile 161/etc/firejail/quassel.profile
34/etc/firejail/pidgin.profile 162/etc/firejail/quiterss.profile
35/etc/firejail/filezilla.profile 163/etc/firejail/qutebrowser.profile
36/etc/firejail/empathy.profile 164/etc/firejail/ranger.profile
37/etc/firejail/disable-common.inc 165/etc/firejail/rhythmbox.profile
38/etc/firejail/deadbeef.profile 166/etc/firejail/rtorrent.profile
39/etc/firejail/icecat.profile 167/etc/firejail/seamonkey-bin.profile
40/etc/firejail/fbreader.profile 168/etc/firejail/seamonkey.profile
41/etc/firejail/spotify.profile 169/etc/firejail/server.profile
170/etc/firejail/simple-scan.profile
171/etc/firejail/skanlite.profile
42/etc/firejail/skype.profile 172/etc/firejail/skype.profile
173/etc/firejail/skypeforlinux.profile
174/etc/firejail/slack.profile
175/etc/firejail/snap.profile
176/etc/firejail/soffice.profile
177/etc/firejail/spotify.profile
178/etc/firejail/ssh-agent.profile
179/etc/firejail/ssh.profile
180/etc/firejail/start-tor-browser.profile
43/etc/firejail/steam.profile 181/etc/firejail/steam.profile
44/etc/firejail/wine.profile 182/etc/firejail/stellarium.profile
45/etc/firejail/disable-devel.inc 183/etc/firejail/strings.profile
46/etc/firejail/conkeror.profile 184/etc/firejail/synfigstudio.profile
185/etc/firejail/tar.profile
186/etc/firejail/telegram.profile
187/etc/firejail/thunderbird.profile
188/etc/firejail/totem.profile
189/etc/firejail/tracker.profile
190/etc/firejail/transmission-cli.profile
191/etc/firejail/transmission-gtk.profile
192/etc/firejail/transmission-qt.profile
193/etc/firejail/transmission-show.profile
194/etc/firejail/uget-gtk.profile
47/etc/firejail/unbound.profile 195/etc/firejail/unbound.profile
48/etc/firejail/dnscrypt-proxy.profile 196/etc/firejail/unrar.profile
49/etc/firejail/whitelist-common.inc 197/etc/firejail/unzip.profile
50/etc/firejail/nolocal.net 198/etc/firejail/uudeview.profile
199/etc/firejail/vim.profile
200/etc/firejail/virtualbox.profile
201/etc/firejail/vivaldi-beta.profile
202/etc/firejail/vivaldi.profile
203/etc/firejail/vlc.profile
204/etc/firejail/w3m.profile
205/etc/firejail/warzone2100.profile
51/etc/firejail/webserver.net 206/etc/firejail/webserver.net
52/etc/firejail/bitlbee.profile
53/etc/firejail/weechat.profile
54/etc/firejail/weechat-curses.profile 207/etc/firejail/weechat-curses.profile
55/etc/firejail/hexchat.profile 208/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 209/etc/firejail/wesnoth.profile
69/etc/firejail/hedgewars.profile 210/etc/firejail/whitelist-common.inc
70/etc/firejail/vivaldi.profile 211/etc/firejail/wine.profile
71/etc/firejail/vivaldi-beta.profile 212/etc/firejail/wire.profile
72/etc/firejail/atril.profile 213/etc/firejail/wireshark.profile
73/etc/firejail/firejail.config 214/etc/firejail/xchat.profile
74/etc/firejail/qutebrowser.profile 215/etc/firejail/xed.profile
75/etc/firejail/flashpeak-slimjet.profile 216/etc/firejail/xfburn.profile
76/etc/firejail/ssh.profile 217/etc/firejail/xiphos.profile
77/etc/firejail/openbox.profile 218/etc/firejail/xpdf.profile
78/etc/firejail/disable-programs.inc 219/etc/firejail/xplayer.profile
79/etc/firejail/disable-passwdmgr.inc 220/etc/firejail/xpra.profile
80/etc/firejail/dillo.profile 221/etc/firejail/xreader.profile
81/etc/firejail/cmus.profile 222/etc/firejail/xviewer.profile
82/etc/firejail/dnsmasq.profile 223/etc/firejail/xz.profile
83/etc/firejail/palemoon.profile 224/etc/firejail/xzdec.profile
84/etc/firejail/abrowser.profile 225/etc/firejail/zathura.profile
85/etc/firejail/0ad.profile 226/etc/firejail/zoom.profile
227/etc/firejail/wget.profile
228/etc/firejail/bless.profile
229/etc/firejail/gnome-2048.profile
230/etc/firejail/gnome-calculator.profile
231/etc/firejail/gnome-contacts.profile
232/etc/firejail/jd-gui.profile
233/etc/firejail/lollypop.profile
234/etc/firejail/multimc5.profile
235/etc/firejail/pdfsam.profile
236/etc/firejail/pithos.profile
237/etc/firejail/xonotic-glx.profile
238/etc/firejail/xonotic-sdl.profile
239/etc/firejail/xonotic.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..d92660536
--- /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 strncpy(remote.sun_path, sockfile, sizeof(remote.sun_path));
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..84b23fe0a
--- /dev/null
+++ b/src/faudit/pid.c
@@ -0,0 +1,99 @@
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 free(fname);
50 continue;
51 }
52
53 // read file
54 char buf[100];
55 if (fgets(buf, 10, fp) == NULL) {
56 fclose(fp);
57 free(fname);
58 continue;
59 }
60 not_visible = 0;
61
62 // clean /n
63 char *ptr;
64 if ((ptr = strchr(buf, '\n')) != NULL)
65 *ptr = '\0';
66
67 // check process name against the kernel list
68 int j = 0;
69 while (kern_proc[j] != NULL) {
70 if (strncmp(buf, kern_proc[j], strlen(kern_proc[j])) == 0) {
71 fclose(fp);
72 free(fname);
73 printf("BAD: Process %d is not running in a PID namespace. ", getpid());
74 printf("Are you sure you're running in a sandbox?\n");
75 return;
76 }
77 j++;
78 }
79
80 fclose(fp);
81 free(fname);
82 }
83
84 pid_t pid = getpid();
85 if (not_visible && pid > 100)
86 printf("BAD: Process %d is not running in a PID namespace.\n", pid);
87 else
88 printf("GOOD: process %d is running in a PID namespace.\n", pid);
89
90 // try to guess the type of container/sandbox
91 char *str = getenv("container");
92 if (str)
93 printf("INFO: container/sandbox %s.\n", str);
94 else {
95 str = getenv("SNAP");
96 if (str)
97 printf("INFO: this is a snap package\n");
98 }
99}
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..4cd2526ba
--- /dev/null
+++ b/src/faudit/syscall.c
@@ -0,0 +1,102 @@
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 int rv = mount(NULL, NULL, NULL, 0, NULL);
39 (void) rv;
40 printf("\nUGLY: mount syscall permitted.\n");
41 }
42 else if (strcmp(argv[2], "umount2") == 0) {
43 umount2(NULL, 0);
44 printf("\nUGLY: umount2 syscall permitted.\n");
45 }
46 else if (strcmp(argv[2], "ptrace") == 0) {
47 ptrace(0, 0, NULL, NULL);
48 printf("\nUGLY: ptrace syscall permitted.\n");
49 }
50 else if (strcmp(argv[2], "swapon") == 0) {
51 swapon(NULL, 0);
52 printf("\nUGLY: swapon syscall permitted.\n");
53 }
54 else if (strcmp(argv[2], "swapoff") == 0) {
55 swapoff(NULL);
56 printf("\nUGLY: swapoff syscall permitted.\n");
57 }
58 else if (strcmp(argv[2], "init_module") == 0) {
59 init_module(NULL, 0, NULL);
60 printf("\nUGLY: init_module syscall permitted.\n");
61 }
62 else if (strcmp(argv[2], "delete_module") == 0) {
63 delete_module(NULL, 0);
64 printf("\nUGLY: delete_module syscall permitted.\n");
65 }
66 else if (strcmp(argv[2], "chroot") == 0) {
67 int rv = chroot("/blablabla-57281292");
68 (void) rv;
69 printf("\nUGLY: chroot syscall permitted.\n");
70 }
71 else if (strcmp(argv[2], "pivot_root") == 0) {
72 pivot_root(NULL, NULL);
73 printf("\nUGLY: pivot_root syscall permitted.\n");
74 }
75#if defined(__i386__) || defined(__x86_64__)
76 else if (strcmp(argv[2], "iopl") == 0) {
77 iopl(0L);
78 printf("\nUGLY: iopl syscall permitted.\n");
79 }
80 else if (strcmp(argv[2], "ioperm") == 0) {
81 ioperm(0, 0, 0);
82 printf("\nUGLY: ioperm syscall permitted.\n");
83 }
84#endif
85 exit(0);
86}
87
88void syscall_run(const char *name) {
89 assert(prog);
90
91 pid_t child = fork();
92 if (child < 0)
93 errExit("fork");
94 if (child == 0) {
95 execl(prog, prog, "syscall", name, NULL);
96 perror("execl");
97 _exit(1);
98 }
99
100 // wait for the child to finish
101 waitpid(child, NULL, 0);
102}
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/fcopy/Makefile.in b/src/fcopy/Makefile.in
new file mode 100644
index 000000000..278957a4f
--- /dev/null
+++ b/src/fcopy/Makefile.in
@@ -0,0 +1,45 @@
1all: fcopy
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
38fcopy: $(OBJS)
39 $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTRA_LDFLAGS)
40
41clean:; rm -f *.o fcopy *.gcov *.gcda *.gcno
42
43distclean: clean
44 rm -fr Makefile
45
diff --git a/src/fcopy/main.c b/src/fcopy/main.c
new file mode 100644
index 000000000..b1e2813db
--- /dev/null
+++ b/src/fcopy/main.c
@@ -0,0 +1,340 @@
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 "../include/common.h"
22#include <fcntl.h>
23#include <ftw.h>
24
25
26#define COPY_LIMIT (500 * 1024 *1024)
27static int size_limit_reached = 0;
28static unsigned file_cnt = 0;
29static unsigned size_cnt = 0;
30
31static char *outpath = NULL;
32static char *inpath = NULL;
33
34
35// modified version of the function from util.c
36static void copy_file(const char *srcname, const char *destname, mode_t mode, uid_t uid, gid_t gid) {
37 assert(srcname);
38 assert(destname);
39 mode &= 07777;
40
41 // open source
42 int src = open(srcname, O_RDONLY);
43 if (src < 0) {
44 fprintf(stderr, "Warning: cannot open %s, file not copied\n", srcname);
45 return;
46 }
47
48 // open destination
49 int dst = open(destname, O_CREAT|O_WRONLY|O_TRUNC, 0755);
50 if (dst < 0) {
51 fprintf(stderr, "Warning fcopy: cannot open %s, file not copied\n", destname);
52 close(src);
53 return;
54 }
55
56 // copy
57 ssize_t len;
58 static const int BUFLEN = 1024;
59 unsigned char buf[BUFLEN];
60 while ((len = read(src, buf, BUFLEN)) > 0) {
61 int done = 0;
62 while (done != len) {
63 int rv = write(dst, buf + done, len - done);
64 if (rv == -1)
65 goto errexit;
66 done += rv;
67 }
68 }
69 fflush(0);
70
71 if (fchown(dst, uid, gid) == -1)
72 goto errexit;
73 if (fchmod(dst, mode) == -1)
74 goto errexit;
75
76 close(src);
77 close(dst);
78
79 return;
80
81errexit:
82 close(src);
83 close(dst);
84 unlink(destname);
85 fprintf(stderr, "Warning fcopy: cannot copy %s\n", destname);
86}
87
88
89
90// modified version of the function in firejail/util.c
91static void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid) {
92 assert(fname);
93 mode &= 07777;
94
95 if (mkdir(fname, mode) == -1 ||
96 chmod(fname, mode) == -1) {
97 fprintf(stderr, "Error fcopy: failed to create %s directory\n", fname);
98 errExit("mkdir/chmod");
99 }
100 if (chown(fname, uid, gid))
101 fprintf(stderr, "Warning fcopy: failed to change ownership of %s\n", fname);
102}
103
104void copy_link(const char *target, const char *linkpath, mode_t mode, uid_t uid, gid_t gid) {
105 (void) mode;
106 (void) uid;
107 (void) gid;
108 char *rp = realpath(target, NULL);
109 if (rp) {
110 if (symlink(rp, linkpath) == -1)
111 goto errout;
112 free(rp);
113 }
114 else
115 goto errout;
116
117 return;
118errout:
119 fprintf(stderr, "Warning fcopy: cannot create symbolic link %s\n", target);
120}
121
122static int first = 1;
123static int fs_copydir(const char *infname, const struct stat *st, int ftype, struct FTW *sftw) {
124 (void) st;
125 (void) sftw;
126 assert(infname);
127 assert(*infname != '\0');
128 assert(outpath);
129 assert(*outpath != '\0');
130 assert(inpath);
131
132 // check size limit
133 if (size_limit_reached)
134 return 0;
135
136
137 char *outfname;
138 if (asprintf(&outfname, "%s%s", outpath, infname + strlen(inpath)) == -1)
139 errExit("asprintf");
140
141//printf("outpaht %s\n", outpath);
142//printf("inpath %s\n", inpath);
143//printf("infname %s\n", infname);
144//printf("outfname %s\n\n", outfname);
145
146 // don't copy it if we already have the file
147 struct stat s;
148 if (stat(outfname, &s) == 0) {
149 if (first)
150 first = 0;
151 else
152 fprintf(stderr, "Warning fcopy: skipping %s, file already present\n", infname);
153 free(outfname);
154 return 0;
155 }
156
157 // extract mode and ownership
158 if (stat(infname, &s) != 0) {
159 fprintf(stderr, "Warning fcopy: skipping %s, cannot find inode\n", infname);
160 free(outfname);
161 return 0;
162 }
163 uid_t uid = s.st_uid;
164 gid_t gid = s.st_gid;
165 mode_t mode = s.st_mode;
166
167 // recalculate size
168 if ((s.st_size + size_cnt) > COPY_LIMIT) {
169 fprintf(stderr, "Error fcopy: size limit of %dMB reached\n", (COPY_LIMIT / 1024) / 1024);
170 size_limit_reached = 1;
171 free(outfname);
172 return 0;
173 }
174
175 file_cnt++;
176 size_cnt += s.st_size;
177
178 if(ftype == FTW_F) {
179 copy_file(infname, outfname, mode, uid, gid);
180 }
181 else if (ftype == FTW_D) {
182 mkdir_attr(outfname, mode, uid, gid);
183 }
184 else if (ftype == FTW_SL) {
185 copy_link(infname, outfname, mode, uid, gid);
186 }
187
188 return(0);
189}
190
191static char *check(const char *src) {
192 struct stat s;
193 char *rsrc = realpath(src, NULL);
194 if (!rsrc || stat(rsrc, &s) == -1)
195 goto errexit;
196
197 // check uid
198 if (s.st_uid != getuid() || s.st_gid != getgid())
199 goto errexit;
200
201 // dir, link, regular file
202 if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode) || S_ISLNK(s.st_mode))
203 return rsrc; // normal exit from the function
204
205errexit:
206 fprintf(stderr, "Error fcopy: invalid file %s\n", src);
207 exit(1);
208}
209
210static void duplicate_dir(const char *src, const char *dest, struct stat *s) {
211 (void) s;
212 char *rsrc = check(src);
213 char *rdest = check(dest);
214 inpath = rsrc;
215 outpath = rdest;
216
217 // walk
218 if(nftw(rsrc, fs_copydir, 1, FTW_PHYS) != 0) {
219 fprintf(stderr, "Error: unable to copy file\n");
220 exit(1);
221 }
222
223 free(rsrc);
224 free(rdest);
225}
226
227static void duplicate_file(const char *src, const char *dest, struct stat *s) {
228 char *rsrc = check(src);
229 char *rdest = check(dest);
230 uid_t uid = s->st_uid;
231 gid_t gid = s->st_gid;
232 mode_t mode = s->st_mode;
233
234 // build destination file name
235 char *name;
236 char *ptr = strrchr(rsrc, '/');
237 ptr++;
238 if (asprintf(&name, "%s/%s", rdest, ptr) == -1)
239 errExit("asprintf");
240
241 // copy
242 copy_file(rsrc, name, mode, uid, gid);
243
244 free(name);
245 free(rsrc);
246 free(rdest);
247}
248
249static void duplicate_link(const char *src, const char *dest, struct stat *s) {
250 char *rsrc = check(src); // we drop the result and use the original name
251 char *rdest = check(dest);
252 uid_t uid = s->st_uid;
253 gid_t gid = s->st_gid;
254 mode_t mode = s->st_mode;
255
256 // build destination file name
257 char *name;
258// char *ptr = strrchr(rsrc, '/');
259 char *ptr = strrchr(src, '/');
260 ptr++;
261 if (asprintf(&name, "%s/%s", rdest, ptr) == -1)
262 errExit("asprintf");
263
264 // copy
265 copy_link(rsrc, name, mode, uid, gid);
266
267 free(name);
268 free(rsrc);
269 free(rdest);
270}
271
272static void usage(void) {
273 printf("Usage: fcopy src dest\n");
274 printf("Copy src file in dest directory. If src is a directory, copy all the files in\n");
275 printf("src recoursively. If the destination directory does not exist, it will be created.\n");
276}
277
278int main(int argc, char **argv) {
279#if 0
280{
281//system("cat /proc/self/status");
282int i;
283for (i = 0; i < argc; i++)
284 printf("*%s* ", argv[i]);
285printf("\n");
286}
287#endif
288 if (argc != 3) {
289 fprintf(stderr, "Error fcopy: files missing\n");
290 usage();
291 exit(1);
292 }
293
294 // check the two files; remove ending /
295 char *src = argv[1];
296 int len = strlen(src);
297 if (src[len - 1] == '/')
298 src[len - 1] = '\0';
299 if (strcspn(src, "\\*&!?\"'<>%^(){}[];,") != (size_t)len) {
300 fprintf(stderr, "Error fcopy: invalid file name %s\n", src);
301 exit(1);
302 }
303
304 char *dest = argv[2];
305 len = strlen(dest);
306 if (dest[len - 1] == '/')
307 dest[len - 1] = '\0';
308 if (strcspn(dest, "\\*&!?\"'<>%^(){}[];,~") != (size_t)len) {
309 fprintf(stderr, "Error fcopy: invalid file name %s\n", dest);
310 exit(1);
311 }
312
313
314 // the destination should be a directory;
315 struct stat s;
316 if (stat(dest, &s) == -1 ||
317 !S_ISDIR(s.st_mode)) {
318 fprintf(stderr, "Error fcopy: invalid destination directory\n");
319 exit(1);
320 }
321
322 // copy files
323 if (lstat(src, &s) == -1) {
324 fprintf(stderr, "Error fcopy: cannot find source file\n");
325 exit(1);
326 }
327
328 if (S_ISDIR(s.st_mode))
329 duplicate_dir(src, dest, &s);
330 else if (S_ISREG(s.st_mode))
331 duplicate_file(src, dest, &s);
332 else if (S_ISLNK(s.st_mode))
333 duplicate_link(src, dest, &s);
334 else {
335 fprintf(stderr, "Error fcopy: source file unsupported\n");
336 exit(1);
337 }
338
339 return 0;
340}
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..c4f52e256 100644
--- a/src/firecfg/firecfg.config
+++ b/src/firecfg/firecfg.config
@@ -2,44 +2,159 @@
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
17transmission-cli
18transmission-show
19uget-gtk
20
5# browsers/email 21# browsers/email
6firefox 22abrowser
7iceweasel 23brave
8chromium-browser
9chromium 24chromium
25chromium-browser
26claws-mail
10conkeror 27conkeror
11thunderbird 28cyberfox
12epiphany 29firefox
30firefox-esr
13flashpeak-slimjet 31flashpeak-slimjet
32epiphany
33dillo
34google-chrome
14google-chrome-beta 35google-chrome-beta
15google-chrome-stable 36google-chrome-stable
16google-chrome-unstable 37google-chrome-unstable
17google-chrome 38iceweasel
18icecat 39icecat
19icedove 40icedove
20kmail 41kmail
21midori 42midori
43mutt
44netsurf
22opera-beta 45opera-beta
23opera 46opera
47palemoon
24qutebrowser 48qutebrowser
49start-tor-browser
25seamonkey 50seamonkey
26seamonkey-bin 51seamonkey-bin
52thunderbird
27vivaldi-beta 53vivaldi-beta
28vivaldi 54vivaldi
29dillo 55evolution
56elinks
57lynx
58w3m
30 59
31# bittorrent/ftp 60# chat/messaging
32deluge 61bitlbee
33filezilla 62corebird
34qbittorrent 63# Cryptocat is added but commented since isn't installed to a */bin... keep an eye on this
35rtorrent 64empathy
36transmission-gtk 65gitter
37transmission-qt 66hexchat
67jitsi
68konversation
69pidgin
70polari
71psi-plus
72qtox
73quassel
74skype
75telegram
76weechat
77weechat-curses
78wire
79xchat
80
81# dns
82dnscrypt-proxy
83dnsmaq
84unbound
85
86# emulators/compatibility layers
87mupen64plus
88wine
89dosbox
90virtualbox
91qemu-launcher
92qemu-system-x86_64
93
94# games
950ad
96gnome-chess
97hedgewars
98steam
99wesnot
100warzone2100
101
102# Media
103amarok
104audacious
105audacity
106bleachbit
107brasero
108clementine
109cmus
110deadbeef
111display
112dolphin
113dragon
114exiftool
115feh
116gjs
117gnome-books
118gnome-clocks
119gnome-documents
120gnome-maps
121gnome-mplayer
122gnome-music
123goobox
124google-play-music-desktop-player
125img2txt
126k3b
127mediainfo
128mpv
129nautilus
130parole
131rhythmbox
132simple-scan
133skanlite
134spotify
135totem
136vlc
137xfburn
138xplayer
139xviewer
140eom
141
142# news readers
143quiterss
38 144
39# office 145# office
146atril
40cherrytree 147cherrytree
41evince 148evince
42fbreader 149fbreader
150gedit
151gimp
152gthumb
153gwenview
154highlight
155inkscape
156kate
157libreoffice
43localc 158localc
44lodraw 159lodraw
45loffice 160loffice
@@ -48,29 +163,45 @@ loimpress
48lomath 163lomath
49loweb 164loweb
50lowriter 165lowriter
166luminance-hdr
167mupdf
168qpdfview
169soffice
170synfigstudio
51Mathematica 171Mathematica
52mathematica 172mathematica
173odt2txt
174okular
175pdftotext
176pix
177xpdf
178xreader
179zathura
180openshot
181flowblade
182eog
53 183
54# Media 184# other
55vlc 185atom
56audacious 186atom-beta
57clementine 187gpa
58deadbeef 188gpg
59parole 189ranger
60rhythmbox 190keepass
61totem 191keepass2
62cmus 192keepassx
193pluma
194tracker
195wireshark
196xiphos
197xed
63 198
64# chat/messaging 199# weather/climate
65bitlbee 200aweather
66empathy 201gnome-weather
67gnome-mplayer 202
68hexchat 203# compressing tools
69pidgin 204ark
70qtox 205atool
71quassel 206file-roller
72xchat
73 207
74# games
75hedgewars
76wesnot
diff --git a/src/firecfg/main.c b/src/firecfg/main.c
index 70d29a3ed..15ee78384 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,165 @@ 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 /* coverity[toctou] */
346 int fd = open(filename, O_RDONLY);
347 if (fd == -1)
348 errExit("open");
349
350 char *buf = mmap(NULL, sb.st_size + 1, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
351 if (buf == MAP_FAILED)
352 errExit("mmap");
353
354 close(fd);
355
356 // check format
357 if (strstr(buf, "[Desktop Entry]\n") == NULL) {
358 if (arg_debug)
359 fprintf(stderr, "/usr/share/applications/%s - SKIPPED: wrong format?\n", filename);
360 munmap(buf, sb.st_size + 1);
361 continue;
362 }
363
364 // get executable name
365 char *ptr1 = strstr(buf,"\nExec=");
366 if (!ptr1 || strlen(ptr1) < 7) {
367 if (arg_debug)
368 fprintf(stderr, "/usr/share/applications/%s - SKIPPED: wrong format?\n", filename);
369 munmap(buf, sb.st_size + 1);
370 continue;
371 }
372
373 char *execname = ptr1 + 6;
374 // https://specifications.freedesktop.org/desktop-entry-spec/latest/ar01s06.html
375 // The executable program can either be specified with its full path
376 // or with the name of the executable only
377 if (execname[0] != '/') {
378 if (arg_debug)
379 fprintf(stderr, "/usr/share/applications/%s - already OK\n", filename);
380 continue;
381 }
382 // executable name can be quoted, this is rare and currently unsupported, TODO
383 if (execname[0] == '"') {
384 if (arg_debug)
385 fprintf(stderr, "/usr/share/applications/%s - skipped: path quoting unsupported\n", filename);
386 continue;
387 }
388
389 // put '\0' at end of filename
390 char *tail = NULL;
391 char endchar = ' ';
392 if (execname[0] == '/') {
393 char *ptr2 = index(execname, ' ');
394 char *ptr3 = index(execname, '\n');
395 if (ptr2 && (!ptr3 || (ptr2 < ptr3))) {
396 endchar = ptr2[0];
397 ptr2[0] = '\0';
398 tail = ptr2 + 1;
399 } else if (ptr3 && (!ptr2 || (ptr3 < ptr2))) {
400 endchar = ptr3[0];
401 ptr3[0] = '\0';
402 tail = ptr3 + 1;
403 }
404 ptr1[5] = '\0';
405 }
406
407 char *bname = basename(execname);
408 assert(bname);
409
410 // check if basename in PATH
411 if (!which(bname)) {
412 fprintf(stderr, "/usr/share/applications/%s - skipped, %s not in PATH\n", filename, bname);
413 continue;
414 }
415
416 char *outname;
417 if (asprintf(&outname ,"%s/%s", user_apps_dir, filename) == -1)
418 errExit("asprintf");
419
420 int fd1 = open(outname, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
421 free(outname);
422
423 if (fd1 == -1) {
424 fprintf(stderr, "%s/%s skipped: %s\n", user_apps_dir, filename, strerror(errno));
425 munmap(buf, sb.st_size + 1);
426 continue;
427 }
428
429 FILE *outfile = fdopen(fd1, "w");
430 if (!outfile) {
431 fprintf(stderr, "%s/%s skipped: %s\n", user_apps_dir, filename, strerror(errno));
432 munmap(buf, sb.st_size + 1);
433 close(fd1);
434 continue;
435 }
436
437 if (fprintf(outfile,\
438 "# Converted by firecfg --fix from /usr/share/applications/%s\n\n%s=%s%c%s",\
439 filename, buf, bname, endchar, tail) < 0) {
440 fprintf(stderr, "Unable to write %s/%s: %s\n", user_apps_dir, filename, strerror(errno));
441 munmap(buf, sb.st_size + 1);
442 fclose(outfile);
443 continue;
444 }
445
446 fclose(outfile);
447 munmap(buf, sb.st_size + 1);
448
449 printf("%s/%s created\n", user_apps_dir, filename);
450 }
451
452 closedir(dir);
453 free(user_apps_dir);
454}
455
281int main(int argc, char **argv) { 456int main(int argc, char **argv) {
282 int i; 457 int i;
283 458
@@ -288,6 +463,8 @@ int main(int argc, char **argv) {
288 usage(); 463 usage();
289 return 0; 464 return 0;
290 } 465 }
466 else if (strcmp(argv[i], "--debug") == 0)
467 arg_debug = 1;
291 else if (strcmp(argv[i], "--version") == 0) { 468 else if (strcmp(argv[i], "--version") == 0) {
292 printf("firecfg version %s\n\n", VERSION); 469 printf("firecfg version %s\n\n", VERSION);
293 return 0; 470 return 0;
@@ -300,6 +477,10 @@ int main(int argc, char **argv) {
300 list(); 477 list();
301 return 0; 478 return 0;
302 } 479 }
480 else if (strcmp(argv[i], "--fix") == 0) {
481 fix_desktop_files();
482 return 0;
483 }
303 else { 484 else {
304 fprintf(stderr, "Error: invalid command line option\n"); 485 fprintf(stderr, "Error: invalid command line option\n");
305 usage(); 486 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..0d1f8cb4d
--- /dev/null
+++ b/src/firejail/appimage.c
@@ -0,0 +1,184 @@
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
34void appimage_set(const char *appimage) {
35 assert(appimage);
36 assert(devloop == NULL); // don't call this twice!
37 EUID_ASSERT();
38
39#ifdef LOOP_CTL_GET_FREE // test for older kernels; this definition is found in /usr/include/linux/loop.h
40 // check appimage file
41 invalid_filename(appimage);
42 if (access(appimage, R_OK) == -1) {
43 fprintf(stderr, "Error: cannot access AppImage file\n");
44 exit(1);
45 }
46
47 // get appimage type and ELF size
48 // a value of 0 means we are dealing with a type1 appimage
49 long unsigned int size = appimage2_size(appimage);
50 if (arg_debug)
51 printf("AppImage ELF size %lu\n", size);
52
53 // open appimage file
54 /* coverity[toctou] */
55 int ffd = open(appimage, O_RDONLY|O_CLOEXEC);
56 if (ffd == -1) {
57 fprintf(stderr, "Error: cannot open AppImage file\n");
58 exit(1);
59 }
60
61 // find or allocate a free loop device to use
62 EUID_ROOT();
63 int cfd = open("/dev/loop-control", O_RDWR);
64 if (cfd == -1) {
65 fprintf(stderr, "Error: /dev/loop-control interface is not supported by your kernel\n");
66 exit(1);
67 }
68 int devnr = ioctl(cfd, LOOP_CTL_GET_FREE);
69 if (devnr == -1) {
70 fprintf(stderr, "Error: cannot allocate a new loopback device\n");
71 exit(1);
72 }
73 close(cfd);
74 if (asprintf(&devloop, "/dev/loop%d", devnr) == -1)
75 errExit("asprintf");
76
77 int lfd = open(devloop, O_RDONLY);
78 if (lfd == -1) {
79 fprintf(stderr, "Error: cannot open %s\n", devloop);
80 exit(1);
81 }
82 if (ioctl(lfd, LOOP_SET_FD, ffd) == -1) {
83 fprintf(stderr, "Error: cannot configure the loopback device\n");
84 exit(1);
85 }
86
87 if (size) {
88 struct loop_info64 info;
89 memset(&info, 0, sizeof(struct loop_info64));
90 info.lo_offset = size;
91 if (ioctl(lfd, LOOP_SET_STATUS64, &info) == -1)
92 errExit("configure appimage offset");
93 }
94
95 close(lfd);
96 close(ffd);
97 EUID_USER();
98
99 // creates appimage mount point perms 0700
100 if (asprintf(&mntdir, "%s/.appimage-%u", RUN_FIREJAIL_APPIMAGE_DIR, getpid()) == -1)
101 errExit("asprintf");
102 EUID_ROOT();
103 mkdir_attr(mntdir, 0700, getuid(), getgid());
104 EUID_USER();
105
106 // mount
107 char *mode;
108 if (asprintf(&mode, "mode=700,uid=%d,gid=%d", getuid(), getgid()) == -1)
109 errExit("asprintf");
110 EUID_ROOT();
111
112 if (size == 0) {
113 if (mount(devloop, mntdir, "iso9660",MS_MGC_VAL|MS_RDONLY, mode) < 0)
114 errExit("mounting appimage");
115 }
116 else {
117 if (mount(devloop, mntdir, "squashfs",MS_MGC_VAL|MS_RDONLY, mode) < 0)
118 errExit("mounting appimage");
119 }
120
121 if (arg_debug)
122 printf("appimage mounted on %s\n", mntdir);
123 EUID_USER();
124
125 // set environment
126 if (setenv("APPIMAGE", appimage, 1) < 0)
127 errExit("setenv");
128 if (mntdir && setenv("APPDIR", mntdir, 1) < 0)
129 errExit("setenv");
130
131 // build new command line
132 if (asprintf(&cfg.command_line, "%s/AppRun", mntdir) == -1)
133 errExit("asprintf");
134
135 free(mode);
136#ifdef HAVE_GCOV
137 __gcov_flush();
138#endif
139#else
140 fprintf(stderr, "Error: /dev/loop-control interface is not supported by your kernel\n");
141 exit(1);
142#endif
143}
144
145void appimage_clear(void) {
146 int rv;
147
148 EUID_ROOT();
149 if (mntdir) {
150 int i;
151 int rv = 0;
152 for (i = 0; i < 5; i++) {
153 rv = umount2(mntdir, MNT_FORCE);
154 if (rv == 0)
155 break;
156 if (rv == -1 && errno == EBUSY) {
157 if (!arg_quiet)
158 printf("Warning: EBUSY error trying to unmount %s\n", mntdir);
159 sleep(2);
160 continue;
161 }
162
163 // rv = -1
164 if (!arg_quiet) {
165 printf("Warning: error trying to unmount %s\n", mntdir);
166 perror("umount");
167 }
168 }
169
170 if (rv == 0) {
171 rmdir(mntdir);
172 free(mntdir);
173 }
174 }
175
176 if (devloop) {
177 int lfd = open(devloop, O_RDONLY);
178 if (lfd != -1) {
179 rv = ioctl(lfd, LOOP_CLR_FD, 0);
180 (void) rv;
181 close(lfd);
182 }
183 }
184}
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..6cfa36629 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;
@@ -192,12 +181,10 @@ static int caps_find_name(const char *name) {
192} 181}
193 182
194// return 1 if error, 0 if OK 183// return 1 if error, 0 if OK
195int caps_check_list(const char *clist, void (*callback)(int)) { 184void caps_check_list(const char *clist, void (*callback)(int)) {
196 // don't allow empty lists 185 // don't allow empty lists
197 if (clist == NULL || *clist == '\0') { 186 if (clist == NULL || *clist == '\0')
198 fprintf(stderr, "Error: empty capabilities lists are not allowed\n"); 187 goto errexit;
199 return -1;
200 }
201 188
202 // work on a copy of the string 189 // work on a copy of the string
203 char *str = strdup(clist); 190 char *str = strdup(clist);
@@ -212,11 +199,8 @@ int caps_check_list(const char *clist, void (*callback)(int)) {
212 else if (*ptr == ',') { 199 else if (*ptr == ',') {
213 *ptr = '\0'; 200 *ptr = '\0';
214 int nr = caps_find_name(start); 201 int nr = caps_find_name(start);
215 if (nr == -1) { 202 if (nr == -1)
216 fprintf(stderr, "Error: capability %s not found\n", start); 203 goto errexit;
217 free(str);
218 return -1;
219 }
220 else if (callback != NULL) 204 else if (callback != NULL)
221 callback(nr); 205 callback(nr);
222 206
@@ -226,17 +210,18 @@ int caps_check_list(const char *clist, void (*callback)(int)) {
226 } 210 }
227 if (*start != '\0') { 211 if (*start != '\0') {
228 int nr = caps_find_name(start); 212 int nr = caps_find_name(start);
229 if (nr == -1) { 213 if (nr == -1)
230 fprintf(stderr, "Error: capability %s not found\n", start); 214 goto errexit;
231 free(str);
232 return -1;
233 }
234 else if (callback != NULL) 215 else if (callback != NULL)
235 callback(nr); 216 callback(nr);
236 } 217 }
237 218
238 free(str); 219 free(str);
239 return 0; 220 return;
221
222errexit:
223 fprintf(stderr, "Error: capability \"%s\" not found\n", start);
224 exit(1);
240} 225}
241 226
242void caps_print(void) { 227void caps_print(void) {
@@ -267,49 +252,53 @@ void caps_print(void) {
267// enabled by default 252// enabled by default
268int caps_default_filter(void) { 253int caps_default_filter(void) {
269 // drop capabilities 254 // drop capabilities
270 if (prctl(PR_CAPBSET_DROP, CAP_SYS_MODULE, 0, 0, 0) && arg_debug) 255 if (prctl(PR_CAPBSET_DROP, CAP_SYS_MODULE, 0, 0, 0))
271 fprintf(stderr, "Warning: cannot drop CAP_SYS_MODULE"); 256 goto errexit;
272 else if (arg_debug) 257 else if (arg_debug)
273 printf("Drop CAP_SYS_MODULE\n"); 258 printf("Drop CAP_SYS_MODULE\n");
274 259
275 if (prctl(PR_CAPBSET_DROP, CAP_SYS_RAWIO, 0, 0, 0) && arg_debug) 260 if (prctl(PR_CAPBSET_DROP, CAP_SYS_RAWIO, 0, 0, 0))
276 fprintf(stderr, "Warning: cannot drop CAP_SYS_RAWIO"); 261 goto errexit;
277 else if (arg_debug) 262 else if (arg_debug)
278 printf("Drop CAP_SYS_RAWIO\n"); 263 printf("Drop CAP_SYS_RAWIO\n");
279 264
280 if (prctl(PR_CAPBSET_DROP, CAP_SYS_BOOT, 0, 0, 0) && arg_debug) 265 if (prctl(PR_CAPBSET_DROP, CAP_SYS_BOOT, 0, 0, 0))
281 fprintf(stderr, "Warning: cannot drop CAP_SYS_BOOT"); 266 goto errexit;
282 else if (arg_debug) 267 else if (arg_debug)
283 printf("Drop CAP_SYS_BOOT\n"); 268 printf("Drop CAP_SYS_BOOT\n");
284 269
285 if (prctl(PR_CAPBSET_DROP, CAP_SYS_NICE, 0, 0, 0) && arg_debug) 270 if (prctl(PR_CAPBSET_DROP, CAP_SYS_NICE, 0, 0, 0))
286 fprintf(stderr, "Warning: cannot drop CAP_SYS_NICE"); 271 goto errexit;
287 else if (arg_debug) 272 else if (arg_debug)
288 printf("Drop CAP_SYS_NICE\n"); 273 printf("Drop CAP_SYS_NICE\n");
289 274
290 if (prctl(PR_CAPBSET_DROP, CAP_SYS_TTY_CONFIG, 0, 0, 0) && arg_debug) 275 if (prctl(PR_CAPBSET_DROP, CAP_SYS_TTY_CONFIG, 0, 0, 0))
291 fprintf(stderr, "Warning: cannot drop CAP_SYS_TTY_CONFIG"); 276 goto errexit;
292 else if (arg_debug) 277 else if (arg_debug)
293 printf("Drop CAP_SYS_TTY_CONFIG\n"); 278 printf("Drop CAP_SYS_TTY_CONFIG\n");
294 279
295#ifdef CAP_SYSLOG 280#ifdef CAP_SYSLOG
296 if (prctl(PR_CAPBSET_DROP, CAP_SYSLOG, 0, 0, 0) && arg_debug) 281 if (prctl(PR_CAPBSET_DROP, CAP_SYSLOG, 0, 0, 0))
297 fprintf(stderr, "Warning: cannot drop CAP_SYSLOG"); 282 goto errexit;
298 else if (arg_debug) 283 else if (arg_debug)
299 printf("Drop CAP_SYSLOG\n"); 284 printf("Drop CAP_SYSLOG\n");
300#endif 285#endif
301 286
302 if (prctl(PR_CAPBSET_DROP, CAP_MKNOD, 0, 0, 0) && arg_debug) 287 if (prctl(PR_CAPBSET_DROP, CAP_MKNOD, 0, 0, 0))
303 fprintf(stderr, "Warning: cannot drop CAP_MKNOD"); 288 goto errexit;
304 else if (arg_debug) 289 else if (arg_debug)
305 printf("Drop CAP_MKNOD\n"); 290 printf("Drop CAP_MKNOD\n");
306 291
307 if (prctl(PR_CAPBSET_DROP, CAP_SYS_ADMIN, 0, 0, 0) && arg_debug) 292 if (prctl(PR_CAPBSET_DROP, CAP_SYS_ADMIN, 0, 0, 0))
308 fprintf(stderr, "Warning: cannot drop CAP_SYS_ADMIN"); 293 goto errexit;
309 else if (arg_debug) 294 else if (arg_debug)
310 printf("Drop CAP_SYS_ADMIN\n"); 295 printf("Drop CAP_SYS_ADMIN\n");
311 296
312 return 0; 297 return 0;
298
299errexit:
300 fprintf(stderr, "Error: cannot drop capabilities\n");
301 exit(1);
313} 302}
314 303
315void caps_drop_all(void) { 304void caps_drop_all(void) {
@@ -370,19 +359,14 @@ static uint64_t extract_caps(int pid) {
370 EUID_ASSERT(); 359 EUID_ASSERT();
371 360
372 char *file; 361 char *file;
373 if (asprintf(&file, "/proc/%d/status", pid) == -1) { 362 if (asprintf(&file, "/proc/%d/status", pid) == -1)
374 errExit("asprintf"); 363 errExit("asprintf");
375 exit(1);
376 }
377 364
378 EUID_ROOT(); // grsecurity 365 EUID_ROOT(); // grsecurity
379 FILE *fp = fopen(file, "r"); 366 FILE *fp = fopen(file, "r");
380 EUID_USER(); // grsecurity 367 EUID_USER(); // grsecurity
381 if (!fp) { 368 if (!fp)
382 printf("Error: cannot open %s\n", file); 369 goto errexit;
383 free(file);
384 exit(1);
385 }
386 370
387 char buf[MAXBUF]; 371 char buf[MAXBUF];
388 while (fgets(buf, MAXBUF, fp)) { 372 while (fgets(buf, MAXBUF, fp)) {
@@ -396,27 +380,13 @@ static uint64_t extract_caps(int pid) {
396 } 380 }
397 } 381 }
398 fclose(fp); 382 fclose(fp);
383
384errexit:
399 free(file); 385 free(file);
400 printf("Error: cannot read caps configuration\n"); 386 fprintf(stderr, "Error: cannot read caps configuration\n");
401 exit(1); 387 exit(1);
402} 388}
403 389
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) { 390void caps_print_filter(pid_t pid) {
421 EUID_ASSERT(); 391 EUID_ASSERT();
422 392
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..c3eedc510 100644
--- a/src/firejail/checkcfg.c
+++ b/src/firejail/checkcfg.c
@@ -19,17 +19,21 @@
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;
35 FILE *fp = NULL;
36 char *ptr;
33 37
34 if (!initialized) { 38 if (!initialized) {
35 // initialize defaults 39 // initialize defaults
@@ -37,16 +41,21 @@ int checkcfg(int val) {
37 for (i = 0; i < CFG_MAX; i++) 41 for (i = 0; i < CFG_MAX; i++)
38 cfg_val[i] = 1; // most of them are enabled by default 42 cfg_val[i] = 1; // most of them are enabled by default
39 cfg_val[CFG_RESTRICTED_NETWORK] = 0; // disabled by default 43 cfg_val[CFG_RESTRICTED_NETWORK] = 0; // disabled by default
44 cfg_val[CFG_FORCE_NONEWPRIVS] = 0; // disabled by default
45 cfg_val[CFG_PRIVATE_BIN_NO_LOCAL] = 0; // disabled by default
46 cfg_val[CFG_FIREJAIL_PROMPT] = 0; // disabled by default
40 47
41 // open configuration file 48 // open configuration file
42 char *fname; 49 const char *fname = SYSCONFDIR "/firejail.config";
43 if (asprintf(&fname, "%s/firejail.config", SYSCONFDIR) == -1) 50 fp = fopen(fname, "r");
44 errExit("asprintf");
45
46 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
52 // read configuration file 61 // read configuration file
@@ -57,7 +66,7 @@ int checkcfg(int val) {
57 continue; 66 continue;
58 67
59 // parse line 68 // parse line
60 char *ptr = line_remove_spaces(buf); 69 ptr = line_remove_spaces(buf);
61 if (!ptr) 70 if (!ptr)
62 continue; 71 continue;
63 72
@@ -106,6 +115,24 @@ int checkcfg(int val) {
106 else 115 else
107 goto errout; 116 goto errout;
108 } 117 }
118 // prompt
119 else if (strncmp(ptr, "firejail-prompt ", 16) == 0) {
120 if (strcmp(ptr + 16, "yes") == 0)
121 cfg_val[CFG_FIREJAIL_PROMPT] = 1;
122 else if (strcmp(ptr + 16, "no") == 0)
123 cfg_val[CFG_FIREJAIL_PROMPT] = 0;
124 else
125 goto errout;
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,30 @@ 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 if (netfilter_default)
189 goto errout;
190 netfilter_default = strdup(fname);
191 if (!netfilter_default)
192 errExit("strdup");
193 if (arg_debug)
194 printf("netfilter default file %s\n", fname);
195 }
136 196
137 // Xephyr screen size 197 // Xephyr screen size
138 else if (strncmp(ptr, "xephyr-screen ", 14) == 0) { 198 else if (strncmp(ptr, "xephyr-screen ", 14) == 0) {
@@ -145,21 +205,194 @@ int checkcfg(int val) {
145 if (asprintf(&xephyr_screen, "%dx%d", n1, n2) == -1) 205 if (asprintf(&xephyr_screen, "%dx%d", n1, n2) == -1)
146 errExit("asprintf"); 206 errExit("asprintf");
147 } 207 }
208
209 // xephyr window title
210 else if (strncmp(ptr, "xephyr-window-title ", 20) == 0) {
211 if (strcmp(ptr + 20, "yes") == 0)
212 cfg_val[CFG_XEPHYR_WINDOW_TITLE] = 1;
213 else if (strcmp(ptr + 20, "no") == 0)
214 cfg_val[CFG_XEPHYR_WINDOW_TITLE] = 0;
215 else
216 goto errout;
217 }
218
219 // Xephyr command extra parameters
220 else if (strncmp(ptr, "xephyr-extra-params ", 19) == 0) {
221 if (*xephyr_extra_params != '\0')
222 goto errout;
223 xephyr_extra_params = strdup(ptr + 19);
224 if (!xephyr_extra_params)
225 errExit("strdup");
226 }
227
228 // quiet by default
229 else if (strncmp(ptr, "quiet-by-default ", 17) == 0) {
230 if (strcmp(ptr + 17, "yes") == 0)
231 arg_quiet = 1;
232 }
233 // remount /proc and /sys
234 else if (strncmp(ptr, "remount-proc-sys ", 17) == 0) {
235 if (strcmp(ptr + 17, "yes") == 0)
236 cfg_val[CFG_REMOUNT_PROC_SYS] = 1;
237 else if (strcmp(ptr + 17, "no") == 0)
238 cfg_val[CFG_REMOUNT_PROC_SYS] = 0;
239 else
240 goto errout;
241 }
242 else if (strncmp(ptr, "overlayfs ", 10) == 0) {
243 if (strcmp(ptr + 10, "yes") == 0)
244 cfg_val[CFG_OVERLAYFS] = 1;
245 else if (strcmp(ptr + 10, "no") == 0)
246 cfg_val[CFG_OVERLAYFS] = 0;
247 else
248 goto errout;
249 }
250 else if (strncmp(ptr, "private-home ", 13) == 0) {
251 if (strcmp(ptr + 13, "yes") == 0)
252 cfg_val[CFG_PRIVATE_HOME] = 1;
253 else if (strcmp(ptr + 13, "no") == 0)
254 cfg_val[CFG_PRIVATE_HOME] = 0;
255 else
256 goto errout;
257 }
258 else if (strncmp(ptr, "chroot-desktop ", 15) == 0) {
259 if (strcmp(ptr + 15, "yes") == 0)
260 cfg_val[CFG_CHROOT_DESKTOP] = 1;
261 else if (strcmp(ptr + 15, "no") == 0)
262 cfg_val[CFG_CHROOT_DESKTOP] = 0;
263 else
264 goto errout;
265 }
266 else if (strncmp(ptr, "private-bin-no-local ", 21) == 0) {
267 if (strcmp(ptr + 21, "yes") == 0)
268 cfg_val[CFG_PRIVATE_BIN_NO_LOCAL] = 1;
269 else if (strcmp(ptr + 21, "no") == 0)
270 cfg_val[CFG_PRIVATE_BIN_NO_LOCAL] = 0;
271 else
272 goto errout;
273 }
148 else 274 else
149 goto errout; 275 goto errout;
150 276
151 free(ptr); 277 free(ptr);
152 } 278 }
153 279
154 fclose(fp); 280 fclose(fp);
155 free(fname);
156 initialized = 1; 281 initialized = 1;
157 } 282 }
158 283
159 return cfg_val[val]; 284 return cfg_val[val];
160 285
161errout: 286errout:
287 assert(ptr);
288 free(ptr);
289 assert(fp);
290 fclose(fp);
162 fprintf(stderr, "Error: invalid line %d in firejail configuration file\n", line ); 291 fprintf(stderr, "Error: invalid line %d in firejail configuration file\n", line );
163 exit(1); 292 exit(1);
164} 293}
165 294
295
296void print_compiletime_support(void) {
297 printf("Compile time support:\n");
298 printf("\t- AppArmor support is %s\n",
299#ifdef HAVE_APPARMOR
300 "enabled"
301#else
302 "disabled"
303#endif
304 );
305
306 printf("\t- AppImage support is %s\n",
307#ifdef LOOP_CTL_GET_FREE // test for older kernels; this definition is found in /usr/include/linux/loop.h
308 "enabled"
309#else
310 "disabled"
311#endif
312 );
313
314 printf("\t- bind support is %s\n",
315#ifdef HAVE_BIND
316 "enabled"
317#else
318 "disabled"
319#endif
320 );
321
322 printf("\t- chroot support is %s\n",
323#ifdef HAVE_CHROOT
324 "enabled"
325#else
326 "disabled"
327#endif
328 );
329
330 printf("\t- file and directory whitelisting support is %s\n",
331#ifdef HAVE_WHITELIST
332 "enabled"
333#else
334 "disabled"
335#endif
336 );
337
338 printf("\t- file transfer support is %s\n",
339#ifdef HAVE_FILE_TRANSFER
340 "enabled"
341#else
342 "disabled"
343#endif
344 );
345
346 printf("\t- networking support is %s\n",
347#ifdef HAVE_NETWORK
348 "enabled"
349#else
350 "disabled"
351#endif
352 );
353
354
355#ifdef HAVE_NETWORK_RESTRICTED
356 printf("\t- networking features are available only to root user\n");
357#endif
358
359 printf("\t- overlayfs support is %s\n",
360#ifdef HAVE_OVERLAYFS
361 "enabled"
362#else
363 "disabled"
364#endif
365 );
366
367 printf("\t- private-home support is %s\n",
368#ifdef HAVE_PRIVATE_HOME
369 "enabled"
370#else
371 "disabled"
372#endif
373 );
374
375 printf("\t- seccomp-bpf support is %s\n",
376#ifdef HAVE_SECCOMP
377 "enabled"
378#else
379 "disabled"
380#endif
381 );
382
383 printf("\t- user namespace support is %s\n",
384#ifdef HAVE_USERNS
385 "enabled"
386#else
387 "disabled"
388#endif
389 );
390
391 printf("\t- X11 sandboxing support is %s\n",
392#ifdef HAVE_X11
393 "enabled"
394#else
395 "disabled"
396#endif
397 );
398}
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..783f019a6 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,39 @@ 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");
115 // set prompt color to green
116 //export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] '
117 if (setenv("PROMPT_COMMAND", "export PS1=\"\\[\\e[1;32m\\][\\u@\\h \\W]\\$\\[\\e[0m\\] \"", 1) < 0)
118 errExit("setenv");
119 130
120 // build the window title and set it 131 // set prompt color to green
121 char *title; 132 int set_prompt = 0;
122 if (asprintf(&title, "\033]0;firejail %s\007\n", cfg.window_title) == -1) 133 if (checkcfg(CFG_FIREJAIL_PROMPT))
123 errExit("asprintf"); 134 set_prompt = 1;
124 printf("%s", title); 135 else { // check FIREJAIL_PROMPT="yes" environment variable
125 free(title); 136 char *prompt = getenv("FIREJAIL_PROMPT");
137 if (prompt && strcmp(prompt, "yes") == 0)
138 set_prompt = 1;
139 }
140
141 if (set_prompt) {
142 //export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] '
143 if (setenv("PROMPT_COMMAND", "export PS1=\"\\[\\e[1;32m\\][\\u@\\h \\W]\\$\\[\\e[0m\\] \"", 1) < 0)
144 errExit("setenv");
145 }
146
147 // set the window title
148 if (!arg_quiet)
149 printf("\033]0;firejail %s\007", cfg.window_title);
150 fflush(0);
126} 151}
127 152
128// parse and store the environment setting 153// parse and store the environment setting
129void env_store(const char *str) { 154void env_store(const char *str, ENV_OP op) {
130 EUID_ASSERT(); 155 EUID_ASSERT();
131 assert(str); 156 assert(str);
132 157
@@ -134,11 +159,13 @@ void env_store(const char *str) {
134 if (*str == '\0') 159 if (*str == '\0')
135 goto errexit; 160 goto errexit;
136 char *ptr = strchr(str, '='); 161 char *ptr = strchr(str, '=');
137 if (!ptr) 162 if (op == SETENV) {
138 goto errexit; 163 if (!ptr)
139 ptr++; 164 goto errexit;
140 if (*ptr == '\0') 165 ptr++;
141 goto errexit; 166 if (*ptr == '\0')
167 goto errexit;
168 }
142 169
143 // build list entry 170 // build list entry
144 Env *env = malloc(sizeof(Env)); 171 Env *env = malloc(sizeof(Env));
@@ -148,10 +175,13 @@ void env_store(const char *str) {
148 env->name = strdup(str); 175 env->name = strdup(str);
149 if (env->name == NULL) 176 if (env->name == NULL)
150 errExit("strdup"); 177 errExit("strdup");
151 char *ptr2 = strchr(env->name, '='); 178 if (op == SETENV) {
152 assert(ptr2); 179 char *ptr2 = strchr(env->name, '=');
153 *ptr2 = '\0'; 180 assert(ptr2);
154 env->value = ptr2 + 1; 181 *ptr2 = '\0';
182 env->value = ptr2 + 1;
183 }
184 env->op = op;
155 185
156 // add entry to the list 186 // add entry to the list
157 env_add(env); 187 env_add(env);
@@ -167,8 +197,13 @@ void env_apply(void) {
167 Env *env = envlist; 197 Env *env = envlist;
168 198
169 while (env) { 199 while (env) {
170 if (setenv(env->name, env->value, 1) < 0) 200 if (env->op == SETENV) {
171 errExit("setenv"); 201 if (setenv(env->name, env->value, 1) < 0)
202 errExit("setenv");
203 }
204 else if (env->op == RMENV) {
205 unsetenv(env->name);
206 }
172 env = env->next; 207 env = env->next;
173 } 208 }
174} 209}
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 24ea53476..8fede5a69 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,17 +37,28 @@
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"
41#define RUN_PROTOCOL_CFG "/run/firejail/mnt/protocol" 43#define RUN_PROTOCOL_CFG "/run/firejail/mnt/protocol"
42#define RUN_CP_COMMAND "/run/firejail/mnt/cp"
43#define RUN_HOME_DIR "/run/firejail/mnt/home" 44#define RUN_HOME_DIR "/run/firejail/mnt/home"
44#define RUN_ETC_DIR "/run/firejail/mnt/etc" 45#define RUN_ETC_DIR "/run/firejail/mnt/etc"
46#define RUN_OPT_DIR "/run/firejail/mnt/opt"
47#define RUN_SRV_DIR "/run/firejail/mnt/srv"
45#define RUN_BIN_DIR "/run/firejail/mnt/bin" 48#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" 49#define RUN_PULSE_DIR "/run/firejail/mnt/pulse"
50
51#define RUN_SECCOMP_PROTOCOL "/run/firejail/mnt/seccomp.protocol" // protocol filter
52#define RUN_SECCOMP_CFG "/run/firejail/mnt/seccomp" // configured filter
53#define RUN_SECCOMP_AMD64 "/run/firejail/mnt/seccomp.amd64" // amd64 filter installed on i386 architectures
54#define RUN_SECCOMP_I386 "/run/firejail/mnt/seccomp.i386" // i386 filter installed on amd64 architectures
55#define PATH_SECCOMP_DEFAULT (LIBDIR "/firejail/seccomp") // default filter built during make
56#define PATH_SECCOMP_DEFAULT_DEBUG (LIBDIR "/firejail/seccomp.debug") // default filter built during make
57#define PATH_SECCOMP_AMD64 (LIBDIR "/firejail/seccomp.amd64") // amd64 filter built during make
58#define PATH_SECCOMP_I386 (LIBDIR "/firejail/seccomp.i386") // i386 filter built during make
59
60
61#define RUN_DEV_DIR "/run/firejail/mnt/dev"
48#define RUN_DEVLOG_FILE "/run/firejail/mnt/devlog" 62#define RUN_DEVLOG_FILE "/run/firejail/mnt/devlog"
49 63
50#define RUN_WHITELIST_X11_DIR "/run/firejail/mnt/orig-x11" 64#define RUN_WHITELIST_X11_DIR "/run/firejail/mnt/orig-x11"
@@ -52,26 +66,78 @@
52#define RUN_WHITELIST_HOME_USER_DIR "/run/firejail/mnt/orig-home-user" // home directory whitelisting 66#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" 67#define RUN_WHITELIST_TMP_DIR "/run/firejail/mnt/orig-tmp"
54#define RUN_WHITELIST_MEDIA_DIR "/run/firejail/mnt/orig-media" 68#define RUN_WHITELIST_MEDIA_DIR "/run/firejail/mnt/orig-media"
69#define RUN_WHITELIST_MNT_DIR "/run/firejail/mnt/orig-mnt"
55#define RUN_WHITELIST_VAR_DIR "/run/firejail/mnt/orig-var" 70#define RUN_WHITELIST_VAR_DIR "/run/firejail/mnt/orig-var"
56#define RUN_WHITELIST_DEV_DIR "/run/firejail/mnt/orig-dev" 71#define RUN_WHITELIST_DEV_DIR "/run/firejail/mnt/orig-dev"
57#define RUN_WHITELIST_OPT_DIR "/run/firejail/mnt/orig-opt" 72#define RUN_WHITELIST_OPT_DIR "/run/firejail/mnt/orig-opt"
73#define RUN_WHITELIST_SRV_DIR "/run/firejail/mnt/orig-srv"
58 74
59#define RUN_XAUTHORITY_FILE "/run/firejail/mnt/.Xauthority" 75#define RUN_XAUTHORITY_FILE "/run/firejail/mnt/.Xauthority"
76#define RUN_XAUTHORITY_SEC_FILE "/run/firejail/mnt/sec.Xauthority"
60#define RUN_ASOUNDRC_FILE "/run/firejail/mnt/.asoundrc" 77#define RUN_ASOUNDRC_FILE "/run/firejail/mnt/.asoundrc"
61#define RUN_HOSTNAME_FILE "/run/firejail/mnt/hostname" 78#define RUN_HOSTNAME_FILE "/run/firejail/mnt/hostname"
62#define RUN_HOSTS_FILE "/run/firejail/mnt/hosts" 79#define RUN_HOSTS_FILE "/run/firejail/mnt/hosts"
63#define RUN_RESOLVCONF_FILE "/run/firejail/mnt/resolv.conf" 80#define RUN_RESOLVCONF_FILE "/run/firejail/mnt/resolv.conf"
81#define RUN_MACHINEID "/run/firejail/mnt/machine-id"
64#define RUN_LDPRELOAD_FILE "/run/firejail/mnt/ld.so.preload" 82#define RUN_LDPRELOAD_FILE "/run/firejail/mnt/ld.so.preload"
65#define RUN_UTMP_FILE "/run/firejail/mnt/utmp" 83#define RUN_UTMP_FILE "/run/firejail/mnt/utmp"
66#define RUN_PASSWD_FILE "/run/firejail/mnt/passwd" 84#define RUN_PASSWD_FILE "/run/firejail/mnt/passwd"
67#define RUN_GROUP_FILE "/run/firejail/mnt/group" 85#define RUN_GROUP_FILE "/run/firejail/mnt/group"
68#define RUN_FSLOGGER_FILE "/run/firejail/mnt/fslogger" 86#define RUN_FSLOGGER_FILE "/run/firejail/mnt/fslogger"
69 87
88
89
70// profiles 90// profiles
71#define DEFAULT_USER_PROFILE "generic" 91#define DEFAULT_USER_PROFILE "default"
72#define DEFAULT_ROOT_PROFILE "server" 92#define DEFAULT_ROOT_PROFILE "server"
73#define MAX_INCLUDE_LEVEL 6 // include levels in profile files 93#define MAX_INCLUDE_LEVEL 6 // include levels in profile files
74 94
95
96#define ASSERT_PERMS(file, uid, gid, mode) \
97 do { \
98 assert(file);\
99 struct stat s;\
100 if (stat(file, &s) == -1) errExit("stat");\
101 assert(s.st_uid == uid);\
102 assert(s.st_gid == gid);\
103 assert((s.st_mode & 07777) == (mode));\
104 } while (0)
105#define ASSERT_PERMS_FD(fd, uid, gid, mode) \
106 do { \
107 struct stat s;\
108 if (stat(fd, &s) == -1) errExit("stat");\
109 assert(s.st_uid == uid);\
110 assert(s.st_gid == gid);\
111 assert((s.st_mode & 07777) == (mode));\
112 } while (0)
113#define ASSERT_PERMS_STREAM(file, uid, gid, mode) \
114 do { \
115 int fd = fileno(file);\
116 if (fd == -1) errExit("fileno");\
117 ASSERT_PERMS_FD(fd, uid, gid, (mode));\
118 } while (0)
119
120#define SET_PERMS_FD(fd, uid, gid, mode) \
121 do { \
122 if (fchmod(fd, (mode)) == -1) errExit("chmod");\
123 if (fchown(fd, uid, gid) == -1) errExit("chown");\
124 } while (0)
125#define SET_PERMS_STREAM(stream, uid, gid, mode) \
126 do { \
127 int fd = fileno(stream);\
128 if (fd == -1) errExit("fileno");\
129 SET_PERMS_FD(fd, uid, gid, (mode));\
130 } while (0)
131#define SET_PERMS_STREAM_NOERR(stream, uid, gid, mode) \
132 do { \
133 int fd = fileno(stream);\
134 if (fd == -1) continue;\
135 int rv = fchmod(fd, (mode));\
136 (void) rv;\
137 rv = fchown(fd, uid, gid);\
138 (void) rv;\
139 } while (0)
140
75// main.c 141// main.c
76typedef struct bridge_t { 142typedef struct bridge_t {
77 // on the host 143 // on the host
@@ -81,6 +147,8 @@ typedef struct bridge_t {
81 uint8_t mac[6]; // interface mac address 147 uint8_t mac[6]; // interface mac address
82 int mtu; // interface mtu 148 int mtu; // interface mtu
83 149
150 char *veth_name; // veth name for the device connected to the bridge
151
84 // inside the sandbox 152 // inside the sandbox
85 char *devsandbox; // name of the device inside the sandbox 153 char *devsandbox; // name of the device inside the sandbox
86 uint32_t ipsandbox; // ip address inside the sandbox 154 uint32_t ipsandbox; // ip address inside the sandbox
@@ -115,9 +183,11 @@ typedef struct profile_entry_t {
115 unsigned home_dir:1; // whitelist in /home/user directory 183 unsigned home_dir:1; // whitelist in /home/user directory
116 unsigned tmp_dir:1; // whitelist in /tmp directory 184 unsigned tmp_dir:1; // whitelist in /tmp directory
117 unsigned media_dir:1; // whitelist in /media directory 185 unsigned media_dir:1; // whitelist in /media directory
186 unsigned mnt_dir:1; // whitelist in /mnt directory
118 unsigned var_dir:1; // whitelist in /var directory 187 unsigned var_dir:1; // whitelist in /var directory
119 unsigned dev_dir:1; // whitelist in /dev directory 188 unsigned dev_dir:1; // whitelist in /dev directory
120 unsigned opt_dir:1; // whitelist in /opt directory 189 unsigned opt_dir:1; // whitelist in /opt directory
190 unsigned srv_dir:1; // whitelist in /srv directory
121}ProfileEntry; 191}ProfileEntry;
122 192
123typedef struct config_t { 193typedef struct config_t {
@@ -131,10 +201,14 @@ typedef struct config_t {
131 char *profile_ignore[MAX_PROFILE_IGNORE]; 201 char *profile_ignore[MAX_PROFILE_IGNORE];
132 char *chrootdir; // chroot directory 202 char *chrootdir; // chroot directory
133 char *home_private; // private home directory 203 char *home_private; // private home directory
204 char *home_private_keep; // keep list for private home directory
134 char *etc_private_keep; // keep list for private etc directory 205 char *etc_private_keep; // keep list for private etc directory
206 char *opt_private_keep; // keep list for private opt directory
207 char *srv_private_keep; // keep list for private srv directory
135 char *bin_private_keep; // keep list for private bin directory 208 char *bin_private_keep; // keep list for private bin directory
136 char *cwd; // current working directory 209 char *cwd; // current working directory
137 char *overlay_dir; 210 char *overlay_dir;
211 char *private_template; // template dir for tmpfs home
138 212
139 // networking 213 // networking
140 char *name; // sandbox name 214 char *name; // sandbox name
@@ -156,7 +230,6 @@ typedef struct config_t {
156 char *seccomp_list;// optional seccomp list on top of default filter 230 char *seccomp_list;// optional seccomp list on top of default filter
157 char *seccomp_list_drop; // seccomp drop list 231 char *seccomp_list_drop; // seccomp drop list
158 char *seccomp_list_keep; // seccomp keep list 232 char *seccomp_list_keep; // seccomp keep list
159 char **seccomp_list_errno; // seccomp errno[nr] lists
160 char *protocol; // protocol list 233 char *protocol; // protocol list
161 234
162 // rlimits 235 // rlimits
@@ -211,6 +284,7 @@ static inline int any_interface_configured(void) {
211void clear_run_files(pid_t pid); 284void clear_run_files(pid_t pid);
212 285
213extern int arg_private; // mount private /home 286extern int arg_private; // mount private /home
287extern int arg_private_template; // private /home template
214extern int arg_debug; // print debug messages 288extern int arg_debug; // print debug messages
215extern int arg_debug_check_filename; // print debug messages for filename checking 289extern int arg_debug_check_filename; // print debug messages for filename checking
216extern int arg_debug_blacklists; // print debug messages for blacklists 290extern int arg_debug_blacklists; // print debug messages for blacklists
@@ -218,9 +292,8 @@ extern int arg_debug_whitelists; // print debug messages for whitelists
218extern int arg_nonetwork; // --net=none 292extern int arg_nonetwork; // --net=none
219extern int arg_command; // -c 293extern int arg_command; // -c
220extern int arg_overlay; // overlay option 294extern int arg_overlay; // overlay option
221extern int arg_overlay_keep; // place overlay diff directory in ~/.firejail 295extern int arg_overlay_keep; // place overlay diff in a known directory
222extern int arg_zsh; // use zsh as default shell 296extern int arg_overlay_reuse; // allow the reuse of overlays
223extern int arg_csh; // use csh as default shell
224 297
225extern int arg_seccomp; // enable default seccomp filter 298extern int arg_seccomp; // enable default seccomp filter
226 299
@@ -237,6 +310,7 @@ extern int arg_rlimit_nproc; // rlimit nproc
237extern int arg_rlimit_fsize; // rlimit fsize 310extern int arg_rlimit_fsize; // rlimit fsize
238extern int arg_rlimit_sigpending;// rlimit sigpending 311extern int arg_rlimit_sigpending;// rlimit sigpending
239extern int arg_nogroups; // disable supplementary groups 312extern int arg_nogroups; // disable supplementary groups
313extern int arg_nonewprivs; // set the NO_NEW_PRIVS prctl
240extern int arg_noroot; // create a new user namespace and disable root user 314extern int arg_noroot; // create a new user namespace and disable root user
241extern int arg_netfilter; // enable netfilter 315extern int arg_netfilter; // enable netfilter
242extern int arg_netfilter6; // enable netfilter6 316extern int arg_netfilter6; // enable netfilter6
@@ -246,17 +320,32 @@ extern int arg_doubledash; // double dash
246extern int arg_shell_none; // run the program directly without a shell 320extern int arg_shell_none; // run the program directly without a shell
247extern int arg_private_dev; // private dev directory 321extern int arg_private_dev; // private dev directory
248extern int arg_private_etc; // private etc directory 322extern int arg_private_etc; // private etc directory
323extern int arg_private_opt; // private opt directory
324extern int arg_private_srv; // private srv directory
249extern int arg_private_bin; // private bin directory 325extern int arg_private_bin; // private bin directory
250extern int arg_private_tmp; // private tmp directory 326extern int arg_private_tmp; // private tmp directory
251extern int arg_scan; // arp-scan all interfaces 327extern int arg_scan; // arp-scan all interfaces
252extern int arg_whitelist; // whitelist commad 328extern int arg_whitelist; // whitelist commad
253extern int arg_nosound; // disable sound 329extern int arg_nosound; // disable sound
330extern int arg_no3d; // disable 3d hardware acceleration
254extern int arg_quiet; // no output for scripting 331extern int arg_quiet; // no output for scripting
255extern int arg_join_network; // join only the network namespace 332extern int arg_join_network; // join only the network namespace
256extern int arg_join_filesystem; // join only the mount namespace 333extern int arg_join_filesystem; // join only the mount namespace
257extern int arg_nice; // nice value configured 334extern int arg_nice; // nice value configured
258extern int arg_ipc; // enable ipc namespace 335extern int arg_ipc; // enable ipc namespace
259 336extern int arg_writable_etc; // writable etc
337extern int arg_writable_var; // writable var
338extern int arg_appimage; // appimage
339extern int arg_audit; // audit
340extern char *arg_audit_prog; // audit
341extern int arg_apparmor; // apparmor
342extern int arg_allow_debuggers; // allow debuggers
343extern int arg_x11_block; // block X11
344extern int arg_x11_xorg; // use X11 security extention
345extern int arg_allusers; // all user home directories visible
346extern int arg_machineid; // preserve /etc/machine-id
347
348extern int login_shell;
260extern int parent_to_child_fds[2]; 349extern int parent_to_child_fds[2];
261extern int child_to_parent_fds[2]; 350extern int child_to_parent_fds[2];
262extern pid_t sandbox_pid; 351extern pid_t sandbox_pid;
@@ -267,16 +356,17 @@ extern int fullargc;
267 356
268// main.c 357// main.c
269void check_user_namespace(void); 358void check_user_namespace(void);
359char *guess_shell(void);
270 360
271// sandbox.c 361// sandbox.c
272int sandbox(void* sandbox_arg); 362int sandbox(void* sandbox_arg);
363void start_application(void);
273 364
274// network_main.c 365// network_main.c
275void net_configure_bridge(Bridge *br, char *dev_name); 366void net_configure_bridge(Bridge *br, char *dev_name);
276void net_configure_sandbox_ip(Bridge *br); 367void net_configure_sandbox_ip(Bridge *br);
277void net_configure_veth_pair(Bridge *br, const char *ifname, pid_t child); 368void net_configure_veth_pair(Bridge *br, const char *ifname, pid_t child);
278void net_check_cfg(void); 369void net_check_cfg(void);
279void net_dns_print_name(const char *name);
280void net_dns_print(pid_t pid); 370void net_dns_print(pid_t pid);
281void network_main(pid_t child); 371void network_main(pid_t child);
282 372
@@ -287,35 +377,32 @@ 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); 377void 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); 378int 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); 379int 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); 380uint32_t network_get_defaultgw(void);
293int net_config_mac(const char *ifname, const unsigned char mac[6]); 381int net_config_mac(const char *ifname, const unsigned char mac[6]);
294int net_get_mac(const char *ifname, unsigned char mac[6]); 382int net_get_mac(const char *ifname, unsigned char mac[6]);
383void net_config_interface(const char *dev, uint32_t ip, uint32_t mask, int mtu);
384
385// preproc.c
386void preproc_build_firejail_dir(void);
387void preproc_mount_mnt_dir(void);
295 388
296// fs.c 389// 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 390// blacklist files or directoies by mounting empty files on top of them
306void fs_blacklist(void); 391void fs_blacklist(void);
307// remount a directory read-only 392// remount a directory read-only
308void fs_rdonly(const char *dir); 393void fs_rdonly(const char *dir);
394// remount a directory noexec, nodev and nosuid
395void fs_noexec(const char *dir);
309// mount /proc and /sys directories 396// mount /proc and /sys directories
310void fs_proc_sys_dev_boot(void); 397void fs_proc_sys_dev_boot(void);
311// build a basic read-only filesystem 398// build a basic read-only filesystem
312void fs_basic_fs(void); 399void fs_basic_fs(void);
313// mount overlayfs on top of / directory 400// mount overlayfs on top of / directory
401char *fs_check_overlay_dir(const char *subdirname, int allow_reuse);
314void fs_overlayfs(void); 402void fs_overlayfs(void);
315// chroot into an existing directory; mount exiting /dev and update /etc/resolv.conf 403// chroot into an existing directory; mount exiting /dev and update /etc/resolv.conf
316void fs_chroot(const char *rootdir); 404void fs_chroot(const char *rootdir);
317int fs_check_chroot_dir(const char *rootdir); 405int fs_check_chroot_dir(const char *rootdir);
318void fs_private_tmp(void);
319 406
320// profile.c 407// profile.c
321// find and read the profile specified by name from dir directory 408// find and read the profile specified by name from dir directory
@@ -340,12 +427,11 @@ void usage(void);
340 427
341// join.c 428// join.c
342void join(pid_t pid, int argc, char **argv, int index); 429void join(pid_t pid, int argc, char **argv, int index);
343void join_name(const char *name, int argc, char **argv, int index); 430
431// shutdown.c
344void shut(pid_t pid); 432void shut(pid_t pid);
345void shut_name(const char *name);
346 433
347// restricted_shell.c 434// restricted_shell.c
348extern char *restricted_user;
349int restricted_shell(const char *user); 435int restricted_shell(const char *user);
350 436
351// arp.c 437// arp.c
@@ -353,13 +439,6 @@ int restricted_shell(const char *user);
353int arp_check(const char *dev, uint32_t destaddr, uint32_t srcaddr); 439int arp_check(const char *dev, uint32_t destaddr, uint32_t srcaddr);
354// assign an IP address using arp scanning 440// assign an IP address using arp scanning
355uint32_t arp_assign(const char *dev, Bridge *br); 441uint32_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 442
364// util.c 443// util.c
365void drop_privs(int nogroups); 444void drop_privs(int nogroups);
@@ -369,7 +448,7 @@ void logsignal(int s);
369void logmsg(const char *msg); 448void logmsg(const char *msg);
370void logargs(int argc, char **argv) ; 449void logargs(int argc, char **argv) ;
371void logerr(const char *msg); 450void logerr(const char *msg);
372int copy_file(const char *srcname, const char *destname); 451int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode);
373int is_dir(const char *fname); 452int is_dir(const char *fname);
374int is_link(const char *fname); 453int is_link(const char *fname);
375char *line_remove_spaces(const char *buf); 454char *line_remove_spaces(const char *buf);
@@ -384,8 +463,14 @@ char *expand_home(const char *path, const char* homedir);
384const char *gnu_basename(const char *path); 463const char *gnu_basename(const char *path);
385uid_t pid_get_uid(pid_t pid); 464uid_t pid_get_uid(pid_t pid);
386void invalid_filename(const char *fname); 465void invalid_filename(const char *fname);
387uid_t get_tty_gid(void); 466uid_t get_group_id(const char *group);
388uid_t get_audio_gid(void); 467int remove_directory(const char *path);
468void flush_stdin(void);
469void create_empty_dir_as_root(const char *dir, mode_t mode);
470void create_empty_file_as_root(const char *dir, mode_t mode);
471int set_perms(const char *fname, uid_t uid, gid_t gid, mode_t mode);
472void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid);
473char *read_text_file_or_exit(const char *fname);
389 474
390// fs_var.c 475// fs_var.c
391void fs_var_log(void); // mounting /var/log 476void fs_var_log(void); // mounting /var/log
@@ -400,41 +485,46 @@ void dbg_test_dir(const char *dir);
400// fs_dev.c 485// fs_dev.c
401void fs_dev_shm(void); 486void fs_dev_shm(void);
402void fs_private_dev(void); 487void fs_private_dev(void);
488void fs_dev_disable_sound(void);
489void fs_dev_disable_3d(void);
403 490
404// fs_home.c 491// fs_home.c
405// private mode (--private) 492// private mode (--private)
406void fs_private(void); 493void fs_private(void);
407// private mode (--private=homedir) 494// private mode (--private=homedir)
408void fs_private_homedir(void); 495void fs_private_homedir(void);
496// private template (--private-template=templatedir)
497void fs_private_template(void);
409// check new private home directory (--private= option) - exit if it fails 498// check new private home directory (--private= option) - exit if it fails
410void fs_check_private_dir(void); 499void fs_check_private_dir(void);
500// check new private template home directory (--private-template= option) exit if it fails
501void fs_check_private_template(void);
502void fs_private_home_list(void);
411 503
412 504
413// seccomp.c 505// seccomp.c
506char *seccomp_check_list(const char *str);
507int seccomp_load(const char *fname);
508void seccomp_filter_32(void);
509void seccomp_filter_64(void);
414int seccomp_filter_drop(int enforce_seccomp); 510int seccomp_filter_drop(int enforce_seccomp);
415int seccomp_filter_keep(void); 511int seccomp_filter_keep(void);
416void seccomp_set(void);
417void seccomp_print_filter_name(const char *name);
418void seccomp_print_filter(pid_t pid); 512void seccomp_print_filter(pid_t pid);
419int seccomp_filter_errno(void);
420 513
421// caps.c 514// caps.c
422int caps_default_filter(void); 515int caps_default_filter(void);
423void caps_print(void); 516void caps_print(void);
424void caps_drop_all(void); 517void caps_drop_all(void);
425void caps_set(uint64_t caps); 518void caps_set(uint64_t caps);
426int caps_check_list(const char *clist, void (*callback)(int)); 519void caps_check_list(const char *clist, void (*callback)(int));
427void caps_drop_list(const char *clist); 520void caps_drop_list(const char *clist);
428void caps_keep_list(const char *clist); 521void caps_keep_list(const char *clist);
429void caps_print_filter(pid_t pid); 522void caps_print_filter(pid_t pid);
430void caps_print_filter_name(const char *name);
431 523
432// syscall.c 524// syscall.c
433const char *syscall_find_nr(int nr); 525const char *syscall_find_nr(int nr);
434// return -1 if error, 0 if no error 526// return -1 if error, 0 if no error
435int syscall_check_list(const char *slist, void (*callback)(int syscall, int arg), int arg); 527int syscall_check_list(const char *slist, void (*callback)(int syscall, int arg), int arg);
436// print all available syscallsseccomp
437void syscall_print(void);
438 528
439// fs_trace.c 529// fs_trace.c
440void fs_trace_preload(void); 530void fs_trace_preload(void);
@@ -452,7 +542,6 @@ void read_cpu_list(const char *str);
452void set_cpu_affinity(void); 542void set_cpu_affinity(void);
453void load_cpu(const char *fname); 543void load_cpu(const char *fname);
454void save_cpu(void); 544void save_cpu(void);
455void cpu_print_filter_name(const char *name);
456void cpu_print_filter(pid_t pid); 545void cpu_print_filter(pid_t pid);
457 546
458// cgroup.c 547// cgroup.c
@@ -470,21 +559,25 @@ void netfilter6(const char *fname);
470 559
471// bandwidth.c 560// bandwidth.c
472void bandwidth_del_run_file(pid_t pid); 561void 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); 562void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, int up);
475void network_del_run_file(pid_t pid); 563void network_del_run_file(pid_t pid);
476void network_set_run_file(pid_t pid); 564void network_set_run_file(pid_t pid);
477 565
478// fs_etc.c 566// fs_etc.c
479void fs_check_etc_list(void); 567void fs_private_dir_list(const char *private_dir, const char *private_run_dir, const char *private_list);
480void fs_private_etc_list(void);
481 568
482// no_sandbox.c 569// no_sandbox.c
570int check_namespace_virt(void);
483int check_kernel_procs(void); 571int check_kernel_procs(void);
484void run_no_sandbox(int argc, char **argv); 572void run_no_sandbox(int argc, char **argv);
485 573
486// env.c 574// env.c
487void env_store(const char *str); 575typedef enum {
576 SETENV = 0,
577 RMENV
578} ENV_OP;
579
580void env_store(const char *str, ENV_OP op);
488void env_apply(void); 581void env_apply(void);
489void env_defaults(void); 582void env_defaults(void);
490void env_ibus_load(void); 583void env_ibus_load(void);
@@ -503,17 +596,12 @@ void pulseaudio_init(void);
503void pulseaudio_disable(void); 596void pulseaudio_disable(void);
504 597
505// fs_bin.c 598// fs_bin.c
506void fs_check_bin_list(void);
507void fs_private_bin_list(void); 599void fs_private_bin_list(void);
508 600
509// protocol.c 601// 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); 602void protocol_filter_save(void);
516void protocol_filter_load(const char *fname); 603void protocol_filter_load(const char *fname);
604void protocol_print_filter(pid_t pid);
517 605
518// restrict_users.c 606// restrict_users.c
519void restrict_users(void); 607void restrict_users(void);
@@ -525,46 +613,95 @@ void fs_logger2int(const char *msg1, int d);
525void fs_logger3(const char *msg1, const char *msg2, const char *msg3); 613void fs_logger3(const char *msg1, const char *msg2, const char *msg3);
526void fs_logger_print(void); 614void fs_logger_print(void);
527void fs_logger_change_owner(void); 615void fs_logger_change_owner(void);
528void fs_logger_print_log_name(const char *name);
529void fs_logger_print_log(pid_t pid); 616void fs_logger_print_log(pid_t pid);
530 617
531// run_symlink.c 618// run_symlink.c
532void run_symlink(int argc, char **argv); 619void run_symlink(int argc, char **argv);
533 620
534// user.c
535void check_user(int argc, char **argv);
536
537// paths.c 621// paths.c
538char **build_paths(void); 622char **build_paths(void);
539 623
540// fs_mkdir.c 624// fs_mkdir.c
541void fs_mkdir(const char *name); 625void fs_mkdir(const char *name);
626void fs_mkfile(const char *name);
542 627
543// x11.c 628// x11.c
629extern int mask_x11_abstract_socket;
544void fs_x11(void); 630void fs_x11(void);
545int x11_display(void); 631int x11_display(void);
546void x11_start(int argc, char **argv); 632void x11_start(int argc, char **argv);
547void x11_start_xpra(int argc, char **argv); 633void x11_start_xpra(int argc, char **argv);
548void x11_start_xephyr(int argc, char **argv); 634void x11_start_xephyr(int argc, char **argv);
549extern char *xephyr_screen; 635void x11_block(void);
550 636
551// ls.c 637// ls.c
552#define SANDBOX_FS_LS 0 638enum {
553#define SANDBOX_FS_GET 1 639 SANDBOX_FS_LS = 0,
554void sandboxfs_name(int op, const char *name, const char *path); 640 SANDBOX_FS_GET,
555void sandboxfs(int op, pid_t pid, const char *patqh); 641 SANDBOX_FS_PUT,
642 SANDBOX_FS_MAX // this should always be the last entry
643};
644void sandboxfs(int op, pid_t pid, const char *path1, const char *path2);
556 645
557// checkcfg.c 646// checkcfg.c
558#define CFG_FILE_TRANSFER 0 647enum {
559#define CFG_X11 1 648 CFG_FILE_TRANSFER = 0,
560#define CFG_BIND 2 649 CFG_X11,
561#define CFG_USERNS 3 650 CFG_BIND,
562#define CFG_CHROOT 4 651 CFG_USERNS,
563#define CFG_SECCOMP 5 652 CFG_CHROOT,
564#define CFG_NETWORK 6 653 CFG_SECCOMP,
565#define CFG_RESTRICTED_NETWORK 7 654 CFG_NETWORK,
566#define CFG_MAX 8 // this should always be the last entry 655 CFG_RESTRICTED_NETWORK,
656 CFG_FORCE_NONEWPRIVS,
657 CFG_WHITELIST,
658 CFG_XEPHYR_WINDOW_TITLE,
659 CFG_REMOUNT_PROC_SYS,
660 CFG_OVERLAYFS,
661 CFG_CHROOT_DESKTOP,
662 CFG_PRIVATE_HOME,
663 CFG_PRIVATE_BIN_NO_LOCAL,
664 CFG_FIREJAIL_PROMPT,
665 CFG_MAX // this should always be the last entry
666};
667extern char *xephyr_screen;
668extern char *xephyr_extra_params;
669extern char *netfilter_default;
567int checkcfg(int val); 670int checkcfg(int val);
671void print_compiletime_support(void);
672void x11_xorg(void);
673
674// appimage.c
675void appimage_set(const char *appimage_path);
676void appimage_clear(void);
677const char *appimage_getdir(void);
678
679// appimage_size.c
680long unsigned int appimage2_size(const char *fname);
681
682// cmdline.c
683void build_cmdline(char **command_line, char **window_title, int argc, char **argv, int index);
684
685// sbox.c
686// programs
687#define PATH_FNET (LIBDIR "/firejail/fnet")
688#define PATH_FIREMON (PREFIX "/bin/firemon")
689#define PATH_FSECCOMP (LIBDIR "/firejail/fseccomp")
690#define PATH_FCOPY (LIBDIR "/firejail/fcopy")
691#define SBOX_STDIN_FILE "/run/firejail/mnt/sbox_stdin"
692
693// bitmapped filters for sbox_run
694#define SBOX_ROOT (1 << 0) // run the sandbox as root
695#define SBOX_USER (1 << 1) // run the sandbox as a regular user
696#define SBOX_SECCOMP (1 << 2) // install seccomp
697#define SBOX_CAPS_NONE (1 << 3) // drop all capabilities
698#define SBOX_CAPS_NETWORK (1 << 4) // caps filter for programs running network programs
699#define SBOX_ALLOW_STDIN (1 << 5) // don't close stdin
700#define SBOX_STDIN_FROM_FILE (1 << 6) // open file and redirect it to stdin
701
702// run sbox
703int sbox_run(unsigned filter, int num, ...);
704
568 705
569#endif 706#endif
570 707
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index 7ee76d096..adddf626b 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 31
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 32
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
145
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,12 +106,17 @@ 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 if (strcmp(filename, fname))
116 printf("Disable %s (requesterd %s)\n", fname, filename);
117 else
118 printf("Disable %s\n", fname);
119 }
307 else if (arg_debug_blacklists) { 120 else if (arg_debug_blacklists) {
308 printf("Disable %s", fname); 121 printf("Disable %s", fname);
309 if (op == BLACKLIST_FILE) 122 if (op == BLACKLIST_FILE)
@@ -311,6 +124,7 @@ static void disable_file(OPERATION op, const char *filename) {
311 else 124 else
312 printf(" - no logging\n"); 125 printf(" - no logging\n");
313 } 126 }
127
314 if (S_ISDIR(s.st_mode)) { 128 if (S_ISDIR(s.st_mode)) {
315 if (mount(RUN_RO_DIR, fname, "none", MS_BIND, "mode=400,gid=0") < 0) 129 if (mount(RUN_RO_DIR, fname, "none", MS_BIND, "mode=400,gid=0") < 0)
316 errExit("disable file"); 130 errExit("disable file");
@@ -332,6 +146,18 @@ static void disable_file(OPERATION op, const char *filename) {
332 fs_rdonly(fname); 146 fs_rdonly(fname);
333// todo: last_disable = SUCCESSFUL; 147// todo: last_disable = SUCCESSFUL;
334 } 148 }
149 else if (op == MOUNT_RDWR) {
150 if (arg_debug)
151 printf("Mounting read-only %s\n", fname);
152 fs_rdwr(fname);
153// todo: last_disable = SUCCESSFUL;
154 }
155 else if (op == MOUNT_NOEXEC) {
156 if (arg_debug)
157 printf("Mounting noexec %s\n", fname);
158 fs_noexec(fname);
159// todo: last_disable = SUCCESSFUL;
160 }
335 else if (op == MOUNT_TMPFS) { 161 else if (op == MOUNT_TMPFS) {
336 if (S_ISDIR(s.st_mode)) { 162 if (S_ISDIR(s.st_mode)) {
337 if (arg_debug) 163 if (arg_debug)
@@ -361,7 +187,7 @@ static void globbing(OPERATION op, const char *pattern, const char *noblacklist[
361 glob_t globbuf; 187 glob_t globbuf;
362 // Profiles contain blacklists for files that might not exist on a user's machine. 188 // Profiles contain blacklists for files that might not exist on a user's machine.
363 // GLOB_NOCHECK makes that okay. 189 // GLOB_NOCHECK makes that okay.
364 int globerr = glob(pattern, GLOB_NOCHECK | GLOB_NOSORT, NULL, &globbuf); 190 int globerr = glob(pattern, GLOB_NOCHECK | GLOB_NOSORT | GLOB_PERIOD, NULL, &globbuf);
365 if (globerr) { 191 if (globerr) {
366 fprintf(stderr, "Error: failed to glob pattern %s\n", pattern); 192 fprintf(stderr, "Error: failed to glob pattern %s\n", pattern);
367 exit(1); 193 exit(1);
@@ -399,7 +225,7 @@ static void globbing(OPERATION op, const char *pattern, const char *noblacklist[
399} 225}
400 226
401 227
402// blacklist files or directoies by mounting empty files on top of them 228// blacklist files or directories by mounting empty files on top of them
403void fs_blacklist(void) { 229void fs_blacklist(void) {
404 char *homedir = cfg.homedir; 230 char *homedir = cfg.homedir;
405 assert(homedir); 231 assert(homedir);
@@ -426,21 +252,13 @@ void fs_blacklist(void) {
426 252
427 // process bind command 253 // process bind command
428 if (strncmp(entry->data, "bind ", 5) == 0) { 254 if (strncmp(entry->data, "bind ", 5) == 0) {
255 struct stat s;
429 char *dname1 = entry->data + 5; 256 char *dname1 = entry->data + 5;
430 char *dname2 = split_comma(dname1); 257 char *dname2 = split_comma(dname1);
431 if (dname2 == NULL) { 258 if (dname2 == NULL ||
432 fprintf(stderr, "Error: second directory missing in bind command\n"); 259 stat(dname1, &s) == -1 ||
433 entry = entry->next; 260 stat(dname2, &s) == -1) {
434 continue; 261 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; 262 entry = entry->next;
445 continue; 263 continue;
446 } 264 }
@@ -452,11 +270,8 @@ void fs_blacklist(void) {
452 if (mount(dname1, dname2, NULL, MS_BIND|MS_REC, NULL) < 0) 270 if (mount(dname1, dname2, NULL, MS_BIND|MS_REC, NULL) < 0)
453 errExit("mount bind"); 271 errExit("mount bind");
454 /* coverity[toctou] */ 272 /* coverity[toctou] */
455 if (chown(dname2, s.st_uid, s.st_gid) == -1) 273 if (set_perms(dname2, s.st_uid, s.st_gid,s.st_mode))
456 errExit("mount-bind chown"); 274 errExit("set_perms");
457 /* coverity[toctou] */
458 if (chmod(dname2, s.st_mode) == -1)
459 errExit("mount-bind chmod");
460 275
461 entry = entry->next; 276 entry = entry->next;
462 continue; 277 continue;
@@ -464,12 +279,40 @@ void fs_blacklist(void) {
464 279
465 // Process noblacklist command 280 // Process noblacklist command
466 if (strncmp(entry->data, "noblacklist ", 12) == 0) { 281 if (strncmp(entry->data, "noblacklist ", 12) == 0) {
467 if (noblacklist_c >= noblacklist_m) { 282 char **paths = build_paths();
468 noblacklist_m *= 2; 283
469 noblacklist = realloc(noblacklist, sizeof(*noblacklist) * noblacklist_m); 284 char *enames[sizeof(paths)+1] = {0};
470 if (noblacklist == NULL) 285 int i = 0;
471 errExit("failed increasing memory for noblacklist entries");} 286
472 noblacklist[noblacklist_c++] = expand_home(entry->data + 12, homedir); 287 if (strncmp(entry->data + 12, "${PATH}", 7) == 0) {
288 // expand ${PATH} macro
289 while (paths[i] != NULL) {
290 if (asprintf(&enames[i], "%s%s", paths[i], entry->data + 19) == -1)
291 errExit("asprintf");
292 i++;
293 }
294 } else {
295 // expand ${HOME} macro if found or pass as is
296 enames[0] = expand_home(entry->data + 12, homedir);
297 enames[1] = NULL;
298 }
299
300 i = 0;
301 while (enames[i] != NULL) {
302 if (noblacklist_c >= noblacklist_m) {
303 noblacklist_m *= 2;
304 noblacklist = realloc(noblacklist, sizeof(*noblacklist) * noblacklist_m);
305 if (noblacklist == NULL)
306 errExit("failed increasing memory for noblacklist entries");
307 }
308 noblacklist[noblacklist_c++] = enames[i];
309 i++;
310 }
311
312 while (enames[i] != NULL) {
313 free(enames[i]);
314 }
315
473 entry = entry->next; 316 entry = entry->next;
474 continue; 317 continue;
475 } 318 }
@@ -487,10 +330,32 @@ void fs_blacklist(void) {
487 ptr = entry->data + 10; 330 ptr = entry->data + 10;
488 op = MOUNT_READONLY; 331 op = MOUNT_READONLY;
489 } 332 }
333 else if (strncmp(entry->data, "read-write ", 11) == 0) {
334 ptr = entry->data + 11;
335 op = MOUNT_RDWR;
336 }
337 else if (strncmp(entry->data, "noexec ", 7) == 0) {
338 ptr = entry->data + 7;
339 op = MOUNT_NOEXEC;
340 }
490 else if (strncmp(entry->data, "tmpfs ", 6) == 0) { 341 else if (strncmp(entry->data, "tmpfs ", 6) == 0) {
491 ptr = entry->data + 6; 342 ptr = entry->data + 6;
492 op = MOUNT_TMPFS; 343 op = MOUNT_TMPFS;
493 } 344 }
345 else if (strncmp(entry->data, "mkdir ", 6) == 0) {
346 EUID_USER();
347 fs_mkdir(entry->data + 6);
348 EUID_ROOT();
349 entry = entry->next;
350 continue;
351 }
352 else if (strncmp(entry->data, "mkfile ", 7) == 0) {
353 EUID_USER();
354 fs_mkfile(entry->data + 7);
355 EUID_ROOT();
356 entry = entry->next;
357 continue;
358 }
494 else { 359 else {
495 fprintf(stderr, "Error: invalid profile line %s\n", entry->data); 360 fprintf(stderr, "Error: invalid profile line %s\n", entry->data);
496 entry = entry->next; 361 entry = entry->next;
@@ -542,38 +407,56 @@ void fs_rdonly(const char *dir) {
542 int rv = stat(dir, &s); 407 int rv = stat(dir, &s);
543 if (rv == 0) { 408 if (rv == 0) {
544 // mount --bind /bin /bin 409 // 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 410 // mount --bind -o remount,ro /bin
548 if (mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_REC, NULL) < 0) 411 if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0 ||
412 mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_REC, NULL) < 0)
549 errExit("mount read-only"); 413 errExit("mount read-only");
550 fs_logger2("read-only", dir); 414 fs_logger2("read-only", dir);
551 } 415 }
552} 416}
553void fs_rdonly_noexit(const char *dir) { 417
418static void fs_rdwr(const char *dir) {
419 assert(dir);
420 // check directory exists
421 struct stat s;
422 int rv = stat(dir, &s);
423 if (rv == 0) {
424 // if the file is outside /home directory, allow only root user
425 uid_t u = getuid();
426 if (u != 0 && s.st_uid != u) {
427 if (!arg_quiet)
428 fprintf(stderr, "Warning: you are not allowed to change %s to read-write\n", dir);
429 return;
430 }
431
432 // mount --bind /bin /bin
433 // mount --bind -o remount,rw /bin
434 if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0 ||
435 mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_REC, NULL) < 0)
436 errExit("mount read-write");
437 fs_logger2("read-write", dir);
438 }
439}
440
441void fs_noexec(const char *dir) {
554 assert(dir); 442 assert(dir);
555 // check directory exists 443 // check directory exists
556 struct stat s; 444 struct stat s;
557 int rv = stat(dir, &s); 445 int rv = stat(dir, &s);
558 if (rv == 0) { 446 if (rv == 0) {
559 int merr = 0;
560 // mount --bind /bin /bin 447 // 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 448 // mount --bind -o remount,ro /bin
564 if (mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_REC, NULL) < 0) 449 if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0 ||
565 merr = 1; 450 mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_NOEXEC|MS_NODEV|MS_NOSUID|MS_REC, NULL) < 0)
566 if (merr) 451 errExit("mount noexec");
567 fprintf(stderr, "Warning: cannot mount %s read-only\n", dir); 452 fs_logger2("noexec", dir);
568 else
569 fs_logger2("read-only", dir);
570 } 453 }
571} 454}
572 455
456
457
573// mount /proc and /sys directories 458// mount /proc and /sys directories
574void fs_proc_sys_dev_boot(void) { 459void fs_proc_sys_dev_boot(void) {
575 struct stat s;
576
577 if (arg_debug) 460 if (arg_debug)
578 printf("Remounting /proc and /proc/sys filesystems\n"); 461 printf("Remounting /proc and /proc/sys filesystems\n");
579 if (mount("proc", "/proc", "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_REC, NULL) < 0) 462 if (mount("proc", "/proc", "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_REC, NULL) < 0)
@@ -581,10 +464,8 @@ void fs_proc_sys_dev_boot(void) {
581 fs_logger("remount /proc"); 464 fs_logger("remount /proc");
582 465
583 // remount /proc/sys readonly 466 // remount /proc/sys readonly
584 if (mount("/proc/sys", "/proc/sys", NULL, MS_BIND | MS_REC, NULL) < 0) 467 if (mount("/proc/sys", "/proc/sys", NULL, MS_BIND | MS_REC, NULL) < 0 ||
585 errExit("mounting /proc/sys"); 468 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"); 469 errExit("mounting /proc/sys");
589 fs_logger("read-only /proc/sys"); 470 fs_logger("read-only /proc/sys");
590 471
@@ -601,114 +482,148 @@ void fs_proc_sys_dev_boot(void) {
601 fs_logger("remount /sys"); 482 fs_logger("remount /sys");
602 } 483 }
603 484
604 if (stat("/sys/firmware", &s) == 0) { 485 disable_file(BLACKLIST_FILE, "/sys/firmware");
605 disable_file(BLACKLIST_FILE, "/sys/firmware"); 486 disable_file(BLACKLIST_FILE, "/sys/hypervisor");
606 } 487 { // allow user access to /sys/fs if "--noblacklist=/sys/fs" is present on the command line
607 488 EUID_USER();
608 if (stat("/sys/hypervisor", &s) == 0) { 489 profile_add("blacklist /sys/fs");
609 disable_file(BLACKLIST_FILE, "/sys/hypervisor"); 490 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 }
619
620 if (stat("/sys/power", &s) == 0) {
621 disable_file(BLACKLIST_FILE, "/sys/power");
622 } 491 }
623 492 disable_file(BLACKLIST_FILE, "/sys/module");
624// if (mount("sysfs", "/sys", "sysfs", MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REC, NULL) < 0) 493 disable_file(BLACKLIST_FILE, "/sys/power");
625// errExit("mounting /sys"); 494 disable_file(BLACKLIST_FILE, "/sys/kernel/debug");
626 495 disable_file(BLACKLIST_FILE, "/sys/kernel/vmcoreinfo");
627 // Disable SysRq 496 disable_file(BLACKLIST_FILE, "/sys/kernel/uevent_helper");
628 // a linux box can be shut down easily using the following commands (as root): 497
629 // # echo 1 > /proc/sys/kernel/sysrq 498 // various /proc/sys files
630 // #echo b > /proc/sysrq-trigger 499 disable_file(BLACKLIST_FILE, "/proc/sys/security");
631 // for more information see https://www.kernel.org/doc/Documentation/sysrq.txt 500 disable_file(BLACKLIST_FILE, "/proc/sys/efi/vars");
632 if (arg_debug) 501 disable_file(BLACKLIST_FILE, "/proc/sys/fs/binfmt_misc");
633 printf("Disable /proc/sysrq-trigger\n"); 502 disable_file(BLACKLIST_FILE, "/proc/sys/kernel/core_pattern");
634 fs_rdonly_noexit("/proc/sysrq-trigger"); 503 disable_file(BLACKLIST_FILE, "/proc/sys/kernel/modprobe");
635 504 disable_file(BLACKLIST_FILE, "/proc/sysrq-trigger");
636 // disable hotplug and uevent_helper 505 disable_file(BLACKLIST_FILE, "/proc/sys/kernel/hotplug");
637 if (arg_debug) 506 disable_file(BLACKLIST_FILE, "/proc/sys/vm/panic_on_oom");
638 printf("Disable /proc/sys/kernel/hotplug\n"); 507
639 fs_rdonly_noexit("/proc/sys/kernel/hotplug"); 508 // various /proc files
640 if (arg_debug) 509 disable_file(BLACKLIST_FILE, "/proc/irq");
641 printf("Disable /sys/kernel/uevent_helper\n"); 510 disable_file(BLACKLIST_FILE, "/proc/bus");
642 fs_rdonly_noexit("/sys/kernel/uevent_helper"); 511 disable_file(BLACKLIST_FILE, "/proc/config.gz");
643 512 disable_file(BLACKLIST_FILE, "/proc/sched_debug");
644 // read-only /proc/irq and /proc/bus 513 disable_file(BLACKLIST_FILE, "/proc/timer_list");
645 if (arg_debug) 514 disable_file(BLACKLIST_FILE, "/proc/timer_stats");
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"); 515 disable_file(BLACKLIST_FILE, "/proc/kcore");
654
655 // disable /proc/kallsyms
656 disable_file(BLACKLIST_FILE, "/proc/kallsyms"); 516 disable_file(BLACKLIST_FILE, "/proc/kallsyms");
517 disable_file(BLACKLIST_FILE, "/proc/mem");
518 disable_file(BLACKLIST_FILE, "/proc/kmem");
657 519
658 // disable /boot 520 // remove kernel symbol information
659 if (stat("/boot", &s) == 0) { 521 if (!arg_allow_debuggers) {
660 if (arg_debug) 522 disable_file(BLACKLIST_FILE, "/usr/src/linux");
661 printf("Disable /boot directory\n"); 523 disable_file(BLACKLIST_FILE, "/lib/modules");
524 disable_file(BLACKLIST_FILE, "/usr/lib/debug");
662 disable_file(BLACKLIST_FILE, "/boot"); 525 disable_file(BLACKLIST_FILE, "/boot");
663 } 526 }
664 527
665 // disable /selinux 528 // disable /selinux
666 if (stat("/selinux", &s) == 0) { 529 disable_file(BLACKLIST_FILE, "/selinux");
667 if (arg_debug)
668 printf("Disable /selinux directory\n");
669 disable_file(BLACKLIST_FILE, "/selinux");
670 }
671 530
672 // disable /dev/port 531 // disable /dev/port
673 if (stat("/dev/port", &s) == 0) { 532 disable_file(BLACKLIST_FILE, "/dev/port");
674 disable_file(BLACKLIST_FILE, "/dev/port"); 533
675 }
676 534
677 if (getuid() != 0) { 535 // disable various ipc sockets
678 // disable /dev/kmsg 536 struct stat s;
679 if (stat("/dev/kmsg", &s) == 0) { 537
680 disable_file(BLACKLIST_FILE, "/dev/kmsg"); 538 // disable /run/user/{uid}/gnupg
681 } 539 char *fnamegpg;
540 if (asprintf(&fnamegpg, "/run/user/%d/gnupg", getuid()) == -1)
541 errExit("asprintf");
542 if (stat(fnamegpg, &s) == -1)
543 mkdir_attr(fnamegpg, 0700, getuid(), getgid());
544 if (stat(fnamegpg, &s) == 0)
545 disable_file(BLACKLIST_FILE, fnamegpg);
546 free(fnamegpg);
547
548 // disable /run/user/{uid}/systemd
549 char *fnamesysd;
550 if (asprintf(&fnamesysd, "/run/user/%d/systemd", getuid()) == -1)
551 errExit("asprintf");
552 if (stat(fnamesysd, &s) == -1)
553 mkdir_attr(fnamesysd, 0755, getuid(), getgid());
554 if (stat(fnamesysd, &s) == 0)
555 disable_file(BLACKLIST_FILE, fnamesysd);
556 free(fnamesysd);
557
558
559// todo: investigate
560#if 0
561 // breaks too many applications, option needed
562 /* // disable /run/user/{uid}/bus */
563 /* char *fnamebus; */
564 /* if (asprintf(&fnamebus, "/run/user/%d/bus", getuid()) == -1) */
565 /* errExit("asprintf"); */
566 /* if (stat(fnamebus, &s) == 0) */
567 /* disable_file(BLACKLIST_FILE, fnamebus); */
568 /* free(fnamebus); */
569
570 // WARNING: not working
571 // disable /run/user/{uid}/kdeinit*
572 //char *fnamekde;
573 //if (asprintf(&fnamekde, "/run/user/%d/kdeinit*", getuid()) == -1)
574 // errExit("asprintf");
575 //if (stat(fnamekde, &s) == 0)
576 // disable_file(BLACKLIST_FILE, fnamekde);
577 //free(fnamekde);
578
579
580 // disable /run/user/{uid}/pulse
581 /* char *fnamepulse; */
582 /* if (asprintf(&fnamepulse, "/run/user/%d/pulse", getuid()) == -1) */
583 /* errExit("asprintf"); */
584 /* if (stat(fnamepulse, &s) == 0) */
585 /* disable_file(BLACKLIST_FILE, fnamepulse); */
586 /* free(fnamepulse); */
587
588 // disable /run/user/{uid}/dconf
589 /* char *fnamedconf; */
590 /* if (asprintf(&fnamedconf, "/run/user/%d/dconf", getuid()) == -1) */
591 /* errExit("asprintf"); */
592 /* if (stat(fnamedconf, &s) == 0) */
593 /* disable_file(BLACKLIST_FILE, fnamedconf); */
594 /* free(fnamedconf); */
595
596
597 // dirs in /run/user/{uid}/
598 // using gnome:
599 // bus, dconf, gdm, gnome-shell, gnupg, gvfs, keyring, pulse, systemd
600
601 // using kde:
602 // kdeinit__0, ...
682 603
683 // disable /proc/kmsg 604 // more files with sockets to be blacklisted
684 if (stat("/proc/kmsg", &s) == 0) { 605 // /run/dbus /run/systemd /run/udev /run/lvm
685 disable_file(BLACKLIST_FILE, "/proc/kmsg"); 606
686 } 607 // /run/user/{uid} does not exist on some systems, usually used and created by desktop applications
608
609#endif
610
611 if (getuid() != 0) {
612 // disable /dev/kmsg and /proc/kmsg
613 disable_file(BLACKLIST_FILE, "/dev/kmsg");
614 disable_file(BLACKLIST_FILE, "/proc/kmsg");
687 } 615 }
688} 616}
689 617
690// disable firejail configuration in /etc/firejail and in ~/.config/firejail 618// disable firejail configuration in /etc/firejail and in ~/.config/firejail
691static void disable_firejail_config(void) { 619static void disable_config(void) {
692 struct stat s; 620 struct stat s;
693 if (stat("/etc/firejail", &s) == 0)
694 disable_file(BLACKLIST_FILE, "/etc/firejail");
695 621
696 char *fname; 622 char *fname;
697 if (asprintf(&fname, "%s/.config/firejail", cfg.homedir) == -1) 623 if (asprintf(&fname, "%s/.config/firejail", cfg.homedir) == -1)
698 errExit("asprintf"); 624 errExit("asprintf");
699 if (stat(fname, &s) == 0) 625 if (stat(fname, &s) == 0)
700 disable_file(BLACKLIST_FILE, fname); 626 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); 627 free(fname);
713 628
714 // disable run time information 629 // disable run time information
@@ -725,8 +640,23 @@ static void disable_firejail_config(void) {
725 640
726// build a basic read-only filesystem 641// build a basic read-only filesystem
727void fs_basic_fs(void) { 642void fs_basic_fs(void) {
643 uid_t uid = getuid();
644
728 if (arg_debug) 645 if (arg_debug)
729 printf("Mounting read-only /bin, /sbin, /lib, /lib32, /lib64, /usr, /etc, /var\n"); 646 printf("Mounting read-only /bin, /sbin, /lib, /lib32, /lib64, /usr");
647 if (!arg_writable_etc) {
648 fs_rdonly("/etc");
649 if (uid)
650 fs_noexec("/etc");
651 if (arg_debug) printf(", /etc");
652 }
653 if (!arg_writable_var) {
654 fs_rdonly("/var");
655 if (uid)
656 fs_noexec("/var");
657 if (arg_debug) printf(", /var");
658 }
659 if (arg_debug) printf("\n");
730 fs_rdonly("/bin"); 660 fs_rdonly("/bin");
731 fs_rdonly("/sbin"); 661 fs_rdonly("/sbin");
732 fs_rdonly("/lib"); 662 fs_rdonly("/lib");
@@ -734,26 +664,66 @@ void fs_basic_fs(void) {
734 fs_rdonly("/lib32"); 664 fs_rdonly("/lib32");
735 fs_rdonly("/libx32"); 665 fs_rdonly("/libx32");
736 fs_rdonly("/usr"); 666 fs_rdonly("/usr");
737 fs_rdonly("/etc");
738 fs_rdonly("/var");
739 667
740 // update /var directory in order to support multiple sandboxes running on the same root directory 668 // update /var directory in order to support multiple sandboxes running on the same root directory
741 if (!arg_private_dev) 669// if (!arg_private_dev)
742 fs_dev_shm(); 670// fs_dev_shm();
743 fs_var_lock(); 671 fs_var_lock();
744 fs_var_tmp(); 672 fs_var_tmp();
745 fs_var_log(); 673 fs_var_log();
746 fs_var_lib(); 674 fs_var_lib();
747 fs_var_cache(); 675 fs_var_cache();
748 fs_var_utmp(); 676 fs_var_utmp();
749 677 fs_machineid();
678
750 // don't leak user information 679 // don't leak user information
751 restrict_users(); 680 restrict_users();
752 681
753 disable_firejail_config(); 682 // when starting as root, firejail config is not disabled;
683 // this mode could be used to install and test new software by chaining
684 // firejail sandboxes (firejail --force)
685 if (uid)
686 disable_config();
754} 687}
755 688
756 689
690
691#ifdef HAVE_OVERLAYFS
692char *fs_check_overlay_dir(const char *subdirname, int allow_reuse) {
693 struct stat s;
694 char *dirname;
695
696 // create ~/.firejail directory
697 if (asprintf(&dirname, "%s/.firejail", cfg.homedir) == -1)
698 errExit("asprintf");
699 if (stat(dirname, &s) == -1) {
700 mkdir_attr(dirname, 0700, 0, 0);
701 }
702 else if (is_link(dirname)) {
703 fprintf(stderr, "Error: invalid ~/.firejail directory\n");
704 exit(1);
705 }
706 free(dirname);
707
708 // check overlay directory
709 if (asprintf(&dirname, "%s/.firejail/%s", cfg.homedir, subdirname) == -1)
710 errExit("asprintf");
711 if (is_link(dirname)) {
712 fprintf(stderr, "Error: overlay directory is a symbolic link\n");
713 exit(1);
714 }
715 if (allow_reuse == 0) {
716 if (stat(dirname, &s) == 0) {
717 fprintf(stderr, "Error: overlay directory already exists: %s\n", dirname);
718 exit(1);
719 }
720 }
721
722 return dirname;
723}
724
725
726
757// mount overlayfs on top of / directory 727// mount overlayfs on top of / directory
758// mounting an overlay and chrooting into it: 728// mounting an overlay and chrooting into it:
759// 729//
@@ -806,48 +776,54 @@ void fs_overlayfs(void) {
806 if (major == 3 && minor < 18) 776 if (major == 3 && minor < 18)
807 oldkernel = 1; 777 oldkernel = 1;
808 778
809 // build overlay directories
810 fs_build_mnt_dir();
811
812 char *oroot; 779 char *oroot;
813 if(asprintf(&oroot, "%s/oroot", RUN_MNT_DIR) == -1) 780 if(asprintf(&oroot, "%s/oroot", RUN_MNT_DIR) == -1)
814 errExit("asprintf"); 781 errExit("asprintf");
815 if (mkdir(oroot, 0755)) 782 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 783
784 struct stat s;
822 char *basedir = RUN_MNT_DIR; 785 char *basedir = RUN_MNT_DIR;
823 if (arg_overlay_keep) { 786 if (arg_overlay_keep) {
824 // set base for working and diff directories 787 // set base for working and diff directories
825 basedir = cfg.overlay_dir; 788 basedir = cfg.overlay_dir;
826 if (mkdir(basedir, 0755) != 0) { 789
827 fprintf(stderr, "Error: cannot create overlay directory\n"); 790 // does the overlay exist?
828 exit(1); 791 if (stat(basedir, &s) == 0) {
792 if (arg_overlay_reuse == 0) {
793 fprintf(stderr, "Error: overlay directory exists, but reuse is not allowed\n");
794 exit(1);
795 }
796 }
797 else {
798 /* coverity[toctou] */
799 if (mkdir(basedir, 0755) != 0) {
800 fprintf(stderr, "Error: cannot create overlay directory\n");
801 exit(1);
802 }
829 } 803 }
830 } 804 }
831 805
832 char *odiff; 806 char *odiff;
833 if(asprintf(&odiff, "%s/odiff", basedir) == -1) 807 if(asprintf(&odiff, "%s/odiff", basedir) == -1)
834 errExit("asprintf"); 808 errExit("asprintf");
835 if (mkdir(odiff, 0755)) 809
836 errExit("mkdir"); 810 // no need to check arg_overlay_reuse
837 if (chown(odiff, 0, 0) < 0) 811 if (stat(odiff, &s) != 0) {
838 errExit("chown"); 812 mkdir_attr(odiff, 0755, 0, 0);
839 if (chmod(odiff, 0755) < 0) 813 }
840 errExit("chmod"); 814 else if (set_perms(odiff, 0, 0, 0755))
815 errExit("set_perms");
841 816
842 char *owork; 817 char *owork;
843 if(asprintf(&owork, "%s/owork", basedir) == -1) 818 if(asprintf(&owork, "%s/owork", basedir) == -1)
844 errExit("asprintf"); 819 errExit("asprintf");
845 if (mkdir(owork, 0755)) 820
846 errExit("mkdir"); 821 // no need to check arg_overlay_reuse
847 if (chown(owork, 0, 0) < 0) 822 if (stat(owork, &s) != 0) {
823 mkdir_attr(owork, 0755, 0, 0);
824 }
825 else if (set_perms(owork, 0, 0, 0755))
848 errExit("chown"); 826 errExit("chown");
849 if (chmod(owork, 0755) < 0)
850 errExit("chmod");
851 827
852 // mount overlayfs 828 // mount overlayfs
853 if (arg_debug) 829 if (arg_debug)
@@ -899,21 +875,23 @@ void fs_overlayfs(void) {
899 875
900 if(asprintf(&hdiff, "%s/hdiff", basedir) == -1) 876 if(asprintf(&hdiff, "%s/hdiff", basedir) == -1)
901 errExit("asprintf"); 877 errExit("asprintf");
902 if (mkdir(hdiff, S_IRWXU | S_IRWXG | S_IRWXO)) 878
903 errExit("mkdir"); 879 // no need to check arg_overlay_reuse
904 if (chown(hdiff, 0, 0) < 0) 880 if (stat(hdiff, &s) != 0) {
905 errExit("chown"); 881 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) 882 }
907 errExit("chmod"); 883 else if (set_perms(hdiff, 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH))
884 errExit("set_perms");
908 885
909 if(asprintf(&hwork, "%s/hwork", basedir) == -1) 886 if(asprintf(&hwork, "%s/hwork", basedir) == -1)
910 errExit("asprintf"); 887 errExit("asprintf");
911 if (mkdir(hwork, S_IRWXU | S_IRWXG | S_IRWXO)) 888
912 errExit("mkdir"); 889 // no need to check arg_overlay_reuse
913 if (chown(hwork, 0, 0) < 0) 890 if (stat(hwork, &s) != 0) {
914 errExit("chown"); 891 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) 892 }
916 errExit("chmod"); 893 else if (set_perms(hwork, 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH))
894 errExit("set_perms");
917 895
918 // no homedir in overlay so now mount another overlay for /home 896 // no homedir in overlay so now mount another overlay for /home
919 if (asprintf(&option, "lowerdir=/home,upperdir=%s,workdir=%s", hdiff, hwork) == -1) 897 if (asprintf(&option, "lowerdir=/home,upperdir=%s,workdir=%s", hdiff, hwork) == -1)
@@ -950,37 +928,53 @@ void fs_overlayfs(void) {
950 errExit("mounting /run"); 928 errExit("mounting /run");
951 fs_logger("whitelist /run"); 929 fs_logger("whitelist /run");
952 930
931 // mount-bind /tmp/.X11-unix directory
932 if (stat("/tmp/.X11-unix", &s) == 0) {
933 if (arg_debug)
934 printf("Mounting /tmp/.X11-unix\n");
935 char *x11;
936 if (asprintf(&x11, "%s/tmp/.X11-unix", oroot) == -1)
937 errExit("asprintf");
938 if (mount("/tmp/.X11-unix", x11, NULL, MS_BIND|MS_REC, NULL) < 0)
939 fprintf(stderr, "Warning: cannot mount /tmp/.X11-unix in overlay\n");
940 else
941 fs_logger("whitelist /tmp/.X11-unix");
942 free(x11);
943 }
944
953 // chroot in the new filesystem 945 // chroot in the new filesystem
946#ifdef HAVE_GCOV
947 __gcov_flush();
948#endif
954 if (chroot(oroot) == -1) 949 if (chroot(oroot) == -1)
955 errExit("chroot"); 950 errExit("chroot");
956 951
957 // update /var directory in order to support multiple sandboxes running on the same root directory 952 // update /var directory in order to support multiple sandboxes running on the same root directory
958 if (!arg_private_dev) 953// if (!arg_private_dev)
959 fs_dev_shm(); 954// fs_dev_shm();
960 fs_var_lock(); 955 fs_var_lock();
961 fs_var_tmp(); 956 fs_var_tmp();
962 fs_var_log(); 957 fs_var_log();
963 fs_var_lib(); 958 fs_var_lib();
964 fs_var_cache(); 959 fs_var_cache();
965 fs_var_utmp(); 960 fs_var_utmp();
961 fs_machineid();
966 962
967 // don't leak user information 963 // don't leak user information
968 restrict_users(); 964 restrict_users();
969 965
970 // when starting as root in overlay mode, firejail config is not disabled; 966 // when starting as root, firejail config is not disabled;
971 // this mode could be used to install and test new software by chaining 967 // this mode could be used to install and test new software by chaining
972 // firejail sandboxes (firejail --force) 968 // firejail sandboxes (firejail --force)
973 if (getuid() != 0) 969 if (getuid() != 0)
974 disable_firejail_config(); 970 disable_config();
975 else
976 fprintf(stderr, "Warning: masking /etc/firejail disabled when starting the sandbox as root using --overlay option\n");
977 971
978 // cleanup and exit 972 // cleanup and exit
979 free(option); 973 free(option);
980 free(oroot); 974 free(oroot);
981 free(odiff); 975 free(odiff);
982} 976}
983 977#endif
984 978
985 979
986#ifdef HAVE_CHROOT 980#ifdef HAVE_CHROOT
@@ -991,6 +985,16 @@ int fs_check_chroot_dir(const char *rootdir) {
991 struct stat s; 985 struct stat s;
992 char *name; 986 char *name;
993 987
988 // rootdir has to be owned by root
989 if (stat(rootdir, &s) != 0) {
990 fprintf(stderr, "Error: cannot find chroot directory\n");
991 return 1;
992 }
993 if (s.st_uid != 0) {
994 fprintf(stderr, "Error: chroot directory should be owned by root\n");
995 return 1;
996 }
997
994 // check /dev 998 // check /dev
995 if (asprintf(&name, "%s/dev", rootdir) == -1) 999 if (asprintf(&name, "%s/dev", rootdir) == -1)
996 errExit("asprintf"); 1000 errExit("asprintf");
@@ -1018,7 +1022,7 @@ int fs_check_chroot_dir(const char *rootdir) {
1018 } 1022 }
1019 free(name); 1023 free(name);
1020 1024
1021 // check /proc 1025 // check /tmp
1022 if (asprintf(&name, "%s/tmp", rootdir) == -1) 1026 if (asprintf(&name, "%s/tmp", rootdir) == -1)
1023 errExit("asprintf"); 1027 errExit("asprintf");
1024 if (stat(name, &s) == -1) { 1028 if (stat(name, &s) == -1) {
@@ -1026,16 +1030,29 @@ int fs_check_chroot_dir(const char *rootdir) {
1026 return 1; 1030 return 1;
1027 } 1031 }
1028 free(name); 1032 free(name);
1029 1033
1030 // check /bin/bash 1034 // check /bin/bash
1031 if (asprintf(&name, "%s/bin/bash", rootdir) == -1) 1035// if (asprintf(&name, "%s/bin/bash", rootdir) == -1)
1032 errExit("asprintf"); 1036// errExit("asprintf");
1033 if (stat(name, &s) == -1) { 1037// if (stat(name, &s) == -1) {
1034 fprintf(stderr, "Error: cannot find /bin/bash in chroot directory\n"); 1038// fprintf(stderr, "Error: cannot find /bin/bash in chroot directory\n");
1035 return 1; 1039// return 1;
1040// }
1041// free(name);
1042
1043 // check x11 socket directory
1044 if (getenv("FIREJAIL_X11")) {
1045 mask_x11_abstract_socket = 1;
1046 char *name;
1047 if (asprintf(&name, "%s/tmp/.X11-unix", rootdir) == -1)
1048 errExit("asprintf");
1049 if (stat(name, &s) == -1) {
1050 fprintf(stderr, "Error: cannot find /tmp/.X11-unix in chroot directory\n");
1051 return 1;
1052 }
1053 free(name);
1036 } 1054 }
1037 free(name); 1055
1038
1039 return 0; 1056 return 0;
1040} 1057}
1041 1058
@@ -1043,77 +1060,98 @@ int fs_check_chroot_dir(const char *rootdir) {
1043void fs_chroot(const char *rootdir) { 1060void fs_chroot(const char *rootdir) {
1044 assert(rootdir); 1061 assert(rootdir);
1045 1062
1046 //*********************************** 1063 if (checkcfg(CFG_CHROOT_DESKTOP)) {
1047 // mount-bind a /dev in rootdir 1064 // mount-bind a /dev in rootdir
1048 //*********************************** 1065 char *newdev;
1049 // mount /dev 1066 if (asprintf(&newdev, "%s/dev", rootdir) == -1)
1050 char *newdev; 1067 errExit("asprintf");
1051 if (asprintf(&newdev, "%s/dev", rootdir) == -1) 1068 if (arg_debug)
1052 errExit("asprintf"); 1069 printf("Mounting /dev on %s\n", newdev);
1053 if (arg_debug) 1070 if (mount("/dev", newdev, NULL, MS_BIND|MS_REC, NULL) < 0)
1054 printf("Mounting /dev on %s\n", newdev); 1071 errExit("mounting /dev");
1055 if (mount("/dev", newdev, NULL, MS_BIND|MS_REC, NULL) < 0) 1072 free(newdev);
1056 errExit("mounting /dev"); 1073
1057 1074 // x11
1058 // some older distros don't have a /run directory 1075 if (getenv("FIREJAIL_X11")) {
1059 // create one by default 1076 mask_x11_abstract_socket = 1;
1060 // no exit on error, let the user deal with any problems 1077 char *newx11;
1061 char *rundir; 1078 if (asprintf(&newx11, "%s/tmp/.X11-unix", rootdir) == -1)
1062 if (asprintf(&rundir, "%s/run", rootdir) == -1) 1079 errExit("asprintf");
1063 errExit("asprintf"); 1080 if (arg_debug)
1064 if (!is_dir(rundir)) { 1081 printf("Mounting /tmp/.X11-unix on %s\n", newx11);
1065 int rv = mkdir(rundir, 0755); 1082 if (mount("/tmp/.X11-unix", newx11, NULL, MS_BIND|MS_REC, NULL) < 0)
1066 (void) rv; 1083 errExit("mounting /tmp/.X11-unix");
1067 rv = chown(rundir, 0, 0); 1084 free(newx11);
1068 (void) rv; 1085 }
1086
1087 // create /run/firejail directory in chroot
1088 char *rundir;
1089 if (asprintf(&rundir, "%s/run", rootdir) == -1)
1090 errExit("asprintf");
1091 create_empty_dir_as_root(rundir, 0755);
1092 free(rundir);
1093 if (asprintf(&rundir, "%s/run/firejail", rootdir) == -1)
1094 errExit("asprintf");
1095 create_empty_dir_as_root(rundir, 0755);
1096 free(rundir);
1097
1098 // create /run/firejail/mnt directory in chroot and mount the current one
1099 if (asprintf(&rundir, "%s%s", rootdir, RUN_MNT_DIR) == -1)
1100 errExit("asprintf");
1101 create_empty_dir_as_root(rundir, 0755);
1102 if (mount(RUN_MNT_DIR, rundir, NULL, MS_BIND|MS_REC, NULL) < 0)
1103 errExit("mount bind");
1104
1105 // copy /etc/resolv.conf in chroot directory
1106 // if resolv.conf in chroot is a symbolic link, this will fail
1107 // no exit on error, let the user deal with the problem
1108 char *fname;
1109 if (asprintf(&fname, "%s/etc/resolv.conf", rootdir) == -1)
1110 errExit("asprintf");
1111 if (arg_debug)
1112 printf("Updating /etc/resolv.conf in %s\n", fname);
1113 if (is_link(fname)) {
1114 fprintf(stderr, "Error: invalid %s file\n", fname);
1115 exit(1);
1116 }
1117 if (copy_file("/etc/resolv.conf", fname, 0, 0, 0644) == -1)
1118 fprintf(stderr, "Warning: /etc/resolv.conf not initialized\n");
1069 } 1119 }
1070 1120
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 1121 // chroot into the new directory
1122#ifdef HAVE_GCOV
1123 __gcov_flush();
1124#endif
1087 if (arg_debug) 1125 if (arg_debug)
1088 printf("Chrooting into %s\n", rootdir); 1126 printf("Chrooting into %s\n", rootdir);
1089 if (chroot(rootdir) < 0) 1127 if (chroot(rootdir) < 0)
1090 errExit("chroot"); 1128 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 1129
1104 // don't leak user information 1130 // create all other /run/firejail files and directories
1105 restrict_users(); 1131 preproc_build_firejail_dir();
1106 1132
1107 disable_firejail_config(); 1133 if (checkcfg(CFG_CHROOT_DESKTOP)) {
1134 // update /var directory in order to support multiple sandboxes running on the same root directory
1135// if (!arg_private_dev)
1136// fs_dev_shm();
1137 fs_var_lock();
1138 fs_var_tmp();
1139 fs_var_log();
1140 fs_var_lib();
1141 fs_var_cache();
1142 fs_var_utmp();
1143 fs_machineid();
1144
1145 // don't leak user information
1146 restrict_users();
1147
1148 // when starting as root, firejail config is not disabled;
1149 // this mode could be used to install and test new software by chaining
1150 // firejail sandboxes (firejail --force)
1151 if (getuid() != 0)
1152 disable_config();
1153 }
1108} 1154}
1109#endif 1155#endif
1110 1156
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 1157
diff --git a/src/firejail/fs_bin.c b/src/firejail/fs_bin.c
index c3d24aaac..7c56d524e 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",
@@ -37,19 +39,45 @@ static char *paths[] = {
37// return 1 if found, 0 if not found 39// return 1 if found, 0 if not found
38static char *check_dir_or_file(const char *name) { 40static char *check_dir_or_file(const char *name) {
39 assert(name); 41 assert(name);
40 invalid_filename(name);
41 42
42 struct stat s; 43 struct stat s;
43 char *fname = NULL; 44 char *fname = NULL;
44 45
45 int i = 0; 46 int i = 0;
46 while (paths[i]) { 47 while (paths[i]) {
48 // private-bin-no-local can be disabled in /etc/firejail/firejail.config
49 if (checkcfg(CFG_PRIVATE_BIN_NO_LOCAL) && strstr(paths[i], "local/")) {
50 i++;
51 continue;
52 }
53
54 // check file
47 if (asprintf(&fname, "%s/%s", paths[i], name) == -1) 55 if (asprintf(&fname, "%s/%s", paths[i], name) == -1)
48 errExit("asprintf"); 56 errExit("asprintf");
49 if (arg_debug) 57 if (arg_debug)
50 printf("Checking %s/%s\n", paths[i], name); 58 printf("Checking %s/%s\n", paths[i], name);
51 if (stat(fname, &s) == 0 && !S_ISDIR(s.st_mode)) // do not allow directories 59 if (stat(fname, &s) == 0 && !S_ISDIR(s.st_mode)) { // do not allow directories
60 // check symlink to firejail executable in /usr/local/bin
61 if (strcmp(paths[i], "/usr/local/bin") == 0 && is_link(fname)) {
62 /* coverity[toctou] */
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
@@ -65,69 +94,13 @@ static char *check_dir_or_file(const char *name) {
65 return paths[i]; 94 return paths[i];
66} 95}
67 96
68void fs_check_bin_list(void) { 97static void duplicate(char *fname) {
69 EUID_ASSERT(); 98 if (*fname == '~' || *fname == '/' || strstr(fname, "..")) {
70 if (strstr(cfg.bin_private_keep, "..")) { 99 fprintf(stderr, "Error: \"%s\" is an invalid filename\n", fname);
71 fprintf(stderr, "Error: invalid private bin list\n");
72 exit(1); 100 exit(1);
73 } 101 }
74 102 invalid_filename(fname);
75 char *dlist = strdup(cfg.bin_private_keep);
76 if (!dlist)
77 errExit("strdup");
78
79 // create a new list removing files not found
80 char *newlist = malloc(strlen(dlist) + 1 + 1); // +',' + '\0'
81 if (!newlist)
82 errExit("malloc");
83 *newlist = '\0';
84 char *newlistptr = newlist;
85
86 // check the first file
87 char *ptr = strtok(dlist, ",");
88 int notfound = 0;
89 if (check_dir_or_file(ptr)) {
90 // file found, copy the name in the new list
91 strcpy(newlistptr, ptr);
92 strcat(newlistptr, ",");
93 newlistptr += strlen(newlistptr);
94 }
95 else
96 notfound = 1;
97
98 // check the rest of the list
99 while ((ptr = strtok(NULL, ",")) != NULL) {
100 if (check_dir_or_file(ptr)) {
101 // file found, copy the name in the new list
102 strcpy(newlistptr, ptr);
103 strcat(newlistptr, ",");
104 newlistptr += strlen(newlistptr);
105 }
106 else
107 notfound = 1;
108 }
109
110 if (*newlist == '\0') {
111 fprintf(stderr, "Warning: no --private-bin list executable found, option disabled\n");
112 cfg.bin_private_keep = NULL;
113 arg_private_bin = 0;
114 free(newlist);
115 }
116 else {
117 ptr = strrchr(newlist, ',');
118 assert(ptr);
119 *ptr = '\0';
120 if (notfound)
121 fprintf(stderr, "Warning: not all executables from --private-bin list were found. The current list is %s\n", newlist);
122
123 cfg.bin_private_keep = newlist;
124 }
125
126 free(dlist);
127}
128 103
129static void duplicate(char *fname) {
130 char *cmd;
131 char *path = check_dir_or_file(fname); 104 char *path = check_dir_or_file(fname);
132 if (!path) 105 if (!path)
133 return; 106 return;
@@ -137,33 +110,9 @@ static void duplicate(char *fname) {
137 if (asprintf(&full_path, "%s/%s", path, fname) == -1) 110 if (asprintf(&full_path, "%s/%s", path, fname) == -1)
138 errExit("asprintf"); 111 errExit("asprintf");
139 112
140 char *actual_path = realpath(full_path, NULL); 113 // copy the file
141 if (actual_path) { 114 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, full_path, RUN_BIN_DIR);
142 // if the file is a symbolic link not under path, make a symbolic link 115 fs_logger2("clone", fname);
143 if (is_link(full_path) && strncmp(actual_path, path, strlen(path))) {
144 char *lnkname;
145 if (asprintf(&lnkname, "%s/%s", RUN_BIN_DIR, fname) == -1)
146 errExit("asprintf");
147 int rv = symlink(actual_path, lnkname);
148 if (rv)
149 fprintf(stderr, "Warning cannot create symbolic link %s\n", lnkname);
150 else if (arg_debug)
151 printf("Created symbolic link %s -> %s\n", lnkname, actual_path);
152 free(lnkname);
153 }
154 else {
155 // 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)
159 printf("%s\n", cmd);
160 if (system(cmd))
161 errExit("system cp -a");
162 free(cmd);
163 }
164 free(actual_path);
165 }
166
167 free(full_path); 116 free(full_path);
168} 117}
169 118
@@ -172,66 +121,26 @@ void fs_private_bin_list(void) {
172 char *private_list = cfg.bin_private_keep; 121 char *private_list = cfg.bin_private_keep;
173 assert(private_list); 122 assert(private_list);
174 123
175 // check bin paths 124 // create /run/firejail/mnt/bin directory
176 int i = 0; 125 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 126
198 127 if (arg_debug)
199 // copy the list of files in the new etc directory 128 printf("Copying files in the new bin directory\n");
200 // using a new child process without root privileges
201 fs_logger_print(); // save the current log
202 pid_t child = fork();
203 if (child < 0)
204 errExit("fork");
205 if (child == 0) {
206 if (arg_debug)
207 printf("Copying files in the new home:\n");
208 129
209 // elevate privileges - files in the new /bin directory belong to root 130 // copy the list of files in the new home directory
210 if (setreuid(0, 0) < 0) 131 char *dlist = strdup(private_list);
211 errExit("setreuid"); 132 if (!dlist)
212 if (setregid(0, 0) < 0) 133 errExit("strdup");
213 errExit("setregid");
214
215 // copy the list of files in the new home directory
216 char *dlist = strdup(private_list);
217 if (!dlist)
218 errExit("strdup");
219
220 134
221 char *ptr = strtok(dlist, ","); 135 char *ptr = strtok(dlist, ",");
136 duplicate(ptr);
137 while ((ptr = strtok(NULL, ",")) != NULL)
222 duplicate(ptr); 138 duplicate(ptr);
223 139 free(dlist);
224 while ((ptr = strtok(NULL, ",")) != NULL)
225 duplicate(ptr);
226 free(dlist);
227 fs_logger_print(); 140 fs_logger_print();
228 exit(0);
229 }
230 // wait for the child to finish
231 waitpid(child, NULL, 0);
232 141
233 // mount-bind 142 // mount-bind
234 i = 0; 143 int i = 0;
235 while (paths[i]) { 144 while (paths[i]) {
236 struct stat s; 145 struct stat s;
237 if (stat(paths[i], &s) == 0) { 146 if (stat(paths[i], &s) == 0) {
@@ -244,29 +153,5 @@ void fs_private_bin_list(void) {
244 } 153 }
245 i++; 154 i++;
246 } 155 }
247
248 // log cloned files
249 char *dlist = strdup(private_list);
250 if (!dlist)
251 errExit("strdup");
252
253
254 char *ptr = strtok(dlist, ",");
255 while (ptr) {
256 i = 0;
257 while (paths[i]) {
258 struct stat s;
259 if (stat(paths[i], &s) == 0) {
260 char *fname;
261 if (asprintf(&fname, "%s/%s", paths[i], ptr) == -1)
262 errExit("asprintf");
263 fs_logger2("clone", fname);
264 free(fname);
265 }
266 i++;
267 }
268 ptr = strtok(NULL, ",");
269 }
270 free(dlist);
271} 156}
272 157
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..a27c0e41b 100644
--- a/src/firejail/fs_etc.c
+++ b/src/firejail/fs_etc.c
@@ -21,130 +21,136 @@
21#include <sys/mount.h> 21#include <sys/mount.h>
22#include <sys/stat.h> 22#include <sys/stat.h>
23#include <sys/types.h> 23#include <sys/types.h>
24#include <sys/wait.h>
25#include <unistd.h> 24#include <unistd.h>
26 25
27// return 0 if file not found, 1 if found 26// spoof /etc/machine_id
28static int check_dir_or_file(const char *name) { 27void fs_machineid(void) {
29 assert(name); 28 union machineid_t {
30 invalid_filename(name); 29 uint8_t u8[16];
30 uint32_t u32[4];
31 } mid;
32
33 // if --machine-id flag is active, do nothing
34 if (arg_machineid)
35 return;
36
37 // init random number generator
38 srand(time(NULL));
31 39
40 // generate random id
41 mid.u32[0] = rand();
42 mid.u32[1] = rand();
43 mid.u32[2] = rand();
44 mid.u32[3] = rand();
45
46 // UUID version 4 and DCE variant
47 mid.u8[6] = (mid.u8[6] & 0x0F) | 0x40;
48 mid.u8[8] = (mid.u8[8] & 0x3F) | 0x80;
49
50 // write it in a file
51 FILE *fp = fopen(RUN_MACHINEID, "w");
52 if (!fp)
53 errExit("fopen");
54 fprintf(fp, "%08x%08x%08x%08x\n", mid.u32[0], mid.u32[1], mid.u32[2], mid.u32[3]);
55 fclose(fp);
56 if (set_perms(RUN_MACHINEID, 0, 0, 0444))
57 errExit("set_perms");
58
59
60 struct stat s;
61 if (stat("/etc/machine-id", &s) == 0) {
62 if (arg_debug)
63 printf("installing a new /etc/machine-id\n");
64
65 if (mount(RUN_MACHINEID, "/etc/machine-id", "none", MS_BIND, "mode=444,gid=0"))
66 errExit("mount");
67 }
68 if (stat("/var/lib/dbus/machine-id", &s) == 0) {
69 if (mount(RUN_MACHINEID, "/var/lib/dbus/machine-id", "none", MS_BIND, "mode=444,gid=0"))
70 errExit("mount");
71 }
72}
73
74// return 0 if file not found, 1 if found
75static int check_dir_or_file(const char *fname) {
76 assert(fname);
77
32 struct stat s; 78 struct stat s;
33 char *fname;
34 if (asprintf(&fname, "/etc/%s", name) == -1)
35 errExit("asprintf");
36 if (arg_debug)
37 printf("Checking %s\n", fname);
38 if (stat(fname, &s) == -1) { 79 if (stat(fname, &s) == -1) {
39 if (arg_debug) 80 if (arg_debug)
40 printf("Warning: file %s not found.\n", fname); 81 printf("Warning: file %s not found.\n", fname);
41 return 0; 82 return 0;
42 } 83 }
43 84
85 // read access
86 if (access(fname, R_OK) == -1)
87 goto errexit;
88
44 // dir or regular file 89 // dir or regular file
45 if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode)) { 90 if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode) || !is_link(fname))
46 free(fname); 91 return 1; // normal exit
47 return 1;
48 }
49 92
50 if (!is_link(fname)) { 93errexit:
51 free(fname);
52 return 1;
53 }
54
55 fprintf(stderr, "Error: invalid file type, %s.\n", fname); 94 fprintf(stderr, "Error: invalid file type, %s.\n", fname);
56 exit(1); 95 exit(1);
57} 96}
58 97
59void fs_check_etc_list(void) { 98static void duplicate(const char *fname, const char *private_dir, const char *private_run_dir) {
60 EUID_ASSERT(); 99 if (*fname == '~' || *fname == '/' || strstr(fname, "..")) {
61 if (strstr(cfg.etc_private_keep, "..")) { 100 fprintf(stderr, "Error: \"%s\" is an invalid filename\n", fname);
62 fprintf(stderr, "Error: invalid private etc list\n");
63 exit(1); 101 exit(1);
64 } 102 }
65 103 invalid_filename(fname);
66 char *dlist = strdup(cfg.etc_private_keep);
67 if (!dlist)
68 errExit("strdup");
69
70 // build a new list only with the files found
71 char *newlist = malloc(strlen(cfg.etc_private_keep) + 1);
72 if (!newlist)
73 errExit("malloc");
74 *newlist = '\0';
75
76 char *ptr = strtok(dlist, ",");
77 if (check_dir_or_file(ptr))
78 strcat(newlist, ptr);
79 while ((ptr = strtok(NULL, ",")) != NULL) {
80 if (check_dir_or_file(ptr)) {
81 strcat(newlist, ",");
82 strcat(newlist, ptr);
83 }
84 }
85 cfg.etc_private_keep = newlist;
86
87 free(dlist);
88}
89
90static void duplicate(char *fname) {
91 char *cmd;
92 104
93 // copy the file - this code assumes ETC_DIR is actually MNT_DIR/etc 105 char *src;
94 if (asprintf(&cmd, "%s -a --parents /etc/%s %s", RUN_CP_COMMAND, fname, RUN_MNT_DIR) == -1) 106 if (asprintf(&src, "%s/%s", private_dir, fname) == -1)
95 errExit("asprintf"); 107 errExit("asprintf");
108 if (check_dir_or_file(src) == 0) {
109 if (!arg_quiet)
110 fprintf(stderr, "Warning: skipping %s for private %s\n", fname, private_dir);
111 free(src);
112 return;
113 }
114
96 if (arg_debug) 115 if (arg_debug)
97 printf("%s\n", cmd); 116 printf("copying %s to private %s\n", src, private_dir);
98 if (system(cmd)) 117
99 fprintf(stderr, "Warning (fs_etc): error copying file /etc/%s, skipping...\n", fname); 118 struct stat s;
119 if (stat(src, &s) == 0 && S_ISDIR(s.st_mode)) {
120 // create the directory in RUN_ETC_DIR
121 char *dirname;
122 if (asprintf(&dirname, "%s/%s", private_run_dir, fname) == -1)
123 errExit("asprintf");
124 create_empty_dir_as_root(dirname, s.st_mode);
125 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, src, dirname);
126 free(dirname);
127 }
128 else
129 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, src, private_run_dir);
100 130
101 free(cmd); 131 fs_logger2("clone", src);
102 132 free(src);
103 char *name;
104 if (asprintf(&name, "/etc/%s", fname) == -1)
105 errExit("asprintf");
106 fs_logger2("clone", name);
107 free(name);
108} 133}
109 134
110 135
111void fs_private_etc_list(void) { 136void fs_private_dir_list(const char *private_dir, const char *private_run_dir, const char *private_list) {
112 char *private_list = cfg.etc_private_keep; 137 assert(private_dir);
138 assert(private_run_dir);
113 assert(private_list); 139 assert(private_list);
114 140
115 struct stat s; 141 // create /run/firejail/mnt/etc directory
116 if (stat("/etc", &s) == -1) { 142 mkdir_attr(private_run_dir, 0755, 0, 0);
117 fprintf(stderr, "Error: cannot find user /etc directory\n"); 143 fs_logger2("tmpfs", private_dir);
118 exit(1);
119 }
120
121 // create /tmp/firejail/mnt/etc directory
122 fs_build_mnt_dir();
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");
131 144
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 145 fs_logger_print(); // save the current log
135 pid_t child = fork(); 146
136 if (child < 0) 147
137 errExit("fork"); 148 // copy the list of files in the new etc directory
138 if (child == 0) { 149 // using a new child process with root privileges
150 if (*private_list != '\0') {
139 if (arg_debug) 151 if (arg_debug)
140 printf("Copying files in the new etc directory:\n"); 152 printf("Copying files in the new %s directory:\n", private_dir);
141 153
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 154 // copy the list of files in the new home directory
149 char *dlist = strdup(private_list); 155 char *dlist = strdup(private_list);
150 if (!dlist) 156 if (!dlist)
@@ -152,21 +158,18 @@ void fs_private_etc_list(void) {
152 158
153 159
154 char *ptr = strtok(dlist, ","); 160 char *ptr = strtok(dlist, ",");
155 duplicate(ptr); 161 duplicate(ptr, private_dir, private_run_dir);
156 162
157 while ((ptr = strtok(NULL, ",")) != NULL) 163 while ((ptr = strtok(NULL, ",")) != NULL)
158 duplicate(ptr); 164 duplicate(ptr, private_dir, private_run_dir);
159 free(dlist); 165 free(dlist);
160 fs_logger_print(); 166 fs_logger_print();
161 exit(0);
162 } 167 }
163 // wait for the child to finish 168
164 waitpid(child, NULL, 0);
165
166 if (arg_debug) 169 if (arg_debug)
167 printf("Mount-bind %s on top of /etc\n", RUN_ETC_DIR); 170 printf("Mount-bind %s on top of %s\n", private_run_dir, private_dir);
168 if (mount(RUN_ETC_DIR, "/etc", NULL, MS_BIND|MS_REC, NULL) < 0) 171 if (mount(private_run_dir, private_dir, NULL, MS_BIND|MS_REC, NULL) < 0)
169 errExit("mount bind"); 172 errExit("mount bind");
170 fs_logger("mount /etc"); 173 fs_logger2("mount", private_dir);
171} 174}
172 175
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c
index d4a16da0a..0872bf0d0 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)
@@ -165,6 +137,7 @@ static int store_asoundrc(void) {
165 if (stat(src, &s) == 0) { 137 if (stat(src, &s) == 0) {
166 if (is_link(src)) { 138 if (is_link(src)) {
167 // make sure the real path of the file is inside the home directory 139 // make sure the real path of the file is inside the home directory
140 /* coverity[toctou] */
168 char* rp = realpath(src, NULL); 141 char* rp = realpath(src, NULL);
169 if (!rp) { 142 if (!rp) {
170 fprintf(stderr, "Error: Cannot access %s\n", src); 143 fprintf(stderr, "Error: Cannot access %s\n", src);
@@ -177,7 +150,7 @@ static int store_asoundrc(void) {
177 free(rp); 150 free(rp);
178 } 151 }
179 152
180 int rv = copy_file(src, dest); 153 int rv = copy_file(src, dest, -1, -1, -0644);
181 if (rv) { 154 if (rv) {
182 fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n"); 155 fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n");
183 return 0; 156 return 0;
@@ -194,17 +167,12 @@ static void copy_xauthority(void) {
194 char *dest; 167 char *dest;
195 if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1) 168 if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1)
196 errExit("asprintf"); 169 errExit("asprintf");
197 int rv = copy_file(src, dest); 170 // copy, set permissions and ownership
171 int rv = copy_file(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR);
198 if (rv) 172 if (rv)
199 fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n"); 173 fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n");
200 else { 174 else {
201 fs_logger2("clone", dest); 175 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 } 176 }
209 177
210 // delete the temporary file 178 // delete the temporary file
@@ -217,17 +185,12 @@ static void copy_asoundrc(void) {
217 char *dest; 185 char *dest;
218 if (asprintf(&dest, "%s/.asoundrc", cfg.homedir) == -1) 186 if (asprintf(&dest, "%s/.asoundrc", cfg.homedir) == -1)
219 errExit("asprintf"); 187 errExit("asprintf");
220 int rv = copy_file(src, dest); 188 // copy, set permissions and ownership
189 int rv = copy_file(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR);
221 if (rv) 190 if (rv)
222 fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n"); 191 fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n");
223 else { 192 else {
224 fs_logger2("clone", dest); 193 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 } 194 }
232 195
233 // delete the temporary file 196 // delete the temporary file
@@ -250,17 +213,11 @@ void fs_private_homedir(void) {
250 213
251 uid_t u = getuid(); 214 uid_t u = getuid();
252 gid_t g = getgid(); 215 gid_t g = getgid();
253 struct stat s;
254 if (stat(homedir, &s) == -1) {
255 fprintf(stderr, "Error: cannot find user home directory\n");
256 exit(1);
257 }
258
259 216
260 // mount bind private_homedir on top of homedir 217 // mount bind private_homedir on top of homedir
261 if (arg_debug) 218 if (arg_debug)
262 printf("Mount-bind %s on top of %s\n", private_homedir, homedir); 219 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) 220 if (mount(private_homedir, homedir, NULL, MS_NOSUID | MS_NODEV | MS_BIND | MS_REC, NULL) < 0)
264 errExit("mount bind"); 221 errExit("mount bind");
265 fs_logger3("mount-bind", private_homedir, cfg.homedir); 222 fs_logger3("mount-bind", private_homedir, cfg.homedir);
266 fs_logger2("whitelist", cfg.homedir); 223 fs_logger2("whitelist", cfg.homedir);
@@ -274,7 +231,7 @@ void fs_private_homedir(void) {
274 // mask /root 231 // mask /root
275 if (arg_debug) 232 if (arg_debug)
276 printf("Mounting a new /root directory\n"); 233 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) 234 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"); 235 errExit("mounting home directory");
279 fs_logger("tmpfs /root"); 236 fs_logger("tmpfs /root");
280 } 237 }
@@ -282,7 +239,7 @@ void fs_private_homedir(void) {
282 // mask /home 239 // mask /home
283 if (arg_debug) 240 if (arg_debug)
284 printf("Mounting a new /home directory\n"); 241 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) 242 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"); 243 errExit("mounting home directory");
287 fs_logger("tmpfs /home"); 244 fs_logger("tmpfs /home");
288 } 245 }
@@ -312,14 +269,14 @@ void fs_private(void) {
312 // mask /home 269 // mask /home
313 if (arg_debug) 270 if (arg_debug)
314 printf("Mounting a new /home directory\n"); 271 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) 272 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"); 273 errExit("mounting home directory");
317 fs_logger("tmpfs /home"); 274 fs_logger("tmpfs /home");
318 275
319 // mask /root 276 // mask /root
320 if (arg_debug) 277 if (arg_debug)
321 printf("Mounting a new /root directory\n"); 278 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) 279 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"); 280 errExit("mounting root directory");
324 fs_logger("tmpfs /root"); 281 fs_logger("tmpfs /root");
325 282
@@ -343,8 +300,8 @@ void fs_private(void) {
343 copy_xauthority(); 300 copy_xauthority();
344 if (aflag) 301 if (aflag)
345 copy_asoundrc(); 302 copy_asoundrc();
346}
347 303
304}
348 305
349// check new private home directory (--private= option) - exit if it fails 306// check new private home directory (--private= option) - exit if it fails
350void fs_check_private_dir(void) { 307void fs_check_private_dir(void) {
@@ -384,3 +341,163 @@ void fs_check_private_dir(void) {
384 } 341 }
385} 342}
386 343
344//***********************************************************************************
345// --private-home
346//***********************************************************************************
347static char *check_dir_or_file(const char *name) {
348 assert(name);
349
350 // basic checks
351 invalid_filename(name);
352 if (arg_debug)
353 printf("Private home: checking %s\n", name);
354
355 // expand home directory
356 char *fname = expand_home(name, cfg.homedir);
357 assert(fname);
358
359 // If it doesn't start with '/', it must be relative to homedir
360 if (fname[0] != '/') {
361 char* tmp;
362 if (asprintf(&tmp, "%s/%s", cfg.homedir, fname) == -1)
363 errExit("asprintf");
364 free(fname);
365 fname = tmp;
366 }
367
368 // we allow only files in user home directory or symbolic links to files or directories owned by the user
369 struct stat s;
370 if (lstat(fname, &s) == 0 && S_ISLNK(s.st_mode)) {
371 if (stat(fname, &s) == 0) {
372 if (s.st_uid != getuid()) {
373 fprintf(stderr, "Error: symbolic link %s to file or directory not owned by the user\n", fname);
374 exit(1);
375 }
376 return fname;
377 }
378 else {
379 fprintf(stderr, "Error: invalid file %s\n", name);
380 exit(1);
381 }
382 }
383 else {
384 // check the file is in user home directory, a full home directory is not allowed
385 char *rname = realpath(fname, NULL);
386 if (!rname ||
387 strncmp(rname, cfg.homedir, strlen(cfg.homedir)) != 0 ||
388 strcmp(rname, cfg.homedir) == 0) {
389 fprintf(stderr, "Error: invalid file %s\n", name);
390 exit(1);
391 }
392
393 // only top files and directories in user home are allowed
394 char *ptr = rname + strlen(cfg.homedir);
395 assert(*ptr != '\0');
396 ptr = strchr(++ptr, '/');
397 if (ptr) {
398 if (*ptr != '\0') {
399 fprintf(stderr, "Error: only top files and directories in user home are allowed\n");
400 exit(1);
401 }
402 }
403 free(fname);
404 return rname;
405 }
406}
407
408static void duplicate(char *name) {
409 char *fname = check_dir_or_file(name);
410
411 if (arg_debug)
412 printf("Private home: duplicating %s\n", fname);
413 assert(strncmp(fname, cfg.homedir, strlen(cfg.homedir)) == 0);
414
415 struct stat s;
416 if (lstat(fname, &s) == -1) {
417 free(fname);
418 return;
419 }
420 else if (S_ISDIR(s.st_mode)) {
421 // create the directory in RUN_HOME_DIR
422 char *name;
423 char *ptr = strrchr(fname, '/');
424 ptr++;
425 if (asprintf(&name, "%s/%s", RUN_HOME_DIR, ptr) == -1)
426 errExit("asprintf");
427 mkdir_attr(name, 0755, getuid(), getgid());
428 sbox_run(SBOX_USER| SBOX_CAPS_NONE | SBOX_SECCOMP, 3, PATH_FCOPY, fname, name);
429 free(name);
430 }
431 else
432 sbox_run(SBOX_USER| SBOX_CAPS_NONE | SBOX_SECCOMP, 3, PATH_FCOPY, fname, RUN_HOME_DIR);
433 fs_logger2("clone", fname);
434 fs_logger_print(); // save the current log
435
436 free(fname);
437}
438
439// private mode (--private-home=list):
440// mount homedir on top of /home/user,
441// tmpfs on top of /root in nonroot mode,
442// tmpfs on top of /tmp in root mode,
443// set skel files,
444// restore .Xauthority
445void fs_private_home_list(void) {
446 char *homedir = cfg.homedir;
447 char *private_list = cfg.home_private_keep;
448 assert(homedir);
449 assert(private_list);
450
451 int xflag = store_xauthority();
452 int aflag = store_asoundrc();
453
454 uid_t uid = getuid();
455 gid_t gid = getgid();
456
457 // create /run/firejail/mnt/home directory
458 mkdir_attr(RUN_HOME_DIR, 0755, uid, gid);
459 fs_logger_print(); // save the current log
460
461 if (arg_debug)
462 printf("Copying files in the new home:\n");
463
464 // copy the list of files in the new home directory
465 char *dlist = strdup(cfg.home_private_keep);
466 if (!dlist)
467 errExit("strdup");
468
469 char *ptr = strtok(dlist, ",");
470 duplicate(ptr);
471 while ((ptr = strtok(NULL, ",")) != NULL)
472 duplicate(ptr);
473
474 fs_logger_print(); // save the current log
475 free(dlist);
476
477 if (arg_debug)
478 printf("Mount-bind %s on top of %s\n", RUN_HOME_DIR, homedir);
479
480 if (mount(RUN_HOME_DIR, homedir, NULL, MS_BIND|MS_REC, NULL) < 0)
481 errExit("mount bind");
482
483 if (uid != 0) {
484 // mask /root
485 if (arg_debug)
486 printf("Mounting a new /root directory\n");
487 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=700,gid=0") < 0)
488 errExit("mounting home directory");
489 }
490 else {
491 // mask /home
492 if (arg_debug)
493 printf("Mounting a new /home directory\n");
494 if (mount("tmpfs", "/home", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
495 errExit("mounting home directory");
496 }
497
498 skel(homedir, uid, gid);
499 if (xflag)
500 copy_xauthority();
501 if (aflag)
502 copy_asoundrc();
503}
diff --git a/src/firejail/fs_hostname.c b/src/firejail/fs_hostname.c
index aa391c0cb..b2e1b4a99 100644
--- a/src/firejail/fs_hostname.c
+++ b/src/firejail/fs_hostname.c
@@ -27,27 +27,14 @@
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) {
34 if (arg_debug) 33 if (arg_debug)
35 printf("Creating a new /etc/hostname file\n"); 34 printf("Creating a new /etc/hostname file\n");
36 35
37 FILE *fp = fopen(RUN_HOSTNAME_FILE, "w"); 36 create_empty_file_as_root(RUN_HOSTNAME_FILE, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH);
38 if (!fp) { 37
39 fprintf(stderr, "Error: cannot create %s\n", RUN_HOSTNAME_FILE);
40 exit(1);
41 }
42 fprintf(fp, "%s\n", hostname);
43 fclose(fp);
44
45 // mode and owner
46 if (chown(RUN_HOSTNAME_FILE, 0, 0) < 0)
47 errExit("chown");
48 if (chmod(RUN_HOSTNAME_FILE, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0)
49 errExit("chmod");
50
51 // bind-mount the file on top of /etc/hostname 38 // bind-mount the file on top of /etc/hostname
52 if (mount(RUN_HOSTNAME_FILE, "/etc/hostname", NULL, MS_BIND|MS_REC, NULL) < 0) 39 if (mount(RUN_HOSTNAME_FILE, "/etc/hostname", NULL, MS_BIND|MS_REC, NULL) < 0)
53 errExit("mount bind /etc/hostname"); 40 errExit("mount bind /etc/hostname");
@@ -61,14 +48,13 @@ void fs_hostname(const char *hostname) {
61 // copy /etc/host into our new file, and modify it on the fly 48 // copy /etc/host into our new file, and modify it on the fly
62 /* coverity[toctou] */ 49 /* coverity[toctou] */
63 FILE *fp1 = fopen("/etc/hosts", "r"); 50 FILE *fp1 = fopen("/etc/hosts", "r");
64 if (!fp1) { 51 if (!fp1)
65 fprintf(stderr, "Error: cannot open /etc/hosts\n"); 52 goto errexit;
66 exit(1); 53
67 }
68 FILE *fp2 = fopen(RUN_HOSTS_FILE, "w"); 54 FILE *fp2 = fopen(RUN_HOSTS_FILE, "w");
69 if (!fp2) { 55 if (!fp2) {
70 fprintf(stderr, "Error: cannot create %s\n", RUN_HOSTS_FILE); 56 fclose(fp1);
71 exit(1); 57 goto errexit;
72 } 58 }
73 59
74 char buf[4096]; 60 char buf[4096];
@@ -88,19 +74,20 @@ void fs_hostname(const char *hostname) {
88 fprintf(fp2, "%s\n", buf); 74 fprintf(fp2, "%s\n", buf);
89 } 75 }
90 fclose(fp1); 76 fclose(fp1);
91 fclose(fp2);
92
93 // mode and owner 77 // mode and owner
94 if (chown(RUN_HOSTS_FILE, 0, 0) < 0) 78 SET_PERMS_STREAM(fp2, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH);
95 errExit("chown"); 79 fclose(fp2);
96 if (chmod(RUN_HOSTS_FILE, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0)
97 errExit("chmod");
98 80
99 // bind-mount the file on top of /etc/hostname 81 // bind-mount the file on top of /etc/hostname
100 if (mount(RUN_HOSTS_FILE, "/etc/hosts", NULL, MS_BIND|MS_REC, NULL) < 0) 82 if (mount(RUN_HOSTS_FILE, "/etc/hosts", NULL, MS_BIND|MS_REC, NULL) < 0)
101 errExit("mount bind /etc/hosts"); 83 errExit("mount bind /etc/hosts");
102 fs_logger("create /etc/hosts"); 84 fs_logger("create /etc/hosts");
103 } 85 }
86 return;
87
88errexit:
89 fprintf(stderr, "Error: cannot create hostname file\n");
90 exit(1);
104} 91}
105 92
106void fs_resolvconf(void) { 93void fs_resolvconf(void) {
@@ -108,7 +95,6 @@ void fs_resolvconf(void) {
108 return; 95 return;
109 96
110 struct stat s; 97 struct stat s;
111 fs_build_mnt_dir();
112 98
113 // create a new /etc/hostname 99 // create a new /etc/hostname
114 if (stat("/etc/resolv.conf", &s) == 0) { 100 if (stat("/etc/resolv.conf", &s) == 0) {
@@ -126,13 +112,11 @@ void fs_resolvconf(void) {
126 fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns2)); 112 fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns2));
127 if (cfg.dns3) 113 if (cfg.dns3)
128 fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns3)); 114 fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns3));
129 fclose(fp); 115
130
131 // mode and owner 116 // mode and owner
132 if (chown(RUN_RESOLVCONF_FILE, 0, 0) < 0) 117 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH);
133 errExit("chown"); 118
134 if (chmod(RUN_RESOLVCONF_FILE, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH ) < 0) 119 fclose(fp);
135 errExit("chmod");
136 120
137 // bind-mount the file on top of /etc/hostname 121 // 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) 122 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..5b6ceae90 100644
--- a/src/firejail/fs_mkdir.c
+++ b/src/firejail/fs_mkdir.c
@@ -22,8 +22,39 @@
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 /* coverity[toctou] */
41 if (mkdir(subdir, 0700) == -1) {
42 fprintf(stderr, "Warning: cannot create %s directory\n", subdir);
43 return;
44 }
45 } else if (!S_ISDIR(s.st_mode)) {
46 fprintf(stderr, "Warning: '%s' exists, but is no directory\n", subdir);
47 return;
48 }
49 if (chdir(subdir)) {
50 fprintf(stderr, "Error: can't chdir to %s", subdir);
51 return;
52 }
53
54 subdir = strtok(NULL, "/");
55 }
56}
57
27void fs_mkdir(const char *name) { 58void fs_mkdir(const char *name) {
28 EUID_ASSERT(); 59 EUID_ASSERT();
29 60
@@ -42,9 +73,72 @@ void fs_mkdir(const char *name) {
42 } 73 }
43 74
44 // create directory 75 // create directory
45 if (mkdir(expanded, 0700) == -1) 76 pid_t child = fork();
46 fprintf(stderr, "Warning: cannot create %s directory\n", expanded); 77 if (child < 0)
78 errExit("fork");
79 if (child == 0) {
80 // drop privileges
81 drop_privs(0);
82
83 // create directory
84 mkdir_recursive(expanded);
85#ifdef HAVE_GCOV
86 __gcov_flush();
87#endif
88 _exit(0);
89 }
90 // wait for the child to finish
91 waitpid(child, NULL, 0);
47 92
48doexit: 93doexit:
49 free(expanded); 94 free(expanded);
50} 95}
96
97void fs_mkfile(const char *name) {
98 EUID_ASSERT();
99
100 // check file name
101 invalid_filename(name);
102 char *expanded = expand_home(name, cfg.homedir);
103 if (strncmp(expanded, cfg.homedir, strlen(cfg.homedir)) != 0) {
104 fprintf(stderr, "Error: only files in user home are supported by mkfile\n");
105 exit(1);
106 }
107
108 struct stat s;
109 if (stat(expanded, &s) == 0) {
110 // file exists, do nothing
111 goto doexit;
112 }
113
114 // create file
115 pid_t child = fork();
116 if (child < 0)
117 errExit("fork");
118 if (child == 0) {
119 // drop privileges
120 drop_privs(0);
121
122 /* coverity[toctou] */
123 FILE *fp = fopen(expanded, "w");
124 if (!fp)
125 fprintf(stderr, "Warning: cannot create %s file\n", expanded);
126 else {
127 int fd = fileno(fp);
128 if (fd == -1)
129 errExit("fileno");
130 int rv = fchmod(fd, 0600);
131 (void) rv;
132 fclose(fp);
133 }
134#ifdef HAVE_GCOV
135 __gcov_flush();
136#endif
137 _exit(0);
138 }
139 // wait for the child to finish
140 waitpid(child, NULL, 0);
141
142doexit:
143 free(expanded);
144}
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..f742e7e22 100644
--- a/src/firejail/fs_var.c
+++ b/src/firejail/fs_var.c
@@ -65,10 +65,9 @@ static void build_list(const char *srcdir) {
65 struct stat s; 65 struct stat s;
66 char *name; 66 char *name;
67 if (asprintf(&name, "%s/%s", srcdir, dir->d_name) == -1) 67 if (asprintf(&name, "%s/%s", srcdir, dir->d_name) == -1)
68 continue; 68 errExit("asprintf");
69 if (stat(name, &s) == -1) 69 if (stat(name, &s) == -1 ||
70 continue; 70 S_ISLNK(s.st_mode)) {
71 if (S_ISLNK(s.st_mode)) {
72 free(name); 71 free(name);
73 continue; 72 continue;
74 } 73 }
@@ -98,10 +97,7 @@ static void build_dirs(void) {
98 // create directories under /var/log 97 // create directories under /var/log
99 DirData *ptr = dirlist; 98 DirData *ptr = dirlist;
100 while (ptr) { 99 while (ptr) {
101 if (mkdir(ptr->name, ptr->st_mode)) 100 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); 101 fs_logger2("mkdir", ptr->name);
106 ptr = ptr->next; 102 ptr = ptr->next;
107 } 103 }
@@ -110,6 +106,7 @@ static void build_dirs(void) {
110void fs_var_log(void) { 106void fs_var_log(void) {
111 build_list("/var/log"); 107 build_list("/var/log");
112 108
109 // note: /var/log is not created here, if it does not exist, this section fails.
113 // create /var/log if it doesn't exit 110 // create /var/log if it doesn't exit
114 if (is_dir("/var/log")) { 111 if (is_dir("/var/log")) {
115 // extract group id for /var/log/wtmp 112 // extract group id for /var/log/wtmp
@@ -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,26 +128,22 @@ 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");
134 if (fp) 131 if (fp) {
132 SET_PERMS_STREAM(fp, 0, wtmp_group, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH);
135 fclose(fp); 133 fclose(fp);
136 if (chown("/var/log/wtmp", 0, wtmp_group) < 0) 134 }
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"); 135 fs_logger("touch /var/log/wtmp");
141 136
142 // create an empty /var/log/btmp file 137 // create an empty /var/log/btmp file
143 fp = fopen("/var/log/btmp", "w"); 138 fp = fopen("/var/log/btmp", "w");
144 if (fp) 139 if (fp) {
140 SET_PERMS_STREAM(fp, 0, wtmp_group, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP);
145 fclose(fp); 141 fclose(fp);
146 if (chown("/var/log/btmp", 0, wtmp_group) < 0) 142 }
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"); 143 fs_logger("touch /var/log/btmp");
151 } 144 }
152 else 145 else
153 fprintf(stderr, "Warning: cannot mount tmpfs on top of /var/log\n"); 146 fprintf(stderr, "Warning: cannot hide /var/log directory\n");
154} 147}
155 148
156void fs_var_lib(void) { 149void fs_var_lib(void) {
@@ -160,7 +153,7 @@ void fs_var_lib(void) {
160 if (stat("/var/lib/dhcp", &s) == 0) { 153 if (stat("/var/lib/dhcp", &s) == 0) {
161 if (arg_debug) 154 if (arg_debug)
162 printf("Mounting tmpfs on /var/lib/dhcp\n"); 155 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) 156 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"); 157 errExit("mounting /var/lib/dhcp");
165 fs_logger("tmpfs /var/lib/dhcp"); 158 fs_logger("tmpfs /var/lib/dhcp");
166 159
@@ -169,11 +162,8 @@ void fs_var_lib(void) {
169 162
170 if (fp) { 163 if (fp) {
171 fprintf(fp, "\n"); 164 fprintf(fp, "\n");
165 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
172 fclose(fp); 166 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"); 167 fs_logger("touch /var/lib/dhcp/dhcpd.leases");
178 } 168 }
179 } 169 }
@@ -182,7 +172,7 @@ void fs_var_lib(void) {
182 if (stat("/var/lib/nginx", &s) == 0) { 172 if (stat("/var/lib/nginx", &s) == 0) {
183 if (arg_debug) 173 if (arg_debug)
184 printf("Mounting tmpfs on /var/lib/nginx\n"); 174 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) 175 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"); 176 errExit("mounting /var/lib/nginx");
187 fs_logger("tmpfs /var/lib/nginx"); 177 fs_logger("tmpfs /var/lib/nginx");
188 } 178 }
@@ -191,7 +181,7 @@ void fs_var_lib(void) {
191 if (stat("/var/lib/snmp", &s) == 0) { 181 if (stat("/var/lib/snmp", &s) == 0) {
192 if (arg_debug) 182 if (arg_debug)
193 printf("Mounting tmpfs on /var/lib/snmp\n"); 183 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) 184 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"); 185 errExit("mounting /var/lib/snmp");
196 fs_logger("tmpfs /var/lib/snmp"); 186 fs_logger("tmpfs /var/lib/snmp");
197 } 187 }
@@ -200,7 +190,7 @@ void fs_var_lib(void) {
200 if (stat("/var/lib/sudo", &s) == 0) { 190 if (stat("/var/lib/sudo", &s) == 0) {
201 if (arg_debug) 191 if (arg_debug)
202 printf("Mounting tmpfs on /var/lib/sudo\n"); 192 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) 193 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"); 194 errExit("mounting /var/lib/sudo");
205 fs_logger("tmpfs /var/lib/sudo"); 195 fs_logger("tmpfs /var/lib/sudo");
206 } 196 }
@@ -212,7 +202,7 @@ void fs_var_cache(void) {
212 if (stat("/var/cache/apache2", &s) == 0) { 202 if (stat("/var/cache/apache2", &s) == 0) {
213 if (arg_debug) 203 if (arg_debug)
214 printf("Mounting tmpfs on /var/cache/apache2\n"); 204 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) 205 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"); 206 errExit("mounting /var/cache/apache2");
217 fs_logger("tmpfs /var/cache/apache2"); 207 fs_logger("tmpfs /var/cache/apache2");
218 } 208 }
@@ -220,7 +210,7 @@ void fs_var_cache(void) {
220 if (stat("/var/cache/lighttpd", &s) == 0) { 210 if (stat("/var/cache/lighttpd", &s) == 0) {
221 if (arg_debug) 211 if (arg_debug)
222 printf("Mounting tmpfs on /var/cache/lighttpd\n"); 212 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) 213 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"); 214 errExit("mounting /var/cache/lighttpd");
225 fs_logger("tmpfs /var/cache/lighttpd"); 215 fs_logger("tmpfs /var/cache/lighttpd");
226 216
@@ -232,18 +222,10 @@ void fs_var_cache(void) {
232 gid = p->pw_gid; 222 gid = p->pw_gid;
233 } 223 }
234 224
235 int rv = mkdir("/var/cache/lighttpd/compress", 0755); 225 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"); 226 fs_logger("mkdir /var/cache/lighttpd/compress");
241 227
242 rv = mkdir("/var/cache/lighttpd/uploads", 0755); 228 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"); 229 fs_logger("/var/cache/lighttpd/uploads");
248 } 230 }
249} 231}
@@ -268,7 +250,7 @@ void fs_var_lock(void) {
268 if (is_dir("/var/lock")) { 250 if (is_dir("/var/lock")) {
269 if (arg_debug) 251 if (arg_debug)
270 printf("Mounting tmpfs on /var/lock\n"); 252 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) 253 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"); 254 errExit("mounting /lock");
273 fs_logger("tmpfs /var/lock"); 255 fs_logger("tmpfs /var/lock");
274 } 256 }
@@ -277,16 +259,11 @@ void fs_var_lock(void) {
277 if (lnk) { 259 if (lnk) {
278 if (!is_dir(lnk)) { 260 if (!is_dir(lnk)) {
279 // create directory 261 // create directory
280 if (mkdir(lnk, S_IRWXU|S_IRWXG|S_IRWXO)) 262 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 } 263 }
287 if (arg_debug) 264 if (arg_debug)
288 printf("Mounting tmpfs on %s on behalf of /var/lock\n", lnk); 265 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) 266 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"); 267 errExit("mounting /var/lock");
291 free(lnk); 268 free(lnk);
292 fs_logger("tmpfs /var/lock"); 269 fs_logger("tmpfs /var/lock");
@@ -304,7 +281,7 @@ void fs_var_tmp(void) {
304 if (!is_link("/var/tmp")) { 281 if (!is_link("/var/tmp")) {
305 if (arg_debug) 282 if (arg_debug)
306 printf("Mounting tmpfs on /var/tmp\n"); 283 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) 284 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"); 285 errExit("mounting /var/tmp");
309 fs_logger("tmpfs /var/tmp"); 286 fs_logger("tmpfs /var/tmp");
310 } 287 }
@@ -327,9 +304,6 @@ void fs_var_utmp(void) {
327 return; 304 return;
328 } 305 }
329 306
330 // create /tmp/firejail/mnt directory
331 fs_build_mnt_dir();
332
333 // create a new utmp file 307 // create a new utmp file
334 if (arg_debug) 308 if (arg_debug)
335 printf("Create the new utmp file\n"); 309 printf("Create the new utmp file\n");
@@ -353,16 +327,13 @@ void fs_var_utmp(void) {
353 327
354 // save new utmp file 328 // save new utmp file
355 fwrite(&u_boot, sizeof(u_boot), 1, fp); 329 fwrite(&u_boot, sizeof(u_boot), 1, fp);
330 SET_PERMS_STREAM(fp, 0, utmp_group, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH);
356 fclose(fp); 331 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 332
362 // mount the new utmp file 333 // mount the new utmp file
363 if (arg_debug) 334 if (arg_debug)
364 printf("Mount the new utmp file\n"); 335 printf("Mount the new utmp file\n");
365 if (mount(RUN_UTMP_FILE, UTMP_FILE, NULL, MS_BIND|MS_REC, NULL) < 0) 336 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"); 337 errExit("mount bind utmp");
367 fs_logger("create /var/run/utmp"); 338 fs_logger("create /var/run/utmp");
368} 339}
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c
index 617e61dcd..b10858411 100644
--- a/src/firejail/fs_whitelist.c
+++ b/src/firejail/fs_whitelist.c
@@ -95,34 +95,29 @@ static char *resolve_downloads(void) {
95 if (asprintf(&fname, "%s/%s", cfg.homedir, ptr1) == -1) 95 if (asprintf(&fname, "%s/%s", cfg.homedir, ptr1) == -1)
96 errExit("asprintf"); 96 errExit("asprintf");
97 97
98 if (stat(fname, &s) == -1) { 98 if (stat(fname, &s) == -1)
99 fprintf(stderr, "***\n");
100 fprintf(stderr, "*** Error: directory %s not found.\n", fname);
101 fprintf(stderr, "*** \tThis directory is configured in ~/.config/user-dirs.dirs.\n");
102 fprintf(stderr, "*** \tPlease create a Downloads directory.\n");
103 fprintf(stderr, "***\n");
104 free(fname); 99 free(fname);
105 return NULL; 100 goto errout;
106 }
107 101
108 char *rv; 102 char *rv;
109 if (asprintf(&rv, "whitelist ~/%s", ptr + 24) == -1) 103 if (asprintf(&rv, "whitelist ~/%s", ptr + 24) == -1)
110 errExit("asprintf"); 104 errExit("asprintf");
111 return rv; 105 return rv;
112 } 106 }
113 else { 107 else
114 fprintf(stderr, "***\n"); 108 goto errout;
115 fprintf(stderr, "*** Error: invalid XDG_DOWNLOAD_DIR entry in ~/.config/user-dirs.dirs.\n");
116 fprintf(stderr, "*** \tPlease specify a valid Downloads directory, example:\n");
117 fprintf(stderr, "***\n");
118 fprintf(stderr, "***\t\tXDG_DOWNLOAD_DIR=\"$HOME/Downloads\"\n");
119 fprintf(stderr, "***\n");
120 return NULL;
121 }
122 } 109 }
123 } 110 }
124 } 111 }
112
125 fclose(fp); 113 fclose(fp);
114 return NULL;
115
116errout:
117 fprintf(stderr, "***\n");
118 fprintf(stderr, "*** Error: Downloads directory was not found in user home.\n");
119 fprintf(stderr, "*** \tAny files saved by the program, will be lost when the sandbox is closed.\n");
120 fprintf(stderr, "***\n");
126 121
127 return NULL; 122 return NULL;
128} 123}
@@ -157,10 +152,8 @@ static int mkpath(const char* path, mode_t mode) {
157 } 152 }
158 } 153 }
159 else { 154 else {
160 if (chmod(file_path, mode) == -1) 155 if (set_perms(file_path, uid, gid, mode))
161 errExit("chmod"); 156 errExit("set_perms");
162 if (chown(file_path, uid, gid) == -1)
163 errExit("chown");
164 done = 1; 157 done = 1;
165 } 158 }
166 159
@@ -181,66 +174,73 @@ static void whitelist_path(ProfileEntry *entry) {
181 char *wfile = NULL; 174 char *wfile = NULL;
182 175
183 if (entry->home_dir) { 176 if (entry->home_dir) {
184 fname = path + strlen(cfg.homedir); 177 if (strncmp(path, cfg.homedir, strlen(cfg.homedir)) == 0) {
185 if (*fname == '\0') { 178 fname = path + strlen(cfg.homedir);
186 fprintf(stderr, "Error: file %s is not in user home directory, exiting...\n", path); 179 if (*fname == '\0')
187 exit(1); 180 goto errexit;
188 } 181 }
182 else
183 fname = path;
189 184
190 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_HOME_USER_DIR, fname) == -1) 185 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_HOME_USER_DIR, fname) == -1)
191 errExit("asprintf"); 186 errExit("asprintf");
192 } 187 }
193 else if (entry->tmp_dir) { 188 else if (entry->tmp_dir) {
194 fname = path + 4; // strlen("/tmp") 189 fname = path + 4; // strlen("/tmp")
195 if (*fname == '\0') { 190 if (*fname == '\0')
196 fprintf(stderr, "Error: file %s is not in /tmp directory, exiting...\n", path); 191 goto errexit;
197 exit(1);
198 }
199 192
200 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_TMP_DIR, fname) == -1) 193 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_TMP_DIR, fname) == -1)
201 errExit("asprintf"); 194 errExit("asprintf");
202 } 195 }
203 else if (entry->media_dir) { 196 else if (entry->media_dir) {
204 fname = path + 6; // strlen("/media") 197 fname = path + 6; // strlen("/media")
205 if (*fname == '\0') { 198 if (*fname == '\0')
206 fprintf(stderr, "Error: file %s is not in /media directory, exiting...\n", path); 199 goto errexit;
207 exit(1);
208 }
209 200
210 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_MEDIA_DIR, fname) == -1) 201 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_MEDIA_DIR, fname) == -1)
211 errExit("asprintf"); 202 errExit("asprintf");
212 } 203 }
204 else if (entry->mnt_dir) {
205 fname = path + 4; // strlen("/mnt")
206 if (*fname == '\0')
207 goto errexit;
208
209 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_MNT_DIR, fname) == -1)
210 errExit("asprintf");
211 }
213 else if (entry->var_dir) { 212 else if (entry->var_dir) {
214 fname = path + 4; // strlen("/var") 213 fname = path + 4; // strlen("/var")
215 if (*fname == '\0') { 214 if (*fname == '\0')
216 fprintf(stderr, "Error: file %s is not in /var directory, exiting...\n", path); 215 goto errexit;
217 exit(1);
218 }
219 216
220 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_VAR_DIR, fname) == -1) 217 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_VAR_DIR, fname) == -1)
221 errExit("asprintf"); 218 errExit("asprintf");
222 } 219 }
223 else if (entry->dev_dir) { 220 else if (entry->dev_dir) {
224 fname = path + 4; // strlen("/dev") 221 fname = path + 4; // strlen("/dev")
225 if (*fname == '\0') { 222 if (*fname == '\0')
226 fprintf(stderr, "Error: file %s is not in /dev directory, exiting...\n", path); 223 goto errexit;
227 exit(1);
228 }
229 224
230 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_DEV_DIR, fname) == -1) 225 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_DEV_DIR, fname) == -1)
231 errExit("asprintf"); 226 errExit("asprintf");
232 } 227 }
233 else if (entry->opt_dir) { 228 else if (entry->opt_dir) {
234 fname = path + 4; // strlen("/opt") 229 fname = path + 4; // strlen("/opt")
235 if (*fname == '\0') { 230 if (*fname == '\0')
236 fprintf(stderr, "Error: file %s is not in /opt directory, exiting...\n", path); 231 goto errexit;
237 exit(1);
238 }
239 232
240 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_OPT_DIR, fname) == -1) 233 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_OPT_DIR, fname) == -1)
241 errExit("asprintf"); 234 errExit("asprintf");
242 } 235 }
236 else if (entry->srv_dir) {
237 fname = path + 4; // strlen("/srv")
238 if (*fname == '\0')
239 goto errexit;
243 240
241 if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_SRV_DIR, fname) == -1)
242 errExit("asprintf");
243 }
244 // check if the file exists 244 // check if the file exists
245 struct stat s; 245 struct stat s;
246 if (wfile && stat(wfile, &s) == 0) { 246 if (wfile && stat(wfile, &s) == 0) {
@@ -248,9 +248,6 @@ static void whitelist_path(ProfileEntry *entry) {
248 printf("Whitelisting %s\n", path); 248 printf("Whitelisting %s\n", path);
249 } 249 }
250 else { 250 else {
251 if (arg_debug || arg_debug_whitelists) {
252 fprintf(stderr, "Warning (whitelisting): %s is an invalid file, skipping...\n", path);
253 }
254 return; 251 return;
255 } 252 }
256 253
@@ -267,26 +264,31 @@ static void whitelist_path(ProfileEntry *entry) {
267 264
268 // process regular file 265 // process regular file
269 else { 266 else {
270 // create an empty file 267 if (access(path, R_OK)) {
271 FILE *fp = fopen(path, "w"); 268 // create an empty file
272 if (!fp) { 269 FILE *fp = fopen(path, "w");
273 fprintf(stderr, "Error: cannot create empty file in home directory\n"); 270 if (!fp) {
274 exit(1); 271 fprintf(stderr, "Error: cannot create empty file in home directory\n");
272 exit(1);
273 }
274 // set file properties
275 SET_PERMS_STREAM(fp, s.st_uid, s.st_gid, s.st_mode);
276 fclose(fp);
275 } 277 }
276 fclose(fp); 278 else
279 return; // the file is already present
277 } 280 }
278 281
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 282 // mount
286 if (mount(wfile, path, NULL, MS_BIND|MS_REC, NULL) < 0) 283 if (mount(wfile, path, NULL, MS_BIND|MS_REC, NULL) < 0)
287 errExit("mount bind"); 284 errExit("mount bind");
288 285
289 free(wfile); 286 free(wfile);
287 return;
288
289errexit:
290 fprintf(stderr, "Error: file %s is not in the whitelisted directory\n", path);
291 exit(1);
290} 292}
291 293
292 294
@@ -302,10 +304,11 @@ void fs_whitelist(void) {
302 int home_dir = 0; // /home/user directory flag 304 int home_dir = 0; // /home/user directory flag
303 int tmp_dir = 0; // /tmp directory flag 305 int tmp_dir = 0; // /tmp directory flag
304 int media_dir = 0; // /media directory flag 306 int media_dir = 0; // /media directory flag
307 int mnt_dir = 0; // /mnt directory flag
305 int var_dir = 0; // /var directory flag 308 int var_dir = 0; // /var directory flag
306 int dev_dir = 0; // /dev directory flag 309 int dev_dir = 0; // /dev directory flag
307 int opt_dir = 0; // /opt directory flag 310 int opt_dir = 0; // /opt directory flag
308 311 int srv_dir = 0; // /srv directory flag
309 // verify whitelist files, extract symbolic links, etc. 312 // verify whitelist files, extract symbolic links, etc.
310 while (entry) { 313 while (entry) {
311 // handle only whitelist commands 314 // handle only whitelist commands
@@ -331,6 +334,8 @@ void fs_whitelist(void) {
331 } 334 }
332 335
333 // replace ~/ or ${HOME} into /home/username 336 // replace ~/ or ${HOME} into /home/username
337// if (new_name)
338// free(new_name);
334 new_name = expand_home(entry->data + 10, cfg.homedir); 339 new_name = expand_home(entry->data + 10, cfg.homedir);
335 assert(new_name); 340 assert(new_name);
336 if (arg_debug) 341 if (arg_debug)
@@ -367,13 +372,17 @@ void fs_whitelist(void) {
367 tmp_dir = 1; 372 tmp_dir = 1;
368 else if (strncmp(new_name, "/media/", 7) == 0) 373 else if (strncmp(new_name, "/media/", 7) == 0)
369 media_dir = 1; 374 media_dir = 1;
375 else if (strncmp(new_name, "/mnt/", 5) == 0)
376 mnt_dir = 1;
370 else if (strncmp(new_name, "/var/", 5) == 0) 377 else if (strncmp(new_name, "/var/", 5) == 0)
371 var_dir = 1; 378 var_dir = 1;
372 else if (strncmp(new_name, "/dev/", 5) == 0) 379 else if (strncmp(new_name, "/dev/", 5) == 0)
373 dev_dir = 1; 380 dev_dir = 1;
374 else if (strncmp(new_name, "/opt/", 5) == 0) 381 else if (strncmp(new_name, "/opt/", 5) == 0)
375 opt_dir = 1; 382 opt_dir = 1;
376 383 else if (strncmp(new_name, "/srv/", 5) == 0)
384 opt_dir = 1;
385
377 continue; 386 continue;
378 } 387 }
379 388
@@ -390,12 +399,16 @@ void fs_whitelist(void) {
390 399
391 entry->home_dir = 1; 400 entry->home_dir = 1;
392 home_dir = 1; 401 home_dir = 1;
402 if (arg_debug || arg_debug_whitelists)
403 fprintf(stderr, "Debug %d: fname #%s#, cfg.homedir #%s#\n",
404 __LINE__, fname, cfg.homedir);
405
393 // both path and absolute path are under /home 406 // both path and absolute path are under /home
394 if (strncmp(fname, cfg.homedir, strlen(cfg.homedir)) != 0) { 407 if (strncmp(fname, cfg.homedir, strlen(cfg.homedir)) != 0) {
395 if (arg_debug) 408 // check if the file is owned by the user
396 fprintf(stderr, "Debug %d: fname #%s#, cfg.homedir #%s#\n", 409 struct stat s;
397 __LINE__, fname, cfg.homedir); 410 if (stat(fname, &s) == 0 && s.st_uid != getuid())
398 goto errexit; 411 goto errexit;
399 } 412 }
400 } 413 }
401 else if (strncmp(new_name, "/tmp/", 5) == 0) { 414 else if (strncmp(new_name, "/tmp/", 5) == 0) {
@@ -403,8 +416,6 @@ void fs_whitelist(void) {
403 tmp_dir = 1; 416 tmp_dir = 1;
404 // both path and absolute path are under /tmp 417 // both path and absolute path are under /tmp
405 if (strncmp(fname, "/tmp/", 5) != 0) { 418 if (strncmp(fname, "/tmp/", 5) != 0) {
406 if (arg_debug)
407 fprintf(stderr, "Debug %d: fname #%s#\n", __LINE__, fname);
408 goto errexit; 419 goto errexit;
409 } 420 }
410 } 421 }
@@ -413,8 +424,14 @@ void fs_whitelist(void) {
413 media_dir = 1; 424 media_dir = 1;
414 // both path and absolute path are under /media 425 // both path and absolute path are under /media
415 if (strncmp(fname, "/media/", 7) != 0) { 426 if (strncmp(fname, "/media/", 7) != 0) {
416 if (arg_debug) 427 goto errexit;
417 fprintf(stderr, "Debug %d: fname #%s#\n", __LINE__, fname); 428 }
429 }
430 else if (strncmp(new_name, "/mnt/", 5) == 0) {
431 entry->mnt_dir = 1;
432 mnt_dir = 1;
433 // both path and absolute path are under /mnt
434 if (strncmp(fname, "/mnt/", 5) != 0) {
418 goto errexit; 435 goto errexit;
419 } 436 }
420 } 437 }
@@ -428,8 +445,6 @@ void fs_whitelist(void) {
428 else if (strcmp(new_name, "/var/lock")== 0) 445 else if (strcmp(new_name, "/var/lock")== 0)
429 ; 446 ;
430 else if (strncmp(fname, "/var/", 5) != 0) { 447 else if (strncmp(fname, "/var/", 5) != 0) {
431 if (arg_debug)
432 fprintf(stderr, "Debug %d: fname #%s#\n", __LINE__, fname);
433 goto errexit; 448 goto errexit;
434 } 449 }
435 } 450 }
@@ -438,8 +453,6 @@ void fs_whitelist(void) {
438 dev_dir = 1; 453 dev_dir = 1;
439 // both path and absolute path are under /dev 454 // both path and absolute path are under /dev
440 if (strncmp(fname, "/dev/", 5) != 0) { 455 if (strncmp(fname, "/dev/", 5) != 0) {
441 if (arg_debug)
442 fprintf(stderr, "Debug %d: fname #%s#\n", __LINE__, fname);
443 goto errexit; 456 goto errexit;
444 } 457 }
445 } 458 }
@@ -448,14 +461,18 @@ void fs_whitelist(void) {
448 opt_dir = 1; 461 opt_dir = 1;
449 // both path and absolute path are under /dev 462 // both path and absolute path are under /dev
450 if (strncmp(fname, "/opt/", 5) != 0) { 463 if (strncmp(fname, "/opt/", 5) != 0) {
451 if (arg_debug) 464 goto errexit;
452 fprintf(stderr, "Debug %d: fname #%s#\n", __LINE__, fname); 465 }
466 }
467 else if (strncmp(new_name, "/srv/", 5) == 0) {
468 entry->srv_dir = 1;
469 srv_dir = 1;
470 // both path and absolute path are under /srv
471 if (strncmp(fname, "/srv/", 5) != 0) {
453 goto errexit; 472 goto errexit;
454 } 473 }
455 } 474 }
456 else { 475 else {
457 if (arg_debug)
458 fprintf(stderr, "Debug %d: \n", __LINE__);
459 goto errexit; 476 goto errexit;
460 } 477 }
461 478
@@ -480,21 +497,10 @@ void fs_whitelist(void) {
480 entry = entry->next; 497 entry = entry->next;
481 } 498 }
482 499
483 // create mount points
484 fs_build_mnt_dir();
485
486
487 // /home/user 500 // /home/user
488 if (home_dir) { 501 if (home_dir) {
489 // keep a copy of real home dir in RUN_WHITELIST_HOME_USER_DIR 502 // keep a copy of real home dir in RUN_WHITELIST_HOME_USER_DIR
490 int rv = mkdir(RUN_WHITELIST_HOME_USER_DIR, 0755); 503 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) 504 if (mount(cfg.homedir, RUN_WHITELIST_HOME_USER_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
499 errExit("mount bind"); 505 errExit("mount bind");
500 506
@@ -504,15 +510,8 @@ void fs_whitelist(void) {
504 510
505 // /tmp mountpoint 511 // /tmp mountpoint
506 if (tmp_dir) { 512 if (tmp_dir) {
507 // keep a copy of real /tmp directory in WHITELIST_TMP_DIR 513 // keep a copy of real /tmp directory in
508 int rv = mkdir(RUN_WHITELIST_TMP_DIR, 1777); 514 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) 515 if (mount("/tmp", RUN_WHITELIST_TMP_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
517 errExit("mount bind"); 516 errExit("mount bind");
518 517
@@ -526,37 +525,51 @@ void fs_whitelist(void) {
526 525
527 // /media mountpoint 526 // /media mountpoint
528 if (media_dir) { 527 if (media_dir) {
529 // keep a copy of real /media directory in RUN_WHITELIST_MEDIA_DIR 528 // some distros don't have a /media directory
530 int rv = mkdir(RUN_WHITELIST_MEDIA_DIR, 0755); 529 struct stat s;
531 if (rv == -1) 530 if (stat("/media", &s) == 0) {
532 errExit("mkdir"); 531 // keep a copy of real /media directory in RUN_WHITELIST_MEDIA_DIR
533 if (chown(RUN_WHITELIST_MEDIA_DIR, 0, 0) < 0) 532 mkdir_attr(RUN_WHITELIST_MEDIA_DIR, 0755, 0, 0);
534 errExit("chown"); 533 if (mount("/media", RUN_WHITELIST_MEDIA_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
535 if (chmod(RUN_WHITELIST_MEDIA_DIR, 0755) < 0) 534 errExit("mount bind");
536 errExit("chmod");
537 535
538 if (mount("/media", RUN_WHITELIST_MEDIA_DIR, NULL, MS_BIND|MS_REC, NULL) < 0) 536 // mount tmpfs on /media
539 errExit("mount bind"); 537 if (arg_debug || arg_debug_whitelists)
540 538 printf("Mounting tmpfs on /media directory\n");
541 // mount tmpfs on /media 539 if (mount("tmpfs", "/media", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
542 if (arg_debug || arg_debug_whitelists) 540 errExit("mounting tmpfs on /media");
543 printf("Mounting tmpfs on /media directory\n"); 541 fs_logger("tmpfs /media");
544 if (mount("tmpfs", "/media", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0) 542 }
545 errExit("mounting tmpfs on /media"); 543 else
546 fs_logger("tmpfs /media"); 544 media_dir = 0;
547 } 545 }
548 546
547 // /mnt mountpoint
548 if (mnt_dir) {
549 // check if /mnt directory exists
550 struct stat s;
551 if (stat("/mnt", &s) == 0) {
552 // keep a copy of real /mnt directory in RUN_WHITELIST_MNT_DIR
553 mkdir_attr(RUN_WHITELIST_MNT_DIR, 0755, 0, 0);
554 if (mount("/mnt", RUN_WHITELIST_MNT_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
555 errExit("mount bind");
556
557 // mount tmpfs on /mnt
558 if (arg_debug || arg_debug_whitelists)
559 printf("Mounting tmpfs on /mnt directory\n");
560 if (mount("tmpfs", "/mnt", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
561 errExit("mounting tmpfs on /mnt");
562 fs_logger("tmpfs /mnt");
563 }
564 else
565 mnt_dir = 0;
566 }
567
568
549 // /var mountpoint 569 // /var mountpoint
550 if (var_dir) { 570 if (var_dir) {
551 // keep a copy of real /var directory in RUN_WHITELIST_VAR_DIR 571 // keep a copy of real /var directory in RUN_WHITELIST_VAR_DIR
552 int rv = mkdir(RUN_WHITELIST_VAR_DIR, 0755); 572 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) 573 if (mount("/var", RUN_WHITELIST_VAR_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
561 errExit("mount bind"); 574 errExit("mount bind");
562 575
@@ -571,14 +584,7 @@ void fs_whitelist(void) {
571 // /dev mountpoint 584 // /dev mountpoint
572 if (dev_dir) { 585 if (dev_dir) {
573 // keep a copy of real /dev directory in RUN_WHITELIST_DEV_DIR 586 // keep a copy of real /dev directory in RUN_WHITELIST_DEV_DIR
574 int rv = mkdir(RUN_WHITELIST_DEV_DIR, 0755); 587 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) 588 if (mount("/dev", RUN_WHITELIST_DEV_DIR, NULL, MS_BIND|MS_REC, "mode=755,gid=0") < 0)
583 errExit("mount bind"); 589 errExit("mount bind");
584 590
@@ -593,14 +599,7 @@ void fs_whitelist(void) {
593 // /opt mountpoint 599 // /opt mountpoint
594 if (opt_dir) { 600 if (opt_dir) {
595 // keep a copy of real /opt directory in RUN_WHITELIST_OPT_DIR 601 // keep a copy of real /opt directory in RUN_WHITELIST_OPT_DIR
596 int rv = mkdir(RUN_WHITELIST_OPT_DIR, 0755); 602 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) 603 if (mount("/opt", RUN_WHITELIST_OPT_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
605 errExit("mount bind"); 604 errExit("mount bind");
606 605
@@ -612,6 +611,29 @@ void fs_whitelist(void) {
612 fs_logger("tmpfs /opt"); 611 fs_logger("tmpfs /opt");
613 } 612 }
614 613
614 // /srv mountpoint
615 if (srv_dir) {
616 // check if /srv directory exists
617 struct stat s;
618 if (stat("/srv", &s) == 0) {
619 // keep a copy of real /srv directory in RUN_WHITELIST_SRV_DIR
620 mkdir_attr(RUN_WHITELIST_SRV_DIR, 0755, 0, 0);
621 if (mount("/srv", RUN_WHITELIST_SRV_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
622 errExit("mount bind");
623
624 // mount tmpfs on /srv
625 if (arg_debug || arg_debug_whitelists)
626 printf("Mounting tmpfs on /srv directory\n");
627 if (mount("tmpfs", "/srv", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
628 errExit("mounting tmpfs on /srv");
629 fs_logger("tmpfs /srv");
630 }
631 else
632 srv_dir = 0;
633 }
634
635
636
615 // go through profile rules again, and interpret whitelist commands 637 // go through profile rules again, and interpret whitelist commands
616 entry = cfg.profile; 638 entry = cfg.profile;
617 while (entry) { 639 while (entry) {
@@ -696,6 +718,20 @@ void fs_whitelist(void) {
696 fs_logger2("tmpfs", RUN_WHITELIST_MEDIA_DIR); 718 fs_logger2("tmpfs", RUN_WHITELIST_MEDIA_DIR);
697 } 719 }
698 720
721 // mask the real /mnt directory, currently mounted on RUN_WHITELIST_MNT_DIR
722 if (mnt_dir) {
723 if (mount("tmpfs", RUN_WHITELIST_MNT_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
724 errExit("mount tmpfs");
725 fs_logger2("tmpfs", RUN_WHITELIST_MNT_DIR);
726 }
727
728 // mask the real /srv directory, currently mounted on RUN_WHITELIST_SRV_DIR
729 if (srv_dir) {
730 if (mount("tmpfs", RUN_WHITELIST_SRV_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
731 errExit("mount tmpfs");
732 fs_logger2("tmpfs", RUN_WHITELIST_SRV_DIR);
733 }
734
699 if (new_name) 735 if (new_name)
700 free(new_name); 736 free(new_name);
701 737
diff --git a/src/firejail/join.c b/src/firejail/join.c
index 98e140ce4..bcf951f33 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,24 +273,17 @@ 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
313 // fix qt 4.8
314 if (setenv("QT_X11_NO_MITSHM", "1", 1) < 0)
315 errExit("setenv");
316 if (setenv("container", "firejail", 1) < 0) // LXC sets container=lxc,
317 errExit("setenv");
318 287
319 // mount user namespace or drop privileges 288 // mount user namespace or drop privileges
320 if (arg_noroot) { // not available for uid 0 289 if (arg_noroot) { // not available for uid 0
@@ -322,76 +291,61 @@ void join(pid_t pid, int argc, char **argv, int index) {
322 printf("Joining user namespace\n"); 291 printf("Joining user namespace\n");
323 if (join_namespace(1, "user")) 292 if (join_namespace(1, "user"))
324 exit(1); 293 exit(1);
294
295 // user namespace resets capabilities
296 // set caps filter
297 if (apply_caps == 1) // not available for uid 0
298 caps_set(caps);
325 } 299 }
326 else 300 else
327 drop_privs(arg_nogroups); // nogroups not available for uid 0 301 drop_privs(arg_nogroups); // nogroups not available for uid 0
328 302
329 // set prompt color to green
330 //export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] '
331 if (setenv("PROMPT_COMMAND", "export PS1=\"\\[\\e[1;32m\\][\\u@\\h \\W]\\$\\[\\e[0m\\] \"", 1) < 0)
332 errExit("setenv");
333 303
334 // run cmdline trough /bin/bash 304 // set nice
305 if (arg_nice) {
306 errno = 0;
307 int rv = nice(cfg.nice);
308 (void) rv;
309 if (errno) {
310 fprintf(stderr, "Warning: cannot set nice value\n");
311 errno = 0;
312 }
313 }
314
315 env_defaults();
335 if (cfg.command_line == NULL) { 316 if (cfg.command_line == NULL) {
336 struct stat s; 317 assert(cfg.shell);
318 cfg.command_line = cfg.shell;
319 cfg.window_title = cfg.shell;
320 }
337 321
338 // replace the process with a shell 322 int cwd = 0;
339 if (stat("/bin/bash", &s) == 0) 323 if (cfg.cwd) {
340 execlp("/bin/bash", "/bin/bash", NULL); 324 if (chdir(cfg.cwd) == 0)
341 else if (stat("/usr/bin/zsh", &s) == 0) 325 cwd = 1;
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 } 326 }
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 327
373 char *arg[5]; 328 if (!cwd) {
374 arg[0] = "/bin/bash"; 329 if (chdir("/") < 0)
375 arg[1] = "-c"; 330 errExit("chdir");
376 if (arg_debug) 331 if (cfg.homedir) {
377 printf("Starting %s\n", cfg.command_line); 332 struct stat s;
378 if (!arg_doubledash) { 333 if (stat(cfg.homedir, &s) == 0) {
379 arg[2] = cfg.command_line; 334 /* coverity[toctou] */
380 arg[3] = NULL; 335 if (chdir(cfg.homedir) < 0)
381 } 336 errExit("chdir");
382 else { 337 }
383 arg[2] = "--";
384 arg[3] = cfg.command_line;
385 arg[4] = NULL;
386 } 338 }
387 execvp("/bin/bash", arg);
388 } 339 }
389 340
341 start_application();
342
390 // it will never get here!!! 343 // it will never get here!!!
391 } 344 }
392 345
393 // wait for the child to finish 346 // wait for the child to finish
394 waitpid(child, NULL, 0); 347 waitpid(child, NULL, 0);
348 flush_stdin();
395 exit(0); 349 exit(0);
396} 350}
397 351
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..77eb35f97 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 } 239 }
238 else if (*path == '~') { 240 if (arg_debug) {
239 if (asprintf(&fname, "%s%s", cfg.homedir, path + 1) == -1) 241 printf("file1 %s\n", fname1);
240 errExit("asprintf"); 242 printf("file2 %s\n", fname2);
241 } 243 }
242 else { 244
243 fprintf(stderr, "Error: Cannot access %s\n", path);
244 exit(1);
245 }
246
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,43 +255,39 @@ 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 // check access
262 if (access(fname1, R_OK) == -1) {
263 fprintf(stderr, "Error: Cannot access %s\n", fname1);
264 exit(1);
265 }
266 /* coverity[toctou] */
267 char *rp = realpath(fname1, NULL);
268 if (!rp) {
269 fprintf(stderr, "Error: Cannot access %s\n", fname1);
263 exit(1); 270 exit(1);
264 } 271 }
272 if (arg_debug)
273 printf("realpath %s\n", rp);
274
265 275
266 // list directory contents 276 // list directory contents
267 struct stat s; 277 struct stat s;
268 if (stat(fname, &s) == -1) { 278 if (stat(rp, &s) == -1) {
269 fprintf(stderr, "Error: Cannot access %s\n", fname); 279 fprintf(stderr, "Error: Cannot access %s\n", rp);
270 exit(1); 280 exit(1);
271 } 281 }
272 if (S_ISDIR(s.st_mode)) { 282 if (S_ISDIR(s.st_mode)) {
273 char *rp = realpath(fname, NULL);
274 if (!rp) {
275 fprintf(stderr, "Error: Cannot access %s\n", fname);
276 exit(1);
277 }
278 if (arg_debug)
279 printf("realpath %s\n", rp);
280
281 char *dir; 283 char *dir;
282 if (asprintf(&dir, "%s/", rp) == -1) 284 if (asprintf(&dir, "%s/", rp) == -1)
283 errExit("asprintf"); 285 errExit("asprintf");
284 286
285 print_directory(dir); 287 print_directory(dir);
286 free(rp);
287 free(dir); 288 free(dir);
288 } 289 }
289 else { 290 else {
290 char *rp = realpath(fname, NULL);
291 if (!rp) {
292 fprintf(stderr, "Error: Cannot access %s\n", fname);
293 exit(1);
294 }
295 if (arg_debug)
296 printf("realpath %s\n", rp);
297 char *split = strrchr(rp, '/'); 291 char *split = strrchr(rp, '/');
298 if (split) { 292 if (split) {
299 *split = '\0'; 293 *split = '\0';
@@ -302,25 +296,32 @@ void sandboxfs(int op, pid_t pid, const char *path) {
302 printf("path %s, file %s\n", rp, rp2); 296 printf("path %s, file %s\n", rp, rp2);
303 print_file_or_dir(rp, rp2, 1); 297 print_file_or_dir(rp, rp2, 1);
304 } 298 }
305 free(rp);
306 } 299 }
300 free(rp);
307 } 301 }
308 302
309 // get file from sandbox and store it in the current directory 303 // get file from sandbox and store it in the current directory
310 else if (op == SANDBOX_FS_GET) { 304 else if (op == SANDBOX_FS_GET) {
311 // check source file (sandbox) 305 char *src_fname =fname1;
312 char *src_fname; 306 char *dest_fname = strrchr(fname1, '/');
313 if (asprintf(&src_fname, "%s%s", rootdir, fname) == -1) 307 if (!dest_fname || *(++dest_fname) == '\0') {
314 errExit("asprintf"); 308 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); 309 exit(1);
320 } 310 }
311
312 EUID_ROOT();
313 if (arg_debug)
314 printf("copy %s to %s\n", src_fname, dest_fname);
315
316 // create a user-owned temporary file in /run/firejail directory
317 char tmp_fname[] = "/run/firejail/tmpget-XXXXXX";
318 int fd = mkstemp(tmp_fname);
319 if (fd != -1) {
320 SET_PERMS_FD(fd, getuid(), getgid(), 0600);
321 close(fd);
322 }
321 323
322 324 // copy the source file into the temporary file - we need to chroot
323 // try to open the source file - we need to chroot
324 pid_t child = fork(); 325 pid_t child = fork();
325 if (child < 0) 326 if (child < 0)
326 errExit("fork"); 327 errExit("fork");
@@ -334,55 +335,139 @@ void sandboxfs(int op, pid_t pid, const char *path) {
334 // drop privileges 335 // drop privileges
335 drop_privs(0); 336 drop_privs(0);
336 337
337 // try to read the file 338 // copy the file
338 if (access(fname, R_OK) == -1) { 339 if (copy_file(src_fname, tmp_fname, getuid(), getgid(), 0600))
339 fprintf(stderr, "Error: Cannot read %s\n", fname); 340 _exit(1);
340 exit(1); 341#ifdef HAVE_GCOV
341 } 342 __gcov_flush();
342 exit(0); 343#endif
344 _exit(0);
343 } 345 }
344 346
345 // wait for the child to finish 347 // wait for the child to finish
346 int status = 0; 348 int status = 0;
347 waitpid(child, &status, 0); 349 waitpid(child, &status, 0);
348 if (WIFEXITED(status) && WEXITSTATUS(status) == 0); 350 if (WIFEXITED(status) && WEXITSTATUS(status) == 0);
349 else 351 else {
352 unlink(tmp_fname);
350 exit(1); 353 exit(1);
351 EUID_USER(); 354 }
352 355
353 // check destination file (host) 356 // copy the temporary file into the destionation file
354 char *dest_fname = strrchr(fname, '/'); 357 child = fork();
355 if (!dest_fname || *(++dest_fname) == '\0') { 358 if (child < 0)
356 fprintf(stderr, "Error: invalid file name %s\n", fname); 359 errExit("fork");
360 if (child == 0) {
361 // drop privileges
362 drop_privs(0);
363
364 // copy the file
365 if (copy_file(tmp_fname, dest_fname, getuid(), getgid(), 0600))
366 _exit(1);
367#ifdef HAVE_GCOV
368 __gcov_flush();
369#endif
370 _exit(0);
371 }
372
373 // wait for the child to finish
374 status = 0;
375 waitpid(child, &status, 0);
376 if (WIFEXITED(status) && WEXITSTATUS(status) == 0);
377 else {
378 unlink(tmp_fname);
357 exit(1); 379 exit(1);
358 } 380 }
359 381
360 if (access(dest_fname, F_OK) == -1) { 382 // remove the temporary file
361 // try to create the file 383 unlink(tmp_fname);
362 FILE *fp = fopen(dest_fname, "w"); 384 EUID_USER();
363 if (!fp) { 385 }
364 fprintf(stderr, "Error: cannot create %s\n", dest_fname); 386 // get file from host and store it in the sandbox
365 exit(1); 387 else if (op == SANDBOX_FS_PUT && path2) {
366 } 388 char *src_fname =fname1;
367 fclose(fp); 389 char *dest_fname = fname2;
390
391 EUID_ROOT();
392 if (arg_debug)
393 printf("copy %s to %s\n", src_fname, dest_fname);
394
395 // create a user-owned temporary file in /run/firejail directory
396 char tmp_fname[] = "/run/firejail/tmpget-XXXXXX";
397 int fd = mkstemp(tmp_fname);
398 if (fd == -1) {
399 fprintf(stderr, "Error: cannot create temporary file %s\n", tmp_fname);
400 exit(1);
401 }
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..b25bad9f2 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
@@ -86,16 +88,33 @@ int arg_doubledash = 0; // double dash
86int arg_shell_none = 0; // run the program directly without a shell 88int arg_shell_none = 0; // run the program directly without a shell
87int arg_private_dev = 0; // private dev directory 89int arg_private_dev = 0; // private dev directory
88int arg_private_etc = 0; // private etc directory 90int arg_private_etc = 0; // private etc directory
91int arg_private_opt = 0; // private opt directory
92int arg_private_srv = 0; // private srv directory
89int arg_private_bin = 0; // private bin directory 93int arg_private_bin = 0; // private bin directory
90int arg_private_tmp = 0; // private tmp directory 94int arg_private_tmp = 0; // private tmp directory
91int arg_scan = 0; // arp-scan all interfaces 95int arg_scan = 0; // arp-scan all interfaces
92int arg_whitelist = 0; // whitelist commad 96int arg_whitelist = 0; // whitelist commad
93int arg_nosound = 0; // disable sound 97int arg_nosound = 0; // disable sound
98int arg_no3d; // disable 3d hardware acceleration
94int arg_quiet = 0; // no output for scripting 99int arg_quiet = 0; // no output for scripting
95int arg_join_network = 0; // join only the network namespace 100int arg_join_network = 0; // join only the network namespace
96int arg_join_filesystem = 0; // join only the mount namespace 101int arg_join_filesystem = 0; // join only the mount namespace
97int arg_nice = 0; // nice value configured 102int arg_nice = 0; // nice value configured
98int arg_ipc = 0; // enable ipc namespace 103int arg_ipc = 0; // enable ipc namespace
104int arg_writable_etc = 0; // writable etc
105int arg_writable_var = 0; // writable var
106int arg_appimage = 0; // appimage
107int arg_audit = 0; // audit
108char *arg_audit_prog = NULL; // audit
109int arg_apparmor = 0; // apparmor
110int arg_allow_debuggers = 0; // allow debuggers
111int arg_x11_block = 0; // block X11
112int arg_x11_xorg = 0; // use X11 security extention
113int arg_allusers = 0; // all user home directories visible
114int arg_machineid = 0; // preserve /etc/machine-id
115
116int login_shell = 0;
117
99 118
100int parent_to_child_fds[2]; 119int parent_to_child_fds[2];
101int child_to_parent_fds[2]; 120int child_to_parent_fds[2];
@@ -126,7 +145,8 @@ static void myexit(int rv) {
126 // delete sandbox files in shared memory 145 // delete sandbox files in shared memory
127 EUID_ROOT(); 146 EUID_ROOT();
128 clear_run_files(sandbox_pid); 147 clear_run_files(sandbox_pid);
129 148 appimage_clear();
149 flush_stdin();
130 exit(rv); 150 exit(rv);
131} 151}
132 152
@@ -141,20 +161,37 @@ static void my_handler(int s){
141 myexit(1); 161 myexit(1);
142} 162}
143 163
144// return 1 if error, 0 if a valid pid was found 164static pid_t extract_pid(const char *name) {
145static inline int read_pid(char *str, pid_t *pid) { 165 EUID_ASSERT();
166 if (!name || strlen(name) == 0) {
167 fprintf(stderr, "Error: invalid sandbox name\n");
168 exit(1);
169 }
170
171 pid_t pid;
172 EUID_ROOT();
173 if (name2pid(name, &pid)) {
174 fprintf(stderr, "Error: cannot find sandbox %s\n", name);
175 exit(1);
176 }
177 EUID_USER();
178 return pid;
179}
180
181
182static pid_t read_pid(const char *str) {
146 char *endptr; 183 char *endptr;
147 errno = 0; 184 errno = 0;
148 long int pidtmp = strtol(str, &endptr, 10); 185 long int pidtmp = strtol(str, &endptr, 10);
149 if ((errno == ERANGE && (pidtmp == LONG_MAX || pidtmp == LONG_MIN)) 186 if ((errno == ERANGE && (pidtmp == LONG_MAX || pidtmp == LONG_MIN))
150 || (errno != 0 && pidtmp == 0)) { 187 || (errno != 0 && pidtmp == 0)) {
151 return 1; 188 return extract_pid(str);
152 } 189 }
153 if (endptr == str) { 190 // endptr points to '\0' char in str if the entire string is valid
154 return 1; 191 if (endptr == NULL || endptr[0]!='\0') {
192 return extract_pid(str);
155 } 193 }
156 *pid = (pid_t)pidtmp; 194 return (pid_t)pidtmp;
157 return 0;
158} 195}
159 196
160// init configuration 197// init configuration
@@ -214,10 +251,8 @@ static void check_network(Bridge *br) {
214#ifdef HAVE_USERNS 251#ifdef HAVE_USERNS
215void check_user_namespace(void) { 252void check_user_namespace(void) {
216 EUID_ASSERT(); 253 EUID_ASSERT();
217 if (getuid() == 0) { 254 if (getuid() == 0)
218 fprintf(stderr, "Error: --noroot option cannot be used when starting the sandbox as root.\n"); 255 goto errout;
219 exit(1);
220 }
221 256
222 // test user namespaces available in the kernel 257 // test user namespaces available in the kernel
223 struct stat s1; 258 struct stat s1;
@@ -227,14 +262,27 @@ void check_user_namespace(void) {
227 stat("/proc/self/uid_map", &s2) == 0 && 262 stat("/proc/self/uid_map", &s2) == 0 &&
228 stat("/proc/self/gid_map", &s3) == 0) 263 stat("/proc/self/gid_map", &s3) == 0)
229 arg_noroot = 1; 264 arg_noroot = 1;
230 else { 265 else
231 fprintf(stderr, "Warning: user namespaces not available in the current kernel.\n"); 266 goto errout;
232 arg_noroot = 0; 267
233 } 268 return;
269
270errout:
271 if (!arg_quiet || arg_debug)
272 fprintf(stderr, "Warning: noroot option is not available\n");
273 arg_noroot = 0;
274
234} 275}
235#endif 276#endif
236 277
237// exit commands 278
279static void exit_err_feature(const char *feature) {
280 fprintf(stderr, "Error: %s feature is disabled in Firejail configuration file\n", feature);
281 exit(1);
282}
283
284// run independent commands and exit program
285// this function handles command line options such as --version and --help
238static void run_cmd_and_exit(int i, int argc, char **argv) { 286static void run_cmd_and_exit(int i, int argc, char **argv) {
239 EUID_ASSERT(); 287 EUID_ASSERT();
240 288
@@ -248,62 +296,54 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
248 } 296 }
249 else if (strcmp(argv[i], "--version") == 0) { 297 else if (strcmp(argv[i], "--version") == 0) {
250 printf("firejail version %s\n", VERSION); 298 printf("firejail version %s\n", VERSION);
251#ifndef HAVE_NETWORK 299 printf("\n");
252 printf("Networking support is disabled.\n"); 300 print_compiletime_support();
253#endif 301 printf("\n");
254#ifdef HAVE_NETWORK_RESTRICTED
255 printf("Networking support is allowed only to root user.\n");
256#endif
257#ifndef HAVE_USERNS
258 printf("User namespace support is disabled.\n");
259#endif
260#ifndef HAVE_SECCOMP
261 printf("Seccomp-bpf support is disabled.\n");
262#endif
263#ifndef HAVE_BIND
264 printf("Bind support is disabled.\n");
265#endif
266#ifndef HAVE_CHROOT
267 printf("Chroot support is disabled.\n");
268#endif
269#ifndef HAVE_X11
270 printf("X11 support is disabled.\n");
271#endif
272#ifndef HAVE_FILE_TRANSFER
273 printf("File transfer support is disabled.\n");
274#endif
275 exit(0); 302 exit(0);
276 } 303 }
304#ifdef HAVE_OVERLAYFS
305 else if (strcmp(argv[i], "--overlay-clean") == 0) {
306 if (checkcfg(CFG_OVERLAYFS)) {
307 char *path;
308 if (asprintf(&path, "%s/.firejail", cfg.homedir) == -1)
309 errExit("asprintf");
310 EUID_ROOT();
311 if (setreuid(0, 0) < 0 ||
312 setregid(0, 0) < 0)
313 errExit("setreuid/setregid");
314 errno = 0;
315 if (remove_directory(path))
316 errExit("remove_directory");
317 }
318 else
319 exit_err_feature("overlayfs");
320 exit(0);
321 }
322#endif
277#ifdef HAVE_X11 323#ifdef HAVE_X11
278 else if (strcmp(argv[i], "--x11") == 0) { 324 else if (strcmp(argv[i], "--x11") == 0) {
279 if (checkcfg(CFG_X11)) { 325 if (checkcfg(CFG_X11)) {
280 x11_start(argc, argv); 326 x11_start(argc, argv);
281 exit(0); 327 exit(0);
282 } 328 }
283 else { 329 else
284 fprintf(stderr, "Error: --x11 feature is disabled in Firejail configuration file\n"); 330 exit_err_feature("x11");
285 exit(1);
286 }
287 } 331 }
288 else if (strcmp(argv[i], "--x11=xpra") == 0) { 332 else if (strcmp(argv[i], "--x11=xpra") == 0) {
289 if (checkcfg(CFG_X11)) { 333 if (checkcfg(CFG_X11)) {
290 x11_start_xpra(argc, argv); 334 x11_start_xpra(argc, argv);
291 exit(0); 335 exit(0);
292 } 336 }
293 else { 337 else
294 fprintf(stderr, "Error: --x11 feature is disabled in Firejail configuration file\n"); 338 exit_err_feature("x11");
295 exit(1);
296 }
297 } 339 }
298 else if (strcmp(argv[i], "--x11=xephyr") == 0) { 340 else if (strcmp(argv[i], "--x11=xephyr") == 0) {
299 if (checkcfg(CFG_X11)) { 341 if (checkcfg(CFG_X11)) {
300 x11_start_xephyr(argc, argv); 342 x11_start_xephyr(argc, argv);
301 exit(0); 343 exit(0);
302 } 344 }
303 else { 345 else
304 fprintf(stderr, "Error: --x11 feature is disabled in Firejail configuration file\n"); 346 exit_err_feature("x11");
305 exit(1);
306 }
307 } 347 }
308#endif 348#endif
309#ifdef HAVE_NETWORK 349#ifdef HAVE_NETWORK
@@ -361,16 +401,11 @@ 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 }
370 else {
371 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n");
372 exit(1);
373 } 406 }
407 else
408 exit_err_feature("networking");
374 exit(0); 409 exit(0);
375 } 410 }
376#endif 411#endif
@@ -380,93 +415,68 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
380#ifdef HAVE_SECCOMP 415#ifdef HAVE_SECCOMP
381 else if (strcmp(argv[i], "--debug-syscalls") == 0) { 416 else if (strcmp(argv[i], "--debug-syscalls") == 0) {
382 if (checkcfg(CFG_SECCOMP)) { 417 if (checkcfg(CFG_SECCOMP)) {
383 syscall_print(); 418 int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FSECCOMP, "debug-syscalls");
384 exit(0); 419 exit(rv);
385 }
386 else {
387 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
388 exit(1);
389 } 420 }
421 else
422 exit_err_feature("seccomp");
390 } 423 }
391 else if (strcmp(argv[i], "--debug-errnos") == 0) { 424 else if (strcmp(argv[i], "--debug-errnos") == 0) {
392 if (checkcfg(CFG_SECCOMP)) { 425 if (checkcfg(CFG_SECCOMP)) {
393 errno_print(); 426 int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FSECCOMP, "debug-errnos");
394 } 427 exit(rv);
395 else {
396 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
397 exit(1);
398 } 428 }
429 else
430 exit_err_feature("seccomp");
399 exit(0); 431 exit(0);
400 } 432 }
401 else if (strncmp(argv[i], "--seccomp.print=", 16) == 0) { 433 else if (strncmp(argv[i], "--seccomp.print=", 16) == 0) {
402 if (checkcfg(CFG_SECCOMP)) { 434 if (checkcfg(CFG_SECCOMP)) {
403 // print seccomp filter for a sandbox specified by pid or by name 435 // print seccomp filter for a sandbox specified by pid or by name
404 pid_t pid; 436 pid_t pid = read_pid(argv[i] + 16);
405 if (read_pid(argv[i] + 16, &pid) == 0) 437 seccomp_print_filter(pid);
406 seccomp_print_filter(pid);
407 else
408 seccomp_print_filter_name(argv[i] + 16);
409 }
410 else {
411 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
412 exit(1);
413 } 438 }
439 else
440 exit_err_feature("seccomp");
414 exit(0); 441 exit(0);
415 } 442 }
416 else if (strcmp(argv[i], "--debug-protocols") == 0) { 443 else if (strcmp(argv[i], "--debug-protocols") == 0) {
417 protocol_list(); 444 int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FSECCOMP, "debug-protocols");
418 exit(0); 445 exit(rv);
419 } 446 }
420 else if (strncmp(argv[i], "--protocol.print=", 17) == 0) { 447 else if (strncmp(argv[i], "--protocol.print=", 17) == 0) {
421 if (checkcfg(CFG_SECCOMP)) { 448 if (checkcfg(CFG_SECCOMP)) {
422 // print seccomp filter for a sandbox specified by pid or by name 449 // print seccomp filter for a sandbox specified by pid or by name
423 pid_t pid; 450 pid_t pid = read_pid(argv[i] + 17);
424 if (read_pid(argv[i] + 17, &pid) == 0) 451 protocol_print_filter(pid);
425 protocol_print_filter(pid);
426 else
427 protocol_print_filter_name(argv[i] + 17);
428 }
429 else {
430 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
431 exit(1);
432 } 452 }
453 else
454 exit_err_feature("seccomp");
433 exit(0); 455 exit(0);
434 } 456 }
435#endif 457#endif
436 else if (strncmp(argv[i], "--cpu.print=", 12) == 0) { 458 else if (strncmp(argv[i], "--cpu.print=", 12) == 0) {
437 // join sandbox by pid or by name 459 // join sandbox by pid or by name
438 pid_t pid; 460 pid_t pid = read_pid(argv[i] + 12);
439 if (read_pid(argv[i] + 12, &pid) == 0) 461 cpu_print_filter(pid);
440 cpu_print_filter(pid);
441 else
442 cpu_print_filter_name(argv[i] + 12);
443 exit(0); 462 exit(0);
444 } 463 }
445 else if (strncmp(argv[i], "--caps.print=", 13) == 0) { 464 else if (strncmp(argv[i], "--caps.print=", 13) == 0) {
446 // join sandbox by pid or by name 465 // join sandbox by pid or by name
447 pid_t pid; 466 pid_t pid = read_pid(argv[i] + 13);
448 if (read_pid(argv[i] + 13, &pid) == 0) 467 caps_print_filter(pid);
449 caps_print_filter(pid);
450 else
451 caps_print_filter_name(argv[i] + 13);
452 exit(0); 468 exit(0);
453 } 469 }
454 else if (strncmp(argv[i], "--fs.print=", 11) == 0) { 470 else if (strncmp(argv[i], "--fs.print=", 11) == 0) {
455 // join sandbox by pid or by name 471 // join sandbox by pid or by name
456 pid_t pid; 472 pid_t pid = read_pid(argv[i] + 11);
457 if (read_pid(argv[i] + 11, &pid) == 0) 473 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); 474 exit(0);
462 } 475 }
463 else if (strncmp(argv[i], "--dns.print=", 12) == 0) { 476 else if (strncmp(argv[i], "--dns.print=", 12) == 0) {
464 // join sandbox by pid or by name 477 // join sandbox by pid or by name
465 pid_t pid; 478 pid_t pid = read_pid(argv[i] + 12);
466 if (read_pid(argv[i] + 12, &pid) == 0) 479 net_dns_print(pid);
467 net_dns_print(pid);
468 else
469 net_dns_print_name(argv[i] + 12);
470 exit(0); 480 exit(0);
471 } 481 }
472 else if (strcmp(argv[i], "--debug-caps") == 0) { 482 else if (strcmp(argv[i], "--debug-caps") == 0) {
@@ -474,27 +484,42 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
474 exit(0); 484 exit(0);
475 } 485 }
476 else if (strcmp(argv[i], "--list") == 0) { 486 else if (strcmp(argv[i], "--list") == 0) {
477 list(); 487 if (pid_hidepid())
488 sbox_run(SBOX_ROOT| SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FIREMON, "--list");
489 else
490 sbox_run(SBOX_USER| SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FIREMON, "--list");
478 exit(0); 491 exit(0);
479 } 492 }
480 else if (strcmp(argv[i], "--tree") == 0) { 493 else if (strcmp(argv[i], "--tree") == 0) {
481 tree(); 494 if (pid_hidepid())
495 sbox_run(SBOX_ROOT | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FIREMON, "--tree");
496 else
497 sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FIREMON, "--tree");
482 exit(0); 498 exit(0);
483 } 499 }
484 else if (strcmp(argv[i], "--top") == 0) { 500 else if (strcmp(argv[i], "--top") == 0) {
485 top(); 501 if (pid_hidepid())
502 sbox_run(SBOX_ROOT | SBOX_CAPS_NONE | SBOX_SECCOMP | SBOX_ALLOW_STDIN,
503 2, PATH_FIREMON, "--top");
504 else
505 sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP | SBOX_ALLOW_STDIN,
506 2, PATH_FIREMON, "--top");
486 exit(0); 507 exit(0);
487 } 508 }
488#ifdef HAVE_NETWORK 509#ifdef HAVE_NETWORK
489 else if (strcmp(argv[i], "--netstats") == 0) { 510 else if (strcmp(argv[i], "--netstats") == 0) {
490 if (checkcfg(CFG_NETWORK)) { 511 if (checkcfg(CFG_NETWORK)) {
491 netstats(); 512 struct stat s;
492 } 513 if (stat("/proc/sys/kernel/grsecurity", &s) == 0 || pid_hidepid())
493 else { 514 sbox_run(SBOX_ROOT | SBOX_CAPS_NONE | SBOX_SECCOMP | SBOX_ALLOW_STDIN,
494 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n"); 515 2, PATH_FIREMON, "--netstats");
495 exit(1); 516 else
517 sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP | SBOX_ALLOW_STDIN,
518 2, PATH_FIREMON, "--netstats");
519 exit(0);
496 } 520 }
497 exit(0); 521 else
522 exit_err_feature("networking");
498 } 523 }
499#endif 524#endif
500#ifdef HAVE_FILE_TRANSFER 525#ifdef HAVE_FILE_TRANSFER
@@ -515,17 +540,42 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
515 } 540 }
516 541
517 // get file 542 // get file
518 pid_t pid; 543 pid_t pid = read_pid(argv[i] + 6);
519 if (read_pid(argv[i] + 6, &pid) == 0) 544 sandboxfs(SANDBOX_FS_GET, pid, path, NULL);
520 sandboxfs(SANDBOX_FS_GET, pid, path);
521 else
522 sandboxfs_name(SANDBOX_FS_GET, argv[i] + 6, path);
523 exit(0); 545 exit(0);
524 } 546 }
525 else { 547 else
526 fprintf(stderr, "Error: --get feature is disabled in Firejail configuration file\n"); 548 exit_err_feature("file transfer");
527 exit(1); 549 }
550 else if (strncmp(argv[i], "--put=", 6) == 0) {
551 if (checkcfg(CFG_FILE_TRANSFER)) {
552 logargs(argc, argv);
553
554 // verify path
555 if ((i + 3) != argc) {
556 fprintf(stderr, "Error: invalid --put option, 2 paths expected\n");
557 exit(1);
558 }
559 char *path1 = argv[i + 1];
560 invalid_filename(path1);
561 if (strstr(path1, "..")) {
562 fprintf(stderr, "Error: invalid file name %s\n", path1);
563 exit(1);
564 }
565 char *path2 = argv[i + 2];
566 invalid_filename(path2);
567 if (strstr(path2, "..")) {
568 fprintf(stderr, "Error: invalid file name %s\n", path2);
569 exit(1);
570 }
571
572 // get file
573 pid_t pid = read_pid(argv[i] + 6);
574 sandboxfs(SANDBOX_FS_PUT, pid, path1, path2);
575 exit(0);
528 } 576 }
577 else
578 exit_err_feature("file transfer");
529 } 579 }
530 else if (strncmp(argv[i], "--ls=", 5) == 0) { 580 else if (strncmp(argv[i], "--ls=", 5) == 0) {
531 if (checkcfg(CFG_FILE_TRANSFER)) { 581 if (checkcfg(CFG_FILE_TRANSFER)) {
@@ -544,29 +594,59 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
544 } 594 }
545 595
546 // list directory contents 596 // list directory contents
547 pid_t pid; 597 pid_t pid = read_pid(argv[i] + 5);
548 if (read_pid(argv[i] + 5, &pid) == 0) 598 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); 599 exit(0);
553 } 600 }
554 else { 601 else
555 fprintf(stderr, "Error: --ls feature is disabled in Firejail configuration file\n"); 602 exit_err_feature("file transfer");
556 exit(1);
557 }
558 } 603 }
559#endif 604#endif
560 else if (strncmp(argv[i], "--join=", 7) == 0) { 605 else if (strncmp(argv[i], "--join=", 7) == 0) {
561 logargs(argc, argv); 606 logargs(argc, argv);
562 607
608 if (arg_shell_none) {
609 if (argc <= (i+1)) {
610 fprintf(stderr, "Error: --shell=none set, but no command specified\n");
611 exit(1);
612 }
613 cfg.original_program_index = i + 1;
614 }
615
616 if (!cfg.shell && !arg_shell_none)
617 cfg.shell = guess_shell();
618
563 // join sandbox by pid or by name 619 // join sandbox by pid or by name
620 pid_t pid = read_pid(argv[i] + 7);
621 join(pid, argc, argv, i + 1);
622 exit(0);
623
624 }
625 else if (strncmp(argv[i], "--join-or-start=", 16) == 0) {
626 // NOTE: this is first part of option handler,
627 // sandbox name is set in other part
628 logargs(argc, argv);
629
630 if (arg_shell_none) {
631 if (argc <= (i+1)) {
632 fprintf(stderr, "Error: --shell=none set, but no command specified\n");
633 exit(1);
634 }
635 cfg.original_program_index = i + 1;
636 }
637
638#if 0 // todo: redo it
639 // try to join by name only
564 pid_t pid; 640 pid_t pid;
565 if (read_pid(argv[i] + 7, &pid) == 0) 641 if (!name2pid(argv[i] + 16, &pid)) {
642 if (!cfg.shell && !arg_shell_none)
643 cfg.shell = guess_shell();
644
566 join(pid, argc, argv, i + 1); 645 join(pid, argc, argv, i + 1);
567 else 646 exit(0);
568 join_name(argv[i] + 7, argc, argv, i + 1); 647 }
569 exit(0); 648#endif
649 // if there no such sandbox continue argument processing
570 } 650 }
571#ifdef HAVE_NETWORK 651#ifdef HAVE_NETWORK
572 else if (strncmp(argv[i], "--join-network=", 15) == 0) { 652 else if (strncmp(argv[i], "--join-network=", 15) == 0) {
@@ -578,18 +658,15 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
578 exit(1); 658 exit(1);
579 } 659 }
580 660
661 if (!cfg.shell && !arg_shell_none)
662 cfg.shell = guess_shell();
663
581 // join sandbox by pid or by name 664 // join sandbox by pid or by name
582 pid_t pid; 665 pid_t pid = read_pid(argv[i] + 15);
583 if (read_pid(argv[i] + 15, &pid) == 0) 666 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 }
588 else {
589 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n");
590 exit(1);
591 } 667 }
592 668 else
669 exit_err_feature("networking");
593 exit(0); 670 exit(0);
594 } 671 }
595#endif 672#endif
@@ -601,23 +678,20 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
601 exit(1); 678 exit(1);
602 } 679 }
603 680
681 if (!cfg.shell && !arg_shell_none)
682 cfg.shell = guess_shell();
683
604 // join sandbox by pid or by name 684 // join sandbox by pid or by name
605 pid_t pid; 685 pid_t pid = read_pid(argv[i] + 18);
606 if (read_pid(argv[i] + 18, &pid) == 0) 686 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); 687 exit(0);
611 } 688 }
612 else if (strncmp(argv[i], "--shutdown=", 11) == 0) { 689 else if (strncmp(argv[i], "--shutdown=", 11) == 0) {
613 logargs(argc, argv); 690 logargs(argc, argv);
614 691
615 // shutdown sandbox by pid or by name 692 // shutdown sandbox by pid or by name
616 pid_t pid; 693 pid_t pid = read_pid(argv[i] + 11);
617 if (read_pid(argv[i] + 11, &pid) == 0) 694 shut(pid);
618 shut(pid);
619 else
620 shut_name(argv[i] + 11);
621 exit(0); 695 exit(0);
622 } 696 }
623 697
@@ -635,14 +709,10 @@ static void set_name_file(pid_t pid) {
635 exit(1); 709 exit(1);
636 } 710 }
637 fprintf(fp, "%s\n", cfg.name); 711 fprintf(fp, "%s\n", cfg.name);
638 fclose(fp); 712
639
640 // mode and ownership 713 // mode and ownership
641 if (chown(fname, 0, 0) == -1) 714 SET_PERMS_STREAM(fp, 0, 0, 0644);
642 errExit("chown"); 715 fclose(fp);
643 if (chmod(fname, 0644) == -1)
644 errExit("chmod");
645
646} 716}
647 717
648static void delete_name_file(pid_t pid) { 718static void delete_name_file(pid_t pid) {
@@ -651,6 +721,7 @@ static void delete_name_file(pid_t pid) {
651 errExit("asprintf"); 721 errExit("asprintf");
652 int rv = unlink(fname); 722 int rv = unlink(fname);
653 (void) rv; 723 (void) rv;
724 free(fname);
654} 725}
655 726
656static void set_x11_file(pid_t pid, int display) { 727static void set_x11_file(pid_t pid, int display) {
@@ -665,14 +736,10 @@ static void set_x11_file(pid_t pid, int display) {
665 exit(1); 736 exit(1);
666 } 737 }
667 fprintf(fp, "%d\n", display); 738 fprintf(fp, "%d\n", display);
668 fclose(fp); 739
669
670 // mode and ownership 740 // mode and ownership
671 if (chown(fname, 0, 0) == -1) 741 SET_PERMS_STREAM(fp, 0, 0, 0644);
672 errExit("chown"); 742 fclose(fp);
673 if (chmod(fname, 0644) == -1)
674 errExit("chmod");
675
676} 743}
677 744
678static void delete_x11_file(pid_t pid) { 745static void delete_x11_file(pid_t pid) {
@@ -681,6 +748,45 @@ static void delete_x11_file(pid_t pid) {
681 errExit("asprintf"); 748 errExit("asprintf");
682 int rv = unlink(fname); 749 int rv = unlink(fname);
683 (void) rv; 750 (void) rv;
751 free(fname);
752}
753
754char *guess_shell(void) {
755 char *shell = NULL;
756 // shells in order of preference
757 char *shells[] = {"/bin/bash", "/bin/csh", "/usr/bin/zsh", "/bin/sh", "/bin/ash", NULL };
758
759 int i = 0;
760 while (shells[i] != NULL) {
761 struct stat s;
762 // access call checks as real UID/GID, not as effective UID/GID
763 if (stat(shells[i], &s) == 0 && access(shells[i], R_OK) == 0) {
764 shell = shells[i];
765 break;
766 }
767 i++;
768 }
769
770 return shell;
771}
772
773static int check_arg(int argc, char **argv, const char *argument) {
774 int i;
775 int found = 0;
776 for (i = 1; i < argc; i++) {
777 if (strcmp(argv[i], argument) == 0) {
778 found = 1;
779 break;
780 }
781
782 // detect end of firejail params
783 if (strcmp(argv[i], "--") == 0)
784 break;
785 if (strncmp(argv[i], "--", 2) != 0)
786 break;
787 }
788
789 return found;
684} 790}
685 791
686//******************************************* 792//*******************************************
@@ -694,81 +800,62 @@ int main(int argc, char **argv) {
694 int option_force = 0; 800 int option_force = 0;
695 int custom_profile = 0; // custom profile loaded 801 int custom_profile = 0; // custom profile loaded
696 char *custom_profile_dir = NULL; // custom profile directory 802 char *custom_profile_dir = NULL; // custom profile directory
697 int arg_noprofile = 0; // use generic.profile if none other found/specified 803 int arg_noprofile = 0; // use default.profile if none other found/specified
698#ifdef HAVE_SECCOMP 804
699 int highest_errno = errno_highest_nr(); 805 // build /run/firejail directory structure
700#endif 806 preproc_build_firejail_dir();
807
808 if (check_arg(argc, argv, "--quiet"))
809 arg_quiet = 1;
810 if (check_arg(argc, argv, "--allow-debuggers"))
811 arg_allow_debuggers = 1;
701 812
702 // drop permissions by default and rise them when required 813 // drop permissions by default and rise them when required
703 EUID_INIT(); 814 EUID_INIT();
704 EUID_USER(); 815 EUID_USER();
705 816
817
706 // check argv[0] symlink wrapper if this is not a login shell 818 // check argv[0] symlink wrapper if this is not a login shell
707 if (*argv[0] != '-') 819 if (*argv[0] != '-')
708 run_symlink(argc, argv); 820 run_symlink(argc, argv);
709 821
710 // check if we already have a sandbox running 822 // check if we already have a sandbox running
711 EUID_ROOT(); 823 // If LXC is detected, start firejail sandbox
712 int rv = check_kernel_procs(); 824 // otherwise try to detect a PID namespace by looking under /proc for specific kernel processes and:
713 EUID_USER(); 825 // - if --force flag is set, start firejail sandbox
714 if (rv == 0) { 826 // -- if --force flag is not set, start the application in a /bin/bash shell
715 // if --force option is passed to the program, disregard the existing sandbox 827 if (check_namespace_virt() == 0) {
716 int found = 0; 828 EUID_ROOT();
717 for (i = 1; i < argc; i++) { 829 int rv = check_kernel_procs();
718 if (strcmp(argv[i], "--force") == 0 || 830 EUID_USER();
719 strcmp(argv[i], "--list") == 0 || 831 if (rv == 0) {
720 strcmp(argv[i], "--netstats") == 0 || 832 // if --force option is passed to the program, disregard the existing sandbox
721 strcmp(argv[i], "--tree") == 0 || 833 if (check_arg(argc, argv, "--force"))
722 strcmp(argv[i], "--top") == 0 || 834 option_force = 1;
723 strncmp(argv[i], "--ls=", 5) == 0 || 835 else {
724 strncmp(argv[i], "--get=", 6) == 0 || 836 if (check_arg(argc, argv, "--version")) {
725 strcmp(argv[i], "--debug-caps") == 0 || 837 printf("firejail version %s\n", VERSION);
726 strcmp(argv[i], "--debug-errnos") == 0 || 838 exit(0);
727 strcmp(argv[i], "--debug-syscalls") == 0 || 839 }
728 strcmp(argv[i], "--debug-protocols") == 0 || 840
729 strcmp(argv[i], "--help") == 0 || 841 // start the program directly without sandboxing
730 strcmp(argv[i], "--version") == 0 || 842 run_no_sandbox(argc, argv);
731 strncmp(argv[i], "--dns.print=", 12) == 0 || 843 // it will never get here!
732 strncmp(argv[i], "--bandwidth=", 12) == 0 || 844 assert(0);
733 strncmp(argv[i], "--caps.print=", 13) == 0 || 845 }
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 }
752 if (strcmp(argv[i], "--") == 0)
753 break;
754 if (strncmp(argv[i], "--", 2) != 0)
755 break;
756 }
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 } 846 }
764 else
765 option_force = 1;
766 } 847 }
767 848
768 // check root/suid 849 // check root/suid
769 EUID_ROOT(); 850 EUID_ROOT();
770 if (geteuid()) { 851 if (geteuid()) {
771 fprintf(stderr, "Error: the sandbox is not setuid root\n"); 852 // only --version is supported without SUID support
853 if (check_arg(argc, argv, "--version")) {
854 printf("firejail version %s\n", VERSION);
855 exit(0);
856 }
857
858 fprintf(stderr, "Error: cannot rise privileges\n");
772 exit(1); 859 exit(1);
773 } 860 }
774 EUID_USER(); 861 EUID_USER();
@@ -776,10 +863,8 @@ int main(int argc, char **argv) {
776 // initialize globals 863 // initialize globals
777 init_cfg(argc, argv); 864 init_cfg(argc, argv);
778 865
779
780 // check firejail directories 866 // check firejail directories
781 EUID_ROOT(); 867 EUID_ROOT();
782 fs_build_firejail_dir();
783 bandwidth_del_run_file(sandbox_pid); 868 bandwidth_del_run_file(sandbox_pid);
784 network_del_run_file(sandbox_pid); 869 network_del_run_file(sandbox_pid);
785 delete_name_file(sandbox_pid); 870 delete_name_file(sandbox_pid);
@@ -798,15 +883,68 @@ int main(int argc, char **argv) {
798 if (strcmp(comm, "sshd") == 0) { 883 if (strcmp(comm, "sshd") == 0) {
799 arg_quiet = 1; 884 arg_quiet = 1;
800 parent_sshd = 1; 885 parent_sshd = 1;
886
887#ifdef DEBUG_RESTRICTED_SHELL
888 {EUID_ROOT();
889 FILE *fp = fopen("/firelog", "w");
890 if (fp) {
891 int i;
892 fprintf(fp, "argc %d: ", argc);
893 for (i = 0; i < argc; i++)
894 fprintf(fp, "#%s# ", argv[i]);
895 fprintf(fp, "\n");
896 fclose(fp);
897 }
898 EUID_USER();}
899#endif
900 // run sftp and scp directly without any sandboxing
901 // regular login has argv[0] == "-firejail"
902 if (*argv[0] != '-') {
903 if (strcmp(argv[1], "-c") == 0 && argc > 2) {
904 if (strcmp(argv[2], "/usr/lib/openssh/sftp-server") == 0 ||
905 strncmp(argv[2], "scp ", 4) == 0) {
906#ifdef DEBUG_RESTRICTED_SHELL
907 {EUID_ROOT();
908 FILE *fp = fopen("/firelog", "a");
909 if (fp) {
910 fprintf(fp, "run without a sandbox\n");
911 fclose(fp);
912 }
913 EUID_USER();}
914#endif
915
916 drop_privs(1);
917 int rv = system(argv[2]);
918 exit(rv);
919 }
920 }
921 }
801 } 922 }
802 free(comm); 923 free(comm);
803 } 924 }
804 } 925 }
805 926
806 // is this a login shell, or a command passed by sshd insert command line options from /etc/firejail/login.users 927 // 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) { 928 if (*argv[0] == '-' || parent_sshd) {
929 if (argc == 1)
930 login_shell = 1;
808 fullargc = restricted_shell(cfg.username); 931 fullargc = restricted_shell(cfg.username);
809 if (fullargc) { 932 if (fullargc) {
933
934#ifdef DEBUG_RESTRICTED_SHELL
935 {EUID_ROOT();
936 FILE *fp = fopen("/firelog", "a");
937 if (fp) {
938 fprintf(fp, "fullargc %d: ", fullargc);
939 int i;
940 for (i = 0; i < fullargc; i++)
941 fprintf(fp, "#%s# ", fullargv[i]);
942 fprintf(fp, "\n");
943 fclose(fp);
944 }
945 EUID_USER();}
946#endif
947
810 int j; 948 int j;
811 for (i = 1, j = fullargc; i < argc && j < MAX_ARGS; i++, j++, fullargc++) 949 for (i = 1, j = fullargc; i < argc && j < MAX_ARGS; i++, j++, fullargc++)
812 fullargv[j] = argv[i]; 950 fullargv[j] = argv[i];
@@ -814,12 +952,37 @@ int main(int argc, char **argv) {
814 // replace argc/argv with fullargc/fullargv 952 // replace argc/argv with fullargc/fullargv
815 argv = fullargv; 953 argv = fullargv;
816 argc = j; 954 argc = j;
955
956#ifdef DEBUG_RESTRICTED_SHELL
957 {EUID_ROOT();
958 FILE *fp = fopen("/firelog", "a");
959 if (fp) {
960 fprintf(fp, "argc %d: ", argc);
961 int i;
962 for (i = 0; i < argc; i++)
963 fprintf(fp, "#%s# ", argv[i]);
964 fprintf(fp, "\n");
965 fclose(fp);
966 }
967 EUID_USER();}
968#endif
817 } 969 }
818 } 970 }
819 else { 971 else {
820 // check --output option and execute it; 972 // check --output option and execute it;
821 check_output(argc, argv); // the function will not return if --output option was found 973 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 974 }
975
976
977 // check for force-nonewprivs in /etc/firejail/firejail.config file
978 if (checkcfg(CFG_FORCE_NONEWPRIVS))
979 arg_nonewprivs = 1;
980
981 if (arg_allow_debuggers) {
982 char *cmd = strdup("noblacklist ${PATH}/strace");
983 if (!cmd)
984 errExit("strdup");
985 profile_add(cmd);
823 } 986 }
824 987
825 // parse arguments 988 // parse arguments
@@ -845,19 +1008,33 @@ int main(int argc, char **argv) {
845 } 1008 }
846 else if (strcmp(argv[i], "--force") == 0) 1009 else if (strcmp(argv[i], "--force") == 0)
847 ; 1010 ;
1011 else if (strcmp(argv[i], "--allow-debuggers") == 0) {
1012 // already handled
1013 }
848 1014
849 //************************************* 1015 //*************************************
850 // filtering 1016 // filtering
851 //************************************* 1017 //*************************************
1018#ifdef HAVE_APPARMOR
1019 else if (strcmp(argv[i], "--apparmor") == 0)
1020 arg_apparmor = 1;
1021#endif
852#ifdef HAVE_SECCOMP 1022#ifdef HAVE_SECCOMP
853 else if (strncmp(argv[i], "--protocol=", 11) == 0) { 1023 else if (strncmp(argv[i], "--protocol=", 11) == 0) {
854 if (checkcfg(CFG_SECCOMP)) { 1024 if (checkcfg(CFG_SECCOMP)) {
855 protocol_store(argv[i] + 11); 1025 if (cfg.protocol) {
856 } 1026 if (!arg_quiet)
857 else { 1027 fprintf(stderr, "Warning: a protocol list is present, the new list \"%s\" will not be installed\n", argv[i] + 11);
858 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); 1028 }
859 exit(1); 1029 else {
1030 // store list
1031 cfg.protocol = strdup(argv[i] + 11);
1032 if (!cfg.protocol)
1033 errExit("strdup");
1034 }
860 } 1035 }
1036 else
1037 exit_err_feature("seccomp");
861 } 1038 }
862 else if (strcmp(argv[i], "--seccomp") == 0) { 1039 else if (strcmp(argv[i], "--seccomp") == 0) {
863 if (checkcfg(CFG_SECCOMP)) { 1040 if (checkcfg(CFG_SECCOMP)) {
@@ -867,10 +1044,8 @@ int main(int argc, char **argv) {
867 } 1044 }
868 arg_seccomp = 1; 1045 arg_seccomp = 1;
869 } 1046 }
870 else { 1047 else
871 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); 1048 exit_err_feature("seccomp");
872 exit(1);
873 }
874 } 1049 }
875 else if (strncmp(argv[i], "--seccomp=", 10) == 0) { 1050 else if (strncmp(argv[i], "--seccomp=", 10) == 0) {
876 if (checkcfg(CFG_SECCOMP)) { 1051 if (checkcfg(CFG_SECCOMP)) {
@@ -879,14 +1054,10 @@ int main(int argc, char **argv) {
879 exit(1); 1054 exit(1);
880 } 1055 }
881 arg_seccomp = 1; 1056 arg_seccomp = 1;
882 cfg.seccomp_list = strdup(argv[i] + 10); 1057 cfg.seccomp_list = seccomp_check_list(argv[i] + 10);
883 if (!cfg.seccomp_list)
884 errExit("strdup");
885 }
886 else {
887 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
888 exit(1);
889 } 1058 }
1059 else
1060 exit_err_feature("seccomp");
890 } 1061 }
891 else if (strncmp(argv[i], "--seccomp.drop=", 15) == 0) { 1062 else if (strncmp(argv[i], "--seccomp.drop=", 15) == 0) {
892 if (checkcfg(CFG_SECCOMP)) { 1063 if (checkcfg(CFG_SECCOMP)) {
@@ -895,14 +1066,10 @@ int main(int argc, char **argv) {
895 exit(1); 1066 exit(1);
896 } 1067 }
897 arg_seccomp = 1; 1068 arg_seccomp = 1;
898 cfg.seccomp_list_drop = strdup(argv[i] + 15); 1069 cfg.seccomp_list_drop = seccomp_check_list(argv[i] + 15);
899 if (!cfg.seccomp_list_drop)
900 errExit("strdup");
901 }
902 else {
903 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
904 exit(1);
905 } 1070 }
1071 else
1072 exit_err_feature("seccomp");
906 } 1073 }
907 else if (strncmp(argv[i], "--seccomp.keep=", 15) == 0) { 1074 else if (strncmp(argv[i], "--seccomp.keep=", 15) == 0) {
908 if (checkcfg(CFG_SECCOMP)) { 1075 if (checkcfg(CFG_SECCOMP)) {
@@ -911,48 +1078,10 @@ int main(int argc, char **argv) {
911 exit(1); 1078 exit(1);
912 } 1079 }
913 arg_seccomp = 1; 1080 arg_seccomp = 1;
914 cfg.seccomp_list_keep = strdup(argv[i] + 15); 1081 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 }
952 else {
953 fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n");
954 exit(1);
955 } 1082 }
1083 else
1084 exit_err_feature("seccomp");
956 } 1085 }
957#endif 1086#endif
958 else if (strcmp(argv[i], "--caps") == 0) 1087 else if (strcmp(argv[i], "--caps") == 0)
@@ -965,8 +1094,7 @@ int main(int argc, char **argv) {
965 if (!arg_caps_list) 1094 if (!arg_caps_list)
966 errExit("strdup"); 1095 errExit("strdup");
967 // verify caps list and exit if problems 1096 // verify caps list and exit if problems
968 if (caps_check_list(arg_caps_list, NULL)) 1097 caps_check_list(arg_caps_list, NULL);
969 return 1;
970 } 1098 }
971 else if (strncmp(argv[i], "--caps.keep=", 12) == 0) { 1099 else if (strncmp(argv[i], "--caps.keep=", 12) == 0) {
972 arg_caps_keep = 1; 1100 arg_caps_keep = 1;
@@ -974,8 +1102,7 @@ int main(int argc, char **argv) {
974 if (!arg_caps_list) 1102 if (!arg_caps_list)
975 errExit("strdup"); 1103 errExit("strdup");
976 // verify caps list and exit if problems 1104 // verify caps list and exit if problems
977 if (caps_check_list(arg_caps_list, NULL)) 1105 caps_check_list(arg_caps_list, NULL);
978 return 1;
979 } 1106 }
980 1107
981 1108
@@ -1021,6 +1148,8 @@ int main(int argc, char **argv) {
1021 read_cpu_list(argv[i] + 6); 1148 read_cpu_list(argv[i] + 6);
1022 else if (strncmp(argv[i], "--nice=", 7) == 0) { 1149 else if (strncmp(argv[i], "--nice=", 7) == 0) {
1023 cfg.nice = atoi(argv[i] + 7); 1150 cfg.nice = atoi(argv[i] + 7);
1151 if (getuid() != 0 &&cfg.nice < 0)
1152 cfg.nice = 0;
1024 arg_nice = 1; 1153 arg_nice = 1;
1025 } 1154 }
1026 else if (strncmp(argv[i], "--cgroup=", 9) == 0) { 1155 else if (strncmp(argv[i], "--cgroup=", 9) == 0) {
@@ -1039,6 +1168,8 @@ int main(int argc, char **argv) {
1039 //************************************* 1168 //*************************************
1040 // filesystem 1169 // filesystem
1041 //************************************* 1170 //*************************************
1171 else if (strcmp(argv[i], "--allusers") == 0)
1172 arg_allusers = 1;
1042#ifdef HAVE_BIND 1173#ifdef HAVE_BIND
1043 else if (strncmp(argv[i], "--bind=", 7) == 0) { 1174 else if (strncmp(argv[i], "--bind=", 7) == 0) {
1044 if (checkcfg(CFG_BIND)) { 1175 if (checkcfg(CFG_BIND)) {
@@ -1049,10 +1180,8 @@ int main(int argc, char **argv) {
1049 profile_check_line(line, 0, NULL); // will exit if something wrong 1180 profile_check_line(line, 0, NULL); // will exit if something wrong
1050 profile_add(line); 1181 profile_add(line);
1051 } 1182 }
1052 else { 1183 else
1053 fprintf(stderr, "Error: --bind feature is disabled in Firejail configuration file\n"); 1184 exit_err_feature("bind");
1054 exit(1);
1055 }
1056 } 1185 }
1057#endif 1186#endif
1058 else if (strncmp(argv[i], "--tmpfs=", 8) == 0) { 1187 else if (strncmp(argv[i], "--tmpfs=", 8) == 0) {
@@ -1079,98 +1208,146 @@ int main(int argc, char **argv) {
1079 profile_check_line(line, 0, NULL); // will exit if something wrong 1208 profile_check_line(line, 0, NULL); // will exit if something wrong
1080 profile_add(line); 1209 profile_add(line);
1081 } 1210 }
1211
1212#ifdef HAVE_WHITELIST
1082 else if (strncmp(argv[i], "--whitelist=", 12) == 0) { 1213 else if (strncmp(argv[i], "--whitelist=", 12) == 0) {
1214 if (checkcfg(CFG_WHITELIST)) {
1215 char *line;
1216 if (asprintf(&line, "whitelist %s", argv[i] + 12) == -1)
1217 errExit("asprintf");
1218
1219 profile_check_line(line, 0, NULL); // will exit if something wrong
1220 profile_add(line);
1221 }
1222 else
1223 exit_err_feature("whitelist");
1224 }
1225#endif
1226
1227 else if (strncmp(argv[i], "--read-only=", 12) == 0) {
1083 char *line; 1228 char *line;
1084 if (asprintf(&line, "whitelist %s", argv[i] + 12) == -1) 1229 if (asprintf(&line, "read-only %s", argv[i] + 12) == -1)
1085 errExit("asprintf"); 1230 errExit("asprintf");
1086 1231
1087 profile_check_line(line, 0, NULL); // will exit if something wrong 1232 profile_check_line(line, 0, NULL); // will exit if something wrong
1088 profile_add(line); 1233 profile_add(line);
1089 } 1234 }
1090 else if (strncmp(argv[i], "--read-only=", 12) == 0) { 1235 else if (strncmp(argv[i], "--noexec=", 9) == 0) {
1091 char *line; 1236 char *line;
1092 if (asprintf(&line, "read-only %s", argv[i] + 12) == -1) 1237 if (asprintf(&line, "noexec %s", argv[i] + 9) == -1)
1093 errExit("asprintf"); 1238 errExit("asprintf");
1094 1239
1095 profile_check_line(line, 0, NULL); // will exit if something wrong 1240 profile_check_line(line, 0, NULL); // will exit if something wrong
1096 profile_add(line); 1241 profile_add(line);
1097 } 1242 }
1098 else if (strcmp(argv[i], "--overlay") == 0) { 1243 else if (strncmp(argv[i], "--read-write=", 13) == 0) {
1099 if (cfg.chrootdir) { 1244 char *line;
1100 fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); 1245 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"); 1246 errExit("asprintf");
1115 if (stat(dirname, &s) == -1) {
1116 /* coverity[toctou] */
1117 if (mkdir(dirname, 0700))
1118 errExit("mkdir");
1119 if (chown(dirname, getuid(), getgid()) < 0)
1120 errExit("chown");
1121 if (chmod(dirname, 0700) < 0)
1122 errExit("chmod");
1123 }
1124 else if (is_link(dirname)) {
1125 fprintf(stderr, "Error: invalid ~/.firejail directory\n");
1126 exit(1);
1127 }
1128
1129 free(dirname);
1130 1247
1131 // check overlay directory 1248 profile_check_line(line, 0, NULL); // will exit if something wrong
1132 if (asprintf(&dirname, "%s/.firejail/%d", cfg.homedir, getpid()) == -1) 1249 profile_add(line);
1133 errExit("asprintf"); 1250 }
1134 if (stat(dirname, &s) == 0) { 1251#ifdef HAVE_OVERLAYFS
1135 fprintf(stderr, "Error: overlay directory already exists: %s\n", dirname); 1252 else if (strcmp(argv[i], "--overlay") == 0) {
1136 exit(1); 1253 if (checkcfg(CFG_OVERLAYFS)) {
1254 if (cfg.chrootdir) {
1255 fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n");
1256 exit(1);
1257 }
1258 struct stat s;
1259 if (stat("/proc/sys/kernel/grsecurity", &s) == 0) {
1260 fprintf(stderr, "Error: --overlay option is not available on Grsecurity systems\n");
1261 exit(1);
1262 }
1263 arg_overlay = 1;
1264 arg_overlay_keep = 1;
1265
1266 char *subdirname;
1267 if (asprintf(&subdirname, "%d", getpid()) == -1)
1268 errExit("asprintf");
1269 cfg.overlay_dir = fs_check_overlay_dir(subdirname, arg_overlay_reuse);
1270
1271 free(subdirname);
1137 } 1272 }
1138 cfg.overlay_dir = dirname; 1273 else
1274 exit_err_feature("overlayfs");
1139 } 1275 }
1140 else if (strcmp(argv[i], "--overlay-tmpfs") == 0) { 1276 else if (strncmp(argv[i], "--overlay-named=", 16) == 0) {
1141 if (cfg.chrootdir) { 1277 if (checkcfg(CFG_OVERLAYFS)) {
1142 fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); 1278 if (cfg.chrootdir) {
1143 exit(1); 1279 fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n");
1280 exit(1);
1281 }
1282 struct stat s;
1283 if (stat("/proc/sys/kernel/grsecurity", &s) == 0) {
1284 fprintf(stderr, "Error: --overlay option is not available on Grsecurity systems\n");
1285 exit(1);
1286 }
1287 arg_overlay = 1;
1288 arg_overlay_keep = 1;
1289 arg_overlay_reuse = 1;
1290
1291 char *subdirname = argv[i] + 16;
1292 if (subdirname == '\0') {
1293 fprintf(stderr, "Error: invalid overlay option\n");
1294 exit(1);
1295 }
1296
1297 // check name
1298 invalid_filename(subdirname);
1299 if (strstr(subdirname, "..") || strstr(subdirname, "/")) {
1300 fprintf(stderr, "Error: invalid overlay name\n");
1301 exit(1);
1302 }
1303 cfg.overlay_dir = fs_check_overlay_dir(subdirname, arg_overlay_reuse);
1144 } 1304 }
1145 struct stat s; 1305 else
1146 if (stat("/proc/sys/kernel/grsecurity", &s) == 0) { 1306 exit_err_feature("overlayfs");
1147 fprintf(stderr, "Error: --overlay option is not available on Grsecurity systems\n"); 1307 }
1148 exit(1); 1308 else if (strcmp(argv[i], "--overlay-tmpfs") == 0) {
1309 if (checkcfg(CFG_OVERLAYFS)) {
1310 if (cfg.chrootdir) {
1311 fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n");
1312 exit(1);
1313 }
1314 struct stat s;
1315 if (stat("/proc/sys/kernel/grsecurity", &s) == 0) {
1316 fprintf(stderr, "Error: --overlay option is not available on Grsecurity systems\n");
1317 exit(1);
1318 }
1319 arg_overlay = 1;
1149 } 1320 }
1150 arg_overlay = 1; 1321 else
1322 exit_err_feature("overlayfs");
1151 } 1323 }
1324#endif
1152 else if (strncmp(argv[i], "--profile=", 10) == 0) { 1325 else if (strncmp(argv[i], "--profile=", 10) == 0) {
1153 if (arg_noprofile) { 1326 if (arg_noprofile) {
1154 fprintf(stderr, "Error: --noprofile and --profile options are mutually exclusive\n"); 1327 fprintf(stderr, "Error: --noprofile and --profile options are mutually exclusive\n");
1155 exit(1); 1328 exit(1);
1156 } 1329 }
1157 invalid_filename(argv[i] + 10); 1330
1331 char *ppath = expand_home(argv[i] + 10, cfg.homedir);
1332 if (!ppath)
1333 errExit("strdup");
1334 invalid_filename(ppath);
1158 1335
1159 // multiple profile files are allowed! 1336 // multiple profile files are allowed!
1160 char *ptr = argv[i] + 10; 1337 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"); 1338 fprintf(stderr, "Error: invalid profile file\n");
1163 exit(1); 1339 exit(1);
1164 } 1340 }
1165 1341
1166 // access call checks as real UID/GID, not as effective UID/GID 1342 // access call checks as real UID/GID, not as effective UID/GID
1167 if (access(argv[i] + 10, R_OK)) { 1343 if (access(ppath, R_OK)) {
1168 fprintf(stderr, "Error: cannot access profile file\n"); 1344 fprintf(stderr, "Error: cannot access profile file\n");
1169 return 1; 1345 return 1;
1170 } 1346 }
1171 1347
1172 profile_read(argv[i] + 10); 1348 profile_read(ppath);
1173 custom_profile = 1; 1349 custom_profile = 1;
1350 free(ppath);
1174 } 1351 }
1175 else if (strncmp(argv[i], "--profile-path=", 15) == 0) { 1352 else if (strncmp(argv[i], "--profile-path=", 15) == 0) {
1176 if (arg_noprofile) { 1353 if (arg_noprofile) {
@@ -1255,22 +1432,46 @@ int main(int argc, char **argv) {
1255 return 1; 1432 return 1;
1256 } 1433 }
1257 1434
1435 // don't allow "--chroot=/"
1436 char *rpath = realpath(cfg.chrootdir, NULL);
1437 if (rpath == NULL || strcmp(rpath, "/") == 0) {
1438 fprintf(stderr, "Error: invalid chroot directory\n");
1439 exit(1);
1440 }
1441 free(rpath);
1442
1258 // check chroot directory structure 1443 // check chroot directory structure
1259 if (fs_check_chroot_dir(cfg.chrootdir)) { 1444 if (fs_check_chroot_dir(cfg.chrootdir)) {
1260 fprintf(stderr, "Error: invalid chroot\n"); 1445 fprintf(stderr, "Error: invalid chroot\n");
1261 exit(1); 1446 exit(1);
1262 } 1447 }
1263 } 1448 }
1264 else { 1449 else
1265 fprintf(stderr, "Error: --chroot feature is disabled in Firejail configuration file\n"); 1450 exit_err_feature("chroot");
1451 }
1452#endif
1453 else if (strcmp(argv[i], "--writable-etc") == 0) {
1454 if (cfg.etc_private_keep) {
1455 fprintf(stderr, "Error: --private-etc and --writable-etc are mutually exclusive\n");
1266 exit(1); 1456 exit(1);
1267 } 1457 }
1268 1458 arg_writable_etc = 1;
1269 } 1459 }
1270#endif 1460 else if (strcmp(argv[i], "--writable-var") == 0) {
1271 else if (strcmp(argv[i], "--private") == 0) 1461 arg_writable_var = 1;
1462 }
1463 else if (strcmp(argv[i], "--machine-id") == 0) {
1464 arg_machineid = 1;
1465 }
1466 else if (strcmp(argv[i], "--private") == 0) {
1272 arg_private = 1; 1467 arg_private = 1;
1468 }
1273 else if (strncmp(argv[i], "--private=", 10) == 0) { 1469 else if (strncmp(argv[i], "--private=", 10) == 0) {
1470 if (cfg.home_private_keep) {
1471 fprintf(stderr, "Error: a private list of files was already defined with --private-home option.\n");
1472 exit(1);
1473 }
1474
1274 // extract private home dirname 1475 // extract private home dirname
1275 cfg.home_private = argv[i] + 10; 1476 cfg.home_private = argv[i] + 10;
1276 if (*cfg.home_private == '\0') { 1477 if (*cfg.home_private == '\0') {
@@ -1278,25 +1479,64 @@ int main(int argc, char **argv) {
1278 exit(1); 1479 exit(1);
1279 } 1480 }
1280 fs_check_private_dir(); 1481 fs_check_private_dir();
1482
1483 // downgrade to --private if the directory is the user home directory
1484 if (strcmp(cfg.home_private, cfg.homedir) == 0) {
1485 free(cfg.home_private);
1486 cfg.home_private = NULL;
1487 }
1281 arg_private = 1; 1488 arg_private = 1;
1282 } 1489 }
1490#ifdef HAVE_PRIVATE_HOME
1491 else if (strncmp(argv[i], "--private-home=", 15) == 0) {
1492 if (checkcfg(CFG_PRIVATE_HOME)) {
1493 if (cfg.home_private) {
1494 fprintf(stderr, "Error: a private home directory was already defined with --private option.\n");
1495 exit(1);
1496 }
1497
1498 // extract private home dirname
1499 cfg.home_private_keep = argv[i] + 15;
1500 arg_private = 1;
1501 }
1502 else
1503 exit_err_feature("private-home");
1504 }
1505#endif
1283 else if (strcmp(argv[i], "--private-dev") == 0) { 1506 else if (strcmp(argv[i], "--private-dev") == 0) {
1284 arg_private_dev = 1; 1507 arg_private_dev = 1;
1285 } 1508 }
1286 else if (strncmp(argv[i], "--private-etc=", 14) == 0) { 1509 else if (strncmp(argv[i], "--private-etc=", 14) == 0) {
1510 if (arg_writable_etc) {
1511 fprintf(stderr, "Error: --private-etc and --writable-etc are mutually exclusive\n");
1512 exit(1);
1513 }
1514
1287 // extract private etc list 1515 // extract private etc list
1288 cfg.etc_private_keep = argv[i] + 14; 1516 cfg.etc_private_keep = argv[i] + 14;
1289 if (*cfg.etc_private_keep == '\0') { 1517 if (*cfg.etc_private_keep == '\0') {
1290 fprintf(stderr, "Error: invalid private-etc option\n"); 1518 fprintf(stderr, "Error: invalid private-etc option\n");
1291 exit(1); 1519 exit(1);
1292 } 1520 }
1293 fs_check_etc_list(); 1521 arg_private_etc = 1;
1294 if (*cfg.etc_private_keep != '\0') 1522 }
1295 arg_private_etc = 1; 1523 else if (strncmp(argv[i], "--private-opt=", 14) == 0) {
1296 else { 1524 // extract private opt list
1297 arg_private_etc = 0; 1525 cfg.opt_private_keep = argv[i] + 14;
1298 fprintf(stderr, "Warning: private-etc disabled, no file found\n"); 1526 if (*cfg.opt_private_keep == '\0') {
1527 fprintf(stderr, "Error: invalid private-opt option\n");
1528 exit(1);
1529 }
1530 arg_private_opt = 1;
1531 }
1532 else if (strncmp(argv[i], "--private-srv=", 14) == 0) {
1533 // extract private srv list
1534 cfg.srv_private_keep = argv[i] + 14;
1535 if (*cfg.srv_private_keep == '\0') {
1536 fprintf(stderr, "Error: invalid private-etc option\n");
1537 exit(1);
1299 } 1538 }
1539 arg_private_srv = 1;
1300 } 1540 }
1301 else if (strncmp(argv[i], "--private-bin=", 14) == 0) { 1541 else if (strncmp(argv[i], "--private-bin=", 14) == 0) {
1302 // extract private bin list 1542 // extract private bin list
@@ -1306,7 +1546,6 @@ int main(int argc, char **argv) {
1306 exit(1); 1546 exit(1);
1307 } 1547 }
1308 arg_private_bin = 1; 1548 arg_private_bin = 1;
1309 fs_check_bin_list();
1310 } 1549 }
1311 else if (strcmp(argv[i], "--private-tmp") == 0) { 1550 else if (strcmp(argv[i], "--private-tmp") == 0) {
1312 arg_private_tmp = 1; 1551 arg_private_tmp = 1;
@@ -1335,17 +1574,22 @@ int main(int argc, char **argv) {
1335 else if (strcmp(argv[i], "--noroot") == 0) { 1574 else if (strcmp(argv[i], "--noroot") == 0) {
1336 if (checkcfg(CFG_USERNS)) 1575 if (checkcfg(CFG_USERNS))
1337 check_user_namespace(); 1576 check_user_namespace();
1338 else { 1577 else
1339 fprintf(stderr, "Error: --noroot feature is disabled in Firejail configuration file\n"); 1578 exit_err_feature("noroot");
1340 exit(1);
1341 }
1342 } 1579 }
1343#endif 1580#endif
1581 else if (strcmp(argv[i], "--nonewprivs") == 0) {
1582 arg_nonewprivs = 1;
1583 }
1344 else if (strncmp(argv[i], "--env=", 6) == 0) 1584 else if (strncmp(argv[i], "--env=", 6) == 0)
1345 env_store(argv[i] + 6); 1585 env_store(argv[i] + 6, SETENV);
1346 else if (strncmp(argv[i], "--nosound", 9) == 0) { 1586 else if (strncmp(argv[i], "--rmenv=", 8) == 0)
1587 env_store(argv[i] + 8, RMENV);
1588 else if (strcmp(argv[i], "--nosound") == 0) {
1347 arg_nosound = 1; 1589 arg_nosound = 1;
1348 arg_private_dev = 1; 1590 }
1591 else if (strcmp(argv[i], "--no3d") == 0) {
1592 arg_no3d = 1;
1349 } 1593 }
1350 1594
1351 //************************************* 1595 //*************************************
@@ -1401,14 +1645,13 @@ int main(int argc, char **argv) {
1401 errExit("strdup"); 1645 errExit("strdup");
1402 1646
1403 if (net_get_if_addr(intf->dev, &intf->ip, &intf->mask, intf->mac, &intf->mtu)) { 1647 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); 1648 if (!arg_quiet || arg_debug)
1649 fprintf(stderr, "Warning: interface %s is not configured\n", intf->dev);
1405 } 1650 }
1406 intf->configured = 1; 1651 intf->configured = 1;
1407 } 1652 }
1408 else { 1653 else
1409 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n"); 1654 exit_err_feature("networking");
1410 exit(1);
1411 }
1412 } 1655 }
1413 1656
1414 else if (strncmp(argv[i], "--net=", 6) == 0) { 1657 else if (strncmp(argv[i], "--net=", 6) == 0) {
@@ -1458,20 +1701,35 @@ int main(int argc, char **argv) {
1458 } 1701 }
1459 net_configure_bridge(br, argv[i] + 6); 1702 net_configure_bridge(br, argv[i] + 6);
1460 } 1703 }
1461 else { 1704 else
1462 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n"); 1705 exit_err_feature("networking");
1463 exit(1); 1706 }
1707
1708 else if (strncmp(argv[i], "--veth-name=", 12) == 0) {
1709 if (checkcfg(CFG_NETWORK)) {
1710 Bridge *br = last_bridge_configured();
1711 if (br == NULL) {
1712 fprintf(stderr, "Error: no network device configured\n");
1713 exit(1);
1714 }
1715 br->veth_name = strdup(argv[i] + 12);
1716 if (br->veth_name == NULL)
1717 errExit("strdup");
1718 if (*br->veth_name == '\0') {
1719 fprintf(stderr, "Error: no veth-name configured\n");
1720 exit(1);
1721 }
1464 } 1722 }
1723 else
1724 exit_err_feature("networking");
1465 } 1725 }
1466 1726
1467 else if (strcmp(argv[i], "--scan") == 0) { 1727 else if (strcmp(argv[i], "--scan") == 0) {
1468 if (checkcfg(CFG_NETWORK)) { 1728 if (checkcfg(CFG_NETWORK)) {
1469 arg_scan = 1; 1729 arg_scan = 1;
1470 } 1730 }
1471 else { 1731 else
1472 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n"); 1732 exit_err_feature("networking");
1473 exit(1);
1474 }
1475 } 1733 }
1476 else if (strncmp(argv[i], "--iprange=", 10) == 0) { 1734 else if (strncmp(argv[i], "--iprange=", 10) == 0) {
1477 if (checkcfg(CFG_NETWORK)) { 1735 if (checkcfg(CFG_NETWORK)) {
@@ -1511,10 +1769,8 @@ int main(int argc, char **argv) {
1511 return 1; 1769 return 1;
1512 } 1770 }
1513 } 1771 }
1514 else { 1772 else
1515 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n"); 1773 exit_err_feature("networking");
1516 exit(1);
1517 }
1518 } 1774 }
1519 1775
1520 else if (strncmp(argv[i], "--mac=", 6) == 0) { 1776 else if (strncmp(argv[i], "--mac=", 6) == 0) {
@@ -1522,23 +1778,21 @@ int main(int argc, char **argv) {
1522 Bridge *br = last_bridge_configured(); 1778 Bridge *br = last_bridge_configured();
1523 if (br == NULL) { 1779 if (br == NULL) {
1524 fprintf(stderr, "Error: no network device configured\n"); 1780 fprintf(stderr, "Error: no network device configured\n");
1525 return 1; 1781 exit(1);
1526 } 1782 }
1527 if (mac_not_zero(br->macsandbox)) { 1783 if (mac_not_zero(br->macsandbox)) {
1528 fprintf(stderr, "Error: cannot configure the MAC address twice for the same interface\n"); 1784 fprintf(stderr, "Error: cannot configure the MAC address twice for the same interface\n");
1529 return 1; 1785 exit(1);
1530 } 1786 }
1531 1787
1532 // read the address 1788 // read the address
1533 if (atomac(argv[i] + 6, br->macsandbox)) { 1789 if (atomac(argv[i] + 6, br->macsandbox)) {
1534 fprintf(stderr, "Error: invalid MAC address\n"); 1790 fprintf(stderr, "Error: invalid MAC address\n");
1535 return 1; 1791 exit(1);
1536 } 1792 }
1537 } 1793 }
1538 else { 1794 else
1539 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n"); 1795 exit_err_feature("networking");
1540 exit(1);
1541 }
1542 } 1796 }
1543 1797
1544 else if (strncmp(argv[i], "--mtu=", 6) == 0) { 1798 else if (strncmp(argv[i], "--mtu=", 6) == 0) {
@@ -1546,18 +1800,16 @@ int main(int argc, char **argv) {
1546 Bridge *br = last_bridge_configured(); 1800 Bridge *br = last_bridge_configured();
1547 if (br == NULL) { 1801 if (br == NULL) {
1548 fprintf(stderr, "Error: no network device configured\n"); 1802 fprintf(stderr, "Error: no network device configured\n");
1549 return 1; 1803 exit(1);
1550 } 1804 }
1551 1805
1552 if (sscanf(argv[i] + 6, "%d", &br->mtu) != 1 || br->mtu < 576 || br->mtu > 9198) { 1806 if (sscanf(argv[i] + 6, "%d", &br->mtu) != 1 || br->mtu < 576 || br->mtu > 9198) {
1553 fprintf(stderr, "Error: invalid mtu value\n"); 1807 fprintf(stderr, "Error: invalid mtu value\n");
1554 return 1; 1808 exit(1);
1555 } 1809 }
1556 } 1810 }
1557 else { 1811 else
1558 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n"); 1812 exit_err_feature("networking");
1559 exit(1);
1560 }
1561 } 1813 }
1562 1814
1563 else if (strncmp(argv[i], "--ip=", 5) == 0) { 1815 else if (strncmp(argv[i], "--ip=", 5) == 0) {
@@ -1565,11 +1817,11 @@ int main(int argc, char **argv) {
1565 Bridge *br = last_bridge_configured(); 1817 Bridge *br = last_bridge_configured();
1566 if (br == NULL) { 1818 if (br == NULL) {
1567 fprintf(stderr, "Error: no network device configured\n"); 1819 fprintf(stderr, "Error: no network device configured\n");
1568 return 1; 1820 exit(1);
1569 } 1821 }
1570 if (br->arg_ip_none || br->ipsandbox) { 1822 if (br->arg_ip_none || br->ipsandbox) {
1571 fprintf(stderr, "Error: cannot configure the IP address twice for the same interface\n"); 1823 fprintf(stderr, "Error: cannot configure the IP address twice for the same interface\n");
1572 return 1; 1824 exit(1);
1573 } 1825 }
1574 1826
1575 // configure this IP address for the last bridge defined 1827 // configure this IP address for the last bridge defined
@@ -1578,14 +1830,12 @@ int main(int argc, char **argv) {
1578 else { 1830 else {
1579 if (atoip(argv[i] + 5, &br->ipsandbox)) { 1831 if (atoip(argv[i] + 5, &br->ipsandbox)) {
1580 fprintf(stderr, "Error: invalid IP address\n"); 1832 fprintf(stderr, "Error: invalid IP address\n");
1581 return 1; 1833 exit(1);
1582 } 1834 }
1583 } 1835 }
1584 } 1836 }
1585 else { 1837 else
1586 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n"); 1838 exit_err_feature("networking");
1587 exit(1);
1588 }
1589 } 1839 }
1590 1840
1591 else if (strncmp(argv[i], "--ip6=", 6) == 0) { 1841 else if (strncmp(argv[i], "--ip6=", 6) == 0) {
@@ -1593,11 +1843,11 @@ int main(int argc, char **argv) {
1593 Bridge *br = last_bridge_configured(); 1843 Bridge *br = last_bridge_configured();
1594 if (br == NULL) { 1844 if (br == NULL) {
1595 fprintf(stderr, "Error: no network device configured\n"); 1845 fprintf(stderr, "Error: no network device configured\n");
1596 return 1; 1846 exit(1);
1597 } 1847 }
1598 if (br->arg_ip_none || br->ip6sandbox) { 1848 if (br->arg_ip_none || br->ip6sandbox) {
1599 fprintf(stderr, "Error: cannot configure the IP address twice for the same interface\n"); 1849 fprintf(stderr, "Error: cannot configure the IP address twice for the same interface\n");
1600 return 1; 1850 exit(1);
1601 } 1851 }
1602 1852
1603 // configure this IP address for the last bridge defined 1853 // configure this IP address for the last bridge defined
@@ -1605,13 +1855,11 @@ int main(int argc, char **argv) {
1605 br->ip6sandbox = argv[i] + 6; 1855 br->ip6sandbox = argv[i] + 6;
1606// if (atoip(argv[i] + 5, &br->ipsandbox)) { 1856// if (atoip(argv[i] + 5, &br->ipsandbox)) {
1607// fprintf(stderr, "Error: invalid IP address\n"); 1857// fprintf(stderr, "Error: invalid IP address\n");
1608// return 1; 1858// exit(1);
1609// } 1859// }
1610 } 1860 }
1611 else { 1861 else
1612 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n"); 1862 exit_err_feature("networking");
1613 exit(1);
1614 }
1615 } 1863 }
1616 1864
1617 1865
@@ -1619,13 +1867,11 @@ int main(int argc, char **argv) {
1619 if (checkcfg(CFG_NETWORK)) { 1867 if (checkcfg(CFG_NETWORK)) {
1620 if (atoip(argv[i] + 12, &cfg.defaultgw)) { 1868 if (atoip(argv[i] + 12, &cfg.defaultgw)) {
1621 fprintf(stderr, "Error: invalid IP address\n"); 1869 fprintf(stderr, "Error: invalid IP address\n");
1622 return 1; 1870 exit(1);
1623 } 1871 }
1624 } 1872 }
1625 else { 1873 else
1626 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n"); 1874 exit_err_feature("networking");
1627 exit(1);
1628 }
1629 } 1875 }
1630#endif 1876#endif
1631 else if (strncmp(argv[i], "--dns=", 6) == 0) { 1877 else if (strncmp(argv[i], "--dns=", 6) == 0) {
@@ -1649,25 +1895,45 @@ int main(int argc, char **argv) {
1649 1895
1650#ifdef HAVE_NETWORK 1896#ifdef HAVE_NETWORK
1651 else if (strcmp(argv[i], "--netfilter") == 0) { 1897 else if (strcmp(argv[i], "--netfilter") == 0) {
1652 if (checkcfg(CFG_NETWORK)) { 1898#ifdef HAVE_NETWORK_RESTRICTED
1653 arg_netfilter = 1; 1899 // compile time restricted networking
1900 if (getuid() != 0) {
1901 fprintf(stderr, "Error: --netfilter is only allowed for root\n");
1902 exit(1);
1654 } 1903 }
1655 else { 1904#endif
1656 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n"); 1905 // run time restricted networking
1906 if (checkcfg(CFG_RESTRICTED_NETWORK) && getuid() != 0) {
1907 fprintf(stderr, "Error: --netfilter is only allowed for root\n");
1657 exit(1); 1908 exit(1);
1658 } 1909 }
1910 if (checkcfg(CFG_NETWORK)) {
1911 arg_netfilter = 1;
1912 }
1913 else
1914 exit_err_feature("networking");
1659 } 1915 }
1660 1916
1661 else if (strncmp(argv[i], "--netfilter=", 12) == 0) { 1917 else if (strncmp(argv[i], "--netfilter=", 12) == 0) {
1918#ifdef HAVE_NETWORK_RESTRICTED
1919 // compile time restricted networking
1920 if (getuid() != 0) {
1921 fprintf(stderr, "Error: --netfilter is only allowed for root\n");
1922 exit(1);
1923 }
1924#endif
1925 // run time restricted networking
1926 if (checkcfg(CFG_RESTRICTED_NETWORK) && getuid() != 0) {
1927 fprintf(stderr, "Error: --netfilter is only allowed for root\n");
1928 exit(1);
1929 }
1662 if (checkcfg(CFG_NETWORK)) { 1930 if (checkcfg(CFG_NETWORK)) {
1663 arg_netfilter = 1; 1931 arg_netfilter = 1;
1664 arg_netfilter_file = argv[i] + 12; 1932 arg_netfilter_file = argv[i] + 12;
1665 check_netfilter_file(arg_netfilter_file); 1933 check_netfilter_file(arg_netfilter_file);
1666 } 1934 }
1667 else { 1935 else
1668 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n"); 1936 exit_err_feature("networking");
1669 exit(1);
1670 }
1671 } 1937 }
1672 1938
1673 else if (strncmp(argv[i], "--netfilter6=", 13) == 0) { 1939 else if (strncmp(argv[i], "--netfilter6=", 13) == 0) {
@@ -1676,41 +1942,61 @@ int main(int argc, char **argv) {
1676 arg_netfilter6_file = argv[i] + 13; 1942 arg_netfilter6_file = argv[i] + 13;
1677 check_netfilter_file(arg_netfilter6_file); 1943 check_netfilter_file(arg_netfilter6_file);
1678 } 1944 }
1679 else { 1945 else
1680 fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n"); 1946 exit_err_feature("networking");
1681 exit(1);
1682 }
1683 } 1947 }
1684#endif 1948#endif
1685 //************************************* 1949 //*************************************
1686 // command 1950 // command
1687 //************************************* 1951 //*************************************
1952 else if (strcmp(argv[i], "--audit") == 0) {
1953 arg_audit_prog = LIBDIR "/firejail/faudit";
1954 arg_audit = 1;
1955 }
1956 else if (strncmp(argv[i], "--audit=", 8) == 0) {
1957 if (strlen(argv[i] + 8) == 0) {
1958 fprintf(stderr, "Error: invalid audit program\n");
1959 exit(1);
1960 }
1961 arg_audit_prog = strdup(argv[i] + 8);
1962 if (!arg_audit_prog)
1963 errExit("strdup");
1964
1965 struct stat s;
1966 if (stat(arg_audit_prog, &s) != 0) {
1967 fprintf(stderr, "Error: cannot find the audit program %s\n", arg_audit_prog);
1968 exit(1);
1969 }
1970 arg_audit = 1;
1971 }
1972 else if (strcmp(argv[i], "--appimage") == 0)
1973 arg_appimage = 1;
1688 else if (strcmp(argv[i], "--csh") == 0) { 1974 else if (strcmp(argv[i], "--csh") == 0) {
1689 if (arg_shell_none) { 1975 if (arg_shell_none) {
1690 1976
1691 fprintf(stderr, "Error: --shell=none was already specified.\n"); 1977 fprintf(stderr, "Error: --shell=none was already specified.\n");
1692 return 1; 1978 return 1;
1693 } 1979 }
1694 if (arg_zsh || cfg.shell ) { 1980 if (cfg.shell) {
1695 fprintf(stderr, "Error: only one default user shell can be specified\n"); 1981 fprintf(stderr, "Error: only one default user shell can be specified\n");
1696 return 1; 1982 return 1;
1697 } 1983 }
1698 arg_csh = 1; 1984 cfg.shell = "/bin/csh";
1699 } 1985 }
1700 else if (strcmp(argv[i], "--zsh") == 0) { 1986 else if (strcmp(argv[i], "--zsh") == 0) {
1701 if (arg_shell_none) { 1987 if (arg_shell_none) {
1702 fprintf(stderr, "Error: --shell=none was already specified.\n"); 1988 fprintf(stderr, "Error: --shell=none was already specified.\n");
1703 return 1; 1989 return 1;
1704 } 1990 }
1705 if (arg_csh || cfg.shell ) { 1991 if (cfg.shell) {
1706 fprintf(stderr, "Error: only one default user shell can be specified\n"); 1992 fprintf(stderr, "Error: only one default user shell can be specified\n");
1707 return 1; 1993 return 1;
1708 } 1994 }
1709 arg_zsh = 1; 1995 cfg.shell = "/bin/zsh";
1710 } 1996 }
1711 else if (strcmp(argv[i], "--shell=none") == 0) { 1997 else if (strcmp(argv[i], "--shell=none") == 0) {
1712 arg_shell_none = 1; 1998 arg_shell_none = 1;
1713 if (arg_csh || arg_zsh || cfg.shell) { 1999 if (cfg.shell) {
1714 fprintf(stderr, "Error: a shell was already specified\n"); 2000 fprintf(stderr, "Error: a shell was already specified\n");
1715 return 1; 2001 return 1;
1716 } 2002 }
@@ -1722,7 +2008,7 @@ int main(int argc, char **argv) {
1722 } 2008 }
1723 invalid_filename(argv[i] + 8); 2009 invalid_filename(argv[i] + 8);
1724 2010
1725 if (arg_csh || arg_zsh || cfg.shell) { 2011 if (cfg.shell) {
1726 fprintf(stderr, "Error: only one user shell can be specified\n"); 2012 fprintf(stderr, "Error: only one user shell can be specified\n");
1727 return 1; 2013 return 1;
1728 } 2014 }
@@ -1732,9 +2018,18 @@ int main(int argc, char **argv) {
1732 fprintf(stderr, "Error: invalid shell\n"); 2018 fprintf(stderr, "Error: invalid shell\n");
1733 exit(1); 2019 exit(1);
1734 } 2020 }
1735 2021
1736 // access call checks as real UID/GID, not as effective UID/GID 2022 // access call checks as real UID/GID, not as effective UID/GID
1737 if (access(cfg.shell, R_OK)) { 2023 if(cfg.chrootdir) {
2024 char *shellpath;
2025 if (asprintf(&shellpath, "%s%s", cfg.chrootdir, cfg.shell) == -1)
2026 errExit("asprintf");
2027 if (access(shellpath, R_OK)) {
2028 fprintf(stderr, "Error: cannot access shell file in chroot\n");
2029 exit(1);
2030 }
2031 free(shellpath);
2032 } else if (access(cfg.shell, R_OK)) {
1738 fprintf(stderr, "Error: cannot access shell file\n"); 2033 fprintf(stderr, "Error: cannot access shell file\n");
1739 exit(1); 2034 exit(1);
1740 } 2035 }
@@ -1746,6 +2041,30 @@ int main(int argc, char **argv) {
1746 return 1; 2041 return 1;
1747 } 2042 }
1748 } 2043 }
2044
2045 // unlike all other x11 features, this is available always
2046 else if (strcmp(argv[i], "--x11=none") == 0) {
2047 arg_x11_block = 1;
2048 }
2049#ifdef HAVE_X11
2050 else if (strcmp(argv[i], "--x11=xorg") == 0) {
2051 if (checkcfg(CFG_X11))
2052 arg_x11_xorg = 1;
2053 else
2054 exit_err_feature("x11");
2055 }
2056#endif
2057 else if (strncmp(argv[i], "--join-or-start=", 16) == 0) {
2058 // NOTE: this is second part of option handler,
2059 // atempt to find and join sandbox is done in other one
2060
2061 // set sandbox name and start normally
2062 cfg.name = argv[i] + 16;
2063 if (strlen(cfg.name) == 0) {
2064 fprintf(stderr, "Error: please provide a name for sandbox\n");
2065 return 1;
2066 }
2067 }
1749 else if (strcmp(argv[i], "--") == 0) { 2068 else if (strcmp(argv[i], "--") == 0) {
1750 // double dash - positional params to follow 2069 // double dash - positional params to follow
1751 arg_doubledash = 1; 2070 arg_doubledash = 1;
@@ -1766,15 +2085,33 @@ int main(int argc, char **argv) {
1766 } 2085 }
1767 2086
1768 // we have a program name coming 2087 // we have a program name coming
1769 extract_command_name(i, argv); 2088 if (arg_appimage) {
2089 cfg.command_name = strdup(argv[i]);
2090 if (!cfg.command_name)
2091 errExit("strdup");
2092 }
2093 else
2094 extract_command_name(i, argv);
1770 prog_index = i; 2095 prog_index = i;
1771 break; 2096 break;
1772 } 2097 }
1773 } 2098 }
2099
2100 // prog_index could still be -1 if no program was specified
2101 if (prog_index == -1 && arg_shell_none) {
2102 fprintf(stderr, "shell=none configured, but no program specified\n");
2103 exit(1);
2104 }
1774 2105
1775 // check trace configuration 2106 // check trace configuration
1776 if (arg_trace && arg_tracelog) 2107 if (arg_trace && arg_tracelog) {
1777 fprintf(stderr, "Warning: --trace and --tracelog are mutually exclusive; --tracelog disabled\n"); 2108 if (!arg_quiet || arg_debug)
2109 fprintf(stderr, "Warning: --trace and --tracelog are mutually exclusive; --tracelog disabled\n");
2110 }
2111
2112 // disable x11 abstract socket
2113 if (getenv("FIREJAIL_X11"))
2114 mask_x11_abstract_socket = 1;
1778 2115
1779 // check user namespace (--noroot) options 2116 // check user namespace (--noroot) options
1780 if (arg_noroot) { 2117 if (arg_noroot) {
@@ -1798,66 +2135,41 @@ int main(int argc, char **argv) {
1798 free(msg); 2135 free(msg);
1799 } 2136 }
1800 2137
1801 // build the sandbox command 2138 // guess shell if unspecified
1802 if (prog_index == -1 && arg_zsh) { 2139 if (!arg_shell_none && !cfg.shell) {
1803 cfg.command_line = "/usr/bin/zsh"; 2140 cfg.shell = guess_shell();
1804 cfg.window_title = "/usr/bin/zsh"; 2141 if (!cfg.shell) {
1805 cfg.command_name = "zsh"; 2142 fprintf(stderr, "Error: unable to guess your shell, please set explicitly by using --shell option.\n");
1806 } 2143 exit(1);
1807 else if (prog_index == -1 && arg_csh) { 2144 }
1808 cfg.command_line = "/bin/csh"; 2145 if (arg_debug)
1809 cfg.window_title = "/bin/csh"; 2146 printf("Autoselecting %s as shell\n", cfg.shell);
1810 cfg.command_name = "csh";
1811 } 2147 }
1812 else if (prog_index == -1 && cfg.shell) { 2148
2149 // build the sandbox command
2150 if (prog_index == -1 && cfg.shell) {
1813 cfg.command_line = cfg.shell; 2151 cfg.command_line = cfg.shell;
1814 cfg.window_title = cfg.shell; 2152 cfg.window_title = cfg.shell;
1815 cfg.command_name = cfg.shell; 2153 cfg.command_name = cfg.shell;
1816 } 2154 }
1817 else if (prog_index == -1) { 2155 else if (arg_appimage) {
1818 cfg.command_line = "/bin/bash"; 2156 if (arg_debug)
1819 cfg.window_title = "/bin/bash"; 2157 printf("Configuring appimage environment\n");
1820 cfg.command_name = "bash"; 2158 appimage_set(cfg.command_name);
2159 cfg.window_title = "appimage";
1821 } 2160 }
1822 else { 2161 else {
1823 // calculate the length of the command 2162 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 } 2163 }
2164/* else {
2165 fprintf(stderr, "Error: command must be specified when --shell=none used.\n");
2166 exit(1);
2167 }*/
1857 2168
1858 assert(cfg.command_name); 2169 assert(cfg.command_name);
1859 if (arg_debug) 2170 if (arg_debug)
1860 printf("Command name #%s#\n", cfg.command_name); 2171 printf("Command name #%s#\n", cfg.command_name);
2172
1861 2173
1862 // load the profile 2174 // load the profile
1863 if (!arg_noprofile) { 2175 if (!arg_noprofile) {
@@ -1881,14 +2193,16 @@ int main(int argc, char **argv) {
1881 } 2193 }
1882 } 2194 }
1883 2195
1884 // use generic.profile as the default 2196 // use default.profile as the default
1885 if (!custom_profile && !arg_noprofile) { 2197 if (!custom_profile && !arg_noprofile) {
1886 if (cfg.chrootdir) 2198 if (cfg.chrootdir) {
1887 fprintf(stderr, "Warning: default profile disabled by --chroot option\n"); 2199 if (!arg_quiet || arg_debug)
1888 else if (arg_overlay) 2200 fprintf(stderr, "Warning: default profile disabled by --chroot option\n");
1889 fprintf(stderr, "Warning: default profile disabled by --overlay option\n"); 2201 }
1890// else if (cfg.home_private_keep) 2202 else if (arg_overlay) {
1891// fprintf(stderr, "Warning: default profile disabled by --private-home option\n"); 2203 if (!arg_quiet || arg_debug)
2204 fprintf(stderr, "Warning: default profile disabled by --overlay option\n");
2205 }
1892 else { 2206 else {
1893 // try to load a default profile 2207 // try to load a default profile
1894 char *profile_name = DEFAULT_USER_PROFILE; 2208 char *profile_name = DEFAULT_USER_PROFILE;
@@ -1911,12 +2225,20 @@ int main(int argc, char **argv) {
1911 else 2225 else
1912 custom_profile = profile_find(profile_name, SYSCONFDIR); 2226 custom_profile = profile_find(profile_name, SYSCONFDIR);
1913 } 2227 }
2228 if (!custom_profile) {
2229 fprintf(stderr, "Error: no default.profile installed\n");
2230 exit(1);
2231 }
1914 2232
1915 if (custom_profile && !arg_quiet) 2233 if (custom_profile && !arg_quiet)
1916 printf("\n** Note: you can use --noprofile to disable %s.profile **\n\n", profile_name); 2234 printf("\n** Note: you can use --noprofile to disable %s.profile **\n\n", profile_name);
1917 } 2235 }
1918 } 2236 }
1919 2237
2238 // block X11 sockets
2239 if (arg_x11_block)
2240 x11_block();
2241
1920 // check network configuration options - it will exit if anything went wrong 2242 // check network configuration options - it will exit if anything went wrong
1921 net_check_cfg(); 2243 net_check_cfg();
1922 2244
@@ -1947,11 +2269,13 @@ int main(int argc, char **argv) {
1947 errExit("pipe"); 2269 errExit("pipe");
1948 2270
1949 if (arg_noroot && arg_overlay) { 2271 if (arg_noroot && arg_overlay) {
1950 fprintf(stderr, "Warning: --overlay and --noroot are mutually exclusive, noroot disabled\n"); 2272 if (!arg_quiet || arg_debug)
2273 fprintf(stderr, "Warning: --overlay and --noroot are mutually exclusive, noroot disabled\n");
1951 arg_noroot = 0; 2274 arg_noroot = 0;
1952 } 2275 }
1953 else if (arg_noroot && cfg.chrootdir) { 2276 else if (arg_noroot && cfg.chrootdir) {
1954 fprintf(stderr, "Warning: --chroot and --noroot are mutually exclusive, noroot disabled\n"); 2277 if (!arg_quiet || arg_debug)
2278 fprintf(stderr, "Warning: --chroot and --noroot are mutually exclusive, noroot disabled\n");
1955 arg_noroot = 0; 2279 arg_noroot = 0;
1956 } 2280 }
1957 2281
@@ -2012,7 +2336,10 @@ int main(int argc, char **argv) {
2012 network_main(child); 2336 network_main(child);
2013 if (arg_debug) 2337 if (arg_debug)
2014 printf("Host network configured\n"); 2338 printf("Host network configured\n");
2015 exit(0); 2339#ifdef HAVE_GCOV
2340 __gcov_flush();
2341#endif
2342 _exit(0);
2016 } 2343 }
2017 2344
2018 // wait for the child to finish 2345 // wait for the child to finish
@@ -2061,16 +2388,30 @@ int main(int argc, char **argv) {
2061 ptr += strlen(ptr); 2388 ptr += strlen(ptr);
2062 2389
2063 // add tty group 2390 // add tty group
2064 gid_t ttygid = get_tty_gid(); 2391 gid_t g = get_group_id("tty");
2065 if (ttygid) { 2392 if (g) {
2066 sprintf(ptr, "%d %d 1\n", ttygid, ttygid); 2393 sprintf(ptr, "%d %d 1\n", g, g);
2067 ptr += strlen(ptr); 2394 ptr += strlen(ptr);
2068 } 2395 }
2069 2396
2070 // add audio group 2397 // add audio group
2071 gid_t audiogid = get_audio_gid(); 2398 g = get_group_id("audio");
2072 if (ttygid) { 2399 if (g) {
2073 sprintf(ptr, "%d %d 1\n", audiogid, audiogid); 2400 sprintf(ptr, "%d %d 1\n", g, g);
2401 ptr += strlen(ptr);
2402 }
2403
2404 // add video group
2405 g = get_group_id("video");
2406 if (g) {
2407 sprintf(ptr, "%d %d 1\n", g, g);
2408 ptr += strlen(ptr);
2409 }
2410
2411 // add games group
2412 g = get_group_id("games");
2413 if (g) {
2414 sprintf(ptr, "%d %d 1\n", g, g);
2074 } 2415 }
2075 2416
2076 EUID_ROOT(); 2417 EUID_ROOT();
@@ -2084,8 +2425,10 @@ int main(int argc, char **argv) {
2084 close(parent_to_child_fds[1]); 2425 close(parent_to_child_fds[1]);
2085 2426
2086 EUID_ROOT(); 2427 EUID_ROOT();
2087 if (lockfd != -1) 2428 if (lockfd != -1) {
2088 flock(lockfd, LOCK_UN); 2429 flock(lockfd, LOCK_UN);
2430 close(lockfd);
2431 }
2089 2432
2090 // create name file under /run/firejail 2433 // create name file under /run/firejail
2091 2434
@@ -2101,13 +2444,6 @@ int main(int argc, char **argv) {
2101 waitpid(child, &status, 0); 2444 waitpid(child, &status, 0);
2102 2445
2103 // free globals 2446 // 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) { 2447 if (cfg.profile) {
2112 ProfileEntry *prf = cfg.profile; 2448 ProfileEntry *prf = cfg.profile;
2113 while (prf != NULL) { 2449 while (prf != NULL) {
diff --git a/src/firejail/netfilter.c b/src/firejail/netfilter.c
index 71abfb53d..9e759ec70 100644
--- a/src/firejail/netfilter.c
+++ b/src/firejail/netfilter.c
@@ -47,67 +47,14 @@ void check_netfilter_file(const char *fname) {
47 EUID_ASSERT(); 47 EUID_ASSERT();
48 invalid_filename(fname); 48 invalid_filename(fname);
49 49
50 if (is_dir(fname) || is_link(fname) || strstr(fname, "..")) { 50 if (is_dir(fname) || is_link(fname) || strstr(fname, "..") || access(fname, R_OK )) {
51 fprintf(stderr, "Error: invalid network filter file\n"); 51 fprintf(stderr, "Error: invalid network filter file %s\n", fname);
52 exit(1);
53 }
54
55 // access call checks as real UID/GID, not as effective UID/GID
56 if (access(fname, R_OK)) {
57 fprintf(stderr, "Error: cannot access network filter file\n");
58 exit(1); 52 exit(1);
59 } 53 }
60} 54}
61 55
62 56
63void netfilter(const char *fname) { 57void netfilter(const char *fname) {
64 // default filter
65 char *filter = client_filter;
66
67 // custom filter
68 int allocated = 0;
69 if (fname) {
70 // buffer the filter
71 struct stat s;
72 if (stat(fname, &s) == -1) {
73 fprintf(stderr, "Error: cannot find network filter file %s\n", fname);
74 exit(1);
75 }
76
77 filter = malloc(s.st_size + 1); // + '\0'
78 if (!filter)
79 errExit("malloc");
80 memset(filter, 0, s.st_size + 1);
81
82 /* coverity[toctou] */
83 FILE *fp = fopen(fname, "r");
84 if (!fp) {
85 fprintf(stderr, "Error: cannot open network filter file %s\n", fname);
86 exit(1);
87 }
88
89 size_t sz = fread(filter, 1, s.st_size, fp);
90 if ((off_t)sz != s.st_size) {
91 fprintf(stderr, "Error: cannot read network filter file %s\n", fname);
92 exit(1);
93 }
94 fclose(fp);
95 allocated = 1;
96 }
97
98 // temporarily mount a tempfs on top of /tmp directory
99 if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
100 errExit("mounting /tmp");
101
102 // create the filter file
103 FILE *fp = fopen("/tmp/netfilter", "w");
104 if (!fp) {
105 fprintf(stderr, "Error: cannot open /tmp/netfilter file\n");
106 exit(1);
107 }
108 fprintf(fp, "%s\n", filter);
109 fclose(fp);
110
111 // find iptables command 58 // find iptables command
112 struct stat s; 59 struct stat s;
113 char *iptables = NULL; 60 char *iptables = NULL;
@@ -121,108 +68,56 @@ void netfilter(const char *fname) {
121 iptables_restore = "/usr/sbin/iptables-restore"; 68 iptables_restore = "/usr/sbin/iptables-restore";
122 } 69 }
123 if (iptables == NULL || iptables_restore == NULL) { 70 if (iptables == NULL || iptables_restore == NULL) {
124 fprintf(stderr, "Error: iptables command not found\n"); 71 fprintf(stderr, "Error: iptables command not found, netfilter not configured\n");
125 goto doexit; 72 return;
126 } 73 }
127 74
128 // push filter 75 // read filter
129 pid_t child = fork(); 76 char *filter = client_filter;
130 if (child < 0) 77 int allocated = 0;
131 errExit("fork"); 78 if (netfilter_default)
132 if (child == 0) { 79 fname = netfilter_default;
133 if (arg_debug) 80 if (fname) {
134 printf("Installing network filter:\n%s\n", filter); 81 filter = read_text_file_or_exit(fname);
135 82 allocated = 1;
136 int fd;
137 if((fd = open("/tmp/netfilter", O_RDONLY)) == -1) {
138 fprintf(stderr,"Error: cannot open /tmp/netfilter\n");
139 exit(1);
140 }
141 dup2(fd,STDIN_FILENO);
142
143 // wipe out environment variables
144 environ = NULL;
145 execl(iptables_restore, iptables_restore, NULL);
146 // it will never get here!!!
147 } 83 }
148 // wait for the child to finish
149 waitpid(child, NULL, 0);
150 84
151 // debug 85 // create the filter file
152 if (arg_debug) { 86 FILE *fp = fopen(SBOX_STDIN_FILE, "w");
153 child = fork(); 87 if (!fp) {
154 if (child < 0) 88 fprintf(stderr, "Error: cannot open %s\n", SBOX_STDIN_FILE);
155 errExit("fork"); 89 exit(1);
156 if (child == 0) {
157 // elevate privileges in order to get grsecurity working
158 if (setreuid(0, 0))
159 errExit("setreuid");
160 if (setregid(0, 0))
161 errExit("setregid");
162 environ = NULL;
163 execl(iptables, iptables, "-vL", NULL);
164 // it will never get here!!!
165 }
166 // wait for the child to finish
167 waitpid(child, NULL, 0);
168 } 90 }
91 fprintf(fp, "%s\n", filter);
92 fclose(fp);
93
94
95 // push filter
96 if (arg_debug)
97 printf("Installing network filter:\n%s\n", filter);
98
99 // first run of iptables on this platform installs a number of kernel modules such as ip_tables, x_tables, iptable_filter
100 // we run this command with caps and seccomp disabled in order to allow the loading of these modules
101 sbox_run(SBOX_ROOT /* | SBOX_CAPS_NETWORK | SBOX_SECCOMP*/ | SBOX_STDIN_FROM_FILE, 1, iptables_restore);
102 unlink(SBOX_STDIN_FILE);
169 103
170doexit: 104 // debug
171 // unmount /tmp 105 if (arg_debug)
172 umount("/tmp"); 106 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 2, iptables, "-vL");
173 107
174 if (allocated) 108 if (allocated)
175 free(filter); 109 free(filter);
110 return;
176} 111}
177 112
178void netfilter6(const char *fname) { 113void netfilter6(const char *fname) {
179 if (fname == NULL) 114 if (fname == NULL)
180 return; 115 return;
181 116
182 char *filter;
183
184 // buffer the filter
185 struct stat s;
186 if (stat(fname, &s) == -1) {
187 fprintf(stderr, "Error: cannot find network filter file %s\n", fname);
188 exit(1);
189 }
190
191 filter = malloc(s.st_size + 1); // + '\0'
192 if (!filter)
193 errExit("malloc");
194 memset(filter, 0, s.st_size + 1);
195
196 /* coverity[toctou] */
197 FILE *fp = fopen(fname, "r");
198 if (!fp) {
199 fprintf(stderr, "Error: cannot open network filter file %s\n", fname);
200 exit(1);
201 }
202
203 size_t sz = fread(filter, 1, s.st_size, fp);
204 if ((off_t)sz != s.st_size) {
205 fprintf(stderr, "Error: cannot read network filter file %s\n", fname);
206 exit(1);
207 }
208 fclose(fp);
209
210 // temporarily mount a tempfs on top of /tmp directory
211 if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
212 errExit("mounting /tmp");
213
214 // create the filter file
215 fp = fopen("/tmp/netfilter6", "w");
216 if (!fp) {
217 fprintf(stderr, "Error: cannot open /tmp/netfilter6 file\n");
218 exit(1);
219 }
220 fprintf(fp, "%s\n", filter);
221 fclose(fp);
222
223 // find iptables command 117 // find iptables command
224 char *ip6tables = NULL; 118 char *ip6tables = NULL;
225 char *ip6tables_restore = NULL; 119 char *ip6tables_restore = NULL;
120 struct stat s;
226 if (stat("/sbin/ip6tables", &s) == 0) { 121 if (stat("/sbin/ip6tables", &s) == 0) {
227 ip6tables = "/sbin/ip6tables"; 122 ip6tables = "/sbin/ip6tables";
228 ip6tables_restore = "/sbin/ip6tables-restore"; 123 ip6tables_restore = "/sbin/ip6tables-restore";
@@ -232,49 +127,33 @@ void netfilter6(const char *fname) {
232 ip6tables_restore = "/usr/sbin/ip6tables-restore"; 127 ip6tables_restore = "/usr/sbin/ip6tables-restore";
233 } 128 }
234 if (ip6tables == NULL || ip6tables_restore == NULL) { 129 if (ip6tables == NULL || ip6tables_restore == NULL) {
235 fprintf(stderr, "Error: ip6tables command not found\n"); 130 fprintf(stderr, "Error: ip6tables command not found, netfilter6 not configured\n");
236 goto doexit; 131 return;
237 } 132 }
238 133
239 // push filter 134 // create the filter file
240 pid_t child = fork(); 135 char *filter = read_text_file_or_exit(fname);
241 if (child < 0) 136 FILE *fp = fopen(SBOX_STDIN_FILE, "w");
242 errExit("fork"); 137 if (!fp) {
243 if (child == 0) { 138 fprintf(stderr, "Error: cannot open %s\n", SBOX_STDIN_FILE);
244 if (arg_debug) 139 exit(1);
245 printf("Installing network filter:\n%s\n", filter);
246
247 int fd;
248 if((fd = open("/tmp/netfilter6", O_RDONLY)) == -1) {
249 fprintf(stderr,"Error: cannot open /tmp/netfilter6\n");
250 exit(1);
251 }
252 dup2(fd,STDIN_FILENO);
253
254 // wipe out environment variables
255 environ = NULL;
256 execl(ip6tables_restore, ip6tables_restore, NULL);
257 // it will never get here!!!
258 } 140 }
259 // wait for the child to finish 141 fprintf(fp, "%s\n", filter);
260 waitpid(child, NULL, 0); 142 fclose(fp);
261 143
144 // push filter
145 if (arg_debug)
146 printf("Installing network filter:\n%s\n", filter);
147
148 // first run of iptables on this platform installs a number of kernel modules such as ip_tables, x_tables, iptable_filter
149 // we run this command with caps and seccomp disabled in order to allow the loading of these modules
150 sbox_run(SBOX_ROOT | /* SBOX_CAPS_NETWORK | SBOX_SECCOMP | */ SBOX_STDIN_FROM_FILE, 1, ip6tables_restore);
151 unlink(SBOX_STDIN_FILE);
152
262 // debug 153 // debug
263 if (arg_debug) { 154 if (arg_debug)
264 child = fork(); 155 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 2, ip6tables, "-vL");
265 if (child < 0)
266 errExit("fork");
267 if (child == 0) {
268 environ = NULL;
269 execl(ip6tables, ip6tables, "-vL", NULL);
270 // it will never get here!!!
271 }
272 // wait for the child to finish
273 waitpid(child, NULL, 0);
274 }
275 156
276doexit:
277 // unmount /tmp
278 umount("/tmp");
279 free(filter); 157 free(filter);
158 return;
280} 159}
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..c56d90994 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,73 @@ 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], "--debug") == 0)
110 command = "/bin/bash"; 169 arg_debug = 1;
111 else { 170 else if (strcmp(argv[i], "--csh") == 0 ||
112 // calculate length 171 strcmp(argv[i], "--zsh") == 0 ||
113 int len = 0; 172 strcmp(argv[i], "--shell=none") == 0 ||
114 int i; 173 strncmp(argv[i], "--shell=", 8) == 0)
115 for (i = 1; i < argc; i++) { 174 fprintf(stderr, "Warning: shell-related command line options are disregarded - using SHELL environment variable");
116 if (*argv[i] == '-') 175 }
117 continue; 176
177 // use $SHELL to get shell used in sandbox
178 char *shell = getenv("SHELL");
179 if (shell && access(shell, R_OK) == 0)
180 cfg.shell = shell;
181
182 // guess shell otherwise
183 if (!cfg.shell) {
184 cfg.shell = guess_shell();
185 if (arg_debug)
186 printf("Autoselecting %s as shell\n", cfg.shell);
187 }
188 if (!cfg.shell) {
189 fprintf(stderr, "Error: unable to guess your shell, please set SHELL environment variable\n");
190 exit(1);
191 }
192
193 int prog_index = 0;
194 // find first non option arg:
195 // - first argument not starting wiht --,
196 // - whatever follows after -c (example: firejail -c ls)
197 for (i = 1; i < argc; i++) {
198 if (strcmp(argv[i], "-c") == 0) {
199 prog_index = i + 1;
200 if (prog_index == argc) {
201 fprintf(stderr, "Error: option -c requires an argument\n");
202 exit(1);
203 }
118 break; 204 break;
119 } 205 }
120 int start_index = i; 206 // check first argument not starting with --
121 for (i = start_index; i < argc; i++) 207 if (strncmp(argv[i],"--",2) != 0) {
122 len += strlen(argv[i]) + 1; 208 prog_index = i;
123 209 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 } 210 }
136 } 211 }
137 212
138 // start the program in /bin/sh 213 if (prog_index == 0) {
139 fprintf(stderr, "Warning: an existing sandbox was detected. " 214 cfg.command_line = cfg.shell;
140 "%s will run without any additional sandboxing features in a /bin/sh shell\n", command); 215 cfg.window_title = cfg.shell;
141 int rv = system(command); 216 } else {
142 (void) rv; 217 build_cmdline(&cfg.command_line, &cfg.window_title, argc, argv, prog_index);
143 if (allocated) 218 }
144 free(command); 219
145 exit(1); 220 cfg.original_argv = argv;
221 cfg.original_program_index = prog_index;
222
223 char *command;
224 if (prog_index == 0)
225 command = cfg.shell;
226 else
227 command = argv[prog_index];
228 if (!arg_quiet)
229 fprintf(stderr, "Warning: an existing sandbox was detected. "
230 "%s will run without any additional sandboxing features\n", command);
231
232 arg_quiet = 1;
233 start_application();
146} 234}
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..d2db7d3dd
--- /dev/null
+++ b/src/firejail/preproc.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 "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 //copy defaultl seccomp files
79 copy_file(PATH_SECCOMP_I386, RUN_SECCOMP_I386, getuid(), getgid(), 0644);
80 copy_file(PATH_SECCOMP_AMD64, RUN_SECCOMP_AMD64, getuid(), getgid(), 0644);
81 if (arg_allow_debuggers)
82 copy_file(PATH_SECCOMP_DEFAULT_DEBUG, RUN_SECCOMP_CFG, getuid(), getgid(), 0644);
83 else
84 copy_file(PATH_SECCOMP_DEFAULT, RUN_SECCOMP_CFG, getuid(), getgid(), 0644);
85
86 // as root, create an empty RUN_SECCOMP_PROTOCOL file
87 create_empty_file_as_root(RUN_SECCOMP_PROTOCOL, 0644);
88 if (set_perms(RUN_SECCOMP_PROTOCOL, getuid(), getgid(), 0644))
89 errExit("set_perms");
90 }
91}
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 6ded0ca2f..da3daf95a 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -63,6 +63,13 @@ int profile_find(const char *name, const char *dir) {
63// run-time profiles 63// run-time profiles
64//*************************************************** 64//***************************************************
65 65
66static void warning_feature_disabled(const char *feature) {
67 if (!arg_quiet)
68 fprintf(stderr, "Warning: %s feature is disabled in Firejail configuration file\n", feature);
69}
70
71
72
66// check profile line; if line == 0, this was generated from a command line option 73// check profile line; if line == 0, this was generated from a command line option
67// return 1 if the command is to be added to the linked list of profile commands 74// return 1 if the command is to be added to the linked list of profile commands
68// return 0 if the command was already executed inside the function 75// return 0 if the command was already executed inside the function
@@ -105,7 +112,12 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
105 // mkdir 112 // mkdir
106 if (strncmp(ptr, "mkdir ", 6) == 0) { 113 if (strncmp(ptr, "mkdir ", 6) == 0) {
107 fs_mkdir(ptr + 6); 114 fs_mkdir(ptr + 6);
108 return 0; 115 return 1; // process mkdir again while applying blacklists
116 }
117 // mkfile
118 if (strncmp(ptr, "mkfile ", 7) == 0) {
119 fs_mkfile(ptr + 7);
120 return 1; // process mkfile again while applying blacklists
109 } 121 }
110 // sandbox name 122 // sandbox name
111 else if (strncmp(ptr, "name ", 5) == 0) { 123 else if (strncmp(ptr, "name ", 5) == 0) {
@@ -126,17 +138,21 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
126 if (checkcfg(CFG_USERNS)) 138 if (checkcfg(CFG_USERNS))
127 check_user_namespace(); 139 check_user_namespace();
128 else 140 else
129 fprintf(stderr, "Warning: user namespace feature is disabled in Firejail configuration file\n"); 141 warning_feature_disabled("noroot");
130#endif 142#endif
131 143
132 return 0; 144 return 0;
133 } 145 }
146 else if (strcmp(ptr, "nonewprivs") == 0) {
147 arg_nonewprivs = 1;
148 return 0;
149 }
134 else if (strcmp(ptr, "seccomp") == 0) { 150 else if (strcmp(ptr, "seccomp") == 0) {
135#ifdef HAVE_SECCOMP 151#ifdef HAVE_SECCOMP
136 if (checkcfg(CFG_SECCOMP)) 152 if (checkcfg(CFG_SECCOMP))
137 arg_seccomp = 1; 153 arg_seccomp = 1;
138 else 154 else
139 fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); 155 warning_feature_disabled("seccomp");
140#endif 156#endif
141 return 0; 157 return 0;
142 } 158 }
@@ -160,6 +176,21 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
160 arg_private = 1; 176 arg_private = 1;
161 return 0; 177 return 0;
162 } 178 }
179 if (strncmp(ptr, "private-home ", 13) == 0) {
180#ifdef HAVE_PRIVATE_HOME
181 if (checkcfg(CFG_PRIVATE_HOME)) {
182 cfg.home_private_keep = ptr + 13;
183 arg_private = 1;
184 }
185 else
186 warning_feature_disabled("private-home");
187#endif
188 return 0;
189 }
190 else if (strcmp(ptr, "allusers") == 0) {
191 arg_allusers = 1;
192 return 0;
193 }
163 else if (strcmp(ptr, "private-dev") == 0) { 194 else if (strcmp(ptr, "private-dev") == 0) {
164 arg_private_dev = 1; 195 arg_private_dev = 1;
165 return 0; 196 return 0;
@@ -174,7 +205,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
174 } 205 }
175 else if (strcmp(ptr, "nosound") == 0) { 206 else if (strcmp(ptr, "nosound") == 0) {
176 arg_nosound = 1; 207 arg_nosound = 1;
177 arg_private_dev = 1; 208 return 0;
209 }
210 else if (strcmp(ptr, "no3d") == 0) {
211 arg_no3d = 1;
178 return 0; 212 return 0;
179 } 213 }
180 else if (strcmp(ptr, "netfilter") == 0) { 214 else if (strcmp(ptr, "netfilter") == 0) {
@@ -182,7 +216,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
182 if (checkcfg(CFG_NETWORK)) 216 if (checkcfg(CFG_NETWORK))
183 arg_netfilter = 1; 217 arg_netfilter = 1;
184 else 218 else
185 fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); 219 warning_feature_disabled("networking");
186#endif 220#endif
187 return 0; 221 return 0;
188 } 222 }
@@ -196,7 +230,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
196 check_netfilter_file(arg_netfilter_file); 230 check_netfilter_file(arg_netfilter_file);
197 } 231 }
198 else 232 else
199 fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); 233 warning_feature_disabled("networking");
200#endif 234#endif
201 return 0; 235 return 0;
202 } 236 }
@@ -210,7 +244,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
210 check_netfilter_file(arg_netfilter6_file); 244 check_netfilter_file(arg_netfilter6_file);
211 } 245 }
212 else 246 else
213 fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); 247 warning_feature_disabled("networking");
214#endif 248#endif
215 return 0; 249 return 0;
216 } 250 }
@@ -228,7 +262,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
228 cfg.interface3.configured = 0; 262 cfg.interface3.configured = 0;
229 } 263 }
230 else 264 else
231 fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); 265 warning_feature_disabled("networking");
232#endif 266#endif
233 return 0; 267 return 0;
234 } 268 }
@@ -269,11 +303,34 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
269 net_configure_bridge(br, ptr + 4); 303 net_configure_bridge(br, ptr + 4);
270 } 304 }
271 else 305 else
272 fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); 306 warning_feature_disabled("networking");
273#endif 307#endif
274 return 0; 308 return 0;
275 } 309 }
276 310
311 else if (strncmp(ptr, "veth-name ", 10) == 0) {
312#ifdef HAVE_NETWORK
313 if (checkcfg(CFG_NETWORK)) {
314 Bridge *br = last_bridge_configured();
315 if (br == NULL) {
316 fprintf(stderr, "Error: no network device configured\n");
317 exit(1);
318 }
319
320 br->veth_name = strdup(ptr + 10);
321 if (br->veth_name == NULL)
322 errExit("strdup");
323 if (*br->veth_name == '\0') {
324 fprintf(stderr, "Error: no veth-name configured\n");
325 exit(1);
326 }
327 }
328 else
329 warning_feature_disabled("networking");
330#endif
331 return 0;
332 }
333
277 else if (strncmp(ptr, "iprange ", 8) == 0) { 334 else if (strncmp(ptr, "iprange ", 8) == 0) {
278#ifdef HAVE_NETWORK 335#ifdef HAVE_NETWORK
279 if (checkcfg(CFG_NETWORK)) { 336 if (checkcfg(CFG_NETWORK)) {
@@ -314,24 +371,162 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
314 } 371 }
315 } 372 }
316 else 373 else
317 fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); 374 warning_feature_disabled("networking");
375#endif
376 return 0;
377 }
378
379
380 else if (strncmp(ptr, "mac ", 4) == 0) {
381#ifdef HAVE_NETWORK
382 if (checkcfg(CFG_NETWORK)) {
383 Bridge *br = last_bridge_configured();
384 if (br == NULL) {
385 fprintf(stderr, "Error: no network device configured\n");
386 exit(1);
387 }
388
389 if (mac_not_zero(br->macsandbox)) {
390 fprintf(stderr, "Error: cannot configure the MAC address twice for the same interface\n");
391 exit(1);
392 }
393
394 // read the address
395 if (atomac(ptr + 4, br->macsandbox)) {
396 fprintf(stderr, "Error: invalid MAC address\n");
397 exit(1);
398 }
399 }
400 else
401 warning_feature_disabled("networking");
402#endif
403 return 0;
404 }
405
406 else if (strncmp(ptr, "mtu ", 4) == 0) {
407#ifdef HAVE_NETWORK
408 if (checkcfg(CFG_NETWORK)) {
409 Bridge *br = last_bridge_configured();
410 if (br == NULL) {
411 fprintf(stderr, "Error: no network device configured\n");
412 exit(1);
413 }
414
415 if (sscanf(ptr + 4, "%d", &br->mtu) != 1 || br->mtu < 576 || br->mtu > 9198) {
416 fprintf(stderr, "Error: invalid mtu value\n");
417 exit(1);
418 }
419 }
420 else
421 warning_feature_disabled("networking");
422#endif
423 return 0;
424 }
425
426 else if (strncmp(ptr, "ip ", 3) == 0) {
427#ifdef HAVE_NETWORK
428 if (checkcfg(CFG_NETWORK)) {
429 Bridge *br = last_bridge_configured();
430 if (br == NULL) {
431 fprintf(stderr, "Error: no network device configured\n");
432 exit(1);
433 }
434 if (br->arg_ip_none || br->ipsandbox) {
435 fprintf(stderr, "Error: cannot configure the IP address twice for the same interface\n");
436 exit(1);
437 }
438
439 // configure this IP address for the last bridge defined
440 if (strcmp(ptr + 3, "none") == 0)
441 br->arg_ip_none = 1;
442 else {
443 if (atoip(ptr + 3, &br->ipsandbox)) {
444 fprintf(stderr, "Error: invalid IP address\n");
445 exit(1);
446 }
447 }
448 }
449 else
450 warning_feature_disabled("networking");
451#endif
452 return 0;
453 }
454
455 else if (strncmp(ptr, "ip6 ", 4) == 0) {
456#ifdef HAVE_NETWORK
457 if (checkcfg(CFG_NETWORK)) {
458 Bridge *br = last_bridge_configured();
459 if (br == NULL) {
460 fprintf(stderr, "Error: no network device configured\n");
461 exit(1);
462 }
463 if (br->arg_ip_none || br->ip6sandbox) {
464 fprintf(stderr, "Error: cannot configure the IP address twice for the same interface\n");
465 exit(1);
466 }
467
468 // configure this IP address for the last bridge defined
469 // todo: verify ipv6 syntax
470 br->ip6sandbox = ptr + 4;
471// if (atoip(argv[i] + 5, &br->ipsandbox)) {
472// fprintf(stderr, "Error: invalid IP address\n");
473// exit(1);
474// }
475
476 }
477 else
478 warning_feature_disabled("networking");
479#endif
480 return 0;
481 }
482
483 else if (strncmp(ptr, "defaultgw ", 10) == 0) {
484#ifdef HAVE_NETWORK
485 if (checkcfg(CFG_NETWORK)) {
486 if (atoip(ptr + 10, &cfg.defaultgw)) {
487 fprintf(stderr, "Error: invalid IP address\n");
488 exit(1);
489 }
490 }
491 else
492 warning_feature_disabled("networking");
493#endif
494 return 0;
495 }
496
497 if (strcmp(ptr, "apparmor") == 0) {
498#ifdef HAVE_APPARMOR
499 arg_apparmor = 1;
318#endif 500#endif
319 return 0; 501 return 0;
320 } 502 }
321 503
322
323 if (strncmp(ptr, "protocol ", 9) == 0) { 504 if (strncmp(ptr, "protocol ", 9) == 0) {
324#ifdef HAVE_SECCOMP 505#ifdef HAVE_SECCOMP
325 if (checkcfg(CFG_SECCOMP)) 506 if (checkcfg(CFG_SECCOMP)) {
326 protocol_store(ptr + 9); 507 if (cfg.protocol) {
508 if (!arg_quiet)
509 fprintf(stderr, "Warning: a protocol list is present, the new list \"%s\" will not be installed\n", ptr + 9);
510 return 0;
511 }
512
513 // store list
514 cfg.protocol = strdup(ptr + 9);
515 if (!cfg.protocol)
516 errExit("strdup");
517 }
327 else 518 else
328 fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); 519 warning_feature_disabled("seccomp");
329#endif 520#endif
330 return 0; 521 return 0;
331 } 522 }
332 523
333 if (strncmp(ptr, "env ", 4) == 0) { 524 if (strncmp(ptr, "env ", 4) == 0) {
334 env_store(ptr + 4); 525 env_store(ptr + 4, SETENV);
526 return 0;
527 }
528 if (strncmp(ptr, "rmenv ", 6) == 0) {
529 env_store(ptr + 6, RMENV);
335 return 0; 530 return 0;
336 } 531 }
337 532
@@ -340,12 +535,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
340#ifdef HAVE_SECCOMP 535#ifdef HAVE_SECCOMP
341 if (checkcfg(CFG_SECCOMP)) { 536 if (checkcfg(CFG_SECCOMP)) {
342 arg_seccomp = 1; 537 arg_seccomp = 1;
343 cfg.seccomp_list = strdup(ptr + 8); 538 cfg.seccomp_list = seccomp_check_list(ptr + 8);
344 if (!cfg.seccomp_list)
345 errExit("strdup");
346 } 539 }
347 else 540 else if (!arg_quiet)
348 fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); 541 warning_feature_disabled("seccomp");
349#endif 542#endif
350 543
351 return 0; 544 return 0;
@@ -356,12 +549,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
356#ifdef HAVE_SECCOMP 549#ifdef HAVE_SECCOMP
357 if (checkcfg(CFG_SECCOMP)) { 550 if (checkcfg(CFG_SECCOMP)) {
358 arg_seccomp = 1; 551 arg_seccomp = 1;
359 cfg.seccomp_list_drop = strdup(ptr + 13); 552 cfg.seccomp_list_drop = seccomp_check_list(ptr + 13);
360 if (!cfg.seccomp_list_drop)
361 errExit("strdup");
362 } 553 }
363 else 554 else
364 fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); 555 warning_feature_disabled("seccomp");
365#endif 556#endif
366 return 0; 557 return 0;
367 } 558 }
@@ -371,12 +562,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
371#ifdef HAVE_SECCOMP 562#ifdef HAVE_SECCOMP
372 if (checkcfg(CFG_SECCOMP)) { 563 if (checkcfg(CFG_SECCOMP)) {
373 arg_seccomp = 1; 564 arg_seccomp = 1;
374 cfg.seccomp_list_keep= strdup(ptr + 13); 565 cfg.seccomp_list_keep= seccomp_check_list(ptr + 13);
375 if (!cfg.seccomp_list_keep)
376 errExit("strdup");
377 } 566 }
378 else 567 else
379 fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); 568 warning_feature_disabled("seccomp");
380#endif 569#endif
381 return 0; 570 return 0;
382 } 571 }
@@ -387,9 +576,8 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
387 arg_caps_list = strdup(ptr + 10); 576 arg_caps_list = strdup(ptr + 10);
388 if (!arg_caps_list) 577 if (!arg_caps_list)
389 errExit("strdup"); 578 errExit("strdup");
390 // verify seccomp list and exit if problems 579 // verify caps list and exit if problems
391 if (caps_check_list(arg_caps_list, NULL)) 580 caps_check_list(arg_caps_list, NULL);
392 exit(1);
393 return 0; 581 return 0;
394 } 582 }
395 583
@@ -399,9 +587,8 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
399 arg_caps_list = strdup(ptr + 10); 587 arg_caps_list = strdup(ptr + 10);
400 if (!arg_caps_list) 588 if (!arg_caps_list)
401 errExit("strdup"); 589 errExit("strdup");
402 // verify seccomp list and exit if problems 590 // verify caps list and exit if problems
403 if (caps_check_list(arg_caps_list, NULL)) 591 caps_check_list(arg_caps_list, NULL);
404 exit(1);
405 return 0; 592 return 0;
406 } 593 }
407 594
@@ -441,6 +628,8 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
441 // nice value 628 // nice value
442 if (strncmp(ptr, "nice ", 4) == 0) { 629 if (strncmp(ptr, "nice ", 4) == 0) {
443 cfg.nice = atoi(ptr + 5); 630 cfg.nice = atoi(ptr + 5);
631 if (getuid() != 0 &&cfg.nice < 0)
632 cfg.nice = 0;
444 arg_nice = 1; 633 arg_nice = 1;
445 return 0; 634 return 0;
446 } 635 }
@@ -451,6 +640,26 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
451 return 0; 640 return 0;
452 } 641 }
453 642
643 // writable-etc
644 if (strcmp(ptr, "writable-etc") == 0) {
645 if (cfg.etc_private_keep) {
646 fprintf(stderr, "Error: private-etc and writable-etc are mutually exclusive\n");
647 exit(1);
648 }
649 arg_writable_etc = 1;
650 return 0;
651 }
652
653 if (strcmp(ptr, "machine-id") == 0) {
654 arg_machineid = 1;
655 return 0;
656 }
657 // writable-var
658 if (strcmp(ptr, "writable-var") == 0) {
659 arg_writable_var = 1;
660 return 0;
661 }
662
454 // private directory 663 // private directory
455 if (strncmp(ptr, "private ", 8) == 0) { 664 if (strncmp(ptr, "private ", 8) == 0) {
456 cfg.home_private = ptr + 8; 665 cfg.home_private = ptr + 8;
@@ -459,16 +668,104 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
459 return 0; 668 return 0;
460 } 669 }
461 670
671 if (strcmp(ptr, "x11 none") == 0) {
672 arg_x11_block = 1;
673 return 0;
674 }
675
676 if (strcmp(ptr, "x11 xephyr") == 0) {
677#ifdef HAVE_X11
678 if (checkcfg(CFG_X11)) {
679 char *x11env = getenv("FIREJAIL_X11");
680 if (x11env && strcmp(x11env, "yes") == 0) {
681 mask_x11_abstract_socket = 1;
682 return 0;
683 }
684 else {
685 // start x11
686 x11_start_xephyr(cfg.original_argc, cfg.original_argv);
687 exit(0);
688 }
689 }
690 else
691 warning_feature_disabled("x11");
692#endif
693 return 0;
694 }
695
696 if (strcmp(ptr, "x11 xorg") == 0) {
697#ifdef HAVE_X11
698 if (checkcfg(CFG_X11))
699 arg_x11_xorg = 1;
700 else
701 warning_feature_disabled("x11");
702#endif
703 return 0;
704 }
705 if (strcmp(ptr, "x11 xpra") == 0) {
706#ifdef HAVE_X11
707 if (checkcfg(CFG_X11)) {
708 char *x11env = getenv("FIREJAIL_X11");
709 if (x11env && strcmp(x11env, "yes") == 0) {
710 mask_x11_abstract_socket = 1;
711 return 0;
712 }
713 else {
714 // start x11
715 x11_start_xpra(cfg.original_argc, cfg.original_argv);
716 exit(0);
717 }
718 }
719 else
720 warning_feature_disabled("x11");
721#endif
722 return 0;
723 }
724
725 if (strcmp(ptr, "x11") == 0) {
726#ifdef HAVE_X11
727 if (checkcfg(CFG_X11)) {
728 char *x11env = getenv("FIREJAIL_X11");
729 if (x11env && strcmp(x11env, "yes") == 0) {
730 mask_x11_abstract_socket = 1;
731 return 0;
732 }
733 else {
734 // start x11
735 x11_start(cfg.original_argc, cfg.original_argv);
736 exit(0);
737 }
738 }
739 else
740 warning_feature_disabled("x11");
741#endif
742 return 0;
743 }
744
462 // private /etc list of files and directories 745 // private /etc list of files and directories
463 if (strncmp(ptr, "private-etc ", 12) == 0) { 746 if (strncmp(ptr, "private-etc ", 12) == 0) {
464 cfg.etc_private_keep = ptr + 12; 747 if (arg_writable_etc) {
465 fs_check_etc_list(); 748 fprintf(stderr, "Error: --private-etc and --writable-etc are mutually exclusive\n");
466 if (*cfg.etc_private_keep != '\0') 749 exit(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 } 750 }
751 cfg.etc_private_keep = ptr + 12;
752 arg_private_etc = 1;
753
754 return 0;
755 }
756
757 // private /opt list of files and directories
758 if (strncmp(ptr, "private-opt ", 12) == 0) {
759 cfg.opt_private_keep = ptr + 12;
760 arg_private_opt = 1;
761
762 return 0;
763 }
764
765 // private /srv list of files and directories
766 if (strncmp(ptr, "private-srv ", 12) == 0) {
767 cfg.srv_private_keep = ptr + 12;
768 arg_private_srv = 1;
472 769
473 return 0; 770 return 0;
474 } 771 }
@@ -477,7 +774,6 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
477 if (strncmp(ptr, "private-bin ", 12) == 0) { 774 if (strncmp(ptr, "private-bin ", 12) == 0) {
478 cfg.bin_private_keep = ptr + 12; 775 cfg.bin_private_keep = ptr + 12;
479 arg_private_bin = 1; 776 arg_private_bin = 1;
480 fs_check_bin_list();
481 return 0; 777 return 0;
482 } 778 }
483 779
@@ -514,13 +810,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
514 *(dname2 - 1) = ','; 810 *(dname2 - 1) = ',';
515 return 1; 811 return 1;
516 } 812 }
517 else { 813 else
518 fprintf(stderr, "Warning: bind feature is disabled in Firejail configuration file\n"); 814 warning_feature_disabled("bind");
519 return 0;
520 }
521#else
522 return 0;
523#endif 815#endif
816 return 0;
524 } 817 }
525 818
526 // rlimit 819 // rlimit
@@ -569,6 +862,30 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
569 return 0; 862 return 0;
570 } 863 }
571 864
865 if (strncmp(ptr, "join-or-start ", 14) == 0) {
866 // try to join by name only
867 pid_t pid;
868 if (!name2pid(ptr + 14, &pid)) {
869 if (!cfg.shell && !arg_shell_none)
870 cfg.shell = guess_shell();
871
872 // find first non-option arg
873 int i;
874 for (i = 1; i < cfg.original_argc && strncmp(cfg.original_argv[i], "--", 2) != 0; i++);
875
876 join(pid, cfg.original_argc,cfg.original_argv, i + 1);
877 exit(0);
878 }
879
880 // set sandbox name and start normally
881 cfg.name = ptr + 14;
882 if (strlen(cfg.name) == 0) {
883 fprintf(stderr, "Error: invalid sandbox name\n");
884 exit(1);
885 }
886 return 0;
887 }
888
572 // rest of filesystem 889 // rest of filesystem
573 if (strncmp(ptr, "blacklist ", 10) == 0) 890 if (strncmp(ptr, "blacklist ", 10) == 0)
574 ptr += 10; 891 ptr += 10;
@@ -577,11 +894,23 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
577 else if (strncmp(ptr, "noblacklist ", 12) == 0) 894 else if (strncmp(ptr, "noblacklist ", 12) == 0)
578 ptr += 12; 895 ptr += 12;
579 else if (strncmp(ptr, "whitelist ", 10) == 0) { 896 else if (strncmp(ptr, "whitelist ", 10) == 0) {
580 arg_whitelist = 1; 897#ifdef HAVE_WHITELIST
581 ptr += 10; 898 if (checkcfg(CFG_WHITELIST)) {
899 arg_whitelist = 1;
900 ptr += 10;
901 }
902 else
903 return 0;
904#else
905 return 0;
906#endif
582 } 907 }
583 else if (strncmp(ptr, "read-only ", 10) == 0) 908 else if (strncmp(ptr, "read-only ", 10) == 0)
584 ptr += 10; 909 ptr += 10;
910 else if (strncmp(ptr, "read-write ", 11) == 0)
911 ptr += 11;
912 else if (strncmp(ptr, "noexec ", 7) == 0)
913 ptr += 7;
585 else if (strncmp(ptr, "tmpfs ", 6) == 0) { 914 else if (strncmp(ptr, "tmpfs ", 6) == 0) {
586 if (getuid() != 0) { 915 if (getuid() != 0) {
587 fprintf(stderr, "Error: tmpfs available only when running the sandbox as root\n"); 916 fprintf(stderr, "Error: tmpfs available only when running the sandbox as root\n");
@@ -651,6 +980,16 @@ void profile_read(const char *fname) {
651 exit(1); 980 exit(1);
652 } 981 }
653 982
983 // allow debuggers
984 if (arg_allow_debuggers) {
985 char *tmp = strrchr(fname, '/');
986 if (tmp && *(tmp + 1) != '\0') {
987 tmp++;
988 if (strcmp(tmp, "disable-devel.inc") == 0)
989 return;
990 }
991 }
992
654 // open profile file: 993 // open profile file:
655 FILE *fp = fopen(fname, "r"); 994 FILE *fp = fopen(fname, "r");
656 if (fp == NULL) { 995 if (fp == NULL) {
@@ -658,8 +997,7 @@ void profile_read(const char *fname) {
658 exit(1); 997 exit(1);
659 } 998 }
660 999
661 if (!arg_quiet) 1000 int msg_printed = 0;
662 fprintf(stderr, "Reading profile %s\n", fname);
663 1001
664 // read the file line by line 1002 // read the file line by line
665 char buf[MAX_READ + 1]; 1003 char buf[MAX_READ + 1];
@@ -677,6 +1015,18 @@ void profile_read(const char *fname) {
677 continue; 1015 continue;
678 } 1016 }
679 1017
1018 // process quiet
1019 if (strcmp(ptr, "quiet") == 0) {
1020 arg_quiet = 1;
1021 free(ptr);
1022 continue;
1023 }
1024 if (!msg_printed) {
1025 if (!arg_quiet)
1026 fprintf(stderr, "Reading profile %s\n", fname);
1027 msg_printed = 1;
1028 }
1029
680 // process include 1030 // process include
681 if (strncmp(ptr, "include ", 8) == 0) { 1031 if (strncmp(ptr, "include ", 8) == 0) {
682 include_level++; 1032 include_level++;
@@ -703,6 +1053,9 @@ void profile_read(const char *fname) {
703// else { 1053// else {
704// free(ptr); 1054// free(ptr);
705// } 1055// }
1056#ifdef HAVE_GCOV
1057 __gcov_flush();
1058#endif
706 } 1059 }
707 fclose(fp); 1060 fclose(fp);
708} 1061}
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..f890dd534 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,22 +129,19 @@ 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);
137 if (asprintf(&dir1, "%s/.config/pulse", cfg.homedir) == -1) 137 if (asprintf(&dir1, "%s/.config/pulse", cfg.homedir) == -1)
138 errExit("asprintf"); 138 errExit("asprintf");
139 if (stat(dir1, &s) == -1) { 139 if (stat(dir1, &s) == -1) {
140 /* coverity[toctou] */
140 int rv = mkdir(dir1, 0700); 141 int rv = mkdir(dir1, 0700);
141 if (rv == 0) { 142 if (rv == 0) {
142 rv = chown(dir1, getuid(), getgid()); 143 if (set_perms(dir1, getuid(), getgid(), 0700))
143 (void) rv; 144 {;} // do nothing
144 rv = chmod(dir1, 0700);
145 (void) rv;
146 } 145 }
147 } 146 }
148 free(dir1); 147 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/rlimit.c b/src/firejail/rlimit.c
index a774fd6f5..47dd846d2 100644
--- a/src/firejail/rlimit.c
+++ b/src/firejail/rlimit.c
@@ -27,6 +27,9 @@ void set_rlimits(void) {
27 if (arg_rlimit_nofile) { 27 if (arg_rlimit_nofile) {
28 rl.rlim_cur = (rlim_t) cfg.rlimit_nofile; 28 rl.rlim_cur = (rlim_t) cfg.rlimit_nofile;
29 rl.rlim_max = (rlim_t) cfg.rlimit_nofile; 29 rl.rlim_max = (rlim_t) cfg.rlimit_nofile;
30#ifdef HAVE_GCOV // gcov-instrumented programs might crash at this point
31 __gcov_dump();
32#endif
30 if (setrlimit(RLIMIT_NOFILE, &rl) == -1) 33 if (setrlimit(RLIMIT_NOFILE, &rl) == -1)
31 errExit("setrlimit"); 34 errExit("setrlimit");
32 if (arg_debug) 35 if (arg_debug)
@@ -36,6 +39,9 @@ void set_rlimits(void) {
36 if (arg_rlimit_nproc) { 39 if (arg_rlimit_nproc) {
37 rl.rlim_cur = (rlim_t) cfg.rlimit_nproc; 40 rl.rlim_cur = (rlim_t) cfg.rlimit_nproc;
38 rl.rlim_max = (rlim_t) cfg.rlimit_nproc; 41 rl.rlim_max = (rlim_t) cfg.rlimit_nproc;
42#ifdef HAVE_GCOV
43 __gcov_dump();
44#endif
39 if (setrlimit(RLIMIT_NPROC, &rl) == -1) 45 if (setrlimit(RLIMIT_NPROC, &rl) == -1)
40 errExit("setrlimit"); 46 errExit("setrlimit");
41 if (arg_debug) 47 if (arg_debug)
@@ -45,6 +51,9 @@ void set_rlimits(void) {
45 if (arg_rlimit_fsize) { 51 if (arg_rlimit_fsize) {
46 rl.rlim_cur = (rlim_t) cfg.rlimit_fsize; 52 rl.rlim_cur = (rlim_t) cfg.rlimit_fsize;
47 rl.rlim_max = (rlim_t) cfg.rlimit_fsize; 53 rl.rlim_max = (rlim_t) cfg.rlimit_fsize;
54#ifdef HAVE_GCOV
55 __gcov_dump();
56#endif
48 if (setrlimit(RLIMIT_FSIZE, &rl) == -1) 57 if (setrlimit(RLIMIT_FSIZE, &rl) == -1)
49 errExit("setrlimit"); 58 errExit("setrlimit");
50 if (arg_debug) 59 if (arg_debug)
@@ -54,6 +63,9 @@ void set_rlimits(void) {
54 if (arg_rlimit_sigpending) { 63 if (arg_rlimit_sigpending) {
55 rl.rlim_cur = (rlim_t) cfg.rlimit_sigpending; 64 rl.rlim_cur = (rlim_t) cfg.rlimit_sigpending;
56 rl.rlim_max = (rlim_t) cfg.rlimit_sigpending; 65 rl.rlim_max = (rlim_t) cfg.rlimit_sigpending;
66#ifdef HAVE_GCOV
67 __gcov_dump();
68#endif
57 if (setrlimit(RLIMIT_SIGPENDING, &rl) == -1) 69 if (setrlimit(RLIMIT_SIGPENDING, &rl) == -1)
58 errExit("setrlimit"); 70 errExit("setrlimit");
59 if (arg_debug) 71 if (arg_debug)
diff --git a/src/firejail/run_symlink.c b/src/firejail/run_symlink.c
index d57816e12..753c50208 100644
--- a/src/firejail/run_symlink.c
+++ b/src/firejail/run_symlink.c
@@ -59,6 +59,7 @@ void run_symlink(int argc, char **argv) {
59 59
60 struct stat s; 60 struct stat s;
61 if (stat(name, &s) == 0) { 61 if (stat(name, &s) == 0) {
62 /* coverity[toctou] */
62 char* rp = realpath(name, NULL); 63 char* rp = realpath(name, NULL);
63 if (!rp) 64 if (!rp)
64 errExit("realpath"); 65 errExit("realpath");
@@ -89,16 +90,22 @@ void run_symlink(int argc, char **argv) {
89 if (asprintf(&firejail, "%s/bin/firejail", PREFIX) == -1) 90 if (asprintf(&firejail, "%s/bin/firejail", PREFIX) == -1)
90 errExit("asprintf"); 91 errExit("asprintf");
91 92
92 printf("Redirecting symlink to %s\n", program); 93 // drop privileges
94 if (setgid(getgid()) < 0)
95 errExit("setgid/getgid");
96 if (setuid(getuid()) < 0)
97 errExit("setuid/getuid");
93 98
94 // run command 99 // run command
95 char *a[3 + argc]; 100 char *a[3 + argc];
96 a[0] = firejail; 101 a[0] = firejail;
97 a[1] = program; 102 a[1] = program;
98 int i; 103 int i;
99 for (i = 0; i < (argc - 1); i++) 104 for (i = 0; i < (argc - 1); i++) {
100 a[i + 2] = argv[i + 1]; 105 a[i + 2] = argv[i + 1];
106 }
101 a[i + 2] = NULL; 107 a[i + 2] = NULL;
108 assert(getenv("LD_PRELOAD") == NULL);
102 execvp(a[0], a); 109 execvp(a[0], a);
103 110
104 perror("execvp"); 111 perror("execvp");
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 3f3564295..50fcd6ed0 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
@@ -219,12 +236,15 @@ static int monitor_application(pid_t app_pid) {
219 236
220 // todo: make this generic 237 // todo: make this generic
221 // Dillo browser leaves a dpid process running, we need to shut it down 238 // Dillo browser leaves a dpid process running, we need to shut it down
239 int found = 0;
222 if (strcmp(cfg.command_name, "dillo") == 0) { 240 if (strcmp(cfg.command_name, "dillo") == 0) {
223 char *pidname = pid_proc_comm(pid); 241 char *pidname = pid_proc_comm(pid);
224 if (pidname && strcmp(pidname, "dpid") == 0) 242 if (pidname && strcmp(pidname, "dpid") == 0)
225 break; 243 found = 1;
226 free(pidname); 244 free(pidname);
227 } 245 }
246 if (found)
247 break;
228 248
229 monitored_pid = pid; 249 monitored_pid = pid;
230 break; 250 break;
@@ -237,40 +257,44 @@ static int monitor_application(pid_t app_pid) {
237 257
238 // return the latest exit status. 258 // return the latest exit status.
239 return status; 259 return status;
260}
240 261
241#if 0 262void start_audit(void) {
242// todo: find a way to shut down interfaces before closing the namespace 263 char *audit_prog;
243// the problem is we don't have enough privileges to shutdown interfaces in this moment 264 if (asprintf(&audit_prog, "%s/firejail/faudit", LIBDIR) == -1)
244 // shut down bridge/macvlan interfaces 265 errExit("asprintf");
245 if (any_bridge_configured()) { 266 assert(getenv("LD_PRELOAD") == NULL);
246 267 execl(audit_prog, audit_prog, NULL);
247 if (cfg.bridge0.configured) { 268 perror("execl");
248 printf("Shutting down %s\n", cfg.bridge0.devsandbox); 269 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} 270}
267 271
272void start_application(void) {
273//if (setsid() == -1)
274//errExit("setsid");
268 275
269static void start_application(void) { 276 // set environment
277 env_defaults();
278 env_apply();
279 if (arg_debug) {
280 printf("starting application\n");
281 printf("LD_PRELOAD=%s\n", getenv("LD_PRELOAD"));
282 }
283
284 //****************************************
285 // audit
286 //****************************************
287 if (arg_audit) {
288 assert(arg_audit_prog);
289#ifdef HAVE_GCOV
290 __gcov_dump();
291#endif
292 execl(arg_audit_prog, arg_audit_prog, NULL);
293 }
270 //**************************************** 294 //****************************************
271 // start the program without using a shell 295 // start the program without using a shell
272 //**************************************** 296 //****************************************
273 if (arg_shell_none) { 297 else if (arg_shell_none) {
274 if (arg_debug) { 298 if (arg_debug) {
275 int i; 299 int i;
276 for (i = cfg.original_program_index; i < cfg.original_argc; i++) { 300 for (i = cfg.original_program_index; i < cfg.original_argc; i++) {
@@ -288,36 +312,37 @@ static void start_application(void) {
288 if (!arg_command && !arg_quiet) 312 if (!arg_command && !arg_quiet)
289 printf("Child process initialized\n"); 313 printf("Child process initialized\n");
290 314
315#ifdef HAVE_GCOV
316 __gcov_dump();
317#endif
291 execvp(cfg.original_argv[cfg.original_program_index], &cfg.original_argv[cfg.original_program_index]); 318 execvp(cfg.original_argv[cfg.original_program_index], &cfg.original_argv[cfg.original_program_index]);
319 exit(1);
292 } 320 }
293 //**************************************** 321 //****************************************
294 // start the program using a shell 322 // start the program using a shell
295 //**************************************** 323 //****************************************
296 else { 324 else {
297 // choose the shell requested by the user, or use bash as default 325 assert(cfg.shell);
298 char *sh; 326 assert(cfg.command_line);
299 if (cfg.shell) 327
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]; 328 char *arg[5];
309 int index = 0; 329 int index = 0;
310 arg[index++] = sh; 330 arg[index++] = cfg.shell;
311 arg[index++] = "-c"; 331 if (login_shell) {
312 assert(cfg.command_line); 332 arg[index++] = "-l";
313 if (arg_debug) 333 if (arg_debug)
314 printf("Starting %s\n", cfg.command_line); 334 printf("Starting %s login shell\n", cfg.shell);
315 if (arg_doubledash) 335 } else {
316 arg[index++] = "--"; 336 arg[index++] = "-c";
317 arg[index++] = cfg.command_line; 337 if (arg_debug)
338 printf("Running %s command through %s\n", cfg.command_line, cfg.shell);
339 if (arg_doubledash)
340 arg[index++] = "--";
341 arg[index++] = cfg.command_line;
342 }
318 arg[index] = NULL; 343 arg[index] = NULL;
319 assert(index < 5); 344 assert(index < 5);
320 345
321 if (arg_debug) { 346 if (arg_debug) {
322 char *msg; 347 char *msg;
323 if (asprintf(&msg, "sandbox %d, execvp into %s", sandbox_pid, cfg.command_line) == -1) 348 if (asprintf(&msg, "sandbox %d, execvp into %s", sandbox_pid, cfg.command_line) == -1)
@@ -325,7 +350,7 @@ static void start_application(void) {
325 logmsg(msg); 350 logmsg(msg);
326 free(msg); 351 free(msg);
327 } 352 }
328 353
329 if (arg_debug) { 354 if (arg_debug) {
330 int i; 355 int i;
331 for (i = 0; i < 5; i++) { 356 for (i = 0; i < 5; i++) {
@@ -334,17 +359,43 @@ static void start_application(void) {
334 printf("execvp argument %d: %s\n", i, arg[i]); 359 printf("execvp argument %d: %s\n", i, arg[i]);
335 } 360 }
336 } 361 }
337 362
338 if (!arg_command && !arg_quiet) 363 if (!arg_command && !arg_quiet)
339 printf("Child process initialized\n"); 364 printf("Child process initialized\n");
340 execvp(sh, arg); 365#ifdef HAVE_GCOV
366 __gcov_dump();
367#endif
368 execvp(arg[0], arg);
341 } 369 }
342 370
343 perror("execvp"); 371 perror("execvp");
344 exit(1); // it should never get here!!! 372 exit(1); // it should never get here!!!
345} 373}
346 374
347 375static void enforce_filters(void) {
376 // force default seccomp inside the chroot, no keep or drop list
377 // the list build on top of the default drop list is kept intact
378 arg_seccomp = 1;
379 if (cfg.seccomp_list_drop) {
380 free(cfg.seccomp_list_drop);
381 cfg.seccomp_list_drop = NULL;
382 }
383 if (cfg.seccomp_list_keep) {
384 free(cfg.seccomp_list_keep);
385 cfg.seccomp_list_keep = NULL;
386 }
387
388 // disable all capabilities
389 if (arg_caps_default_filter || arg_caps_list)
390 fprintf(stderr, "Warning: all capabilities disabled for a regular user in chroot\n");
391 arg_caps_drop_all = 1;
392
393 // drop all supplementary groups; /etc/group file inside chroot
394 // is controlled by a regular usr
395 arg_nogroups = 1;
396 if (!arg_quiet)
397 printf("Dropping all Linux capabilities and enforcing default seccomp filter\n");
398}
348 399
349int sandbox(void* sandbox_arg) { 400int sandbox(void* sandbox_arg) {
350 // Get rid of unused parameter warning 401 // Get rid of unused parameter warning
@@ -364,6 +415,7 @@ int sandbox(void* sandbox_arg) {
364 if (arg_debug && child_pid == 1) 415 if (arg_debug && child_pid == 1)
365 printf("PID namespace installed\n"); 416 printf("PID namespace installed\n");
366 417
418
367 //**************************** 419 //****************************
368 // set hostname 420 // set hostname
369 //**************************** 421 //****************************
@@ -379,7 +431,8 @@ int sandbox(void* sandbox_arg) {
379 if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) { 431 if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) {
380 chk_chroot(); 432 chk_chroot();
381 } 433 }
382 434 // ... and mount a tmpfs on top of /run/firejail/mnt directory
435 preproc_mount_mnt_dir();
383 436
384 //**************************** 437 //****************************
385 // log sandbox data 438 // log sandbox data
@@ -396,7 +449,7 @@ int sandbox(void* sandbox_arg) {
396 fs_logger("install mount namespace"); 449 fs_logger("install mount namespace");
397 450
398 //**************************** 451 //****************************
399 // netfilter etc. 452 // netfilter
400 //**************************** 453 //****************************
401 if (arg_netfilter && any_bridge_configured()) { // assuming by default the client filter 454 if (arg_netfilter && any_bridge_configured()) { // assuming by default the client filter
402 netfilter(arg_netfilter_file); 455 netfilter(arg_netfilter_file);
@@ -405,6 +458,101 @@ int sandbox(void* sandbox_arg) {
405 netfilter6(arg_netfilter6_file); 458 netfilter6(arg_netfilter6_file);
406 } 459 }
407 460
461 //****************************
462 // networking
463 //****************************
464 int gw_cfg_failed = 0; // default gw configuration flag
465 if (arg_nonetwork) {
466 net_if_up("lo");
467 if (arg_debug)
468 printf("Network namespace enabled, only loopback interface available\n");
469 }
470 else if (any_bridge_configured() || any_interface_configured()) {
471 // configure lo and eth0...eth3
472 net_if_up("lo");
473
474 if (mac_not_zero(cfg.bridge0.macsandbox))
475 net_config_mac(cfg.bridge0.devsandbox, cfg.bridge0.macsandbox);
476 sandbox_if_up(&cfg.bridge0);
477
478 if (mac_not_zero(cfg.bridge1.macsandbox))
479 net_config_mac(cfg.bridge1.devsandbox, cfg.bridge1.macsandbox);
480 sandbox_if_up(&cfg.bridge1);
481
482 if (mac_not_zero(cfg.bridge2.macsandbox))
483 net_config_mac(cfg.bridge2.devsandbox, cfg.bridge2.macsandbox);
484 sandbox_if_up(&cfg.bridge2);
485
486 if (mac_not_zero(cfg.bridge3.macsandbox))
487 net_config_mac(cfg.bridge3.devsandbox, cfg.bridge3.macsandbox);
488 sandbox_if_up(&cfg.bridge3);
489
490
491 // moving an interface in a namespace using --interface will reset the interface configuration;
492 // we need to put the configuration back
493 if (cfg.interface0.configured && cfg.interface0.ip) {
494 if (arg_debug)
495 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface0.ip), cfg.interface0.dev);
496 net_config_interface(cfg.interface0.dev, cfg.interface0.ip, cfg.interface0.mask, cfg.interface0.mtu);
497 }
498 if (cfg.interface1.configured && cfg.interface1.ip) {
499 if (arg_debug)
500 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface1.ip), cfg.interface1.dev);
501 net_config_interface(cfg.interface1.dev, cfg.interface1.ip, cfg.interface1.mask, cfg.interface1.mtu);
502 }
503 if (cfg.interface2.configured && cfg.interface2.ip) {
504 if (arg_debug)
505 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface2.ip), cfg.interface2.dev);
506 net_config_interface(cfg.interface2.dev, cfg.interface2.ip, cfg.interface2.mask, cfg.interface2.mtu);
507 }
508 if (cfg.interface3.configured && cfg.interface3.ip) {
509 if (arg_debug)
510 printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface3.ip), cfg.interface3.dev);
511 net_config_interface(cfg.interface3.dev, cfg.interface3.ip, cfg.interface3.mask, cfg.interface3.mtu);
512 }
513
514 // add a default route
515 if (cfg.defaultgw) {
516 // set the default route
517 if (net_add_route(0, 0, cfg.defaultgw)) {
518 fprintf(stderr, "Warning: cannot configure default route\n");
519 gw_cfg_failed = 1;
520 }
521 }
522
523 if (arg_debug)
524 printf("Network namespace enabled\n");
525 }
526
527
528 // print network configuration
529 if (!arg_quiet) {
530 if (any_bridge_configured() || any_interface_configured() || cfg.defaultgw || cfg.dns1) {
531 printf("\n");
532 if (any_bridge_configured() || any_interface_configured()) {
533// net_ifprint();
534 if (arg_scan)
535 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 3, PATH_FNET, "printif", "scan");
536 else
537 sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 2, PATH_FNET, "printif", "scan");
538
539 }
540 if (cfg.defaultgw != 0) {
541 if (gw_cfg_failed)
542 printf("Default gateway configuration failed\n");
543 else
544 printf("Default gateway %d.%d.%d.%d\n", PRINT_IP(cfg.defaultgw));
545 }
546 if (cfg.dns1 != 0)
547 printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns1));
548 if (cfg.dns2 != 0)
549 printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns2));
550 if (cfg.dns3 != 0)
551 printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns3));
552 printf("\n");
553 }
554 }
555
408 // load IBUS env variables 556 // load IBUS env variables
409 if (arg_nonetwork || any_bridge_configured() || any_interface_configured()) { 557 if (arg_nonetwork || any_bridge_configured() || any_interface_configured()) {
410 // do nothing - there are problems with ibus version 1.5.11 558 // do nothing - there are problems with ibus version 1.5.11
@@ -412,11 +560,26 @@ int sandbox(void* sandbox_arg) {
412 else 560 else
413 env_ibus_load(); 561 env_ibus_load();
414 562
415 // grab a copy of cp command 563 //****************************
416 fs_build_cp_command(); 564 // fs pre-processing:
417 565 // - build seccomp filters
566 // - create an empty /etc/ld.so.preload
567 //****************************
568#ifdef HAVE_SECCOMP
569 if (cfg.protocol) {
570 if (arg_debug)
571 printf("Build protocol filter: %s\n", cfg.protocol);
572
573 // build the seccomp filter as a regular user
574 int rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 5,
575 PATH_FSECCOMP, "protocol", "build", cfg.protocol, RUN_SECCOMP_PROTOCOL);
576 if (rv)
577 exit(rv);
578 }
579#endif
580
418 // trace pre-install 581 // trace pre-install
419 if (arg_trace || arg_tracelog) 582 if (arg_trace || arg_tracelog || mask_x11_abstract_socket)
420 fs_trace_preload(); 583 fs_trace_preload();
421 584
422 //**************************** 585 //****************************
@@ -425,39 +588,23 @@ int sandbox(void* sandbox_arg) {
425#ifdef HAVE_SECCOMP 588#ifdef HAVE_SECCOMP
426 int enforce_seccomp = 0; 589 int enforce_seccomp = 0;
427#endif 590#endif
591 if (arg_appimage) {
592 enforce_filters();
593#ifdef HAVE_SECCOMP
594 enforce_seccomp = 1;
595#endif
596 }
597
428#ifdef HAVE_CHROOT 598#ifdef HAVE_CHROOT
429 if (cfg.chrootdir) { 599 if (cfg.chrootdir) {
430 fs_chroot(cfg.chrootdir); 600 fs_chroot(cfg.chrootdir);
431 // redo cp command
432 fs_build_cp_command();
433 601
434 // force caps and seccomp if not started as root 602 // force caps and seccomp if not started as root
435 if (getuid() != 0) { 603 if (getuid() != 0) {
436 // force default seccomp inside the chroot, no keep or drop list 604 enforce_filters();
437 // the list build on top of the default drop list is kept intact
438 arg_seccomp = 1;
439#ifdef HAVE_SECCOMP 605#ifdef HAVE_SECCOMP
440 enforce_seccomp = 1; 606 enforce_seccomp = 1;
441#endif 607#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 } 608 }
462 else 609 else
463 arg_seccomp = 1; 610 arg_seccomp = 1;
@@ -465,17 +612,28 @@ int sandbox(void* sandbox_arg) {
465 //**************************** 612 //****************************
466 // trace pre-install, this time inside chroot 613 // trace pre-install, this time inside chroot
467 //**************************** 614 //****************************
468 if (arg_trace || arg_tracelog) 615 if (arg_trace || arg_tracelog || mask_x11_abstract_socket)
469 fs_trace_preload(); 616 fs_trace_preload();
470 } 617 }
471 else 618 else
472#endif 619#endif
473 if (arg_overlay) 620#ifdef HAVE_OVERLAYFS
621 if (arg_overlay) {
474 fs_overlayfs(); 622 fs_overlayfs();
623 // force caps and seccomp if not started as root
624 if (getuid() != 0) {
625 enforce_filters();
626#ifdef HAVE_SECCOMP
627 enforce_seccomp = 1;
628#endif
629 }
630 else
631 arg_seccomp = 1;
632 }
475 else 633 else
634#endif
476 fs_basic_fs(); 635 fs_basic_fs();
477 636
478
479 //**************************** 637 //****************************
480 // set hostname in /etc/hostname 638 // set hostname in /etc/hostname
481 //**************************** 639 //****************************
@@ -487,145 +645,153 @@ int sandbox(void* sandbox_arg) {
487 // private mode 645 // private mode
488 //**************************** 646 //****************************
489 if (arg_private) { 647 if (arg_private) {
490 if (cfg.home_private) // --private= 648 if (cfg.home_private) { // --private=
491 fs_private_homedir(); 649 if (cfg.chrootdir)
650 fprintf(stderr, "Warning: private=directory feature is disabled in chroot\n");
651 else if (arg_overlay)
652 fprintf(stderr, "Warning: private=directory feature is disabled in overlay\n");
653 else
654 fs_private_homedir();
655 }
656 else if (cfg.home_private_keep) { // --private-home=
657 if (cfg.chrootdir)
658 fprintf(stderr, "Warning: private-home= feature is disabled in chroot\n");
659 else if (arg_overlay)
660 fprintf(stderr, "Warning: private-home= feature is disabled in overlay\n");
661 else
662 fs_private_home_list();
663 }
492 else // --private 664 else // --private
493 fs_private(); 665 fs_private();
494 } 666 }
495 667
496 if (arg_private_dev) 668 if (arg_private_dev) {
497 fs_private_dev(); 669 if (cfg.chrootdir)
670 fprintf(stderr, "Warning: private-dev feature is disabled in chroot\n");
671 else if (arg_overlay)
672 fprintf(stderr, "Warning: private-dev feature is disabled in overlay\n");
673 else
674 fs_private_dev();
675 }
676
498 if (arg_private_etc) { 677 if (arg_private_etc) {
499 fs_private_etc_list(); 678 if (cfg.chrootdir)
500 // create /etc/ld.so.preload file again 679 fprintf(stderr, "Warning: private-etc feature is disabled in chroot\n");
501 if (arg_trace || arg_tracelog) 680 else if (arg_overlay)
502 fs_trace_preload(); 681 fprintf(stderr, "Warning: private-etc feature is disabled in overlay\n");
682 else {
683 fs_private_dir_list("/etc", RUN_ETC_DIR, cfg.etc_private_keep);
684 // create /etc/ld.so.preload file again
685 if (arg_trace || arg_tracelog || mask_x11_abstract_socket)
686 fs_trace_preload();
687 }
688 }
689
690 if (arg_private_opt) {
691 if (cfg.chrootdir)
692 fprintf(stderr, "Warning: private-opt feature is disabled in chroot\n");
693 else if (arg_overlay)
694 fprintf(stderr, "Warning: private-opt feature is disabled in overlay\n");
695 else {
696 fs_private_dir_list("/opt", RUN_OPT_DIR, cfg.opt_private_keep);
697 }
698 }
699
700 if (arg_private_srv) {
701 if (cfg.chrootdir)
702 fprintf(stderr, "Warning: private-srv feature is disabled in chroot\n");
703 else if (arg_overlay)
704 fprintf(stderr, "Warning: private-srv feature is disabled in overlay\n");
705 else {
706 fs_private_dir_list("/srv", RUN_SRV_DIR, cfg.srv_private_keep);
707 }
708 }
709
710 if (arg_private_bin) {
711 if (cfg.chrootdir)
712 fprintf(stderr, "Warning: private-bin feature is disabled in chroot\n");
713 else if (arg_overlay)
714 fprintf(stderr, "Warning: private-bin feature is disabled in overlay\n");
715 else {
716 // for --x11=xorg we need to add xauth command
717 if (arg_x11_xorg) {
718 EUID_USER();
719 char *tmp;
720 if (asprintf(&tmp, "%s,xauth", cfg.bin_private_keep) == -1)
721 errExit("asprintf");
722 cfg.bin_private_keep = tmp;
723 EUID_ROOT();
724 }
725 fs_private_bin_list();
726 }
503 } 727 }
504 if (arg_private_bin) 728
505 fs_private_bin_list(); 729 if (arg_private_tmp) {
506 if (arg_private_tmp) 730 if (cfg.chrootdir)
507 fs_private_tmp(); 731 fprintf(stderr, "Warning: private-tmp feature is disabled in chroot\n");
732 else if (arg_overlay)
733 fprintf(stderr, "Warning: private-tmp feature is disabled in overlay\n");
734 else {
735 // private-tmp is implemented as a whitelist
736 EUID_USER();
737 profile_add("whitelist /tmp/.X11-unix");
738 EUID_ROOT();
739 }
740 }
741
742 //****************************
743 // update /proc, /sys, /dev, /boot directorymy
744 //****************************
745 if (checkcfg(CFG_REMOUNT_PROC_SYS))
746 fs_proc_sys_dev_boot();
508 747
509 //**************************** 748 //****************************
510 // apply the profile file 749 // apply the profile file
511 //**************************** 750 //****************************
512 if (cfg.profile) { 751 // apply all whitelist commands ...
513 // apply all whitelist commands ... 752 if (cfg.chrootdir)
753 fprintf(stderr, "Warning: whitelist feature is disabled in chroot\n");
754 else if (arg_overlay)
755 fprintf(stderr, "Warning: whitelist feature is disabled in overlay\n");
756 else
514 fs_whitelist(); 757 fs_whitelist();
515 758
516 // ... followed by blacklist commands 759 // ... followed by blacklist commands
517 fs_blacklist(); 760 fs_blacklist(); // mkdir and mkfile are processed all over again
518 }
519 761
520 //**************************** 762 //****************************
521 // install trace 763 // install trace
522 //**************************** 764 //****************************
523 if (arg_trace || arg_tracelog) 765 if (arg_trace || arg_tracelog || mask_x11_abstract_socket)
524 fs_trace(); 766 fs_trace();
525 767
526 //**************************** 768 //****************************
527 // update /proc, /dev, /boot directorymy 769 // 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 //**************************** 770 //****************************
534 if (arg_nosound) 771 if (arg_nosound) {
772 // disable pulseaudio
535 pulseaudio_disable(); 773 pulseaudio_disable();
774
775 // disable /dev/snd
776 fs_dev_disable_sound();
777 }
536 else 778 else
537 pulseaudio_init(); 779 pulseaudio_init();
538 780
781 if (arg_no3d)
782 fs_dev_disable_3d();
783
539 //**************************** 784 //****************************
540 // networking 785 // set dns
541 //**************************** 786 //****************************
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(); 787 fs_resolvconf();
788
789 //****************************
790 // fs post-processing
791 //****************************
606 fs_logger_print(); 792 fs_logger_print();
607 fs_logger_change_owner(); 793 fs_logger_change_owner();
608 794
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 //**************************** 795 //****************************
630 // set application environment 796 // set application environment
631 //**************************** 797 //****************************
@@ -649,12 +815,6 @@ int sandbox(void* sandbox_arg) {
649 } 815 }
650 } 816 }
651 817
652 // set environment
653 env_defaults();
654
655 // set user-supplied environment variables
656 env_apply();
657
658 // set nice 818 // set nice
659 if (arg_nice) { 819 if (arg_nice) {
660 errno = 0; 820 errno = 0;
@@ -668,6 +828,8 @@ int sandbox(void* sandbox_arg) {
668 828
669 // clean /tmp/.X11-unix sockets 829 // clean /tmp/.X11-unix sockets
670 fs_x11(); 830 fs_x11();
831 if (arg_x11_xorg)
832 x11_xorg();
671 833
672 //**************************** 834 //****************************
673 // set security filters 835 // set security filters
@@ -679,35 +841,35 @@ int sandbox(void* sandbox_arg) {
679 // set rlimits 841 // set rlimits
680 set_rlimits(); 842 set_rlimits();
681 843
682 // set seccomp 844 // set cpu affinity
845 if (cfg.cpus) {
846 save_cpu(); // save cpu affinity mask to CPU_CFG file
847 set_cpu_affinity();
848 }
849
850 // save cgroup in CGROUP_CFG file
851 if (cfg.cgroup)
852 save_cgroup();
853
854 // set seccomp //todo: push it down after drop_privs and/or configuring noroot
683#ifdef HAVE_SECCOMP 855#ifdef HAVE_SECCOMP
684 // install protocol filter 856 // install protocol filter
685 if (cfg.protocol) { 857 if (cfg.protocol) {
686 protocol_filter(); // install filter 858 if (arg_debug)
687 protocol_filter_save(); // save filter in PROTOCOL_CFG 859 printf("Install protocol filter: %s\n", cfg.protocol);
860 seccomp_load(RUN_SECCOMP_PROTOCOL); // install filter
861 protocol_filter_save(); // save filter in RUN_PROTOCOL_CFG
688 } 862 }
689 863
690 // if a keep list is available, disregard the drop list 864 // if a keep list is available, disregard the drop list
691 if (arg_seccomp == 1) { 865 if (arg_seccomp == 1) {
692 if (cfg.seccomp_list_keep) 866 if (cfg.seccomp_list_keep)
693 seccomp_filter_keep(); 867 seccomp_filter_keep();
694 else if (cfg.seccomp_list_errno)
695 seccomp_filter_errno();
696 else 868 else
697 seccomp_filter_drop(enforce_seccomp); 869 seccomp_filter_drop(enforce_seccomp);
698 } 870 }
699#endif 871#endif
700 872
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 //**************************************** 873 //****************************************
712 // drop privileges or create a new user namespace 874 // drop privileges or create a new user namespace
713 //**************************************** 875 //****************************************
@@ -715,7 +877,7 @@ int sandbox(void* sandbox_arg) {
715 if (arg_noroot) { 877 if (arg_noroot) {
716 int rv = unshare(CLONE_NEWUSER); 878 int rv = unshare(CLONE_NEWUSER);
717 if (rv == -1) { 879 if (rv == -1) {
718 fprintf(stderr, "Warning: cannot mount a new user namespace, going forward without it...\n"); 880 fprintf(stderr, "Warning: cannot create a new user namespace, going forward without it...\n");
719 drop_privs(arg_nogroups); 881 drop_privs(arg_nogroups);
720 arg_noroot = 0; 882 arg_noroot = 0;
721 } 883 }
@@ -739,6 +901,18 @@ int sandbox(void* sandbox_arg) {
739 printf("noroot user namespace installed\n"); 901 printf("noroot user namespace installed\n");
740 set_caps(); 902 set_caps();
741 } 903 }
904
905 //****************************************
906 // Set NO_NEW_PRIVS if desired
907 //****************************************
908 if (arg_nonewprivs) {
909 int no_new_privs = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
910
911 if(no_new_privs != 0)
912 fprintf(stderr, "Warning: NO_NEW_PRIVS disabled, it requires a Linux kernel version 3.5 or newer.\n");
913 else if (arg_debug)
914 printf("NO_NEW_PRIVS set\n");
915 }
742 916
743 //**************************************** 917 //****************************************
744 // fork the application and monitor it 918 // fork the application and monitor it
@@ -746,13 +920,27 @@ int sandbox(void* sandbox_arg) {
746 pid_t app_pid = fork(); 920 pid_t app_pid = fork();
747 if (app_pid == -1) 921 if (app_pid == -1)
748 errExit("fork"); 922 errExit("fork");
749 923
750 if (app_pid == 0) { 924 if (app_pid == 0) {
925#ifdef HAVE_APPARMOR
926 if (arg_apparmor) {
927 errno = 0;
928 if (aa_change_onexec("firejail-default")) {
929 fprintf(stderr, "Error: cannot confine the application using AppArmor.\n");
930 fprintf(stderr, "Maybe firejail-default AppArmor profile is not loaded into the kernel.\n");
931 fprintf(stderr, "As root, run \"aa-enforce firejail-default\" to load it.\n");
932 exit(1);
933 }
934 else if (arg_debug)
935 printf("AppArmor enabled\n");
936 }
937#endif
751 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died 938 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died
752 start_application(); // start app 939 start_application(); // start app
753 } 940 }
754 941
755 int status = monitor_application(app_pid); // monitor application 942 int status = monitor_application(app_pid); // monitor application
943 flush_stdin();
756 944
757 if (WIFEXITED(status)) { 945 if (WIFEXITED(status)) {
758 // if we had a proper exit, return that exit status 946 // 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..f28bbaf1a
--- /dev/null
+++ b/src/firejail/sbox.c
@@ -0,0 +1,221 @@
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
142 if (filter & SBOX_STDIN_FROM_FILE) {
143 int fd;
144 if((fd = open(SBOX_STDIN_FILE, O_RDONLY)) == -1) {
145 fprintf(stderr,"Error: cannot open /tmp/netfilter\n");
146 exit(1);
147 }
148 dup2(fd,STDIN_FILENO);
149 }
150 else if ((filter & SBOX_ALLOW_STDIN) == 0) {
151 int fd = open("/dev/null",O_RDWR, 0);
152 if (fd != -1)
153 dup2(fd, STDIN_FILENO);
154 else // the user could run the sandbox without /dev/null
155 close(STDIN_FILENO);
156 }
157
158 // close all other file descriptors
159 int max = 20; // getdtablesize() is overkill for a firejail process
160 for (i = 3; i < max; i++)
161 close(i); // close open files
162
163 if (arg_debug) {
164 printf("sbox file descriptors:\n");
165 int rv = system("ls -l /proc/self/fd");
166 (void) rv;
167 }
168
169 umask(027);
170
171 // apply filters
172 if (filter & SBOX_CAPS_NONE) {
173 caps_drop_all();
174 }
175 else if (filter & SBOX_CAPS_NETWORK) {
176#ifndef HAVE_GCOV // the following filter will prevent GCOV from saving info in .gcda files
177 uint64_t set = ((uint64_t) 1) << CAP_NET_ADMIN;
178 set |= ((uint64_t) 1) << CAP_NET_RAW;
179 caps_set(set);
180#endif
181 }
182
183 if (filter & SBOX_SECCOMP) {
184 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
185 perror("prctl(NO_NEW_PRIVS)");
186 }
187 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
188 perror("prctl(PR_SET_SECCOMP)");
189 }
190 }
191
192 if (filter & SBOX_ROOT) {
193 // elevate privileges in order to get grsecurity working
194 if (setreuid(0, 0))
195 errExit("setreuid");
196 if (setregid(0, 0))
197 errExit("setregid");
198 }
199 else if (filter & SBOX_USER)
200 drop_privs(1);
201
202 clearenv();
203 if (arg[0]) // get rid of scan-build warning
204 execvp(arg[0], arg);
205 else
206 assert(0);
207 perror("execl");
208 _exit(1);
209 }
210
211 int status;
212 if (waitpid(child, &status, 0) == -1 ) {
213 errExit("waitpid");
214 }
215 if (WIFEXITED(status) && status != 0) {
216 fprintf(stderr, "Error: failed to run %s\n", arg[0]);
217 exit(1);
218 }
219
220 return status;
221}
diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c
index 7108b5a05..96dfdaff2 100644
--- a/src/firejail/seccomp.c
+++ b/src/firejail/seccomp.c
@@ -20,798 +20,188 @@
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 24
25#define SECSIZE 128 // initial filter size 25char *seccomp_check_list(const char *str) {
26static struct sock_filter *sfilter = NULL; 26 assert(str);
27static int sfilter_alloc_size = 0; 27 if (strlen(str) == 0) {
28static int sfilter_index = 0; 28 fprintf(stderr, "Error: empty syscall lists are not allowed\n");
29 29 exit(1);
30// debug filter
31void filter_debug(void) {
32 // start filter
33 struct sock_filter filter[] = {
34 VALIDATE_ARCHITECTURE,
35 EXAMINE_SYSCALL
36 };
37
38 // print sizes
39 printf("SECCOMP Filter:\n");
40 if (sfilter == NULL) {
41 printf("SECCOMP filter not allocated\n");
42 return;
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 52
158static void filter_add_blacklist(int syscall, int arg) { 53int seccomp_load(const char *fname) {
159 (void) arg; 54 assert(fname);
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 55
166 if ((sfilter_index + 2) > sfilter_alloc_size) 56 // open filter file
167 filter_realloc(); 57 int fd = open(fname, O_RDONLY);
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
269 int fd = open(RUN_SECCOMP_CFG, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
270 if (fd == -1) 58 if (fd == -1)
271 errExit("open"); 59 goto errexit;
272 60
61 // calculate the number of entries
62 int size = lseek(fd, 0, SEEK_END);
63 if (size == -1)
64 goto errexit;
65 if (lseek(fd, 0 , SEEK_SET) == -1)
66 goto errexit;
67 unsigned short entries = (unsigned short) size / (unsigned short) sizeof(struct sock_filter);
273 if (arg_debug) 68 if (arg_debug)
274 printf("Save seccomp filter, size %u bytes\n", (unsigned) (sfilter_index * sizeof(struct sock_filter))); 69 printf("reading %d seccomp entries from %s\n", entries, fname);
275 errno = 0; 70
276 ssize_t sz = write(fd, sfilter, sfilter_index * sizeof(struct sock_filter)); 71 // read filter
277 if (sz != (ssize_t)(sfilter_index * sizeof(struct sock_filter))) { 72 struct sock_filter *filter = malloc(size);
278 fprintf(stderr, "Error: cannot save seccomp filter\n"); 73 if (filter == NULL)
279 exit(1); 74 goto errexit;
280 } 75 memset(filter, 0, size);
76 int rd = 0;
77 while (rd < size) {
78 int rv = read(fd, (unsigned char *) filter + rd, size - rd);
79 if (rv == -1)
80 goto errexit;
81 rd += rv;
82 }
83
84 // close file
281 close(fd); 85 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 86
290 // check file 87 // install filter
291 struct stat s; 88 struct sock_fprog prog = {
292 if (stat(fname, &s) == -1) { 89 .len = entries,
293 fprintf(stderr, "Warning: seccomp file not found\n"); 90 .filter = filter,
294 return; 91 };
295 } 92 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
296 ssize_t sz = s.st_size; 93 fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n");
297 if (sz == 0 || (sz % sizeof(struct sock_filter)) != 0) { 94 return 1;
298 fprintf(stderr, "Error: invalid seccomp file\n");
299 exit(1);
300 }
301 sfilter = malloc(sz);
302 if (!sfilter)
303 errExit("malloc");
304
305 // read file
306 /* coverity[toctou] */
307 int fd = open(fname,O_RDONLY);
308 if (fd == -1)
309 errExit("open");
310 errno = 0;
311 ssize_t size = read(fd, sfilter, sz);
312 if (size != sz) {
313 fprintf(stderr, "Error: invalid seccomp file\n");
314 exit(1);
315 } 95 }
316 sfilter_index = sz / sizeof(struct sock_filter);
317
318 if (arg_debug)
319 printf("Read seccomp filter, size %u bytes\n", (unsigned) (sfilter_index * sizeof(struct sock_filter)));
320
321 close(fd);
322 96
323 if (arg_debug) 97 return 0;
324 filter_debug(); 98
99errexit:
100 fprintf(stderr, "Error: cannot read %s\n", fname);
101 exit(1);
325} 102}
326 103
327// i386 filter installed on amd64 architectures 104// i386 filter installed on amd64 architectures
328void seccomp_filter_32(void) { 105void seccomp_filter_32(void) {
329 // hardcoded syscall values 106 if (seccomp_load(RUN_SECCOMP_I386) == 0) {
330 struct sock_filter filter[] = { 107 if (arg_debug)
331 VALIDATE_ARCHITECTURE_32, 108 printf("Dual i386/amd64 seccomp filter configured\n");
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
382 struct sock_fprog prog = {
383 .len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
384 .filter = filter,
385 };
386
387 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
388 ;
389 }
390 else if (arg_debug) {
391 printf("Dual i386/amd64 seccomp filter configured\n");
392 } 109 }
393} 110}
394 111
395// amd64 filter installed on i386 architectures 112// amd64 filter installed on i386 architectures
396void seccomp_filter_64(void) { 113void seccomp_filter_64(void) {
397 // hardcoded syscall values 114 if (seccomp_load(RUN_SECCOMP_AMD64) == 0) {
398 struct sock_filter filter[] = { 115 if (arg_debug)
399 VALIDATE_ARCHITECTURE_64, 116 printf("Dual i386/amd64 seccomp filter configured\n");
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
451 struct sock_fprog prog = {
452 .len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
453 .filter = filter,
454 };
455
456 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
457 ;
458 }
459 else if (arg_debug) {
460 printf("Dual i386/amd64 seccomp filter configured\n");
461 } 117 }
462} 118}
463 119
464
465// drop filter for seccomp option 120// drop filter for seccomp option
466int seccomp_filter_drop(int enforce_seccomp) { 121int seccomp_filter_drop(int enforce_seccomp) {
467 filter_init();
468
469 // default seccomp 122 // default seccomp
470 if (cfg.seccomp_list_drop == NULL) { 123 if (cfg.seccomp_list_drop == NULL && cfg.seccomp_list == NULL) {
471#if defined(__x86_64__) 124#if defined(__x86_64__)
472 seccomp_filter_32(); 125 seccomp_filter_32();
473#endif 126#endif
474#if defined(__i386__) 127#if defined(__i386__)
475 seccomp_filter_64(); 128 seccomp_filter_64();
476#endif 129#endif
477 130 }
478#ifdef SYS_mount 131 // default seccomp filter with additional drop list
479 filter_add_blacklist(SYS_mount, 0); 132 else if (cfg.seccomp_list && cfg.seccomp_list_drop == NULL) {
480#endif 133#if defined(__x86_64__)
481#ifdef SYS_umount2 134 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 135#endif
526#ifdef SYS_process_vm_writev 136#if defined(__i386__)
527 filter_add_blacklist(SYS_process_vm_writev, 0); 137 seccomp_filter_64();
528#endif 138#endif
529 139 if (arg_debug)
530// mknod removed in 0.9.29 - it brakes Zotero extension 140 printf("Build default+drop seccomp filter\n");
531//#ifdef SYS_mknod
532// filter_add_blacklist(SYS_mknod, 0);
533//#endif
534 141
535 // new syscalls in 0.9,23 142 // build the seccomp filter as a regular user
536#ifdef SYS_sysfs 143 int rv;
537 filter_add_blacklist(SYS_sysfs, 0); 144 if (arg_allow_debuggers)
538#endif 145 rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 6,
539#ifdef SYS__sysctl 146 PATH_FSECCOMP, "default", "drop", RUN_SECCOMP_CFG, cfg.seccomp_list, "allow-debuggers");
540 filter_add_blacklist(SYS__sysctl, 0); 147 else
541#endif 148 rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 5,
542#ifdef SYS_adjtimex 149 PATH_FSECCOMP, "default", "drop", RUN_SECCOMP_CFG, cfg.seccomp_list);
543 filter_add_blacklist(SYS_adjtimex, 0); 150 if (rv)
544#endif 151 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 } 152 }
667 153
668 154 // drop list without defaults - secondary filters are not installed
669 filter_end_blacklist(); 155 else if (cfg.seccomp_list == NULL && cfg.seccomp_list_drop) {
670 if (arg_debug) 156 if (arg_debug)
671 filter_debug(); 157 printf("Build drop seccomp filter\n");
672 158
673 // save seccomp filter in /tmp/firejail/mnt/seccomp 159 // build the seccomp filter as a regular user
674 // in order to use it in --join operations 160 int rv;
675 write_seccomp_file(); 161 if (arg_allow_debuggers)
676 162 rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 5,
677 163 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 164 else
689 fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); 165 rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 4,
166 PATH_FSECCOMP, "drop", RUN_SECCOMP_CFG, cfg.seccomp_list_drop);
690 167
691 return 1; 168 if (rv)
169 exit(rv);
692 } 170 }
693 171 else {
694 return 0; 172 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 } 173 }
714 174
715 filter_end_whitelist(); 175 // load the filter
716 if (arg_debug) 176 if (seccomp_load(RUN_SECCOMP_CFG) == 0) {
717 filter_debug(); 177 if (arg_debug)
718 178 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 } 179 }
733 else if (arg_debug) { 180 else if (enforce_seccomp) {
734 printf("seccomp enabled\n"); 181 fprintf(stderr, "Error: a seccomp-enabled Linux kernel is required, exiting...\n");
182 exit(1);
735 } 183 }
736 184
737 return 0; 185 if (arg_debug && access(PATH_FSECCOMP, X_OK) == 0)
738} 186 sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 3,
739 187 PATH_FSECCOMP, "print", RUN_SECCOMP_CFG);
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)
759 filter_debug();
760
761 // save seccomp filter in /tmp/firejail/mnt/seccomp
762 // in order to use it in --join operations
763 write_seccomp_file();
764 188
765 struct sock_fprog prog = { 189 return seccomp_load(RUN_SECCOMP_CFG);
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
778 return 0;
779} 190}
780 191
781 192// keep filter for seccomp option
782 193int seccomp_filter_keep(void) {
783void seccomp_set(void) { 194 if (arg_debug)
784 // read seccomp filter from /tmp/firejail/mnt/seccomp 195 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 196
793 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { 197 // 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"); 198 sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 4,
795 return; 199 PATH_FSECCOMP, "keep", RUN_SECCOMP_CFG, cfg.seccomp_list_keep);
796 } 200 if (arg_debug)
797 else if (arg_debug) { 201 printf("seccomp filter configured\n");
798 printf("seccomp enabled\n");
799 }
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 202
814 seccomp_print_filter(pid); 203
204 return seccomp_load(RUN_SECCOMP_CFG);
815} 205}
816 206
817void seccomp_print_filter(pid_t pid) { 207void seccomp_print_filter(pid_t pid) {
@@ -853,10 +243,8 @@ void seccomp_print_filter(pid_t pid) {
853 exit(1); 243 exit(1);
854 } 244 }
855 245
856 // read and print the filter 246 // read and print the filter - run this as root, the user doesn't have access
857 read_seccomp_file(fname); 247 sbox_run(SBOX_ROOT | SBOX_SECCOMP, 3, PATH_FSECCOMP, "print", fname);
858 drop_privs(1);
859 filter_debug();
860 free(fname); 248 free(fname);
861 249
862 exit(0); 250 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..db3c25a5a 100644
--- a/src/firejail/usage.c
+++ b/src/firejail/usage.c
@@ -23,330 +23,193 @@ 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");
119#endif 97#endif
120 printf(" --name=name - set sandbox name.\n\n"); 98 printf(" --machine-id - preserve /etc/machine-id\n");
121#ifdef HAVE_NETWORK 99#ifdef HAVE_NETWORK
122 printf(" --net=bridgename - enable network namespaces and connect to this bridge\n"); 100 printf(" --mtu=number - set interface MTU.\n");
123 printf("\tdevice. Up to four --net devices can be defined.\n\n"); 101#endif
124 102 printf(" --name=name - set sandbox name.\n");
103#ifdef HAVE_NETWORK
104 printf(" --net=bridgename - enable network namespaces and connect to this bridge.\n");
125 printf(" --net=ethernet_interface - enable network namespaces and connect to this\n"); 105 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"); 106 printf("\tEthernet interface.\n");
127 printf("\t--net devices can be defined.\n\n"); 107 printf(" --net=none - enable a new, unconnected network namespace.\n");
128 108 printf(" --netfilter[=filename] - enable the default client network filter.\n");
129 printf(" --net=none - enable a new, unconnected network namespace.\n\n"); 109 printf(" --netfilter6=filename - enable the IPv6 network filter.\n");
130 110 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 111#endif
143 printf(" --nice=value - set nice value\n\n"); 112 printf(" --nice=value - set nice value.\n");
144 printf(" --noblacklist=dirname_or_filename - disable blacklist for directory or\n"); 113 printf(" --no3d - disable 3D hardware acceleration.\n");
145 printf("\tfile.\n\n"); 114 printf(" --noblacklist=filename - disable blacklist for file or directory .\n");
146 printf(" --nogroups - disable supplementary groups. Without this option,\n"); 115 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"); 116 printf(" --nogroups - disable supplementary groups.\n");
148 printf("\t For root, groups are always disabled.\n\n"); 117 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 118#ifdef HAVE_USERNS
156 printf(" --noroot - install a user namespace with a single user - the current\n"); 119 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 120#endif
160 printf(" --nosound - disable sound system.\n\n"); 121 printf(" --nonewprivs - sets the NO_NEW_PRIVS prctl.\n");
161 122 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"); 123 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"); 124 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"); 125 printf("\tfilesystem, and store it in name directory.\n");
170 printf("\tLinux kernel for this option to work). \n\n"); 126 printf(" --overlay-tmpfs - mount a temporary filesystem overlay on top of the current\n");
171 127 printf("\tfilesystem.\n");
172 printf(" --overlay-tmpfs - mount a filesystem overlay on top of the current\n"); 128 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"); 129 printf(" --private - temporary home directory.\n");
174 printf("\tand it is discarded when the sandbox is closed. (OverlayFS\n"); 130 printf(" --private=directory - use directory as user home.\n");
175 printf("\tsupport is required in Linux kernel for this option to work).\n\n"); 131 printf(" --private-home=file,directory - build a new user home in a temporary\n");
176 132 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"); 133 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"); 134 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"); 135 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"); 136 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"); 137 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"); 138 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"); 139 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"); 140 printf(" --private-tmp - mount a tmpfs on top of /tmp directory.\n");
191 141 printf(" --profile=filename - use a custom profile.\n");
192 printf(" --private-tmp - mount a tmpfs on top of /tmp directory\n\n"); 142 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"); 143 printf(" --protocol=protocol,protocol,protocol - enable protocol filter.\n");
198 printf("\tProtocol values: unix, inet, inet6, netlink, packet.\n\n"); 144 printf(" --protocol.print=name|pid - print the protocol filter.\n");
199 printf(" --protocol.print=name|pid - print the protocol filter for the sandbox\n"); 145 printf(" --put=name|pid src-filename dest-filename - put a file in sandbox container.\n");
200 printf("\tidentified by name or PID.\n\n"); 146 printf(" --quiet - turn off Firejail's output.\n");
201 147 printf(" --read-only=filename - set directory or file read-only..\n");
202 printf(" --quiet - turn off Firejail's output.\n\n"); 148 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"); 149 printf(" --rlimit-fsize=number - set the maximum file size that can be created\n");
205 printf("\tby a process.\n\n"); 150 printf("\tby a process.\n");
206 printf(" --rlimit-nofile=number - set the maximum number of files that can be\n"); 151 printf(" --rlimit-nofile=number - set the maximum number of files that can be\n");
207 printf("\topened by a process.\n\n"); 152 printf("\topened by a process.\n");
208 printf(" --rlimit-nproc=number - set the maximum number of processes that can be\n"); 153 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"); 154 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"); 155 printf(" --rlimit-sigpending=number - set the maximum number of pending signals\n");
211 printf("\tfor a process.\n\n"); 156 printf("\tfor a process.\n");
157 printf(" --rmenv=name - remove environment variable in the new sandbox.\n");
212#ifdef HAVE_NETWORK 158#ifdef HAVE_NETWORK
213 printf(" --scan - ARP-scan all the networks from inside a network namespace.\n"); 159 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 160#endif
217#ifdef HAVE_SECCOMP 161#ifdef HAVE_SECCOMP
218 printf(" --seccomp - enable seccomp filter and apply the default blacklist.\n\n"); 162 printf(" --seccomp - enable seccomp filter and apply the default blacklist.\n");
219
220 printf(" --seccomp=syscall,syscall,syscall - enable seccomp filter, blacklist the\n"); 163 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"); 164 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"); 165 printf(" --seccomp.drop=syscall,syscall,syscall - enable seccomp filter, and\n");
224 printf("\tblacklist the syscalls specified by the command.\n\n"); 166 printf("\tblacklist the syscalls specified by the command.\n");
225
226 printf(" --seccomp.keep=syscall,syscall,syscall - enable seccomp filter, and\n"); 167 printf(" --seccomp.keep=syscall,syscall,syscall - enable seccomp filter, and\n");
227 printf("\twhitelist the syscalls specified by the command.\n\n"); 168 printf("\twhitelist the syscalls specified by the command.\n");
228
229 printf(" --seccomp.<errno>=syscall,syscall,syscall - enable seccomp filter, and\n"); 169 printf(" --seccomp.<errno>=syscall,syscall,syscall - enable seccomp filter, and\n");
230 printf("\treturn errno for the syscalls specified by the command.\n\n"); 170 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"); 171 printf(" --seccomp.print=name|pid - print the seccomp filter for the sandbox\n");
233 printf("\tidentified by name or PID.\n\n"); 172 printf("\tidentified by name or PID.\n");
234#endif 173#endif
235 174 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"); 175 printf(" --shell=program - set default user shell.\n");
237 printf(" --shell=program - set default user shell.\n\n"); 176 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"); 177 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"); 178 printf(" --top - monitor the most CPU-intensive sandboxes.\n");
241 printf(" --top - monitor the most CPU-intensive sandboxes.\n\n"); 179 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"); 180 printf(" --tracelog - add a syslog message for every access to files or\n");
244 printf("\tdirectoires blacklisted by the security profile.\n\n"); 181 printf("\tdirectoires blacklisted by the security profile.\n");
245 printf(" --tree - print a tree of all sandboxed processes.\n\n"); 182 printf(" --tree - print a tree of all sandboxed processes.\n");
246 printf(" --user=new_user - switch the user before starting the sandbox.\n\n"); 183 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 184#ifdef HAVE_NETWORK
259 printf("Traffic Shaping\n\n"); 185 printf(" --veth-name=name - use this name for the interface connected to the bridge.\n");
260 186#endif
261 printf("Network bandwidth is an expensive resource shared among all sandboxes\n"); 187#ifdef HAVE_WHITELIST
262 printf("running on a system. Traffic shaping allows the user to increase network\n"); 188 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"); 189#endif
264 printf("sandboxes. Firejail implements a simple rate-limiting shaper based on Linux\n"); 190 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"); 191 printf(" --writable-var - /var directory is mounted read-write.\n");
266 printf("sandboxes configured with new network namespaces.\n\n"); 192 printf(" --x11 - enable X11 sandboxing. The software checks first if Xpra is\n");
267 193 printf("\tinstalled, then it checks if Xephyr is installed. If all fails, it will\n");
268 printf("Set rate-limits:\n"); 194 printf("\tattempt to use X11 security extension.\n");
269 printf(" firejail --bandwidth={name|pid} set network-name down-speed up-speed\n\n"); 195 printf(" --x11=none - disable access to X11 sockets.\n");
270 printf("Clear rate-limits:\n"); 196 printf(" --x11=xephyr - enable Xephyr X11 server. The window size is 800x600.\n");
271 printf(" firejail --bandwidth={name|pid} clear network-name\n\n"); 197 printf(" --x11=xorg - enable X11 security extension.\n");
272 printf("Status:\n"); 198 printf(" --x11=xpra - enable Xpra X11 server.\n");
273 printf(" firejail --bandwidth={name|pid} status\n\n"); 199 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"); 200 printf("\n");
334 printf("Examples:\n\n"); 201 printf("Examples:\n");
335 printf(" $ firejail\n");
336 printf("\tstart a regular /bin/bash session in sandbox\n");
337 printf(" $ firejail firefox\n"); 202 printf(" $ firejail firefox\n");
338 printf("\tstart Mozilla Firefox\n"); 203 printf("\tstart Mozilla Firefox\n");
339 printf(" $ firejail --debug firefox\n"); 204 printf(" $ firejail --debug firefox\n");
340 printf("\tdebug Firefox sandbox\n"); 205 printf("\tdebug Firefox sandbox\n");
341 printf(" $ firejail --private firefox\n"); 206 printf(" $ firejail --private --sna=8.8.8.8 firefox\n");
342 printf("\tstart Firefox with a new, empty home directory\n"); 207 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"); 208 printf("\tserver setting.\n");
344 printf("\tstart a /bin/bash session in a new network namespace; the session is\n"); 209 printf(" $ firejail --net=eth0 firefox\n");
345 printf("\tconnected to the main network using br0 bridge device, an IP address\n"); 210 printf("\tstart Firefox in a new network namespace\n");
346 printf("\tof 10.10.20.10 is assigned to the sandbox\n"); 211 printf(" $ firejail --x11=xorg firefox\n");
347 printf(" $ firejail --net=br0 --net=br1 --net=br2\n"); 212 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"); 213 printf(" $ firejail --list\n");
351 printf("\tlist all running sandboxes\n"); 214 printf("\tlist all running sandboxes\n");
352 printf("\n"); 215 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..75f2acdb9 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
@@ -204,18 +206,25 @@ int copy_file(const char *srcname, const char *destname) {
204 done += rv; 206 done += rv;
205 } 207 }
206 } 208 }
209 fflush(0);
210
211 if (fchown(dst, uid, gid) == -1)
212 errExit("fchown");
213 if (fchmod(dst, mode) == -1)
214 errExit("fchmod");
207 215
208 close(src); 216 close(src);
209 close(dst); 217 close(dst);
210 return 0; 218 return 0;
211} 219}
212 220
221
213// return 1 if the file is a directory 222// return 1 if the file is a directory
214int is_dir(const char *fname) { 223int is_dir(const char *fname) {
215 assert(fname); 224 assert(fname);
216 if (*fname == '\0') 225 if (*fname == '\0')
217 return 0; 226 return 0;
218 227
219 // if fname doesn't end in '/', add one 228 // if fname doesn't end in '/', add one
220 int rv; 229 int rv;
221 struct stat s; 230 struct stat s;
@@ -226,20 +235,21 @@ int is_dir(const char *fname) {
226 if (asprintf(&tmp, "%s/", fname) == -1) { 235 if (asprintf(&tmp, "%s/", fname) == -1) {
227 fprintf(stderr, "Error: cannot allocate memory, %s:%d\n", __FILE__, __LINE__); 236 fprintf(stderr, "Error: cannot allocate memory, %s:%d\n", __FILE__, __LINE__);
228 errExit("asprintf"); 237 errExit("asprintf");
229 } 238 }
230 rv = stat(tmp, &s); 239 rv = stat(tmp, &s);
231 free(tmp); 240 free(tmp);
232 } 241 }
233 242
234 if (rv == -1) 243 if (rv == -1)
235 return 0; 244 return 0;
236 245
237 if (S_ISDIR(s.st_mode)) 246 if (S_ISDIR(s.st_mode))
238 return 1; 247 return 1;
239 248
240 return 0; 249 return 0;
241} 250}
242 251
252
243// return 1 if the file is a link 253// return 1 if the file is a link
244int is_link(const char *fname) { 254int is_link(const char *fname) {
245 assert(fname); 255 assert(fname);
@@ -324,7 +334,7 @@ char *split_comma(char *str) {
324 334
325int not_unsigned(const char *str) { 335int not_unsigned(const char *str) {
326 EUID_ASSERT(); 336 EUID_ASSERT();
327 337
328 int rv = 0; 338 int rv = 0;
329 const char *ptr = str; 339 const char *ptr = str;
330 while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0') { 340 while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0') {
@@ -346,7 +356,7 @@ int find_child(pid_t parent, pid_t *child) {
346 *child = 0; // use it to flag a found child 356 *child = 0; // use it to flag a found child
347 357
348 DIR *dir; 358 DIR *dir;
349 EUID_ROOT(); // grsecurity fix 359 EUID_ROOT(); // grsecurity fix
350 if (!(dir = opendir("/proc"))) { 360 if (!(dir = opendir("/proc"))) {
351 // sleep 2 seconds and try again 361 // sleep 2 seconds and try again
352 sleep(2); 362 sleep(2);
@@ -403,13 +413,11 @@ int find_child(pid_t parent, pid_t *child) {
403} 413}
404 414
405 415
406
407void extract_command_name(int index, char **argv) { 416void extract_command_name(int index, char **argv) {
408 EUID_ASSERT(); 417 EUID_ASSERT();
409 assert(argv); 418 assert(argv);
410 assert(argv[index]); 419 assert(argv[index]);
411 420
412
413 // configure command index 421 // configure command index
414 cfg.original_program_index = index; 422 cfg.original_program_index = index;
415 423
@@ -418,13 +426,13 @@ void extract_command_name(int index, char **argv) {
418 errExit("strdup"); 426 errExit("strdup");
419 427
420 // if we have a symbolic link, use the real path to extract the name 428 // if we have a symbolic link, use the real path to extract the name
421 if (is_link(argv[index])) { 429// if (is_link(argv[index])) {
422 char*newname = realpath(argv[index], NULL); 430// char*newname = realpath(argv[index], NULL);
423 if (newname) { 431// if (newname) {
424 free(str); 432// free(str);
425 str = newname; 433// str = newname;
426 } 434// }
427 } 435// }
428 436
429 // configure command name 437 // configure command name
430 cfg.command_name = str; 438 cfg.command_name = str;
@@ -446,7 +454,6 @@ void extract_command_name(int index, char **argv) {
446 exit(1); 454 exit(1);
447 } 455 }
448 456
449
450 char *tmp = strdup(ptr); 457 char *tmp = strdup(ptr);
451 if (!tmp) 458 if (!tmp)
452 errExit("strdup"); 459 errExit("strdup");
@@ -532,6 +539,7 @@ void notify_other(int fd) {
532 fclose(stream); 539 fclose(stream);
533} 540}
534 541
542
535// This function takes a pathname supplied by the user and expands '~' and 543// 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 544// '${HOME}' at the start, to refer to a path relative to the user's home
537// directory (supplied). 545// directory (supplied).
@@ -540,7 +548,7 @@ void notify_other(int fd) {
540char *expand_home(const char *path, const char* homedir) { 548char *expand_home(const char *path, const char* homedir) {
541 assert(path); 549 assert(path);
542 assert(homedir); 550 assert(homedir);
543 551
544 // Replace home macro 552 // Replace home macro
545 char *new_name = NULL; 553 char *new_name = NULL;
546 if (strncmp(path, "${HOME}", 7) == 0) { 554 if (strncmp(path, "${HOME}", 7) == 0) {
@@ -548,15 +556,19 @@ char *expand_home(const char *path, const char* homedir) {
548 errExit("asprintf"); 556 errExit("asprintf");
549 return new_name; 557 return new_name;
550 } 558 }
551 else if (strncmp(path, "~/", 2) == 0) { 559 else if (*path == '~') {
552 if (asprintf(&new_name, "%s%s", homedir, path + 1) == -1) 560 if (asprintf(&new_name, "%s%s", homedir, path + 1) == -1)
553 errExit("asprintf"); 561 errExit("asprintf");
554 return new_name; 562 return new_name;
555 } 563 }
556 564
557 return strdup(path); 565 char *rv = strdup(path);
566 if (!rv)
567 errExit("strdup");
568 return rv;
558} 569}
559 570
571
560// Equivalent to the GNU version of basename, which is incompatible with 572// Equivalent to the GNU version of basename, which is incompatible with
561// the POSIX basename. A few lines of code saves any portability pain. 573// 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 574// https://www.gnu.org/software/libc/manual/html_node/Finding-Tokens-in-a-String.html#index-basename
@@ -567,17 +579,18 @@ const char *gnu_basename(const char *path) {
567 return last_slash+1; 579 return last_slash+1;
568} 580}
569 581
582
570uid_t pid_get_uid(pid_t pid) { 583uid_t pid_get_uid(pid_t pid) {
571 EUID_ASSERT(); 584 EUID_ASSERT();
572 uid_t rv = 0; 585 uid_t rv = 0;
573 586
574 // open status file 587 // open status file
575 char *file; 588 char *file;
576 if (asprintf(&file, "/proc/%u/status", pid) == -1) { 589 if (asprintf(&file, "/proc/%u/status", pid) == -1) {
577 perror("asprintf"); 590 perror("asprintf");
578 exit(1); 591 exit(1);
579 } 592 }
580 EUID_ROOT(); // grsecurity fix 593 EUID_ROOT(); // grsecurity fix
581 FILE *fp = fopen(file, "r"); 594 FILE *fp = fopen(file, "r");
582 if (!fp) { 595 if (!fp) {
583 free(file); 596 free(file);
@@ -596,16 +609,16 @@ uid_t pid_get_uid(pid_t pid) {
596 } 609 }
597 if (*ptr == '\0') 610 if (*ptr == '\0')
598 break; 611 break;
599 612
600 rv = atoi(ptr); 613 rv = atoi(ptr);
601 break; // break regardless! 614 break; // break regardless!
602 } 615 }
603 } 616 }
604 617
605 fclose(fp); 618 fclose(fp);
606 free(file); 619 free(file);
607 EUID_USER(); // grsecurity fix 620 EUID_USER(); // grsecurity fix
608 621
609 if (rv == 0) { 622 if (rv == 0) {
610 fprintf(stderr, "Error: cannot read /proc file\n"); 623 fprintf(stderr, "Error: cannot read /proc file\n");
611 exit(1); 624 exit(1);
@@ -613,14 +626,15 @@ uid_t pid_get_uid(pid_t pid) {
613 return rv; 626 return rv;
614} 627}
615 628
629
616void invalid_filename(const char *fname) { 630void invalid_filename(const char *fname) {
617 EUID_ASSERT(); 631// EUID_ASSERT();
618 assert(fname); 632 assert(fname);
619 const char *ptr = fname; 633 const char *ptr = fname;
620 634
621 if (arg_debug_check_filename) 635 if (arg_debug_check_filename)
622 printf("Checking filename %s\n", fname); 636 printf("Checking filename %s\n", fname);
623 637
624 if (strncmp(ptr, "${HOME}", 7) == 0) 638 if (strncmp(ptr, "${HOME}", 7) == 0)
625 ptr = fname + 7; 639 ptr = fname + 7;
626 else if (strncmp(ptr, "${PATH}", 7) == 0) 640 else if (strncmp(ptr, "${PATH}", 7) == 0)
@@ -636,22 +650,172 @@ void invalid_filename(const char *fname) {
636 } 650 }
637} 651}
638 652
639uid_t get_tty_gid(void) { 653
654uid_t get_group_id(const char *group) {
640 // find tty group id 655 // find tty group id
641 gid_t ttygid = 0; 656 gid_t gid = 0;
642 struct group *g = getgrnam("tty"); 657 struct group *g = getgrnam(group);
643 if (g) 658 if (g)
644 ttygid = g->gr_gid; 659 gid = g->gr_gid;
645 660
646 return ttygid; 661 return gid;
647} 662}
648 663
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 664
656 return audiogid; 665static int remove_callback(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) {
666 (void) sb;
667 (void) typeflag;
668 (void) ftwbuf;
669
670 int rv = remove(fpath);
671 if (rv)
672 perror(fpath);
673
674 return rv;
657} 675}
676
677
678int remove_directory(const char *path) {
679 // FTW_PHYS - do not follow symbolic links
680 return nftw(path, remove_callback, 64, FTW_DEPTH | FTW_PHYS);
681}
682
683void flush_stdin(void) {
684 if (isatty(STDIN_FILENO)) {
685 int cnt = 0;
686 int rv = ioctl(STDIN_FILENO, FIONREAD, &cnt);
687 if (rv == 0 && cnt) {
688 if (!arg_quiet)
689 printf("Warning: removing %d bytes from stdin\n", cnt);
690 rv = ioctl(STDIN_FILENO, TCFLSH, TCIFLUSH);
691 (void) rv;
692 }
693 }
694}
695
696void create_empty_dir_as_root(const char *dir, mode_t mode) {
697 assert(dir);
698 mode &= 07777;
699 struct stat s;
700
701 if (stat(dir, &s)) {
702 if (arg_debug)
703 printf("Creating empty %s directory\n", dir);
704 /* coverity[toctou] */
705 if (mkdir(dir, mode) == -1)
706 errExit("mkdir");
707 if (set_perms(dir, 0, 0, mode))
708 errExit("set_perms");
709 ASSERT_PERMS(dir, 0, 0, mode);
710 }
711}
712
713void create_empty_file_as_root(const char *fname, mode_t mode) {
714 assert(fname);
715 mode &= 07777;
716 struct stat s;
717
718 if (stat(fname, &s)) {
719 if (arg_debug)
720 printf("Creating empty %s file\n", fname);
721
722 /* coverity[toctou] */
723 FILE *fp = fopen(fname, "w");
724 if (!fp)
725 errExit("fopen");
726 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR);
727 fclose(fp);
728 if (chmod(fname, mode) == -1)
729 errExit("chmod");
730 }
731}
732
733// return 1 if error
734int set_perms(const char *fname, uid_t uid, gid_t gid, mode_t mode) {
735 assert(fname);
736 if (chmod(fname, mode) == -1)
737 return 1;
738 if (chown(fname, uid, gid) == -1)
739 return 1;
740 return 0;
741}
742
743void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid) {
744 assert(fname);
745 mode &= 07777;
746#if 0
747 printf("fname %s, uid %d, gid %d, mode %x - ", fname, uid, gid, (unsigned) mode);
748 if (S_ISLNK(mode))
749 printf("l");
750 else if (S_ISDIR(mode))
751 printf("d");
752 else if (S_ISCHR(mode))
753 printf("c");
754 else if (S_ISBLK(mode))
755 printf("b");
756 else if (S_ISSOCK(mode))
757 printf("s");
758 else
759 printf("-");
760 printf( (mode & S_IRUSR) ? "r" : "-");
761 printf( (mode & S_IWUSR) ? "w" : "-");
762 printf( (mode & S_IXUSR) ? "x" : "-");
763 printf( (mode & S_IRGRP) ? "r" : "-");
764 printf( (mode & S_IWGRP) ? "w" : "-");
765 printf( (mode & S_IXGRP) ? "x" : "-");
766 printf( (mode & S_IROTH) ? "r" : "-");
767 printf( (mode & S_IWOTH) ? "w" : "-");
768 printf( (mode & S_IXOTH) ? "x" : "-");
769 printf("\n");
770#endif
771 if (mkdir(fname, mode) == -1 ||
772 chmod(fname, mode) == -1 ||
773 chown(fname, uid, gid)) {
774 fprintf(stderr, "Error: failed to create %s directory\n", fname);
775 errExit("mkdir/chmod");
776 }
777
778 ASSERT_PERMS(fname, uid, gid, mode);
779}
780
781char *read_text_file_or_exit(const char *fname) {
782 assert(fname);
783
784 // open file
785 int fd = open(fname, O_RDONLY);
786 if (fd == -1) {
787 fprintf(stderr, "Error: cannot read %s\n", fname);
788 exit(1);
789 }
790
791 int size = lseek(fd, 0, SEEK_END);
792 if (size == -1)
793 goto errexit;
794 if (lseek(fd, 0 , SEEK_SET) == -1)
795 goto errexit;
796
797 // allocate memory
798 char *data = malloc(size + 1); // + '\0'
799 if (data == NULL)
800 goto errexit;
801 memset(data, 0, size + 1);
802
803 // read file
804 int rd = 0;
805 while (rd < size) {
806 int rv = read(fd, (unsigned char *) data + rd, size - rd);
807 if (rv == -1) {
808 goto errexit;
809 }
810 rd += rv;
811 }
812
813 // close file
814 close(fd);
815 return data;
816
817errexit:
818 close(fd);
819 fprintf(stderr, "Error: cannot read %s\n", fname);
820 exit(1);
821} \ No newline at end of file
diff --git a/src/firejail/x11.c b/src/firejail/x11.c
index ef1095a49..91017237d 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");
@@ -125,18 +151,15 @@ void fs_x11(void) {
125 fs_logger("tmpfs /tmp/.X11-unix"); 151 fs_logger("tmpfs /tmp/.X11-unix");
126 152
127 // create an empty file 153 // create an empty file
154 /* coverity[toctou] */
128 FILE *fp = fopen(x11file, "w"); 155 FILE *fp = fopen(x11file, "w");
129 if (!fp) { 156 if (!fp) {
130 fprintf(stderr, "Error: cannot create empty file in x11 directory\n"); 157 fprintf(stderr, "Error: cannot create empty file in x11 directory\n");
131 exit(1); 158 exit(1);
132 } 159 }
133 fclose(fp);
134
135 // set file properties 160 // set file properties
136 if (chown(x11file, s.st_uid, s.st_gid) < 0) 161 SET_PERMS_STREAM(fp, s.st_uid, s.st_gid, s.st_mode);
137 errExit("chown"); 162 fclose(fp);
138 if (chmod(x11file, s.st_mode) < 0)
139 errExit("chmod");
140 163
141 // mount 164 // mount
142 char *wx11file; 165 char *wx11file;
@@ -164,15 +187,17 @@ void x11_start_xephyr(int argc, char **argv) {
164 EUID_ASSERT(); 187 EUID_ASSERT();
165 int i; 188 int i;
166 struct stat s; 189 struct stat s;
167 pid_t client = 0; 190 pid_t jail = 0;
168 pid_t server = 0; 191 pid_t server = 0;
169 192
193 setenv("FIREJAIL_X11", "yes", 1);
170 194
171 // unfortunately, xephyr does a number of weird things when started by root user!!! 195 // unfortunately, xephyr does a number of weird things when started by root user!!!
172 if (getuid() == 0) { 196 if (getuid() == 0) {
173 fprintf(stderr, "Error: this feature is not available when running as root\n"); 197 fprintf(stderr, "Error: X11 sandboxing is not available when running as root\n");
174 exit(1); 198 exit(1);
175 } 199 }
200 drop_privs(0);
176 201
177 // check xephyr 202 // check xephyr
178 if (x11_check_xephyr() == 0) { 203 if (x11_check_xephyr() == 0) {
@@ -183,23 +208,78 @@ void x11_start_xephyr(int argc, char **argv) {
183 } 208 }
184 209
185 int display = random_display_number(); 210 int display = random_display_number();
186 211 char *display_str;
187 // start xephyr 212 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"); 213 errExit("asprintf");
191 214
192 int len = 50; // DISPLAY... 215 assert(xephyr_screen);
193 for (i = 0; i < argc; i++) { 216 char *server_argv[256] = { "Xephyr", "-ac", "-br", "-noreset", "-screen", xephyr_screen }; // rest initialyzed to NULL
194 len += strlen(argv[i]) + 1; // + ' ' 217 unsigned pos = 0;
218 while (server_argv[pos] != NULL) pos++;
219 if (checkcfg(CFG_XEPHYR_WINDOW_TITLE)) {
220 server_argv[pos++] = "-title";
221 server_argv[pos++] = "firejail x11 sandbox";
222 }
223
224 assert(xephyr_extra_params); // should be "" if empty
225
226 // parse xephyr_extra_params
227 // very basic quoting support
228 char *temp = strdup(xephyr_extra_params);
229 if (*xephyr_extra_params != '\0') {
230 if (!temp)
231 errExit("strdup");
232 bool dquote = false;
233 bool squote = false;
234 for (i = 0; i < (int) strlen(xephyr_extra_params); i++) {
235 if (temp[i] == '\"') {
236 dquote = !dquote;
237 if (dquote) temp[i] = '\0'; // replace closing quote by \0
238 }
239 if (temp[i] == '\'') {
240 squote = !squote;
241 if (squote) temp[i] = '\0'; // replace closing quote by \0
242 }
243 if (!dquote && !squote && temp[i] == ' ') temp[i] = '\0';
244 if (dquote && squote) {
245 fprintf(stderr, "Error: mixed quoting found while parsing xephyr_extra_params\n");
246 exit(1);
247 }
248 }
249 if (dquote) {
250 fprintf(stderr, "Error: unclosed quote found while parsing xephyr_extra_params\n");
251 exit(1);
252 }
253
254 for (i = 0; i < (int) strlen(xephyr_extra_params)-1; i++) {
255 if (pos >= (sizeof(server_argv)/sizeof(*server_argv)) - 2) {
256 fprintf(stderr, "Error: arg count limit exceeded while parsing xephyr_extra_params\n");
257 exit(1);
258 }
259 if (temp[i] == '\0' && (temp[i+1] == '\"' || temp[i+1] == '\'')) server_argv[pos++] = temp + i + 2;
260 else if (temp[i] == '\0' && temp[i+1] != '\0') server_argv[pos++] = temp + i + 1;
261 }
195 } 262 }
196 263
197 char *cmd2 = malloc(len + 1); // + '\0' 264 server_argv[pos++] = display_str;
198 if (!cmd2) 265 server_argv[pos++] = NULL;
199 errExit("malloc"); 266
267 assert(pos < (sizeof(server_argv)/sizeof(*server_argv))); // no overrun
268 assert(server_argv[pos-1] == NULL); // last element is null
200 269
201 sprintf(cmd2, "DISPLAY=:%d ", display); 270 if (arg_debug) {
202 char *ptr = cmd2 + strlen(cmd2); 271 size_t i = 0;
272 printf("xephyr server:");
273 while (server_argv[i]!=NULL) {
274 printf(" \"%s\"", server_argv[i]);
275 i++;
276 }
277 putchar('\n');
278 }
279
280 // remove --x11 arg
281 char *jail_argv[argc+2];
282 int j = 0;
203 for (i = 0; i < argc; i++) { 283 for (i = 0; i < argc; i++) {
204 if (strcmp(argv[i], "--x11") == 0) 284 if (strcmp(argv[i], "--x11") == 0)
205 continue; 285 continue;
@@ -207,32 +287,40 @@ void x11_start_xephyr(int argc, char **argv) {
207 continue; 287 continue;
208 if (strcmp(argv[i], "--x11=xephyr") == 0) 288 if (strcmp(argv[i], "--x11=xephyr") == 0)
209 continue; 289 continue;
210 ptr += sprintf(ptr, "%s ", argv[i]); 290 jail_argv[j] = argv[i];
291 j++;
292 }
293 jail_argv[j] = NULL;
294
295 assert(j < argc+2); // no overrun
296
297 if (arg_debug) {
298 size_t i = 0;
299 printf("xephyr client:");
300 while (jail_argv[i]!=NULL) {
301 printf(" \"%s\"", jail_argv[i]);
302 i++;
303 }
304 putchar('\n');
211 } 305 }
212 if (arg_debug)
213 printf("xephyr server: %s\n", cmd1);
214 if (arg_debug)
215 printf("xephyr client: %s\n", cmd2);
216 306
217 signal(SIGHUP,SIG_IGN); // fix sleep(1) below
218 server = fork(); 307 server = fork();
219 if (server < 0) 308 if (server < 0)
220 errExit("fork"); 309 errExit("fork");
221 if (server == 0) { 310 if (server == 0) {
222 if (arg_debug) 311 if (arg_debug)
223 printf("Starting xephyr...\n"); 312 printf("Starting xephyr...\n");
224 313
225 char *a[4]; 314 // running without privileges - see drop_privs call above
226 a[0] = "/bin/bash"; 315 assert(getenv("LD_PRELOAD") == NULL);
227 a[1] = "-c"; 316 execvp(server_argv[0], server_argv);
228 a[2] = cmd1;
229 a[3] = NULL;
230
231 execvp(a[0], a);
232 perror("execvp"); 317 perror("execvp");
233 exit(1); 318 _exit(1);
234 } 319 }
235 320
321 if (arg_debug)
322 printf("xephyr server pid %d\n", server);
323
236 // check X11 socket 324 // check X11 socket
237 char *fname; 325 char *fname;
238 if (asprintf(&fname, "/tmp/.X11-unix/X%d", display) == -1) 326 if (asprintf(&fname, "/tmp/.X11-unix/X%d", display) == -1)
@@ -250,7 +338,6 @@ void x11_start_xephyr(int argc, char **argv) {
250 exit(1); 338 exit(1);
251 } 339 }
252 free(fname); 340 free(fname);
253 sleep(1);
254 341
255 if (arg_debug) { 342 if (arg_debug) {
256 printf("X11 sockets: "); fflush(0); 343 printf("X11 sockets: "); fflush(0);
@@ -258,26 +345,40 @@ void x11_start_xephyr(int argc, char **argv) {
258 (void) rv; 345 (void) rv;
259 } 346 }
260 347
348 setenv("DISPLAY", display_str, 1);
261 // run attach command 349 // run attach command
262 client = fork(); 350 jail = fork();
263 if (client < 0) 351 if (jail < 0)
264 errExit("fork"); 352 errExit("fork");
265 if (client == 0) { 353 if (jail == 0) {
266 printf("\n*** Attaching to Xephyr display %d ***\n\n", display); 354 if (!arg_quiet)
267 char *a[4]; 355 printf("\n*** Attaching to Xephyr display %d ***\n\n", display);
268 a[0] = "/bin/bash"; 356
269 a[1] = "-c"; 357 // running without privileges - see drop_privs call above
270 a[2] = cmd2; 358 assert(getenv("LD_PRELOAD") == NULL);
271 a[3] = NULL; 359 execvp(jail_argv[0], jail_argv);
272
273 execvp(a[0], a);
274 perror("execvp"); 360 perror("execvp");
275 exit(1); 361 _exit(1);
276 } 362 }
277 sleep(1); 363
278 364 // cleanup
279 if (!arg_quiet) 365 free(display_str);
280 printf("Xephyr server pid %d, client pid %d\n", server, client); 366 free(temp);
367
368 // wait for either server or jail termination
369 pid_t pid = wait(NULL);
370
371 // see which process terminated and kill other
372 if (pid == server) {
373 kill(jail, SIGTERM);
374 } else if (pid == jail) {
375 kill(server, SIGTERM);
376 }
377
378 // without this closing Xephyr window may mess your terminal:
379 // "monitoring" process will release terminal before
380 // jail process ends and releases terminal
381 wait(NULL); // fulneral
281 382
282 exit(0); 383 exit(0);
283} 384}
@@ -289,12 +390,14 @@ void x11_start_xpra(int argc, char **argv) {
289 pid_t client = 0; 390 pid_t client = 0;
290 pid_t server = 0; 391 pid_t server = 0;
291 392
393 setenv("FIREJAIL_X11", "yes", 1);
292 394
293 // unfortunately, xpra does a number of weird things when started by root user!!! 395 // unfortunately, xpra does a number of weird things when started by root user!!!
294 if (getuid() == 0) { 396 if (getuid() == 0) {
295 fprintf(stderr, "Error: this feature is not available when running as root\n"); 397 fprintf(stderr, "Error: X11 sandboxing is not available when running as root\n");
296 exit(1); 398 exit(1);
297 } 399 }
400 drop_privs(0);
298 401
299 // check xpra 402 // check xpra
300 if (x11_check_xpra() == 0) { 403 if (x11_check_xpra() == 0) {
@@ -304,58 +407,44 @@ void x11_start_xpra(int argc, char **argv) {
304 } 407 }
305 408
306 int display = random_display_number(); 409 int display = random_display_number();
410 char *display_str;
411 if (asprintf(&display_str, ":%d", display) == -1)
412 errExit("asprintf");
307 413
308 // build the start command 414 // build the start command
309 int len = 50; // xpra start... 415 char *server_argv[] = { "xpra", "start", display_str, "--no-daemon", NULL };
310 for (i = 0; i < argc; i++) { 416
311 len += strlen(argv[i]) + 1; // + ' ' 417 int fd_null = -1;
312 } 418 if (arg_quiet) {
313 419 fd_null = open("/dev/null", O_RDWR);
314 char *cmd1 = malloc(len + 1); // + '\0' 420 if (fd_null == -1)
315 if (!cmd1) 421 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 } 422 }
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 423
340 signal(SIGHUP,SIG_IGN); // fix sleep(1) below 424 // start
341 server = fork(); 425 server = fork();
342 if (server < 0) 426 if (server < 0)
343 errExit("fork"); 427 errExit("fork");
344 if (server == 0) { 428 if (server == 0) {
345 if (arg_debug) 429 if (arg_debug)
346 printf("Starting xpra...\n"); 430 printf("Starting xpra...\n");
431
432 if (arg_quiet && fd_null != -1) {
433 dup2(fd_null,0);
434 dup2(fd_null,1);
435 dup2(fd_null,2);
436 }
347 437
348 char *a[4]; 438 // running without privileges - see drop_privs call above
349 a[0] = "/bin/bash"; 439 assert(getenv("LD_PRELOAD") == NULL);
350 a[1] = "-c"; 440 execvp(server_argv[0], server_argv);
351 a[2] = cmd1;
352 a[3] = NULL;
353
354 execvp(a[0], a);
355 perror("execvp"); 441 perror("execvp");
356 exit(1); 442 _exit(1);
357 } 443 }
358 444
445 // add a small delay, on some systems it takes some time for the server to start
446 sleep(1);
447
359 // check X11 socket 448 // check X11 socket
360 char *fname; 449 char *fname;
361 if (asprintf(&fname, "/tmp/.X11-unix/X%d", display) == -1) 450 if (asprintf(&fname, "/tmp/.X11-unix/X%d", display) == -1)
@@ -366,14 +455,13 @@ void x11_start_xpra(int argc, char **argv) {
366 sleep(1); 455 sleep(1);
367 if (stat(fname, &s) == 0) 456 if (stat(fname, &s) == 0)
368 break; 457 break;
369 }; 458 }
370 459
371 if (n == 10) { 460 if (n == 10) {
372 fprintf(stderr, "Error: failed to start xpra\n"); 461 fprintf(stderr, "Error: failed to start xpra\n");
373 exit(1); 462 exit(1);
374 } 463 }
375 free(fname); 464 free(fname);
376 sleep(1);
377 465
378 if (arg_debug) { 466 if (arg_debug) {
379 printf("X11 sockets: "); fflush(0); 467 printf("X11 sockets: "); fflush(0);
@@ -381,28 +469,118 @@ void x11_start_xpra(int argc, char **argv) {
381 (void) rv; 469 (void) rv;
382 } 470 }
383 471
472 // build attach command
473 char *attach_argv[] = { "xpra", "--title=\"firejail x11 sandbox\"", "attach", display_str, NULL };
474
384 // run attach command 475 // run attach command
385 client = fork(); 476 client = fork();
386 if (client < 0) 477 if (client < 0)
387 errExit("fork"); 478 errExit("fork");
388 if (client == 0) { 479 if (client == 0) {
389 printf("\n*** Attaching to xpra display %d ***\n\n", display); 480 if (arg_quiet && fd_null != -1) {
390 char *a[4]; 481 dup2(fd_null,0);
391 a[0] = "/bin/bash"; 482 dup2(fd_null,1);
392 a[1] = "-c"; 483 dup2(fd_null,2);
393 a[2] = cmd2; 484 }
394 a[3] = NULL; 485
395 486 if (!arg_quiet)
396 execvp(a[0], a); 487 printf("\n*** Attaching to xpra display %d ***\n\n", display);
488
489 // running without privileges - see drop_privs call above
490 assert(getenv("LD_PRELOAD") == NULL);
491 execvp(attach_argv[0], attach_argv);
492 perror("execvp");
493 _exit(1);
494 }
495
496 setenv("DISPLAY", display_str, 1);
497
498 // build jail command
499 char *firejail_argv[argc+2];
500 int pos = 0;
501 for (i = 0; i < argc; i++) {
502 if (strcmp(argv[i], "--x11") == 0)
503 continue;
504 if (strcmp(argv[i], "--x11=xpra") == 0)
505 continue;
506 if (strcmp(argv[i], "--x11=xephyr") == 0)
507 continue;
508 firejail_argv[pos] = argv[i];
509 pos++;
510 }
511 firejail_argv[pos] = NULL;
512
513 assert(pos < (argc+2));
514 assert(!firejail_argv[pos]);
515
516 // start jail
517 pid_t jail = fork();
518 if (jail < 0)
519 errExit("fork");
520 if (jail == 0) {
521 // running without privileges - see drop_privs call above
522 assert(getenv("LD_PRELOAD") == NULL);
523 if (firejail_argv[0]) // shut up llvm scan-build
524 execvp(firejail_argv[0], firejail_argv);
397 perror("execvp"); 525 perror("execvp");
398 exit(1); 526 exit(1);
399 } 527 }
400 sleep(1);
401
402 if (!arg_quiet)
403 printf("Xpra server pid %d, client pid %d\n", server, client);
404 528
405 exit(0); 529 if (!arg_quiet)
530 printf("Xpra server pid %d, xpra client pid %d, jail %d\n", server, client, jail);
531
532 sleep(1); // let jail start
533
534 // wait for jail or server to end
535 while (1) {
536 pid_t pid = wait(NULL);
537
538 if (pid == jail) {
539 char *stop_argv[] = { "xpra", "stop", display_str, NULL };
540 pid_t stop = fork();
541 if (stop < 0)
542 errExit("fork");
543 if (stop == 0) {
544 if (arg_quiet && fd_null != -1) {
545 dup2(fd_null,0);
546 dup2(fd_null,1);
547 dup2(fd_null,2);
548 }
549 // running without privileges - see drop_privs call above
550 assert(getenv("LD_PRELOAD") == NULL);
551 execvp(stop_argv[0], stop_argv);
552 perror("execvp");
553 _exit(1);
554 }
555
556 // wait for xpra server to stop, 10 seconds limit
557 while (++n < 10) {
558 sleep(1);
559 pid = waitpid(server, NULL, WNOHANG);
560 if (pid == server)
561 break;
562 }
563
564 if (arg_debug) {
565 if (n == 10)
566 printf("failed to stop xpra server gratefully\n");
567 else
568 printf("xpra server successfully stopped in %d secs\n", n);
569 }
570
571 // kill xpra server and xpra client
572 kill(client, SIGTERM);
573 kill(server, SIGTERM);
574 exit(0);
575 }
576 else if (pid == server) {
577 // kill firejail process
578 kill(jail, SIGTERM);
579 // kill xpra client (should die with server, but...)
580 kill(client, SIGTERM);
581 exit(0);
582 }
583 }
406} 584}
407 585
408void x11_start(int argc, char **argv) { 586void x11_start(int argc, char **argv) {
@@ -410,7 +588,7 @@ void x11_start(int argc, char **argv) {
410 588
411 // unfortunately, xpra does a number of weird things when started by root user!!! 589 // unfortunately, xpra does a number of weird things when started by root user!!!
412 if (getuid() == 0) { 590 if (getuid() == 0) {
413 fprintf(stderr, "Error: this feature is not available when running as root\n"); 591 fprintf(stderr, "Error: X11 sandboxing is not available when running as root\n");
414 exit(1); 592 exit(1);
415 } 593 }
416 594
@@ -428,3 +606,129 @@ void x11_start(int argc, char **argv) {
428} 606}
429 607
430#endif 608#endif
609
610void x11_block(void) {
611#ifdef HAVE_X11
612 mask_x11_abstract_socket = 1;
613
614 // check abstract socket presence and network namespace options
615 if ((!arg_nonetwork && !cfg.bridge0.configured && !cfg.interface0.configured)
616 && x11_abstract_sockets_present()) {
617 fprintf(stderr, "ERROR: --x11=none specified, but abstract X11 socket still accessible.\n"
618 "Additional setup required. To block abstract X11 socket you can either:\n"
619 " * use network namespace in firejail (--net=none, --net=...)\n"
620 " * add \"-nolisten local\" to xserver options\n"
621 " (eg. to your display manager config, or /etc/X11/xinit/xserverrc)\n");
622 exit(1);
623 }
624
625 // blacklist sockets
626 profile_check_line("blacklist /tmp/.X11-unix", 0, NULL);
627 profile_add(strdup("blacklist /tmp/.X11-unix"));
628
629 // blacklist .Xauthority
630 profile_check_line("blacklist ${HOME}/.Xauthority", 0, NULL);
631 profile_add(strdup("blacklist ${HOME}/.Xauthority"));
632 char *xauthority = getenv("XAUTHORITY");
633 if (xauthority) {
634 char *line;
635 if (asprintf(&line, "blacklist %s", xauthority) == -1)
636 errExit("asprintf");
637 profile_check_line(line, 0, NULL);
638 profile_add(line);
639 }
640
641 // clear environment
642 env_store("DISPLAY", RMENV);
643 env_store("XAUTHORITY", RMENV);
644#endif
645}
646
647void x11_xorg(void) {
648#ifdef HAVE_X11
649 // destination - create an empty ~/.Xauthotrity file if it doesn't exist already, and use it as a mount point
650 char *dest;
651 if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1)
652 errExit("asprintf");
653 struct stat s;
654 if (stat(dest, &s) == -1) {
655 // create an .Xauthority file
656 FILE *fp = fopen(dest, "w");
657 if (!fp)
658 errExit("fopen");
659 SET_PERMS_STREAM(fp, getuid(), getgid(), 0600);
660 fclose(fp);
661 }
662
663 // check xauth utility is present in the system
664 if (stat("/usr/bin/xauth", &s) == -1) {
665 fprintf(stderr, "Error: cannot find /usr/bin/xauth executable\n");
666 exit(1);
667 }
668
669 // create a temporary .Xauthority file
670 char tmpfname[] = "/tmp/.tmpXauth-XXXXXX";
671 int fd = mkstemp(tmpfname);
672 if (fd == -1) {
673 fprintf(stderr, "Error: cannot create .Xauthority file\n");
674 exit(1);
675 }
676 close(fd);
677 if (chown(tmpfname, getuid(), getgid()) == -1)
678 errExit("chown");
679
680 pid_t child = fork();
681 if (child < 0)
682 errExit("fork");
683 if (child == 0) {
684 // generate the new .Xauthority file using xauth utility
685 if (arg_debug)
686 printf("Generating a new .Xauthority file\n");
687 drop_privs(1);
688
689 char *display = getenv("DISPLAY");
690 if (!display)
691 display = ":0.0";
692
693 clearenv();
694 execlp("/usr/bin/xauth", "/usr/bin/xauth", "-f", tmpfname,
695 "generate", display, "MIT-MAGIC-COOKIE-1", "untrusted", NULL);
696
697#ifdef HAVE_GCOV
698 __gcov_flush();
699#endif
700 _exit(0);
701 }
702
703 // wait for the child to finish
704 waitpid(child, NULL, 0);
705
706 // check the file was created and set mode and ownership
707 if (stat(tmpfname, &s) == -1) {
708 fprintf(stderr, "Error: cannot create the new .Xauthority file\n");
709 exit(1);
710 }
711 if (set_perms(tmpfname, getuid(), getgid(), 0600))
712 errExit("set_perms");
713
714 // move the temporary file in RUN_XAUTHORITY_SEC_FILE in order to have it deleted
715 // automatically when the sandbox is closed
716 if (copy_file(tmpfname, RUN_XAUTHORITY_SEC_FILE, getuid(), getgid(), 0600)) {
717 fprintf(stderr, "Error: cannot create the new .Xauthority file\n");
718 exit(1);
719 }
720 if (set_perms(RUN_XAUTHORITY_SEC_FILE, getuid(), getgid(), 0600))
721 errExit("set_perms");
722 /* coverity[toctou] */
723 unlink(tmpfname);
724
725 // mount
726 if (mount(RUN_XAUTHORITY_SEC_FILE, dest, "none", MS_BIND, "mode=0600") == -1) {
727 fprintf(stderr, "Error: cannot mount the new .Xauthority file\n");
728 exit(1);
729 }
730 if (set_perms(dest, getuid(), getgid(), 0600))
731 errExit("set_perms");
732 free(dest);
733#endif
734}
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..3f8a139ae 100644
--- a/src/firemon/caps.c
+++ b/src/firemon/caps.c
@@ -24,7 +24,6 @@ static void print_caps(int pid) {
24 char *file; 24 char *file;
25 if (asprintf(&file, "/proc/%d/status", pid) == -1) { 25 if (asprintf(&file, "/proc/%d/status", pid) == -1) {
26 errExit("asprintf"); 26 errExit("asprintf");
27 exit(1);
28 } 27 }
29 28
30 FILE *fp = fopen(file, "r"); 29 FILE *fp = fopen(file, "r");
@@ -48,17 +47,15 @@ static void print_caps(int pid) {
48 free(file); 47 free(file);
49} 48}
50 49
51void caps(pid_t pid) { 50void caps(pid_t pid, int print_procs) {
52 if (getuid() == 0)
53 firemon_drop_privs();
54
55 pid_read(pid); // include all processes 51 pid_read(pid); // include all processes
56 52
57 // print processes 53 // print processes
58 int i; 54 int i;
59 for (i = 0; i < max_pids; i++) { 55 for (i = 0; i < max_pids; i++) {
60 if (pids[i].level == 1) { 56 if (pids[i].level == 1) {
61 pid_print_list(i, 0); 57 if (print_procs || pid == 0)
58 pid_print_list(i, 0);
62 int child = find_child(i); 59 int child = find_child(i);
63 if (child != -1) 60 if (child != -1)
64 print_caps(child); 61 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..534d783cb 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");
@@ -215,6 +216,9 @@ void netstats(void) {
215 print_proc(i, itv, col); 216 print_proc(i, itv, col);
216 } 217 }
217 } 218 }
219#ifdef HAVE_GCOV
220 __gcov_flush();
221#endif
218 } 222 }
219} 223}
220 224
diff --git a/src/firemon/procevent.c b/src/firemon/procevent.c
index e2dd5aaa2..edae21951 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
@@ -41,10 +43,8 @@ static int pid_is_firejail(pid_t pid) {
41 43
42 // open /proc/self/comm 44 // open /proc/self/comm
43 char *file; 45 char *file;
44 if (asprintf(&file, "/proc/%u/comm", pid) == -1) { 46 if (asprintf(&file, "/proc/%u/comm", pid) == -1)
45 perror("asprintf"); 47 errExit("asprintf");
46 exit(1);
47 }
48 48
49 FILE *fp = fopen(file, "r"); 49 FILE *fp = fopen(file, "r");
50 if (!fp) { 50 if (!fp) {
@@ -89,7 +89,8 @@ static int pid_is_firejail(pid_t pid) {
89 89
90 // list of firejail arguments that don't trigger sandbox creation 90 // list of firejail arguments that don't trigger sandbox creation
91 // the initial -- is not included 91 // the initial -- is not included
92 char *firejail_args = "ls list tree x11 help version top netstats debug-syscalls debug-errnos debug-protocols"; 92 char *firejail_args = "ls list tree x11 help version top netstats debug-syscalls debug-errnos debug-protocols "
93 "protocol.print debug.caps shutdown bandwidth caps.print cpu.print debug-caps fs.print get overlay-clean ";
93 94
94 int i; 95 int i;
95 char *start; 96 char *start;
@@ -189,6 +190,10 @@ static int procevent_monitor(const int sock, pid_t mypid) {
189 tv.tv_usec = 0; 190 tv.tv_usec = 0;
190 191
191 while (1) { 192 while (1) {
193#ifdef HAVE_GCOV
194 __gcov_flush();
195#endif
196
192#define BUFFSIZE 4096 197#define BUFFSIZE 4096
193 char __attribute__ ((aligned(NLMSG_ALIGNTO)))buf[BUFFSIZE]; 198 char __attribute__ ((aligned(NLMSG_ALIGNTO)))buf[BUFFSIZE];
194 199
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..f11c624ea 100644
--- a/src/firemon/seccomp.c
+++ b/src/firemon/seccomp.c
@@ -22,10 +22,8 @@
22#define MAXBUF 4098 22#define MAXBUF 4098
23static void print_seccomp(int pid) { 23static void print_seccomp(int pid) {
24 char *file; 24 char *file;
25 if (asprintf(&file, "/proc/%d/status", pid) == -1) { 25 if (asprintf(&file, "/proc/%d/status", pid) == -1)
26 errExit("asprintf"); 26 errExit("asprintf");
27 exit(1);
28 }
29 27
30 FILE *fp = fopen(file, "r"); 28 FILE *fp = fopen(file, "r");
31 if (!fp) { 29 if (!fp) {
@@ -48,17 +46,15 @@ static void print_seccomp(int pid) {
48 free(file); 46 free(file);
49} 47}
50 48
51void seccomp(pid_t pid) { 49void seccomp(pid_t pid, int print_procs) {
52 if (getuid() == 0)
53 firemon_drop_privs();
54
55 pid_read(pid); // include all processes 50 pid_read(pid); // include all processes
56 51
57 // print processes 52 // print processes
58 int i; 53 int i;
59 for (i = 0; i < max_pids; i++) { 54 for (i = 0; i < max_pids; i++) {
60 if (pids[i].level == 1) { 55 if (pids[i].level == 1) {
61 pid_print_list(i, 0); 56 if (print_procs || pid == 0)
57 pid_print_list(i, 0);
62 int child = find_child(i); 58 int child = find_child(i);
63 if (child != -1) 59 if (child != -1)
64 print_seccomp(child); 60 print_seccomp(child);
diff --git a/src/firemon/top.c b/src/firemon/top.c
index a6da6f64e..94271523c 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();
@@ -295,6 +292,9 @@ void top(void) {
295 } 292 }
296 } 293 }
297 head_print(col, row); 294 head_print(col, row);
295#ifdef HAVE_GCOV
296 __gcov_flush();
297#endif
298 } 298 }
299} 299}
300 300
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..73dc310d3 100644
--- a/src/firemon/x11.c
+++ b/src/firemon/x11.c
@@ -22,39 +22,35 @@
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
39 if (asprintf(&x11file, "/run/firejail/x11/%d", i) == -1) 37 if (asprintf(&x11file, "/run/firejail/x11/%d", i) == -1)
40 errExit("asprintf"); 38 errExit("asprintf");
41 39
42 struct stat s; 40 FILE *fp = fopen(x11file, "r");
43 if (stat(x11file, &s) == 0) { 41 if (!fp) {
44 FILE *fp = fopen(x11file, "r"); 42 free(x11file);
45 if (!fp) { 43 continue;
46 free(x11file);
47 continue;
48 }
49 int display;
50 int rv = fscanf(fp, "%d", &display);
51 if (rv == 1)
52 printf(" DISPLAY :%d\n", display);
53 fclose(fp);
54 } 44 }
55 45
46 int display;
47 int rv = fscanf(fp, "%d", &display);
48 if (rv == 1)
49 printf(" DISPLAY :%d\n", display);
50 fclose(fp);
56 free(x11file); 51 free(x11file);
57 } 52 }
58 } 53 }
54 printf("\n");
59} 55}
60 56
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..4e7807d07
--- /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 usage();
47 return 1;
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..2f85a786b
--- /dev/null
+++ b/src/fseccomp/main.c
@@ -0,0 +1,93 @@
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 usage();
52 return 1;
53 }
54
55 if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") ==0) {
56 usage();
57 return 0;
58 }
59 else if (argc == 2 && strcmp(argv[1], "debug-syscalls") == 0)
60 syscall_print();
61 else if (argc == 2 && strcmp(argv[1], "debug-errnos") == 0)
62 errno_print();
63 else if (argc == 2 && strcmp(argv[1], "debug-protocols") == 0)
64 protocol_print();
65 else if (argc == 5 && strcmp(argv[1], "protocol") == 0 && strcmp(argv[2], "build") == 0)
66 protocol_build_filter(argv[3], argv[4]);
67 else if (argc == 4 && strcmp(argv[1], "secondary") == 0 && strcmp(argv[2], "64") == 0)
68 seccomp_secondary_64(argv[3]);
69 else if (argc == 4 && strcmp(argv[1], "secondary") == 0 && strcmp(argv[2], "32") == 0)
70 seccomp_secondary_32(argv[3]);
71 else if (argc == 3 && strcmp(argv[1], "default") == 0)
72 seccomp_default(argv[2], 0);
73 else if (argc == 4 && strcmp(argv[1], "default") == 0 && strcmp(argv[3], "allow-debuggers") == 0)
74 seccomp_default(argv[2], 1);
75 else if (argc == 4 && strcmp(argv[1], "drop") == 0)
76 seccomp_drop(argv[2], argv[3], 0);
77 else if (argc == 5 && strcmp(argv[1], "drop") == 0 && strcmp(argv[4], "allow-debuggers") == 0)
78 seccomp_drop(argv[2], argv[3], 1);
79 else if (argc == 5 && strcmp(argv[1], "default") == 0 && strcmp(argv[2], "drop") == 0)
80 seccomp_default_drop(argv[3], argv[4], 0);
81 else if (argc == 6 && strcmp(argv[1], "default") == 0 && strcmp(argv[2], "drop") == 0 && strcmp(argv[5], "allow-debuggers") == 0)
82 seccomp_default_drop(argv[3], argv[4], 1);
83 else if (argc == 4 && strcmp(argv[1], "keep") == 0)
84 seccomp_keep(argv[2], argv[3]);
85 else if (argc == 3 && strcmp(argv[1], "print") == 0)
86 filter_print(argv[2]);
87 else {
88 fprintf(stderr, "Error fseccomp: invalid arguments\n");
89 return 1;
90 }
91
92 return 0;
93} \ 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..e22c682dc
--- /dev/null
+++ b/src/fseccomp/seccomp_print.c
@@ -0,0 +1,122 @@
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 // open filter file
31 int fd = open(fname, O_RDONLY);
32 if (fd == -1)
33 goto errexit;
34
35 // calculate the number of entries
36 int size = lseek(fd, 0, SEEK_END);
37 if (size == -1)
38 goto errexit;
39 if (lseek(fd, 0 , SEEK_SET) == -1)
40 goto errexit;
41 unsigned short entries = (unsigned short) size / (unsigned short) sizeof(struct sock_filter);
42 filter_cnt = entries;
43
44 // read filter
45 filter = malloc(size);
46 if (filter == NULL)
47 goto errexit;
48 memset(filter, 0, size);
49 int rd = 0;
50 while (rd < size) {
51 int rv = read(fd, (unsigned char *) filter + rd, size - rd);
52 if (rv == -1)
53 goto errexit;
54 rd += rv;
55 }
56
57 // close file
58 close(fd);
59 return;
60
61errexit:
62 fprintf(stderr, "Error fseccomp: cannot read %s\n", fname);
63 exit(1);
64}
65
66// debug filter
67void filter_print(const char *fname) {
68 assert(fname);
69 load_seccomp(fname);
70
71 // start filter
72 struct sock_filter start[] = {
73 VALIDATE_ARCHITECTURE,
74 EXAMINE_SYSCALL
75 };
76
77 // print sizes
78 printf("SECCOMP Filter:\n");
79
80 // test the start of the filter
81 if (memcmp(&start[0], filter, sizeof(start)) == 0) {
82 printf(" VALIDATE_ARCHITECTURE\n");
83 printf(" EXAMINE_SYSCAL\n");
84 }
85 else {
86 printf("Invalid seccomp filter %s\n", fname);
87 return;
88 }
89
90 // loop trough blacklists
91 int i = 4;
92 while (i < filter_cnt) {
93 // minimal parsing!
94 unsigned char *ptr = (unsigned char *) &filter[i];
95 int *nr = (int *) (ptr + 4);
96 if (*ptr == 0x15 && *(ptr +14) == 0xff && *(ptr + 15) == 0x7f ) {
97 printf(" WHITELIST %d %s\n", *nr, syscall_find_nr(*nr));
98 i += 2;
99 }
100 else if (*ptr == 0x15 && *(ptr +14) == 0 && *(ptr + 15) == 0) {
101 printf(" BLACKLIST %d %s\n", *nr, syscall_find_nr(*nr));
102 i += 2;
103 }
104 else if (*ptr == 0x15 && *(ptr +14) == 0x5 && *(ptr + 15) == 0) {
105 int err = *(ptr + 13) << 8 | *(ptr + 12);
106 printf(" ERRNO %d %s %d %s\n", *nr, syscall_find_nr(*nr), err, errno_find_nr(err));
107 i += 2;
108 }
109 else if (*ptr == 0x06 && *(ptr +6) == 0 && *(ptr + 7) == 0 ) {
110 printf(" KILL_PROCESS\n");
111 i++;
112 }
113 else if (*ptr == 0x06 && *(ptr +6) == 0xff && *(ptr + 7) == 0x7f ) {
114 printf(" RETURN_ALLOW\n");
115 i++;
116 }
117 else {
118 printf(" UNKNOWN ENTRY!!!\n");
119 i++;
120 }
121 }
122}
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..2b27baa5a 100644
--- a/src/ftee/main.c
+++ b/src/ftee/main.c
@@ -179,10 +179,6 @@ static int is_link(const char *fname) {
179 return 0; 179 return 0;
180} 180}
181 181
182
183
184
185
186static void usage(void) { 182static void usage(void) {
187 printf("Usage: ftee filename\n"); 183 printf("Usage: ftee filename\n");
188} 184}
@@ -193,37 +189,33 @@ int main(int argc, char **argv) {
193 usage(); 189 usage();
194 exit(1); 190 exit(1);
195 } 191 }
192 if (strcmp(argv[1], "--help") == 0) {
193 usage();
194 return 0;
195 }
196 char *fname = argv[1]; 196 char *fname = argv[1];
197 197
198 198
199 // do not accept directories, links, and files with ".." 199 // do not accept directories, links, and files with ".."
200 if (strstr(fname, "..") || is_link(fname) || is_dir(fname)) { 200 if (strstr(fname, "..") || is_link(fname) || is_dir(fname))
201 fprintf(stderr, "Error: invalid output file. Links, directories and files with \"..\" are not allowed.\n"); 201 goto errexit;
202 exit(1);
203 }
204 202
205 struct stat s; 203 struct stat s;
206 if (stat(fname, &s) == 0) { 204 if (stat(fname, &s) == 0) {
207 // check permissions 205 // check permissions
208 if (s.st_uid != getuid() || s.st_gid != getgid()) { 206 if (s.st_uid != getuid() || s.st_gid != getgid())
209 fprintf(stderr, "Error: the output file needs to be owned by the current user.\n"); 207 goto errexit;
210 exit(1);
211 }
212 208
213 // check hard links 209 // check hard links
214 if (s.st_nlink != 1) { 210 if (s.st_nlink != 1)
215 fprintf(stderr, "Error: no hard links allowed.\n"); 211 goto errexit;
216 exit(1);
217 }
218 } 212 }
219 213
220 // check if we can append to this file 214 // check if we can append to this file
221 /* coverity[toctou] */ 215 /* coverity[toctou] */
222 FILE *fp = fopen(fname, "a"); 216 FILE *fp = fopen(fname, "a");
223 if (!fp) { 217 if (!fp)
224 fprintf(stderr, "Error: cannot open output file %s\n", fname); 218 goto errexit;
225 exit(1);
226 }
227 fclose(fp); 219 fclose(fp);
228 220
229 221
@@ -244,4 +236,8 @@ int main(int argc, char **argv) {
244 236
245 log_close(); 237 log_close();
246 return 0; 238 return 0;
239
240errexit:
241 fprintf(stderr, "Error ftee: invalid output file.\n");
242 return 1;
247} 243}
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..3f66fa72a 100644
--- a/src/lib/common.c
+++ b/src/lib/common.c
@@ -39,22 +39,23 @@ int join_namespace(pid_t pid, char *type) {
39 errExit("asprintf"); 39 errExit("asprintf");
40 40
41 int fd = open(path, O_RDONLY); 41 int fd = open(path, O_RDONLY);
42 if (fd < 0) { 42 if (fd < 0)
43 free(path); 43 goto errout;
44 fprintf(stderr, "Error: cannot open /proc/%u/ns/%s.\n", pid, type);
45 return -1;
46 }
47 44
48 if (syscall(__NR_setns, fd, 0) < 0) { 45 if (syscall(__NR_setns, fd, 0) < 0) {
49 free(path);
50 fprintf(stderr, "Error: cannot join namespace %s.\n", type);
51 close(fd); 46 close(fd);
52 return -1; 47 goto errout;
53 } 48 }
54 49
55 close(fd); 50 close(fd);
56 free(path); 51 free(path);
57 return 0; 52 return 0;
53
54errout:
55 free(path);
56 fprintf(stderr, "Error: cannot join namespace %s\\n", type);
57 return -1;
58
58} 59}
59 60
60// return 1 if error 61// return 1 if error
@@ -187,8 +188,6 @@ char *pid_proc_cmdline(const pid_t pid) {
187 for (i = 0; i < len; i++) { 188 for (i = 0; i < len; i++) {
188 if (buffer[i] == '\0') 189 if (buffer[i] == '\0')
189 buffer[i] = ' '; 190 buffer[i] = ' ';
190// if (buffer[i] >= 0x80) // execv in progress!!!
191// return NULL;
192 } 191 }
193 192
194 // return a malloc copy of the command line 193 // return a malloc copy of the command line
@@ -199,3 +198,90 @@ char *pid_proc_cmdline(const pid_t pid) {
199 } 198 }
200 return rv; 199 return rv;
201} 200}
201
202// return 1 if firejail --x11 on command line
203int pid_proc_cmdline_x11_xpra_xephyr(const pid_t pid) {
204 // if comm is not firejail return 0
205 char *comm = pid_proc_comm(pid);
206 if (comm == NULL)
207 return 0;
208 if (strcmp(comm, "firejail") != 0) {
209 free(comm);
210 return 0;
211 }
212 free(comm);
213
214 // open /proc/pid/cmdline file
215 char *fname;
216 int fd;
217 if (asprintf(&fname, "/proc/%d/cmdline", pid) == -1)
218 return 0;
219 if ((fd = open(fname, O_RDONLY)) < 0) {
220 free(fname);
221 return 0;
222 }
223 free(fname);
224
225 // read file
226 unsigned char buffer[BUFLEN];
227 ssize_t len;
228 if ((len = read(fd, buffer, sizeof(buffer) - 1)) <= 0) {
229 close(fd);
230 return 0;
231 }
232 buffer[len] = '\0';
233 close(fd);
234
235 // skip the first argument
236 int i;
237 for (i = 0; buffer[i] != '\0'; i++);
238
239 // parse remaining command line options
240 while (1) {
241 // extract argument
242 i++;
243 if (i >= len)
244 break;
245 char *arg = (char *)buffer + i;
246
247 // detect the last command line option
248 if (strcmp(arg, "--") == 0)
249 break;
250 if (strncmp(arg, "--", 2) != 0)
251 break;
252
253 if (strcmp(arg, "--x11=xorg") == 0)
254 return 0;
255
256 // check x11 xpra or xephyr
257 if (strncmp(arg, "--x11", 5) == 0)
258 return 1;
259 i += strlen(arg);
260 }
261 return 0;
262}
263
264// return 1 if /proc is mounted hidepid, or if /proc/mouns access is denied
265#define BUFLEN 4096
266int pid_hidepid(void) {
267 FILE *fp = fopen("/proc/mounts", "r");
268 if (!fp)
269 return 1;
270
271 char buf[BUFLEN];
272 while (fgets(buf, BUFLEN, fp)) {
273 if (strstr(buf, "proc /proc proc")) {
274 fclose(fp);
275 // check hidepid
276 if (strstr(buf, "hidepid=2") || strstr(buf, "hidepid=1"))
277 return 1;
278 return 0;
279 }
280 }
281
282 fclose(fp);
283 return 0;
284}
285
286
287
diff --git a/src/lib/libnetlink.c b/src/lib/libnetlink.c
index 07457eefe..417ef2c5f 100644
--- a/src/lib/libnetlink.c
+++ b/src/lib/libnetlink.c
@@ -105,6 +105,7 @@ int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions)
105 return rtnl_open_byproto(rth, subscriptions, NETLINK_ROUTE); 105 return rtnl_open_byproto(rth, subscriptions, NETLINK_ROUTE);
106} 106}
107 107
108#if 0
108int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type) 109int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
109{ 110{
110 return rtnl_wilddump_req_filter(rth, family, type, RTEXT_FILTER_VF); 111 return rtnl_wilddump_req_filter(rth, family, type, RTEXT_FILTER_VF);
@@ -303,6 +304,7 @@ int rtnl_dump_filter(struct rtnl_handle *rth,
303 304
304 return rtnl_dump_filter_l(rth, a); 305 return rtnl_dump_filter_l(rth, a);
305} 306}
307#endif
306 308
307int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, 309int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer,
308 unsigned groups, struct nlmsghdr *answer) 310 unsigned groups, struct nlmsghdr *answer)
@@ -422,6 +424,7 @@ int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer,
422 } 424 }
423} 425}
424 426
427#if 0
425int rtnl_listen(struct rtnl_handle *rtnl, 428int rtnl_listen(struct rtnl_handle *rtnl,
426 rtnl_filter_t handler, 429 rtnl_filter_t handler,
427 void *jarg) 430 void *jarg)
@@ -580,7 +583,7 @@ int addattrstrz(struct nlmsghdr *n, int maxlen, int type, const char *str)
580{ 583{
581 return addattr_l(n, maxlen, type, str, strlen(str)+1); 584 return addattr_l(n, maxlen, type, str, strlen(str)+1);
582} 585}
583 586#endif
584 587
585 588
586int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, 589int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
@@ -632,46 +635,8 @@ printf("\tdata length: %d\n", alen);
632 return 0; 635 return 0;
633} 636}
634 637
635#if 0
636int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
637 int alen)
638{
639printf("%s: adding type %d, length %d ", __FUNCTION__, type, alen);
640if (type == IFLA_INFO_KIND) {
641if (alen)
642 printf("(IFLA_INFO_KIND %s)\n", (char *)data);
643else
644printf("(VETH_INFO_PEER)\n");
645}
646else if (type == IFLA_IFNAME) {
647printf("(IFLA_IFNAME %s)\n", (char *) data);
648}
649else if (type == IFLA_NET_NS_PID) {
650printf("(IFLA_NET_NS_PID %u)\n", *((unsigned *) data));
651}
652else if (type == IFLA_LINKINFO)
653printf("(IFLA_LINKINFO)\n");
654else if (type == IFLA_INFO_DATA)
655printf("(IFLA_INFO_DATA)\n");
656else
657 printf("\n");
658
659 int len = RTA_LENGTH(alen);
660 struct rtattr *rta;
661
662 if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
663 fprintf(stderr, "addattr_l ERROR: message exceeded bound of %d\n",maxlen);
664 return -1;
665 }
666 rta = NLMSG_TAIL(n);
667 rta->rta_type = type;
668 rta->rta_len = len;
669 memcpy(RTA_DATA(rta), data, alen);
670 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
671 return 0;
672}
673#endif
674 638
639#if 0
675int addraw_l(struct nlmsghdr *n, int maxlen, const void *data, int len) 640int addraw_l(struct nlmsghdr *n, int maxlen, const void *data, int len)
676{ 641{
677 if ((int)(NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len)) > maxlen) { 642 if ((int)(NLMSG_ALIGN(n->nlmsg_len) + NLMSG_ALIGN(len)) > maxlen) {
@@ -723,7 +688,7 @@ int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data)
723 int len = RTA_LENGTH(4); 688 int len = RTA_LENGTH(4);
724 struct rtattr *subrta; 689 struct rtattr *subrta;
725 690
726 if (RTA_ALIGN(rta->rta_len) + len > maxlen) { 691 if ((int) (RTA_ALIGN(rta->rta_len) + len) > maxlen) {
727 fprintf(stderr,"rta_addattr32: Error! max allowed bound %d exceeded\n",maxlen); 692 fprintf(stderr,"rta_addattr32: Error! max allowed bound %d exceeded\n",maxlen);
728 return -1; 693 return -1;
729 } 694 }
@@ -741,7 +706,7 @@ int rta_addattr_l(struct rtattr *rta, int maxlen, int type,
741 struct rtattr *subrta; 706 struct rtattr *subrta;
742 int len = RTA_LENGTH(alen); 707 int len = RTA_LENGTH(alen);
743 708
744 if (RTA_ALIGN(rta->rta_len) + RTA_ALIGN(len) > maxlen) { 709 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); 710 fprintf(stderr,"rta_addattr_l: Error! max allowed bound %d exceeded\n",maxlen);
746 return -1; 711 return -1;
747 } 712 }
@@ -802,3 +767,4 @@ int __parse_rtattr_nested_compat(struct rtattr *tb[], int max, struct rtattr *rt
802 memset(tb, 0, sizeof(struct rtattr *) * (max + 1)); 767 memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
803 return 0; 768 return 0;
804} 769}
770#endif
diff --git a/src/lib/pid.c b/src/lib/pid.c
index d1ade389e..42687274e 100644
--- a/src/lib/pid.c
+++ b/src/lib/pid.c
@@ -29,16 +29,14 @@
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) {
36 // open stat file 35 // open stat file
37 char *file; 36 char *file;
38 if (asprintf(&file, "/proc/%u/statm", pid) == -1) { 37 if (asprintf(&file, "/proc/%u/statm", pid) == -1)
39 perror("asprintf"); 38 errExit("asprintf");
40 exit(1); 39
41 }
42 FILE *fp = fopen(file, "r"); 40 FILE *fp = fopen(file, "r");
43 if (!fp) { 41 if (!fp) {
44 free(file); 42 free(file);
@@ -60,10 +58,9 @@ void pid_getmem(unsigned pid, unsigned *rss, unsigned *shared) {
60void pid_get_cpu_time(unsigned pid, unsigned *utime, unsigned *stime) { 58void pid_get_cpu_time(unsigned pid, unsigned *utime, unsigned *stime) {
61 // open stat file 59 // open stat file
62 char *file; 60 char *file;
63 if (asprintf(&file, "/proc/%u/stat", pid) == -1) { 61 if (asprintf(&file, "/proc/%u/stat", pid) == -1)
64 perror("asprintf"); 62 errExit("asprintf");
65 exit(1); 63
66 }
67 FILE *fp = fopen(file, "r"); 64 FILE *fp = fopen(file, "r");
68 if (!fp) { 65 if (!fp) {
69 free(file); 66 free(file);
@@ -94,10 +91,9 @@ myexit:
94unsigned long long pid_get_start_time(unsigned pid) { 91unsigned long long pid_get_start_time(unsigned pid) {
95 // open stat file 92 // open stat file
96 char *file; 93 char *file;
97 if (asprintf(&file, "/proc/%u/stat", pid) == -1) { 94 if (asprintf(&file, "/proc/%u/stat", pid) == -1)
98 perror("asprintf"); 95 errExit("asprintf");
99 exit(1); 96
100 }
101 FILE *fp = fopen(file, "r"); 97 FILE *fp = fopen(file, "r");
102 if (!fp) { 98 if (!fp) {
103 free(file); 99 free(file);
@@ -139,10 +135,8 @@ uid_t pid_get_uid(pid_t pid) {
139 135
140 // open status file 136 // open status file
141 char *file; 137 char *file;
142 if (asprintf(&file, "/proc/%u/status", pid) == -1) { 138 if (asprintf(&file, "/proc/%u/status", pid) == -1)
143 perror("asprintf"); 139 errExit("asprintf");
144 exit(1);
145 }
146 140
147 FILE *fp = fopen(file, "r"); 141 FILE *fp = fopen(file, "r");
148 if (!fp) { 142 if (!fp) {
@@ -317,10 +311,9 @@ void pid_read(pid_t mon_pid) {
317 311
318 // open stat file 312 // open stat file
319 char *file; 313 char *file;
320 if (asprintf(&file, "/proc/%u/status", pid) == -1) { 314 if (asprintf(&file, "/proc/%u/status", pid) == -1)
321 perror("asprintf"); 315 errExit("asprintf");
322 exit(1); 316
323 }
324 FILE *fp = fopen(file, "r"); 317 FILE *fp = fopen(file, "r");
325 if (!fp) { 318 if (!fp) {
326 free(file); 319 free(file);
@@ -340,18 +333,12 @@ void pid_read(pid_t mon_pid) {
340 exit(1); 333 exit(1);
341 } 334 }
342 335
343 if (mon_pid == 0 && strncmp(ptr, "firejail", 8) == 0) { 336 if ((strncmp(ptr, "firejail", 8) == 0) && (mon_pid == 0 || mon_pid == pid)) {
344 pids[pid].level = 1; 337 if (pid_proc_cmdline_x11_xpra_xephyr(pid))
345 } 338 pids[pid].level = -1;
346 else if (mon_pid == pid && strncmp(ptr, "firejail", 8) == 0) { 339 else
347 pids[pid].level = 1; 340 pids[pid].level = 1;
348 } 341 }
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 342 else
356 pids[pid].level = -1; 343 pids[pid].level = -1;
357 } 344 }
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..90fe726de 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");
@@ -156,9 +163,9 @@ static char *storage_find(const char *str) {
156#define RUN_FSLOGGER_FILE "/run/firejail/mnt/fslogger" 163#define RUN_FSLOGGER_FILE "/run/firejail/mnt/fslogger"
157#define MAXBUF 4096 164#define MAXBUF 4096
158static int blacklist_loaded = 0; 165static int blacklist_loaded = 0;
159static char *sandbox_pid_str = 0; 166static char *sandbox_pid_str = NULL;
160static char *sandbox_name_str = NULL; 167static char *sandbox_name_str = NULL;
161void load_blacklist(void) { 168static void load_blacklist(void) {
162 if (blacklist_loaded) 169 if (blacklist_loaded)
163 return; 170 return;
164 171
@@ -177,13 +184,15 @@ void load_blacklist(void) {
177 char *ptr = strchr(buf, '\n'); 184 char *ptr = strchr(buf, '\n');
178 if (ptr) 185 if (ptr)
179 *ptr = '\0'; 186 *ptr = '\0';
180 sandbox_pid_str = strdup(buf + 13); 187 if (sandbox_pid_str == NULL)
188 sandbox_pid_str = strdup(buf + 13);
181 } 189 }
182 else if (strncmp(buf, "sandbox name: ", 14) == 0) { 190 else if (strncmp(buf, "sandbox name: ", 14) == 0) {
183 char *ptr = strchr(buf, '\n'); 191 char *ptr = strchr(buf, '\n');
184 if (ptr) 192 if (ptr)
185 *ptr = '\0'; 193 *ptr = '\0';
186 sandbox_name_str = strdup(buf + 14); 194 if (sandbox_name_str == NULL)
195 sandbox_name_str = strdup(buf + 14);
187 } 196 }
188 else if (strncmp(buf, "blacklist ", 10) == 0) { 197 else if (strncmp(buf, "blacklist ", 10) == 0) {
189 char *ptr = strchr(buf, '\n'); 198 char *ptr = strchr(buf, '\n');
@@ -556,7 +565,7 @@ int stat64(const char *pathname, struct stat64 *buf) {
556#ifdef DEBUG 565#ifdef DEBUG
557 printf("%s %s\n", __FUNCTION__, pathname); 566 printf("%s %s\n", __FUNCTION__, pathname);
558#endif 567#endif
559 if (!orig_stat) 568 if (!orig_stat64)
560 orig_stat64 = (orig_stat64_t)dlsym(RTLD_NEXT, "stat64"); 569 orig_stat64 = (orig_stat64_t)dlsym(RTLD_NEXT, "stat64");
561 if (!blacklist_loaded) 570 if (!blacklist_loaded)
562 load_blacklist(); 571 load_blacklist();
@@ -592,7 +601,7 @@ int lstat64(const char *pathname, struct stat64 *buf) {
592#ifdef DEBUG 601#ifdef DEBUG
593 printf("%s %s\n", __FUNCTION__, pathname); 602 printf("%s %s\n", __FUNCTION__, pathname);
594#endif 603#endif
595 if (!orig_lstat) 604 if (!orig_lstat64)
596 orig_lstat64 = (orig_lstat64_t)dlsym(RTLD_NEXT, "lstat64"); 605 orig_lstat64 = (orig_lstat64_t)dlsym(RTLD_NEXT, "lstat64");
597 if (!blacklist_loaded) 606 if (!blacklist_loaded)
598 load_blacklist(); 607 load_blacklist();
@@ -641,9 +650,8 @@ DIR *opendir(const char *pathname) {
641} 650}
642 651
643// chdir 652// chdir
644// definition of orig_chdir placed before storage_find function 653typedef int (*orig_chdir_t)(const char *pathname);
645//typedef int (*orig_chdir_t)(const char *pathname); 654static orig_chdir_t orig_chdir = NULL;
646//static orig_chdir_t orig_chdir = NULL;
647int chdir(const char *pathname) { 655int chdir(const char *pathname) {
648#ifdef DEBUG 656#ifdef DEBUG
649 printf("%s %s\n", __FUNCTION__, pathname); 657 printf("%s %s\n", __FUNCTION__, pathname);
@@ -662,3 +670,32 @@ int chdir(const char *pathname) {
662 int rv = orig_chdir(pathname); 670 int rv = orig_chdir(pathname);
663 return rv; 671 return rv;
664} 672}
673
674// fchdir
675typedef int (*orig_fchdir_t)(int fd);
676static orig_fchdir_t orig_fchdir = NULL;
677int fchdir(int fd) {
678#ifdef DEBUG
679 printf("%s %d\n", __FUNCTION__, fd);
680#endif
681 if (!orig_fchdir)
682 orig_fchdir = (orig_fchdir_t)dlsym(RTLD_NEXT, "fchdir");
683
684 free(cwd);
685 char *pathname=malloc(PATH_MAX);
686 if (pathname) {
687 if (snprintf(pathname,PATH_MAX,"/proc/self/fd/%d", fd)>0) {
688 cwd = realpath(pathname, NULL);
689 } else {
690 cwd = NULL;
691 fprintf(stderr, "Error: snprintf failed\n");
692 }
693 free(pathname);
694 } else {
695 fprintf(stderr, "Error: cannot allocate memory\n");
696 cwd = NULL;
697 }
698
699 int rv = orig_fchdir(fd);
700 return rv;
701}
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..fa522c154 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\fBprivate-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.
@@ -173,20 +199,54 @@ Build a new /etc in a temporary
173filesystem, and copy the files and directories in the list. 199filesystem, 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
202\fBprivate-opt file,directory
203Build a new /optin a temporary
204filesystem, and copy the files and directories in the list.
205All modifications are discarded when the sandbox is closed.
206.TP
207\fBprivate-srv file,directory
208Build a new /srv in a temporary
209filesystem, and copy the files and directories in the list.
210All modifications are discarded when the sandbox is closed.
211.TP
176\fBprivate-tmp 212\fBprivate-tmp
177Mount an empty temporary filesystem on top of /tmp directory. 213Mount an empty temporary filesystem on top of /tmp directory whitelisting /tmp/.X11-unix.
178.TP 214.TP
179\fBwhitelist file_or_directory 215\fBread-only file_or_directory
180Build a new user home in a temporary filesystem, and mount-bind file_or_directory. 216Make directory or file read-only.
181The modifications to file_or_directory are persistent, everything else is discarded 217.TP
182when the sandbox is closed. 218\fBread-write file_or_directory
219Make directory or file read-write.
220.TP
221\fBtmpfs directory
222Mount an empty tmpfs filesystem on top of directory. This option is available only when running the sandbox as root.
183.TP 223.TP
184\fBtracelog 224\fBtracelog
185Blacklist violations logged to syslog. 225Blacklist violations logged to syslog.
226.TP
227\fBwhitelist file_or_directory
228Whitelist directory or file. A temporary file system is mounted on the top directory, and the
229whitelisted files are mount-binded inside. Modifications to whitelisted files are persistent,
230everything else is discarded when the sandbox is closed. The top directory could be
231user home, /dev, /media, /mnt, /opt, /srv, /var, and /tmp.
232.br
233
234.br
235Symbolic link handling: with the exception of user home, both the link and the real file should be in
236the same top directory. For user home, both the link and the real file should be owned by the user.
237.TP
238\fBwritable-etc
239Mount /etc directory read-write.
240.TP
241\fBwritable-var
242Mount /var directory read-write.
186.SH Security filters 243.SH Security filters
187The following security filters are currently implemented: 244The following security filters are currently implemented:
188 245
189.TP 246.TP
247\fBapparmor
248Enable AppArmor confinement.
249.TP
190\fBcaps 250\fBcaps
191Enable default Linux capabilities filter. 251Enable default Linux capabilities filter.
192.TP 252.TP
@@ -205,10 +265,7 @@ first argument to socket system call. Recognized values: \fBunix\fR,
205\fBinet\fR, \fBinet6\fR, \fBnetlink\fR and \fBpacket\fR. 265\fBinet\fR, \fBinet6\fR, \fBnetlink\fR and \fBpacket\fR.
206.TP 266.TP
207\fBseccomp 267\fBseccomp
208Enable default seccomp filter. The default list is as follows: 268Enable 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 269.TP
213\fBseccomp syscall,syscall,syscall 270\fBseccomp syscall,syscall,syscall
214Enable seccomp filter and blacklist the system calls in the list on top of default seccomp filter. 271Enable seccomp filter and blacklist the system calls in the list on top of default seccomp filter.
@@ -219,9 +276,32 @@ Enable seccomp filter and blacklist the system calls in the list.
219\fBseccomp.keep syscall,syscall,syscall 276\fBseccomp.keep syscall,syscall,syscall
220Enable seccomp filter and whitelist the system calls in the list. 277Enable seccomp filter and whitelist the system calls in the list.
221.TP 278.TP
279\fBnonewprivs
280Sets the NO_NEW_PRIVS prctl. This ensures that child processes
281cannot acquire new privileges using execve(2); in particular,
282this means that calling a suid binary (or one with file capabilities)
283does not result in an increase of privilege.
284.TP
222\fBnoroot 285\fBnoroot
223Use this command to enable an user namespace. The namespace has only one user, the current user. 286Use 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. 287There is no root account (uid 0) defined in the namespace.
288.TP
289\fBx11
290Enable X11 sandboxing.
291.TP
292\fBx11 none
293Blacklist /tmp/.X11-unix directory, ${HOME}/.Xauthority and file specified in ${XAUTHORITY} environment variable.
294Remove DISPLAY and XAUTHORITY environment variables.
295Stop with error message if X11 abstract socket will be accessible in jail.
296.TP
297\fBx11 xephyr
298Enable X11 sandboxing with xephyr.
299.TP
300\fBx11 xorg
301Enable X11 sandboxing with X11 security extension.
302.TP
303\fBx11 xpra
304Enable X11 sandboxing with xpra.
225 305
226.SH Resource limits, CPU affinity, Control Groups 306.SH Resource limits, CPU affinity, Control Groups
227These profile entries define the limits on system resources (rlimits) for the processes inside the sandbox. 307These profile entries define the limits on system resources (rlimits) for the processes inside the sandbox.
@@ -255,6 +335,10 @@ The sandbox is placed in g1 control group.
255 335
256.SH User Environment 336.SH User Environment
257.TP 337.TP
338\fBallusers
339All user home directories are visible inside the sandbox. By default, only current user home directory is visible.
340
341.TP
258\fBname sandboxname 342\fBname sandboxname
259Set sandbox name. Example: 343Set sandbox name. Example:
260.br 344.br
@@ -284,9 +368,18 @@ Enable IPC namespace.
284.TP 368.TP
285\fBnosound 369\fBnosound
286Disable sound system. 370Disable sound system.
371.TP
372\fBno3d
373Disable 3D hardware acceleration.
374
287.SH Networking 375.SH Networking
288Networking features available in profile files. 376Networking features available in profile files.
289 377
378.TP
379\fBdefaultgw address
380Use this address as default gateway in the new network namespace.
381
382.TP
290\fBdns address 383\fBdns address
291Set a DNS server for the sandbox. Up to three DNS servers can be defined. 384Set a DNS server for the sandbox. Up to three DNS servers can be defined.
292 385
@@ -295,6 +388,45 @@ Set a DNS server for the sandbox. Up to three DNS servers can be defined.
295Set a hostname for the sandbox. 388Set a hostname for the sandbox.
296 389
297.TP 390.TP
391\fBip address
392Assign IP addresses to the last network interface defined by a net command. A
393default gateway is assigned by default.
394.br
395
396.br
397Example:
398.br
399net eth0
400.br
401ip 10.10.20.56
402
403.TP
404\fBip none
405No IP address and no default gateway are configured for the last interface
406defined by a net command. Use this option
407in case you intend to start an external DHCP client in the sandbox.
408.br
409
410.br
411Example:
412.br
413net eth0
414.br
415ip none
416
417.TP
418\fBip6 address
419Assign IPv6 addresses to the last network interface defined by a net command.
420.br
421
422.br
423Example:
424.br
425net eth0
426.br
427ip6 2001:0db8:0:f101::1/64
428
429.TP
298\fBiprange address,address 430\fBiprange address,address
299Assign an IP address in the provided range to the last network 431Assign an IP address in the provided range to the last network
300interface defined by a net command. A default gateway is assigned by default. 432interface defined by a net command. A default gateway is assigned by default.
@@ -311,6 +443,20 @@ iprange 192.168.1.150,192.168.1.160
311.br 443.br
312 444
313.TP 445.TP
446\fBmac address
447Assign MAC addresses to the last network interface defined by a net command.
448
449.TP
450\fBmachine-id
451Preserve id number in /etc/machine-id file. By default a new random id is generated inside the sandbox.
452
453.TP
454\fBmtu number
455Assign a MTU value to the last network interface defined by a net command.
456
457
458
459.TP
314\fBnetfilter 460\fBnetfilter
315If a new network namespace is created, enabled default network filter. 461If a new network namespace is created, enabled default network filter.
316 462
@@ -345,6 +491,17 @@ available in the new namespace is a new loopback interface (lo).
345Use this option to deny network access to programs that don't 491Use this option to deny network access to programs that don't
346really need network access. 492really need network access.
347 493
494.TP
495\fBveth-name name
496Use this name for the interface connected to the bridge for --net=bridge_interface commands,
497instead of the default one.
498
499.SH Other
500.TP
501\fBjoin-or-start sandboxname
502Join the sandbox identified by name or start a new one.
503Same as "firejail --join=sandboxname" command if sandbox with specified name exists, otherwise same as "name sandboxname".
504
348.SH RELOCATING PROFILES 505.SH RELOCATING PROFILES
349For various reasons some users might want to keep the profile files in a different directory. 506For 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 507Using \fB--profile-path\fR command line option, Firejail can be instructed to look for profiles
@@ -388,7 +545,6 @@ Homepage: http://firejail.wordpress.com
388\&\flfiremon\fR\|(1), 545\&\flfiremon\fR\|(1),
389\&\flfirecfg\fR\|(1), 546\&\flfirecfg\fR\|(1),
390\&\flfirejail-login\fR\|(5) 547\&\flfirejail-login\fR\|(5)
391\&\flfirejail-config\fR\|(5)
392 548
393 549
394 550
diff --git a/src/man/firejail.txt b/src/man/firejail.txt
index 23db832c1..5b43b1ca5 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 directories under /home 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
@@ -619,6 +666,16 @@ Example:
619$ firejail \-\-net=eth0 \-\-mac=00:11:22:33:44:55 firefox 666$ firejail \-\-net=eth0 \-\-mac=00:11:22:33:44:55 firefox
620 667
621.TP 668.TP
669\fB\-\-machine-id
670Preserve id number in /etc/machine-id file. By default a new random id is generated inside the sandbox.
671.br
672
673.br
674Example:
675.br
676$ firejail \-\-machine-id
677
678.TP
622\fB\-\-mtu=number 679\fB\-\-mtu=number
623Assign a MTU value to the last network interface defined by a \-\-net option. 680Assign a MTU value to the last network interface defined by a \-\-net option.
624.br 681.br
@@ -798,13 +855,23 @@ PID User RX(KB/s) TX(KB/s) Command
798.TP 855.TP
799\fB\-\-nice=value 856\fB\-\-nice=value
800Set nice value for all processes running inside the sandbox. 857Set nice value for all processes running inside the sandbox.
858Only root may specify a negative value.
801.br 859.br
802 860
803.br 861.br
804Example: 862Example:
805.br 863.br
806$ firejail --nice=-5 firefox 864$ firejail --nice=2 firefox
865
866.TP
867\fB\-\-no3d
868Disable 3D hardware acceleration.
869.br
807 870
871.br
872Example:
873.br
874$ firejail --no3d firefox
808 875
809.TP 876.TP
810\fB\-\-noblacklist=dirname_or_filename 877\fB\-\-noblacklist=dirname_or_filename
@@ -831,6 +898,21 @@ $ nc dict.org 2628
831220 pan.alephnull.com dictd 1.12.1/rf on Linux 3.14-1-amd64 898220 pan.alephnull.com dictd 1.12.1/rf on Linux 3.14-1-amd64
832.br 899.br
833.TP 900.TP
901\fB\-\-noexec=dirname_or_filename
902Remount directory or file noexec, nodev and nosuid.
903.br
904
905.br
906Example:
907.br
908$ firejail \-\-noexec=/tmp
909.br
910
911.br
912/etc and /var are noexec by default if the sandbox was started as a regular user. If there are more than one mount operation
913on 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.
914
915.TP
834\fB\-\-nogroups 916\fB\-\-nogroups
835Disable supplementary groups. Without this option, supplementary groups are enabled for the user starting the 917Disable supplementary groups. Without this option, supplementary groups are enabled for the user starting the
836sandbox. For root user supplementary groups are always disabled. 918sandbox. For root user supplementary groups are always disabled.
@@ -865,7 +947,7 @@ Example:
865.br 947.br
866$ firejail 948$ firejail
867.br 949.br
868Reading profile /etc/firejail/generic.profile 950Reading profile /etc/firejail/default.profile
869.br 951.br
870Parent pid 8553, child pid 8554 952Parent pid 8553, child pid 8554
871.br 953.br
@@ -908,6 +990,14 @@ ping: icmp open socket: Operation not permitted
908$ 990$
909 991
910.TP 992.TP
993\fB\-\-nonewprivs
994Sets the NO_NEW_PRIVS prctl. This ensures that child processes
995cannot acquire new privileges using execve(2); in particular,
996this means that calling a suid binary (or one with file capabilities)
997does not result in an increase of privilege. This option
998is enabled by default if seccomp filter is activated.
999
1000.TP
911\fB\-\-nosound 1001\fB\-\-nosound
912Disable sound system. 1002Disable sound system.
913.br 1003.br
@@ -946,13 +1036,15 @@ $ ls -l sandboxlog*
946 1036
947.TP 1037.TP
948\fB\-\-overlay 1038\fB\-\-overlay
949Mount a filesystem overlay on top of the current filesystem. All filesystem modifications go into the overlay. 1039Mount 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. 1040the system directories are mounted read-write. All filesystem modifications go into the overlay.
1041The overlay is stored in $HOME/.firejail/<PID> directory.
951.br 1042.br
952 1043
953.br 1044.br
954OverlayFS support is required in Linux kernel for this option to work. 1045OverlayFS support is required in Linux kernel for this option to work.
955OverlayFS was officially introduced in Linux kernel version 3.18 1046OverlayFS was officially introduced in Linux kernel version 3.18.
1047This option is not available on Grsecurity systems.
956.br 1048.br
957 1049
958.br 1050.br
@@ -961,14 +1053,34 @@ Example:
961$ firejail \-\-overlay firefox 1053$ firejail \-\-overlay firefox
962 1054
963.TP 1055.TP
1056\fB\-\-overlay-named=name
1057Mount a filesystem overlay on top of the current filesystem. Unlike the regular filesystem container,
1058the system directories are mounted read-write. All filesystem modifications go into the overlay.
1059The overlay is stored in $HOME/.firejail/<NAME> directory. The created overlay can be reused between multiple
1060sessions.
1061.br
1062
1063.br
1064OverlayFS support is required in Linux kernel for this option to work.
1065OverlayFS was officially introduced in Linux kernel version 3.18.
1066This option is not available on Grsecurity systems.
1067.br
1068
1069.br
1070Example:
1071.br
1072$ firejail \-\-overlay-named=jail1 firefox
1073
1074.TP
964\fB\-\-overlay-tmpfs 1075\fB\-\-overlay-tmpfs
965Mount a filesystem overlay on top of the current filesystem. All filesystem modifications go into the overlay, 1076Mount 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. 1077and are discarded when the sandbox is closed.
967.br 1078.br
968 1079
969.br 1080.br
970OverlayFS support is required in Linux kernel for this option to work. 1081OverlayFS support is required in Linux kernel for this option to work.
971OverlayFS was officially introduced in Linux kernel version 3.18 1082OverlayFS was officially introduced in Linux kernel version 3.18.
1083This option is not available on Grsecurity systems.
972.br 1084.br
973 1085
974.br 1086.br
@@ -977,6 +1089,17 @@ Example:
977$ firejail \-\-overlay-tmpfs firefox 1089$ firejail \-\-overlay-tmpfs firefox
978 1090
979.TP 1091.TP
1092\fB\-\-overlay-clean
1093Clean all overlays stored in $HOME/.firejail directory. Overlays created with --overlay-path=path
1094outside $HOME/.firejail will not be deleted.
1095.br
1096
1097.br
1098Example:
1099.br
1100$ firejail \-\-overlay-clean
1101
1102.TP
980\fB\-\-private 1103\fB\-\-private
981Mount new /root and /home/user directories in temporary 1104Mount new /root and /home/user directories in temporary
982filesystems. All modifications are discarded when the sandbox is 1105filesystems. All modifications are discarded when the sandbox is
@@ -998,9 +1121,24 @@ Example:
998$ firejail \-\-private=/home/netblue/firefox-home firefox 1121$ firejail \-\-private=/home/netblue/firefox-home firefox
999 1122
1000.TP 1123.TP
1124\fB\-\-private-home=file,directory
1125Build a new user home in a temporary
1126filesystem, and copy the files and directories in the list in the
1127new home. All modifications are discarded when the sandbox is
1128closed.
1129.br
1130
1131.br
1132Example:
1133.br
1134$ firejail \-\-private-home=.mozilla firefox
1135
1136.TP
1001\fB\-\-private-bin=file,file 1137\fB\-\-private-bin=file,file
1002Build a new /bin in a temporary filesystem, and copy the programs in the list. 1138Build a new /bin in a temporary filesystem, and copy the programs in the list.
1139If 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. 1140The same directory is also bind-mounted over /sbin, /usr/bin, /usr/sbin and /usr/local/bin.
1141All modifications are discarded when the sandbox is closed.
1004.br 1142.br
1005 1143
1006.br 1144.br
@@ -1018,7 +1156,7 @@ bash cat ls sed
1018 1156
1019.TP 1157.TP
1020\fB\-\-private-dev 1158\fB\-\-private-dev
1021Create a new /dev directory. Only dri, null, full, zero, tty, pts, ptmx, random, urandom, log and shm devices are available. 1159Create a new /dev directory. Only dri, null, full, zero, tty, pts, ptmx, random, snd, urandom, log and shm devices are available.
1022.br 1160.br
1023 1161
1024.br 1162.br
@@ -1032,14 +1170,15 @@ Child process initialized
1032.br 1170.br
1033$ ls /dev 1171$ ls /dev
1034.br 1172.br
1035dri full log null ptmx pts random shm tty urandom zero 1173dri full log null ptmx pts random shm snd tty urandom zero
1036.br 1174.br
1037$ 1175$
1038.TP 1176.TP
1039\fB\-\-private-etc=file,directory 1177\fB\-\-private-etc=file,directory
1040Build a new /etc in a temporary 1178Build a new /etc in a temporary
1041filesystem, and copy the files and directories in the list. 1179filesystem, and copy the files and directories in the list.
1042All modifications are discarded when the sandbox is closed. 1180If no listed file is found, /etc directory will be empty.
1181All modifications are discarded when the sandbox is closed.
1043.br 1182.br
1044 1183
1045.br 1184.br
@@ -1050,8 +1189,34 @@ $ firejail --private-etc=group,hostname,localtime, \\
1050nsswitch.conf,passwd,resolv.conf 1189nsswitch.conf,passwd,resolv.conf
1051 1190
1052.TP 1191.TP
1192\fB\-\-private-opt=file,directory
1193Build a new /opt in a temporary
1194filesystem, and copy the files and directories in the list.
1195If no listed file is found, /opt directory will be empty.
1196All modifications are discarded when the sandbox is closed.
1197.br
1198
1199.br
1200Example:
1201.br
1202$ firejail --private-opt=firefox /opt/firefox/firefox
1203
1204.TP
1205\fB\-\-private-srv=file,directory
1206Build a new /srv in a temporary
1207filesystem, and copy the files and directories in the list.
1208If no listed file is found, /srv directory will be empty.
1209All modifications are discarded when the sandbox is closed.
1210.br
1211
1212.br
1213Example:
1214.br
1215# firejail --private-srv=www /etc/init.d/apache2 start
1216
1217.TP
1053\fB\-\-private-tmp 1218\fB\-\-private-tmp
1054Mount an empty temporary filesystem on top of /tmp directory. 1219Mount an empty temporary filesystem on top of /tmp directory whitelisting /tmp/.X11-unix.
1055.br 1220.br
1056 1221
1057.br 1222.br
@@ -1120,6 +1285,9 @@ $ firejail \-\-protocol.print=3272
1120.br 1285.br
1121unix,inet,inet6,netlink 1286unix,inet,inet6,netlink
1122.TP 1287.TP
1288\fB\-\-put=name|pid src-filename dest-filename
1289Put a file in sandbox container, see \fBFILE TRANSFER\fR section for more details.
1290.TP
1123\fB\-\-quiet 1291\fB\-\-quiet
1124Turn off Firejail's output. 1292Turn off Firejail's output.
1125.TP 1293.TP
@@ -1131,6 +1299,31 @@ Set directory or file read-only.
1131Example: 1299Example:
1132.br 1300.br
1133$ firejail \-\-read-only=~/.mozilla firefox 1301$ firejail \-\-read-only=~/.mozilla firefox
1302.br
1303
1304.br
1305A short note about mixing \-\-whitelist and \-\-read-only options. Whitelisted directories
1306should be made read-only independently. Making a parent directory read-only, will not
1307make the whitelist read-only. Example:
1308.br
1309
1310.br
1311$ firejail --whitelist=~/work --read-only=~ --read-only=~/work
1312
1313.TP
1314\fB\-\-read-write=dirname_or_filename
1315Set directory or file read-write. Only files or directories belonging to the current user are allowed for
1316this operation. Example:
1317.br
1318
1319.br
1320$ mkdir ~/test
1321.br
1322$ touch ~/test/a
1323.br
1324$ firejail --read-only=~/test --read-write=~/test/a
1325
1326
1134.TP 1327.TP
1135\fB\-\-rlimit-fsize=number 1328\fB\-\-rlimit-fsize=number
1136Set the maximum file size that can be created by a process. 1329Set the maximum file size that can be created by a process.
@@ -1143,6 +1336,17 @@ Set the maximum number of processes that can be created for the real user ID of
1143.TP 1336.TP
1144\fB\-\-rlimit-sigpending=number 1337\fB\-\-rlimit-sigpending=number
1145Set the maximum number of pending signals for a process. 1338Set the maximum number of pending signals for a process.
1339
1340.TP
1341\fB\-\-rmenv=name
1342Remove environment variable in the new sandbox.
1343.br
1344
1345.br
1346Example:
1347.br
1348$ firejail \-\-rmenv=DBUS_SESSION_BUS_ADDRESS
1349
1146.TP 1350.TP
1147\fB\-\-scan 1351\fB\-\-scan
1148ARP-scan all the networks from inside a network namespace. 1352ARP-scan all the networks from inside a network namespace.
@@ -1156,13 +1360,13 @@ $ firejail \-\-net=eth0 \-\-scan
1156.TP 1360.TP
1157\fB\-\-seccomp 1361\fB\-\-seccomp
1158Enable seccomp filter and blacklist the syscalls in the default list. The default list is as follows: 1362Enable 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, 1363mount, 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, 1364iopl, 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, 1365sysfs,_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, 1366add_key, request_key, keyctl, uselib, acct, modify_ldt, pivot_root, io_setup,
1163io_destroy, io_getevents, io_submit, io_cancel, 1367io_destroy, io_getevents, io_submit, io_cancel,
1164remap_file_pages, mbind, get_mempolicy, set_mempolicy, 1368remap_file_pages, mbind, get_mempolicy, set_mempolicy,
1165migrate_pages, move_pages, vmsplice, perf_event_open, chroot, 1369migrate_pages, move_pages, vmsplice, chroot,
1166tuxcall, reboot, mfsservctl and get_kernel_syms. 1370tuxcall, reboot, mfsservctl and get_kernel_syms.
1167.br 1371.br
1168 1372
@@ -1173,6 +1377,10 @@ both 32-bit and 64-bit filters are installed.
1173.br 1377.br
1174 1378
1175.br 1379.br
1380Firejail will print seccomp violations to the audit log if the kernel was compiled with audit support (CONFIG_AUDIT flag).
1381.br
1382
1383.br
1176Example: 1384Example:
1177.br 1385.br
1178$ firejail \-\-seccomp 1386$ firejail \-\-seccomp
@@ -1425,15 +1633,7 @@ $ firejail \-\-tree
142511969:netblue:firejail \-\-net=eth0 transmission-gtk 163311969:netblue:firejail \-\-net=eth0 transmission-gtk
1426.br 1634.br
1427 11970:netblue:transmission-gtk 1635 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 1636
1433.br
1434Example:
1435.br
1436# firejail \-\-user=www-data
1437.TP 1637.TP
1438\fB\-\-version 1638\fB\-\-version
1439Print program version and exit. 1639Print program version and exit.
@@ -1445,66 +1645,106 @@ Example:
1445$ firejail \-\-version 1645$ firejail \-\-version
1446.br 1646.br
1447firejail version 0.9.27 1647firejail version 0.9.27
1648
1649.TP
1650\fB\-\-veth-name=name
1651Use this name for the interface connected to the bridge for --net=bridge_interface commands,
1652instead of the default one.
1653.br
1654
1655.br
1656Example:
1657.br
1658$ firejail \-\-net=br0 --veth-name=if0
1659
1448.TP 1660.TP
1449\fB\-\-whitelist=dirname_or_filename 1661\fB\-\-whitelist=dirname_or_filename
1450Whitelist directory or file. This feature is implemented only for user home, /dev, /media, /opt, /var, and /tmp directories. 1662Whitelist 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 1663whitelisted files are mount-binded inside. Modifications to whitelisted files are persistent,
1452(home user, /media, /var etc.) 1664everything else is discarded when the sandbox is closed. The top directory could be
1665user home, /dev, /media, /mnt, /opt, /srv, /var, and /tmp.
1666.br
1667
1668.br
1669Symbolic link handling: with the exception of user home, both the link and the real file should be in
1670the same top directory. For user home, both the link and the real file should be owned by the user.
1453.br 1671.br
1454 1672
1455.br 1673.br
1456Example: 1674Example:
1457.br 1675.br
1458$ firejail \-\-whitelist=~/.mozilla \-\-whitelist=~/Downloads 1676$ firejail \-\-noprofile \-\-whitelist=~/.mozilla
1459.br 1677.br
1460$ firejail \-\-whitelist=/tmp/.X11-unix --whitelist=/dev/null 1678$ firejail \-\-whitelist=/tmp/.X11-unix --whitelist=/dev/null
1461.br 1679.br
1462$ firejail "\-\-whitelist=/home/username/My Virtual Machines" 1680$ firejail "\-\-whitelist=/home/username/My Virtual Machines"
1463 1681
1464.TP 1682.TP
1465\fB\-\-x11 1683\fB\-\-writable-etc
1466Start a new X11 server using Xpra or Xephyr and attach the sandbox to this server. 1684Mount /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 1685.br
1471 1686
1472.br 1687.br
1473Firejail will try first Xpra, and if Xpra is not installed on the system, it will try to find Xephyr. 1688Example:
1474This feature is not available when running as root. 1689.br
1690$ sudo firejail --writable-etc
1691
1692.TP
1693\fB\-\-writable-var
1694Mount /var directory read-write.
1475.br 1695.br
1476 1696
1477.br 1697.br
1478Example: 1698Example:
1479.br 1699.br
1480$ firejail \-\-x11 --net=eth0 firefox 1700$ sudo firejail --writable-var
1701
1481 1702
1482.TP 1703.TP
1483\fB\-\-x11=xpra 1704\fB\-\-x11
1484Start a new X11 server using Xpra (http://xpra.org) and attach the sandbox to this server. 1705Sandbox 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. 1706The 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. 1707clients running outside the sandbox.
1487This feature is not available when running as root. 1708Firejail will try first Xpra, and if Xpra is not installed on the system, it will try to find Xephyr.
1709If all fails, Firejail will not attempt to use X11 security extension.
1710.br
1711
1712.br
1713Xpra and Xephyr modes require a network namespace to be instantiated in order to disable
1714X11 abstract Unix socket. If this is not possible, the user can disable the abstract socket
1715by adding "-nolisten local" on Xorg command line.
1488.br 1716.br
1489 1717
1490.br 1718.br
1491Example: 1719Example:
1492.br 1720.br
1493$ firejail \-\-x11=xpra --net=eth0 firefox 1721$ firejail \-\-x11 --net=eth0 firefox
1722
1723.TP
1724\fB\-\-x11=none
1725Blacklist /tmp/.X11-unix directory, ${HOME}/.Xauthority and the file specified in ${XAUTHORITY} environment variable.
1726Remove DISPLAY and XAUTHORITY environment variables.
1727Stop with error message if X11 abstract socket will be accessible in jail.
1494 1728
1495.TP 1729.TP
1496\fB\-\-x11=xephyr 1730\fB\-\-x11=xephyr
1497Start a new X11 server using Xephyr and attach the sandbox to this server. 1731Start Xephyr and attach the sandbox to this server.
1498Xephyr is a display server implementing the X11 display server protocol. 1732Xephyr 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. 1733A 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, 1734.br
1501see \fBman 5 firejail-config\fR for more details. 1735
1736.br
1737Xephyr runs in a window just like any other X11 application. The default window size is 800x600.
1738This can be modified in /etc/firejail/firejail.config file.
1502.br 1739.br
1503 1740
1504.br 1741.br
1505The recommended way to use this feature is to run a window manager inside the sandbox. 1742The recommended way to use this feature is to run a window manager inside the sandbox.
1506A security profile for OpenBox is provided. 1743A security profile for OpenBox is provided.
1507On Debian platforms Xephyr is installed with the command \fBsudo apt-get install xserver-xephyr\fR. 1744.br
1745
1746.br
1747Xephyr 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. 1748This feature is not available when running as root.
1509.br 1749.br
1510 1750
@@ -1514,6 +1754,42 @@ Example:
1514$ firejail \-\-x11=xephyr --net=eth0 openbox 1754$ firejail \-\-x11=xephyr --net=eth0 openbox
1515 1755
1516.TP 1756.TP
1757\fB\-\-x11=xorg
1758Sandbox the application using the untrusted mode implemented by X11 security extension.
1759The extension is available in Xorg package
1760and it is installed by default on most Linux distributions. It provides support for a simple trusted/untrusted
1761connection model. Untrusted clients are restricted in certain ways to prevent them from reading window
1762contents of other clients, stealing input events, etc.
1763
1764The untrusted mode has several limitations. A lot of regular programs assume they are a trusted X11 clients
1765and will crash or lock up when run in untrusted mode. Chromium browser and xterm are two examples.
1766Firefox and transmission-gtk seem to be working fine.
1767A network namespace is not required for this option.
1768.br
1769
1770.br
1771Example:
1772.br
1773$ firejail \-\-x11=xorg firefox
1774
1775.TP
1776\fB\-\-x11=xpra
1777Start Xpra (http://xpra.org) and attach the sandbox to this server.
1778Xpra is a persistent remote display server and client for forwarding X11 applications and desktop screens.
1779A network namespace needs to be instantiated in order to deny access to X11 abstract Unix domain socket.
1780.br
1781
1782.br
1783On Debian platforms Xpra is installed with the command \fBsudo apt-get install xpra\fR.
1784This feature is not available when running as root.
1785.br
1786
1787.br
1788Example:
1789.br
1790$ firejail \-\-x11=xpra --net=eth0 firefox
1791
1792.TP
1517\fB\-\-zsh 1793\fB\-\-zsh
1518Use /usr/bin/zsh as default user shell. 1794Use /usr/bin/zsh as default user shell.
1519.br 1795.br
@@ -1576,6 +1852,44 @@ $ firejail --tree
1576 1221:netblue:/usr/lib/firefox/firefox 1852 1221:netblue:/usr/lib/firefox/firefox
1577.RE 1853.RE
1578 1854
1855.SH APPARMOR
1856.TP
1857AppArmor support is disabled by default at compile time. Use --enable-apparmor configuration option to enable it:
1858.br
1859
1860.br
1861$ ./configure --prefix=/usr --enable-apparmor
1862.TP
1863During 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:
1864.br
1865
1866.br
1867# aa-enforce firejail-default
1868.TP
1869The installed profile tries to replicate some advanced security features inspired by kernel-based Grsecurity:
1870.br
1871
1872.br
1873- Prevent information leakage in /proc and /sys directories. The resulting filesystem is barely enough for running
1874commands such as "top" and "ps aux".
1875.br
1876
1877.br
1878- Allow running programs only from well-known system paths, such as /bin, /sbin, /usr/bin etc. Running
1879programs and scripts from user home or other directories writable by the user is not allowed.
1880.br
1881
1882.br
1883- Disable D-Bus. D-Bus has long been a huge security hole, and most programs don't use it anyway.
1884You should have no problems running Chromium or Firefox.
1885
1886.TP
1887To 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:
1888.br
1889
1890.br
1891$ firejail --apparmor firefox
1892
1579.SH FILE TRANSFER 1893.SH FILE TRANSFER
1580These features allow the user to inspect the filesystem container of an existing sandbox 1894These features allow the user to inspect the filesystem container of an existing sandbox
1581and transfer files from the container to the host filesystem. 1895and transfer files from the container to the host filesystem.
@@ -1583,12 +1897,16 @@ and transfer files from the container to the host filesystem.
1583.TP 1897.TP
1584\fB\-\-get=name|pid filename 1898\fB\-\-get=name|pid filename
1585Retrieve the container file and store it on the host in the current working directory. 1899Retrieve 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. 1900The container is specified by name or PID.
1587 1901
1588.TP 1902.TP
1589\fB\-\-ls=name|pid dir_or_filename 1903\fB\-\-ls=name|pid dir_or_filename
1590List container files. The container is specified by name or PID. 1904List container files. The container is specified by name or PID.
1591Full path is needed for dir_or_filename. 1905
1906.TP
1907\fB\-\-put=name|pid src-filename dest-filename
1908Put src-filename in sandbox container.
1909The container is specified by name or PID.
1592 1910
1593.TP 1911.TP
1594Examples: 1912Examples:
@@ -1614,7 +1932,11 @@ drwxr-xr-x netblue netblue 4096 ..
1614 1932
1615.br 1933.br
1616$ firejail \-\-get=mybrowser ~/Downloads/xpra-clipboard.png 1934$ firejail \-\-get=mybrowser ~/Downloads/xpra-clipboard.png
1935.br
1617 1936
1937.br
1938$ firejail \-\-put=mybrowser xpra-clipboard.png ~/Downloads/xpra-clipboard.png
1939.br
1618 1940
1619.SH TRAFFIC SHAPING 1941.SH TRAFFIC SHAPING
1620Network bandwidth is an expensive resource shared among all sandboxes running on a system. 1942Network bandwidth is an expensive resource shared among all sandboxes running on a system.
@@ -1626,15 +1948,15 @@ The shaper works at sandbox level, and can be used only for sandboxes configured
1626 1948
1627Set rate-limits: 1949Set rate-limits:
1628 1950
1629 firejail --bandwidth=name|pid set network download upload 1951 $ firejail --bandwidth=name|pid set network download upload
1630 1952
1631Clear rate-limits: 1953Clear rate-limits:
1632 1954
1633 firejail --bandwidth=name|pid clear network 1955 $ firejail --bandwidth=name|pid clear network
1634 1956
1635Status: 1957Status:
1636 1958
1637 firejail --bandwidth=name|pid status 1959 $ firejail --bandwidth=name|pid status
1638 1960
1639where: 1961where:
1640.br 1962.br
@@ -1658,6 +1980,26 @@ Example:
1658.br 1980.br
1659 $ firejail \-\-bandwidth=mybrowser clear eth0 1981 $ firejail \-\-bandwidth=mybrowser clear eth0
1660 1982
1983.SH AUDIT
1984Audit feature allows the user to point out gaps in security profiles. The
1985implementation replaces the program to be sandboxed with a test program. By
1986default, we use faudit program distributed with Firejail. A custom test program
1987can also be supplied by the user. Examples:
1988
1989Running the default audit program:
1990.br
1991 $ firejail --audit transmission-gtk
1992
1993Running a custom audit program:
1994.br
1995 $ firejail --audit=~/sandbox-test transmission-gtk
1996
1997In the examples above, the sandbox configures transmission-gtk profile and
1998starts the test program. The real program, transmission-gtk, will not be
1999started.
2000
2001Limitations: audit feature is not implemented for --x11 commands.
2002
1661.SH MONITORING 2003.SH MONITORING
1662Option \-\-list prints a list of all sandboxes. The format 2004Option \-\-list prints a list of all sandboxes. The format
1663for each process entry is as follows: 2005for each process entry is as follows:
@@ -1751,7 +2093,7 @@ To disable default profile loading, use --noprofile command option. Example:
1751.RS 2093.RS
1752$ firejail 2094$ firejail
1753.br 2095.br
1754Reading profile /etc/firejail/generic.profile 2096Reading profile /etc/firejail/default.profile
1755.br 2097.br
1756Parent pid 8553, child pid 8554 2098Parent pid 8553, child pid 8554
1757.br 2099.br
@@ -1818,7 +2160,6 @@ Homepage: http://firejail.wordpress.com
1818\&\flfirecfg\fR\|(1), 2160\&\flfirecfg\fR\|(1),
1819\&\flfirejail-profile\fR\|(5), 2161\&\flfirejail-profile\fR\|(5),
1820\&\flfirejail-login\fR\|(5) 2162\&\flfirejail-login\fR\|(5)
1821\&\flfirejail-config\fR\|(5)
1822 2163
1823 2164
1824 2165
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/src/tools/unchroot b/src/tools/unchroot
deleted file mode 100755
index d32ce2682..000000000
--- a/src/tools/unchroot
+++ /dev/null
Binary files differ
diff --git a/src/tools/unchroot.c b/src/tools/unchroot.c
deleted file mode 100644
index 21731296e..000000000
--- a/src/tools/unchroot.c
+++ /dev/null
@@ -1,125 +0,0 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <errno.h>
4#include <fcntl.h>
5#include <string.h>
6#include <unistd.h>
7#include <sys/stat.h>
8#include <sys/types.h>
9
10/*
11 ** You should set NEED_FCHDIR to 1 if the chroot() on your
12 ** system changes the working directory of the calling
13 ** process to the same directory as the process was chroot()ed
14 ** to.
15 **
16 ** It is known that you do not need to set this value if you
17 ** running on Solaris 2.7 and below.
18 **
19 */
20#define NEED_FCHDIR 0
21
22#define TEMP_DIR "waterbuffalo"
23
24/* Break out of a chroot() environment in C */
25
26int main() {
27 int x; /* Used to move up a directory tree */
28 int done=0; /* Are we done yet ? */
29#ifdef NEED_FCHDIR
30 int dir_fd; /* File descriptor to directory */
31#endif
32 struct stat sbuf; /* The stat() buffer */
33
34 /*
35 ** First we create the temporary directory if it doesn't exist
36 */
37 if (stat(TEMP_DIR,&sbuf)<0) {
38 if (errno==ENOENT) {
39 if (mkdir(TEMP_DIR,0755)<0) {
40 fprintf(stderr,"Failed to create %s - %s\n", TEMP_DIR,
41 strerror(errno));
42 exit(1);
43 }
44 }
45 else {
46 fprintf(stderr,"Failed to stat %s - %s\n", TEMP_DIR,
47 strerror(errno));
48 exit(1);
49 }
50 }
51 else if (!S_ISDIR(sbuf.st_mode)) {
52 fprintf(stderr,"Error - %s is not a directory!\n",TEMP_DIR);
53 exit(1);
54 }
55
56#ifdef NEED_FCHDIR
57 /*
58 ** Now we open the current working directory
59 **
60 ** Note: Only required if chroot() changes the calling program's
61 ** working directory to the directory given to chroot().
62 **
63 */
64 if ((dir_fd=open(".",O_RDONLY))<0) {
65 fprintf(stderr,"Failed to open \".\" for reading - %s\n",
66 strerror(errno));
67 exit(1);
68 }
69#endif
70
71 /*
72 ** Next we chroot() to the temporary directory
73 */
74 if (chroot(TEMP_DIR)<0) {
75 fprintf(stderr,"Failed to chroot to %s - %s\n",TEMP_DIR,
76 strerror(errno));
77 exit(1);
78 }
79
80#ifdef NEED_FCHDIR
81 /*
82 ** Partially break out of the chroot by doing an fchdir()
83 **
84 ** This only partially breaks out of the chroot() since whilst
85 ** our current working directory is outside of the chroot() jail,
86 ** our root directory is still within it. Thus anything which refers
87 ** to "/" will refer to files under the chroot() point.
88 **
89 ** Note: Only required if chroot() changes the calling program's
90 ** working directory to the directory given to chroot().
91 **
92 */
93 if (fchdir(dir_fd)<0) {
94 fprintf(stderr,"Failed to fchdir - %s\n",
95 strerror(errno));
96 exit(1);
97 }
98 close(dir_fd);
99#endif
100
101 /*
102 ** Completely break out of the chroot by recursing up the directory
103 ** tree and doing a chroot to the current working directory (which will
104 ** be the real "/" at that point). We just do a chdir("..") lots of
105 ** times (1024 times for luck :). If we hit the real root directory before
106 ** we have finished the loop below it doesn't matter as .. in the root
107 ** directory is the same as . in the root.
108 **
109 ** We do the final break out by doing a chroot(".") which sets the root
110 ** directory to the current working directory - at this point the real
111 ** root directory.
112 */
113 for(x=0;x<1024;x++) {
114 chdir("..");
115 }
116 chroot(".");
117
118 /*
119 ** We're finally out - so exec a shell in interactive mode
120 */
121 if (execl("/bin/sh","-i",NULL)<0) {
122 fprintf(stderr,"Failed to exec - %s\n",strerror(errno));
123 exit(1);
124 }
125}
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..f1c1c10f5
--- /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 --debug --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..db221ec8a
--- /dev/null
+++ b/test/appimage/appimage.sh
@@ -0,0 +1,16 @@
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-v2.exp
14
15echo "TESTING: AppImage file name (test/appimage/filename.exp)";
16./filename.exp \ No newline at end of file
diff --git a/test/appimage/filename.exp b/test/appimage/filename.exp
new file mode 100755
index 000000000..ce8d70464
--- /dev/null
+++ b/test/appimage/filename.exp
@@ -0,0 +1,35 @@
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 \"bla;bla\"\r"
11expect {
12 timeout {puts "TESTING ERROR 1\n";exit}
13 "is an invalid filename"
14}
15after 100
16
17send -- "firejail --appimage /etc/shadow\r"
18expect {
19 timeout {puts "TESTING ERROR 2\n";exit}
20 "cannot access"
21}
22after 100
23
24send -- "firejail --appimage appimage.sh\r"
25expect {
26 timeout {puts "TESTING ERROR 2\n";exit}
27 "Error mounting appimage"
28}
29after 100
30
31
32
33
34puts "\nall done\n"
35
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/chroot-resolvconf.exp b/test/chroot-resolvconf.exp
deleted file mode 100755
index 2d0da2fb0..000000000
--- a/test/chroot-resolvconf.exp
+++ /dev/null
@@ -1,14 +0,0 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "firejail --chroot=/tmp/chroot /bin/bash\r"
8expect {
9 timeout {puts "TESTING ERROR 0\n";exit}
10 "invalid /tmp/chroot/etc/resolv.conf file"
11}
12
13puts "\nall done\n"
14
diff --git a/test/chroot/chroot.sh b/test/chroot/chroot.sh
new file mode 100755
index 000000000..34bff2a67
--- /dev/null
+++ b/test/chroot/chroot.sh
@@ -0,0 +1,21 @@
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 -f unchroot
10gcc -o unchroot unchroot.c
11sudo ./configure
12
13echo "TESTING: chroot (test/chroot/fs_chroot.exp)"
14./fs_chroot.exp
15
16echo "TESTING: unchroot as root (test/chroot/unchroot-as-root.exp)"
17sudo ./unchroot-as-root.exp
18
19
20
21rm -f unchroot
diff --git a/test/chroot/configure b/test/chroot/configure
new file mode 100755
index 000000000..ba8238803
--- /dev/null
+++ b/test/chroot/configure
@@ -0,0 +1,46 @@
1#!/bin/bash
2
3# build a very small chroot
4ROOTDIR="/tmp/chroot" # default chroot directory
5DEFAULT_FILES="/bin/bash /bin/sh " # basic chroot files
6DEFAULT_FILES+="/etc/passwd /etc/nsswitch.conf /etc/group "
7DEFAULT_FILES+=`find /lib -name libnss*` # files required by glibc
8DEFAULT_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"
9
10rm -fr $ROOTDIR
11mkdir -p $ROOTDIR/{root,bin,lib,lib64,usr,home,etc,dev/shm,tmp,var/run,var/tmp,var/lock,var/log,proc}
12chmod 777 $ROOTDIR/tmp
13mkdir -p $ROOTDIR/etc/firejail
14mkdir -p $ROOTDIR/home/netblue/.config/firejail
15chown netblue:netblue $ROOTDIR/home/netblue
16chown netblue:netblue $ROOTDIR/home/netblue/.config
17cp /home/netblue/.Xauthority $ROOTDIR/home/netblue/.
18cp -a /etc/skel $ROOTDIR/etc/.
19mkdir $ROOTDIR/home/someotheruser
20mkdir $ROOTDIR/boot
21mkdir $ROOTDIR/selinux
22cp /etc/passwd $ROOTDIR/etc/.
23cp /etc/group $ROOTDIR/etc/.
24cp /etc/hosts $ROOTDIR/etc/.
25cp /etc/hostname $ROOTDIR/etc/.
26mkdir -p $ROOTDIR/usr/lib/x86_64-linux-gnu
27cp -a /usr/lib/x86_64-linux-gnu/openssl-1.0.0 $ROOTDIR/usr/lib/x86_64-linux-gnu/.
28cp -a /usr/lib/ssl $ROOTDIR/usr/lib/.
29touch $ROOTDIR/var/log/syslog
30touch $ROOTDIR/var/tmp/somefile
31SORTED=`for FILE in $* $DEFAULT_FILES; do echo " $FILE "; ldd $FILE | grep -v dynamic | cut -d " " -f 3; done | sort -u`
32for FILE in $SORTED
33do
34 cp --parents $FILE $ROOTDIR
35done
36cp --parents /lib64/ld-linux-x86-64.so.2 $ROOTDIR
37cp --parents /lib/ld-linux.so.2 $ROOTDIR
38cp unchroot $ROOTDIR/.
39touch $ROOTDIR/this-is-my-chroot
40
41cd $ROOTDIR; find .
42mkdir -p usr/lib/firejail/
43cp /usr/lib/firejail/libtrace.so usr/lib/firejail/.
44
45
46echo "To enter the chroot directory run: firejail --chroot=$ROOTDIR"
diff --git a/test/fs_chroot.exp b/test/chroot/fs_chroot.exp
index aeb5669e1..295ff8ff9 100755
--- a/test/fs_chroot.exp
+++ b/test/chroot/fs_chroot.exp
@@ -20,19 +20,14 @@ expect {
20sleep 1 20sleep 1
21send -- "bash\r" 21send -- "bash\r"
22sleep 1 22sleep 1
23send -- "ls /; pwd\r" 23send -- "ls /\r"
24expect { 24expect {
25 timeout {puts "TESTING ERROR 0.2\n";exit} 25 timeout {puts "TESTING ERROR 0.2\n";exit}
26 "this-is-my-chroot" 26 "this-is-my-chroot"
27} 27}
28expect { 28after 100
29 timeout {puts "TESTING ERROR 0.3\n";exit}
30 "home"
31}
32
33 29
34 30send -- "ps aux\r"
35send -- "ps aux; pwd\r"
36expect { 31expect {
37 timeout {puts "TESTING ERROR 1\n";exit} 32 timeout {puts "TESTING ERROR 1\n";exit}
38 "/bin/bash" 33 "/bin/bash"
@@ -45,23 +40,14 @@ expect {
45 timeout {puts "TESTING ERROR 3\n";exit} 40 timeout {puts "TESTING ERROR 3\n";exit}
46 "ps aux" 41 "ps aux"
47} 42}
48expect { 43after 100
49 timeout {puts "TESTING ERROR 4\n";exit}
50 "home"
51}
52sleep 1
53 44
54 45send -- "ps aux | wc -l; pwd\r"
55send -- "ps aux |wc -l; pwd\r"
56expect { 46expect {
57 timeout {puts "TESTING ERROR 5\n";exit} 47 timeout {puts "TESTING ERROR 5\n";exit}
58 "6" 48 "6"
59} 49}
60expect { 50after 100
61 timeout {puts "TESTING ERROR 6\n";exit}
62 "home"
63}
64sleep 1
65 51
66 52
67puts "all done\n" 53puts "all done\n"
diff --git a/test/chroot/unchroot-as-root.exp b/test/chroot/unchroot-as-root.exp
new file mode 100755
index 000000000..9f8a1d784
--- /dev/null
+++ b/test/chroot/unchroot-as-root.exp
@@ -0,0 +1,27 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "firejail --chroot=/tmp/chroot\r"
8expect {
9 timeout {puts "TESTING ERROR 0\n";exit}
10 "Error: --chroot option is not available on Grsecurity systems" {puts "\nall done\n"; exit}
11 "Child process initialized" {puts "chroot available\n"};
12}
13sleep 1
14
15send -- "cd /\r"
16after 100
17
18
19send -- "./unchroot\r"
20expect {
21 timeout {puts "TESTING ERROR 1\n";exit}
22 "Bad system call"
23}
24after 100
25
26puts "all done\n"
27
diff --git a/test/chroot/unchroot.c b/test/chroot/unchroot.c
new file mode 100644
index 000000000..1982e07f3
--- /dev/null
+++ b/test/chroot/unchroot.c
@@ -0,0 +1,40 @@
1// simple unchroot example from http://linux-vserver.org/Secure_chroot_Barrier
2#include <unistd.h>
3#include <stdlib.h>
4#include <stdio.h>
5#include <sys/types.h>
6#include <sys/stat.h>
7
8void die(char *msg) {
9 perror(msg);
10 exit(1);
11}
12
13int main(int argc, char *argv[])
14{
15 int i;
16
17 if (chdir("/") != 0)
18 die("chdir(/)");
19
20 if (mkdir("baz", 0777) != 0)
21 ; //die("mkdir(baz)");
22
23 if (chroot("baz") != 0)
24 die("chroot(baz)");
25
26 for (i=0; i<50; i++) {
27 if (chdir("..") != 0)
28 die("chdir(..)");
29 }
30
31 if (chroot(".") != 0)
32 die("chroot(.)");
33
34 printf("Exploit seems to work. =)\n");
35
36 execl("/bin/bash", "bash", "-i", (char *)0);
37 die("exec bash");
38
39 exit(0);
40}
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..0d12a82f2
--- /dev/null
+++ b/test/environment/dns.exp
@@ -0,0 +1,76 @@
1#!/usr/bin/expect -f
2
3set timeout 30
4spawn $env(SHELL)
5match_max 100000
6
7send -- "firejail --dns=8.8.4.4 --dns=8.8.8.8 --dns=4.2.2.1\r"
8expect {
9 timeout {puts "TESTING ERROR 2.1\n";exit}
10 "Child process initialized"
11}
12sleep 1
13
14send -- "cat /etc/resolv.conf\r"
15expect {
16 timeout {puts "TESTING ERROR 2.2\n";exit}
17 "nameserver 8.8.4.4"
18}
19expect {
20 timeout {puts "TESTING ERROR 2.3\n";exit}
21 "nameserver 8.8.8.8"
22}
23expect {
24 timeout {puts "TESTING ERROR 2.4\n";exit}
25 "nameserver 4.2.2.1"
26}
27after 100
28send -- "exit\r"
29sleep 1
30
31
32send -- "firejail --profile=dns.profile\r"
33expect {
34 timeout {puts "TESTING ERROR 12.1\n";exit}
35 "Child process initialized"
36}
37sleep 1
38
39send -- "cat /etc/resolv.conf\r"
40expect {
41 timeout {puts "TESTING ERROR 12.2\n";exit}
42 "nameserver 8.8.4.4"
43}
44expect {
45 timeout {puts "TESTING ERROR 12.3\n";exit}
46 "nameserver 8.8.8.8"
47}
48expect {
49 timeout {puts "TESTING ERROR 12.4\n";exit}
50 "nameserver 4.2.2.1"
51}
52after 100
53send -- "exit\r"
54sleep 1
55
56send -- "firejail --trace --dns=208.67.222.222 wget -q debian.org\r"
57expect {
58 timeout {puts "TESTING ERROR 1.2\n";exit}
59 "connect"
60}
61expect {
62 timeout {puts "TESTING ERROR 1.2\n";exit}
63 "208.67.222.222"
64}
65expect {
66 timeout {puts "TESTING ERROR 1.2\n";exit}
67 "53"
68}
69after 100
70
71send -- "rm index.html\r"
72after 100
73send -- "exit\r"
74sleep 1
75
76puts "\nall done\n"
diff --git a/test/environment/dns.profile b/test/environment/dns.profile
new file mode 100644
index 000000000..d1b842c86
--- /dev/null
+++ b/test/environment/dns.profile
@@ -0,0 +1,3 @@
1dns 8.8.4.4
2dns 8.8.8.8
3dns 4.2.2.1
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..2bb5a249e
--- /dev/null
+++ b/test/environment/environment.sh
@@ -0,0 +1,113 @@
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
9
10echo "TESTING: DNS (test/environment/dns.exp)"
11./dns.exp
12
13echo "TESTING: doubledash (test/environment/doubledash.exp"
14mkdir -- -testdir
15touch -- -testdir/ttt
16cp -- /bin/bash -testdir/.
17./doubledash.exp
18rm -fr -- -testdir
19
20echo "TESTING: output (test/environment/output.exp)"
21./output.exp
22
23echo "TESTING: extract command (extract_command.exp)"
24./extract_command.exp
25
26echo "TESTING: environment variables (test/environment/env.exp)"
27./env.exp
28
29echo "TESTING: shell none(test/environment/shell-none.exp)"
30./shell-none.exp
31
32which dash
33if [ "$?" -eq 0 ];
34then
35 echo "TESTING: dash (test/environment/dash.exp)"
36 ./dash.exp
37else
38 echo "TESTING SKIP: dash not found"
39fi
40
41which csh
42if [ "$?" -eq 0 ];
43then
44 echo "TESTING: csh (test/environment/csh.exp)"
45 ./csh.exp
46else
47 echo "TESTING SKIP: csh not found"
48fi
49
50which zsh
51if [ "$?" -eq 0 ];
52then
53 echo "TESTING: zsh (test/environment/zsh.exp)"
54 ./zsh.exp
55else
56 echo "TESTING SKIP: zsh not found"
57fi
58
59echo "TESTING: firejail in firejail - single sandbox (test/environment/firejail-in-firejail.exp)"
60./firejail-in-firejail.exp
61
62echo "TESTING: firejail in firejail - force new sandbox (test/environment/firejail-in-firejail2.exp)"
63./firejail-in-firejail2.exp
64
65which aplay
66if [ "$?" -eq 0 ];
67then
68 echo "TESTING: sound (test/environment/sound.exp)"
69 ./sound.exp
70else
71 echo "TESTING SKIP: aplay not found"
72fi
73
74echo "TESTING: nice (test/environment/nice.exp)"
75./nice.exp
76
77echo "TESTING: quiet (test/environment/quiet.exp)"
78./quiet.exp
79
80which strace
81if [ "$?" -eq 0 ];
82then
83 echo "TESTING: --allow-debuggers (test/environment/allow-debuggers.exp)"
84 ./allow-debuggers.exp
85else
86 echo "TESTING SKIP: strace not found"
87fi
88
89# to install ibus:
90# $ sudo apt-get install ibus-table-array30
91# $ ibus-setup
92
93find ~/.config/ibus/bus | grep unix-0
94if [ "$?" -eq 0 ];
95then
96 echo "TESTING: ibus (test/environment/ibus.exp)"
97 ./ibus.exp
98else
99 echo "TESTING SKIP: ibus not configured"
100fi
101
102echo "TESTING: rlimit (test/rlimit/rlimit.exp)"
103./rlimit.exp
104
105echo "TESTING: rlimit profile (test/rlimit/rlimit-profile.exp)"
106./rlimit-profile.exp
107
108echo "TESTING: rlimit errors (test/rlimit/rlimit-bad.exp)"
109./rlimit-bad.exp
110
111echo "TESTING: rlimit errors profile (test/rlimit/rlimit-bad-profile.exp)"
112./rlimit-bad-profile.exp
113
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/environment/firejail-in-firejail.exp b/test/environment/firejail-in-firejail.exp
new file mode 100755
index 000000000..2b851ee72
--- /dev/null
+++ b/test/environment/firejail-in-firejail.exp
@@ -0,0 +1,49 @@
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 -- "firejail\r"
18expect {
19 timeout {puts "TESTING ERROR 2\n";exit}
20 "Warning: an existing sandbox was detected"
21}
22after 100
23
24send -- "exit\r"
25after 100
26
27send -- "firejail --force\r"
28expect {
29 timeout {puts "TESTING ERROR 3\n";exit}
30 "cannot rise privileges"
31}
32after 100
33
34send -- "firejail --version\r"
35expect {
36 timeout {puts "TESTING ERROR 4\n";exit}
37 "firejail version"
38}
39after 100
40
41send -- "firejail --version --force\r"
42expect {
43 timeout {puts "TESTING ERROR 5\n";exit}
44 "firejail version"
45}
46after 100
47
48
49puts "\nall done\n"
diff --git a/test/environment/firejail-in-firejail2.exp b/test/environment/firejail-in-firejail2.exp
new file mode 100755
index 000000000..330e5e372
--- /dev/null
+++ b/test/environment/firejail-in-firejail2.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 --noprofile\r"
11expect {
12 timeout {puts "TESTING ERROR 1\n";exit}
13 "Child process initialized"
14}
15sleep 1
16
17send -- "firejail\r"
18expect {
19 timeout {puts "TESTING ERROR 2\n";exit}
20 "Warning: an existing sandbox was detected"
21}
22after 100
23
24send -- "exit\r"
25after 100
26
27send -- "firejail --force\r"
28expect {
29 timeout {puts "TESTING ERROR 3\n";exit}
30 "Child process initialized"
31}
32after 100
33
34send -- "exit\r"
35after 100
36
37send -- "firejail --version\r"
38expect {
39 timeout {puts "TESTING ERROR 4\n";exit}
40 "firejail version"
41}
42after 100
43
44send -- "firejail --version --force\r"
45expect {
46 timeout {puts "TESTING ERROR 5\n";exit}
47 "firejail version"
48}
49after 100
50
51puts "\nall done\n"
diff --git a/test/sysrq-trigger.exp b/test/environment/ibus.exp
index 18fb4a01a..4344011a6 100755
--- a/test/sysrq-trigger.exp
+++ b/test/environment/ibus.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
@@ -9,13 +10,19 @@ expect {
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 13after 100
13 14
14send -- "echo b > /proc/sysrq-trigger\r" 15send -- "env | grep IBUS\r"
15expect { 16expect {
16 timeout {puts "TESTING ERROR 1\n";exit} 17 timeout {puts "TESTING ERROR 1\n";exit}
17 "Read-only file system" 18 "IBUS_ADDRESS"
18} 19}
19sleep 1 20expect {
21 timeout {puts "TESTING ERROR 2\n";exit}
22 "IBUS_DAEMON_PID"
23}
24after 100
25
26
27puts "\nall done\n"
20 28
21puts "\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/rlimit-bad-profile.exp b/test/environment/rlimit-bad-profile.exp
new file mode 100755
index 000000000..80693a4a0
--- /dev/null
+++ b/test/environment/rlimit-bad-profile.exp
@@ -0,0 +1,35 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7
8send -- "firejail --profile=rlimit-bad1.profile\r"
9expect {
10 timeout {puts "TESTING ERROR 4\n";exit}
11 "Invalid rlimit option"
12}
13after 100
14
15send -- "firejail --profile=rlimit-bad2.profile\r"
16expect {
17 timeout {puts "TESTING ERROR 5\n";exit}
18 "Invalid rlimit option"
19}
20after 100
21
22send -- "firejail --profile=rlimit-bad3.profile\r"
23expect {
24 timeout {puts "TESTING ERROR 6\n";exit}
25 "Invalid rlimit option"
26}
27after 100
28send -- "firejail --profile=rlimit-bad4.profile\r"
29expect {
30 timeout {puts "TESTING ERROR 7\n";exit}
31 "Invalid rlimit option"
32}
33after 100
34
35puts "\nall done\n"
diff --git a/test/environment/rlimit-bad.exp b/test/environment/rlimit-bad.exp
new file mode 100755
index 000000000..574e7e174
--- /dev/null
+++ b/test/environment/rlimit-bad.exp
@@ -0,0 +1,34 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "firejail --rlimit-fsize=-1024\r"
8expect {
9 timeout {puts "TESTING ERROR 0\n";exit}
10 "invalid rlimt fsize"
11}
12after 100
13
14send -- "firejail --rlimit-nofile=asdf\r"
15expect {
16 timeout {puts "TESTING ERROR 1\n";exit}
17 "invalid rlimt nofile"
18}
19after 100
20
21send -- "firejail --rlimit-nproc=100.23\r"
22expect {
23 timeout {puts "TESTING ERROR 2\n";exit}
24 "invalid rlimt nproc"
25}
26after 100
27send -- "firejail --rlimit-sigpending=2345-78\r"
28expect {
29 timeout {puts "TESTING ERROR 3\n";exit}
30 "invalid rlimt sigpending"
31}
32after 100
33
34puts "\nall done\n"
diff --git a/test/environment/rlimit-bad1.profile b/test/environment/rlimit-bad1.profile
new file mode 100644
index 000000000..b6d3340d8
--- /dev/null
+++ b/test/environment/rlimit-bad1.profile
@@ -0,0 +1 @@
rlimit-fsize -1024
diff --git a/test/environment/rlimit-bad2.profile b/test/environment/rlimit-bad2.profile
new file mode 100644
index 000000000..ef3f243c6
--- /dev/null
+++ b/test/environment/rlimit-bad2.profile
@@ -0,0 +1 @@
rlimit-nofile asdf
diff --git a/test/environment/rlimit-bad3.profile b/test/environment/rlimit-bad3.profile
new file mode 100644
index 000000000..af016a29f
--- /dev/null
+++ b/test/environment/rlimit-bad3.profile
@@ -0,0 +1 @@
rlimit-nproc 100.23
diff --git a/test/environment/rlimit-bad4.profile b/test/environment/rlimit-bad4.profile
new file mode 100644
index 000000000..aabe3d008
--- /dev/null
+++ b/test/environment/rlimit-bad4.profile
@@ -0,0 +1 @@
rlimit-sigpending 67asd56 \ No newline at end of file
diff --git a/test/profile_rlimit.exp b/test/environment/rlimit-profile.exp
index 7d2637444..a9e54a405 100755
--- a/test/profile_rlimit.exp
+++ b/test/environment/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/environment/rlimit.exp
index 17d2bd9d1..611f69821 100755
--- a/test/option_rlimit.exp
+++ b/test/environment/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/environment/rlimit.profile
index 271891c03..271891c03 100644
--- a/test/rlimit.profile
+++ b/test/environment/rlimit.profile
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/fcopy/cmdline.exp b/test/fcopy/cmdline.exp
new file mode 100755
index 000000000..24bb19351
--- /dev/null
+++ b/test/fcopy/cmdline.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 -- "/usr/lib/firejail/fcopy\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "files missing"
14}
15expect {
16 timeout {puts "TESTING ERROR 1\n";exit}
17 "Usage:"
18}
19after 100
20
21send -- "/usr/lib/firejail/fcopy foo\r"
22expect {
23 timeout {puts "TESTING ERROR 2\n";exit}
24 "files missing"
25}
26expect {
27 timeout {puts "TESTING ERROR 3\n";exit}
28 "Usage:"
29}
30after 100
31
32send -- "/usr/lib/firejail/fcopy f%oo1 foo2\r"
33expect {
34 timeout {puts "TESTING ERROR 4\n";exit}
35 "invalid file name"
36}
37after 100
38
39send -- "/usr/lib/firejail/fcopy foo1 f,oo2\r"
40expect {
41 timeout {puts "TESTING ERROR 5\n";exit}
42 "invalid file name"
43}
44after 100
45
46puts "\nall done\n"
diff --git a/test/fcopy/dircopy.exp b/test/fcopy/dircopy.exp
new file mode 100755
index 000000000..00b0204ae
--- /dev/null
+++ b/test/fcopy/dircopy.exp
@@ -0,0 +1,106 @@
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
6#
7# copy directory src to dest
8#
9set timeout 10
10spawn $env(SHELL)
11match_max 100000
12
13send -- "rm -fr dest/*\r"
14after 100
15
16send -- "/usr/lib/firejail/fcopy src dest\r"
17after 100
18
19send -- "find dest\r"
20expect {
21 timeout {puts "TESTING ERROR 0\n";exit}
22 "dest/"
23}
24expect {
25 timeout {puts "TESTING ERROR 1\n";exit}
26 "dest/a"
27}
28expect {
29 timeout {puts "TESTING ERROR 2\n";exit}
30 "dest/a/b"
31}
32expect {
33 timeout {puts "TESTING ERROR 3\n";exit}
34 "dest/a/b/file4"
35}
36expect {
37 timeout {puts "TESTING ERROR 4\n";exit}
38 "dest/a/file3"
39}
40expect {
41 timeout {puts "TESTING ERROR 5\n";exit}
42 "dest/dircopy.exp"
43}
44expect {
45 timeout {puts "TESTING ERROR 6\n";exit}
46 "dest/file2"
47}
48expect {
49 timeout {puts "TESTING ERROR 7\n";exit}
50 "dest/file1"
51}
52after 100
53
54
55send -- "ls -al dest\r"
56expect {
57 timeout {puts "TESTING ERROR 8\n";exit}
58 "drwxr-xr-x"
59}
60expect {
61 timeout {puts "TESTING ERROR 9\n";exit}
62 "a"
63}
64expect {
65 timeout {puts "TESTING ERROR 10\n";exit}
66 "lrwxrwxrwx"
67}
68expect {
69 timeout {puts "TESTING ERROR 11\n";exit}
70 "dircopy.exp"
71}
72expect {
73 timeout {puts "TESTING ERROR 12\n";exit}
74 "rwxr-xr-x"
75}
76expect {
77 timeout {puts "TESTING ERROR 13\n";exit}
78 "file1"
79}
80expect {
81 timeout {puts "TESTING ERROR 14\n";exit}
82 "rw-r--r--"
83}
84expect {
85 timeout {puts "TESTING ERROR 15\n";exit}
86 "file2"
87}
88after 100
89
90send -- "diff -q src/a/b/file4 dest/a/b/file4; echo done\r"
91expect {
92 timeout {puts "TESTING ERROR 16\n";exit}
93 "differ" {puts "TESTING ERROR 17\n";exit}
94 "done"
95}
96
97send -- "file dest/dircopy.exp\r"
98expect {
99 timeout {puts "TESTING ERROR 18\n";exit}
100 "symbolic link"
101}
102
103send -- "rm -fr dest/*\r"
104after 100
105
106puts "\nall done\n"
diff --git a/test/fcopy/fcopy.sh b/test/fcopy/fcopy.sh
new file mode 100755
index 000000000..dcda5ca31
--- /dev/null
+++ b/test/fcopy/fcopy.sh
@@ -0,0 +1,23 @@
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
9mkdir dest
10
11echo "TESTING: fcopy cmdline (test/fcopy/cmdline.exp)"
12./cmdline.exp
13
14echo "TESTING: fcopy directory (test/fcopy/dircopy.exp)"
15./dircopy.exp
16
17echo "TESTING: fcopy file (test/fcopy/filecopy.exp)"
18./filecopy.exp
19
20echo "TESTING: fcopy link (test/fcopy/linkcopy.exp)"
21./linkcopy.exp
22
23rm -fr dest/*
diff --git a/test/fcopy/filecopy.exp b/test/fcopy/filecopy.exp
new file mode 100755
index 000000000..d1f0a4424
--- /dev/null
+++ b/test/fcopy/filecopy.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
6#
7# copy directory src to dest
8#
9set timeout 10
10spawn $env(SHELL)
11match_max 100000
12
13send -- "rm -fr dest/*\r"
14after 100
15
16send -- "/usr/lib/firejail/fcopy dircopy.exp dest\r"
17after 100
18
19send -- "find dest\r"
20expect {
21 timeout {puts "TESTING ERROR 0\n";exit}
22 "dest/"
23}
24expect {
25 timeout {puts "TESTING ERROR 1\n";exit}
26 "dest/dircopy.exp"
27}
28after 100
29
30
31send -- "ls -al dest\r"
32expect {
33 timeout {puts "TESTING ERROR 2\n";exit}
34 "rwxr-xr-x"
35}
36after 100
37
38send -- "diff -q dircopy.exp dest/dircopy.exp; echo done\r"
39expect {
40 timeout {puts "TESTING ERROR 3\n";exit}
41 "differ" {puts "TESTING ERROR 4\n";exit}
42 "done"
43}
44
45send -- "file dest/dircopy.exp\r"
46expect {
47 timeout {puts "TESTING ERROR 5\n";exit}
48 "ASCII text"
49}
50
51send -- "rm -fr dest/*\r"
52after 100
53
54puts "\nall done\n"
diff --git a/test/fcopy/linkcopy.exp b/test/fcopy/linkcopy.exp
new file mode 100755
index 000000000..9927e18fe
--- /dev/null
+++ b/test/fcopy/linkcopy.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
6#
7# copy directory src to dest
8#
9set timeout 10
10spawn $env(SHELL)
11match_max 100000
12
13send -- "rm -fr dest/*\r"
14after 100
15
16send -- "/usr/lib/firejail/fcopy src/dircopy.exp dest\r"
17after 100
18
19send -- "find dest\r"
20expect {
21 timeout {puts "TESTING ERROR 0\n";exit}
22 "dest/"
23}
24expect {
25 timeout {puts "TESTING ERROR 1\n";exit}
26 "dest/dircopy.exp"
27}
28after 100
29
30
31send -- "ls -al dest\r"
32expect {
33 timeout {puts "TESTING ERROR 2\n";exit}
34 "lrwxrwxrwx"
35}
36after 100
37
38send -- "diff -q dircopy.exp dest/dircopy.exp; echo done\r"
39expect {
40 timeout {puts "TESTING ERROR 3\n";exit}
41 "differ" {puts "TESTING ERROR 4\n";exit}
42 "done"
43}
44
45send -- "file dest/dircopy.exp\r"
46expect {
47 timeout {puts "TESTING ERROR 5\n";exit}
48 "symbolic link"
49}
50
51send -- "rm -fr dest/*\r"
52after 100
53
54puts "\nall done\n"
diff --git a/test/fcopy/src/a/b/file4 b/test/fcopy/src/a/b/file4
new file mode 100644
index 000000000..ac318d7ab
--- /dev/null
+++ b/test/fcopy/src/a/b/file4
@@ -0,0 +1,11 @@
1
2
3Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam interdum at massa non aliquam. Maecenas molestie id orci volutpat porta. Praesent aliquam nunc quis mi tristique, ac feugiat enim rutrum. Nulla vitae metus sodales, pellentesque risus sit amet, volutpat nisl. Curabitur accumsan arcu congue lacus porta laoreet. Nulla facilisi. Integer nec augue id magna gravida tincidunt id vitae lorem. Curabitur facilisis, tellus vel pellentesque pretium, odio dolor efficitur lorem, et tincidunt dui enim cursus lacus. Cras a orci ac magna semper dapibus nec et velit. Nullam aliquam sollicitudin auctor.
4
5Mauris ac quam vel purus volutpat semper eget a ante. Curabitur arcu nisl, dapibus ac lectus ac, porttitor fermentum metus. Aliquam et sem aliquam magna interdum ultricies at eu orci. Aenean tortor augue, volutpat nec magna nec, rutrum bibendum justo. Vivamus ex quam, auctor ut pellentesque mattis, aliquet a eros. Etiam ac lacus ac ante ullamcorper sollicitudin a quis orci. Suspendisse quis justo ac mauris cursus finibus quis at elit. Vestibulum elementum finibus diam, eget convallis purus aliquet et. Fusce fermentum ornare urna, non ornare nisl tincidunt consectetur. Donec et lacus vitae ex eleifend porttitor id ut odio. Quisque luctus eget lorem et sollicitudin.
6
7Aliquam libero elit, finibus a nisl a, commodo viverra turpis. Nam pulvinar in est sit amet fermentum. Praesent scelerisque tempus lectus, ac porta elit sodales rutrum. Duis faucibus faucibus urna eget accumsan. Vivamus in turpis ut massa rhoncus pretium nec et lorem. Aenean at tellus eget metus porta ornare. Aliquam erat volutpat. Donec hendrerit a massa vel malesuada. Integer varius sapien et orci viverra pretium. In at velit aliquet, vulputate nisi lobortis, aliquam augue.
8
9Ut aliquam turpis ut lorem aliquam, in faucibus elit pulvinar. Vivamus viverra tortor ornare, lacinia leo sit amet, auctor arcu. Sed erat leo, pellentesque vel nibh a, malesuada vehicula purus. Vivamus est dolor, aliquet quis facilisis fermentum, varius in dolor. Nunc quis libero feugiat, imperdiet est vitae, mollis risus. Vestibulum elementum mattis lorem vitae gravida. Nullam id tellus interdum, aliquam erat eu, laoreet nunc. Aliquam ut felis vel mauris maximus pellentesque.
10
11Vestibulum tempus mauris eget ex interdum, vitae vehicula tortor sollicitudin. Pellentesque et dolor cursus dui vulputate laoreet. Morbi eu bibendum quam, at ultrices elit. Vestibulum dictum enim sit amet ultricies imperdiet. Praesent congue magna ac mauris mattis, a iaculis ante aliquet. Vivamus at egestas ex. Suspendisse orci dolor, pharetra at aliquam a, faucibus facilisis leo. Quisque semper lorem eget elit commodo pretium. Aenean posuere augue quis arcu finibus, sit amet fringilla risus congue. Pellentesque rutrum nunc leo, aliquam lobortis lacus molestie nec. Donec convallis congue diam, ullamcorper vestibulum dui varius nec. Praesent pellentesque nisi risus. In aliquam molestie malesuada. Nulla facilisis a risus eu tristique. Morbi molestie et arcu quis efficitur. Curabitur cursus vestibulum luctus.
diff --git a/test/fcopy/src/a/file3 b/test/fcopy/src/a/file3
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/test/fcopy/src/a/file3
diff --git a/test/fcopy/src/dircopy.exp b/test/fcopy/src/dircopy.exp
new file mode 120000
index 000000000..2acf88f7b
--- /dev/null
+++ b/test/fcopy/src/dircopy.exp
@@ -0,0 +1 @@
../dircopy.exp \ No newline at end of file
diff --git a/test/fcopy/src/file1 b/test/fcopy/src/file1
new file mode 100755
index 000000000..e69de29bb
--- /dev/null
+++ b/test/fcopy/src/file1
diff --git a/test/fcopy/src/file2 b/test/fcopy/src/file2
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/test/fcopy/src/file2
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-print.exp b/test/filters/caps-print.exp
new file mode 100755
index 000000000..d9d662239
--- /dev/null
+++ b/test/filters/caps-print.exp
@@ -0,0 +1,103 @@
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 --noprofile --caps --debug\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Drop CAP_SYS_MODULE"
14}
15expect {
16 timeout {puts "TESTING ERROR 1\n";exit}
17 "Drop CAP_SYS_RAWIO"
18}
19expect {
20 timeout {puts "TESTING ERROR 2\n";exit}
21 "Drop CAP_SYS_BOOT"
22}
23expect {
24 timeout {puts "TESTING ERROR 3\n";exit}
25 "Drop CAP_SYS_NICE"
26}
27expect {
28 timeout {puts "TESTING ERROR 4\n";exit}
29 "Drop CAP_SYS_TTY_CONFIG"
30}
31expect {
32 timeout {puts "TESTING ERROR 5\n";exit}
33 "Drop CAP_SYSLOG"
34}
35expect {
36 timeout {puts "TESTING ERROR 6\n";exit}
37 "Drop CAP_MKNOD"
38}
39expect {
40 timeout {puts "TESTING ERROR 7\n";exit}
41 "Drop CAP_SYS_ADMIN"
42}
43expect {
44 timeout {puts "TESTING ERROR 8\n";exit}
45 "Child process initialized"
46}
47sleep 1
48
49spawn $env(SHELL)
50send -- "firejail --caps.print=test\r"
51expect {
52 timeout {puts "TESTING ERROR 9\n";exit}
53 "chown - enabled"
54}
55expect {
56 timeout {puts "TESTING ERROR 10\n";exit}
57 "setgid - enabled"
58}
59expect {
60 timeout {puts "TESTING ERROR 11\n";exit}
61 "setuid - enabled"
62}
63expect {
64 timeout {puts "TESTING ERROR 12\n";exit}
65 "mknod - disabled"
66}
67expect {
68 timeout {puts "TESTING ERROR 13\n";exit}
69 "syslog - disabled"
70}
71after 100
72
73send -- "firejail --debug-caps\r"
74expect {
75 timeout {puts "TESTING ERROR 9\n";exit}
76 "21 - sys_admin"
77}
78expect {
79 timeout {puts "TESTING ERROR 9\n";exit}
80 "22 - sys_boot"
81}
82expect {
83 timeout {puts "TESTING ERROR 9\n";exit}
84 "23 - sys_nice"
85}
86expect {
87 timeout {puts "TESTING ERROR 9\n";exit}
88 "24 - sys_resource"
89}
90after 100
91
92send -- "firejail --caps.keep=\"bla bla bla\"\r"
93expect {
94 timeout {puts "TESTING ERROR 10\n";exit}
95 "capability"
96}
97expect {
98 timeout {puts "TESTING ERROR 11\n";exit}
99 "not found"
100}
101
102after 100
103puts "\nall done\n"
diff --git a/test/filters/caps.exp b/test/filters/caps.exp
new file mode 100755
index 000000000..2954f2e58
--- /dev/null
+++ b/test/filters/caps.exp
@@ -0,0 +1,139 @@
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}
15after 100
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}
34after 100
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}
53after 100
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"
69sleep 1
70
71
72send -- "firejail --profile=caps1.profile --debug\r"
73expect {
74 timeout {puts "TESTING ERROR 11\n";exit}
75 "Drop CAP_SYS_MODULE"
76}
77expect {
78 timeout {puts "TESTING ERROR 12\n";exit}
79 "Drop CAP_SYS_ADMIN"
80}
81expect {
82 timeout {puts "TESTING ERROR 13\n";exit}
83 "Drop CAP_" {puts "TESTING ERROR 14\n";exit}
84 "Child process initialized"
85}
86after 100
87send -- "exit\r"
88sleep 1
89
90
91## tofix: possible problem with caps.keep in profile files
92##send -- "firejail --caps.keep=chown,fowner --noprofile\r"
93#send -- "firejail --profile=caps2.profile\r"
94#expect {
95# timeout {puts "TESTING ERROR 15\n";exit}
96# "Child process initialized"
97#}
98#after 100
99#
100#send -- "cat /proc/self/status\r"
101#expect {
102# timeout {puts "TESTING ERROR 16\n";exit}
103# "CapBnd: 0000000000000009"
104#}
105#expect {
106# timeout {puts "TESTING ERROR 17\n";exit}
107# "Seccomp:"
108#}
109#send -- "exit\r"
110#sleep 1
111
112#send -- "firejail --caps.drop=chown,dac_override,dac_read_search,fowner --noprofile\r"
113send -- "firejail --profile=caps3.profile\r"
114expect {
115 timeout {puts "TESTING ERROR 18\n";exit}
116 "Child process initialized"
117}
118after 100
119
120send -- "cat /proc/self/status\r"
121expect {
122 timeout {puts "TESTING ERROR 19\n";exit}
123 "CapBnd:"
124}
125expect {
126 timeout {puts "TESTING ERROR 20\n";exit}
127 "fffffff0"
128}
129expect {
130 timeout {puts "TESTING ERROR 21\n";exit}
131 "Seccomp:"
132}
133send -- "exit\r"
134sleep 1
135
136
137
138after 100
139puts "\nall done\n"
diff --git a/test/filters/caps1.profile b/test/filters/caps1.profile
new file mode 100644
index 000000000..8b0c3b340
--- /dev/null
+++ b/test/filters/caps1.profile
@@ -0,0 +1 @@
caps
diff --git a/test/filters/caps2.profile b/test/filters/caps2.profile
new file mode 100644
index 000000000..4f0016fad
--- /dev/null
+++ b/test/filters/caps2.profile
@@ -0,0 +1 @@
caps.drop chown,dac_override,dac_read_search,fowner \ No newline at end of file
diff --git a/test/filters/caps3.profile b/test/filters/caps3.profile
new file mode 100644
index 000000000..4f0016fad
--- /dev/null
+++ b/test/filters/caps3.profile
@@ -0,0 +1 @@
caps.drop chown,dac_override,dac_read_search,fowner \ No newline at end of file
diff --git a/test/filters/filters.sh b/test/filters/filters.sh
new file mode 100755
index 000000000..fea4a0296
--- /dev/null
+++ b/test/filters/filters.sh
@@ -0,0 +1,71 @@
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
15echo "TESTING: capabilities print (test/filters/caps-print.exp)"
16./caps-print.exp
17
18rm -f seccomp-test-file
19if [ "$(uname -m)" = "x86_64" ]; then
20 echo "TESTING: fseccomp (test/filters/fseccomp.exp)"
21 ./fseccomp.exp
22else
23 echo "TESTING SKIP: fseccomp test implemented only for x86_64"
24fi
25rm -f seccomp-test-file
26
27
28if [ "$(uname -m)" = "x86_64" ]; then
29 echo "TESTING: protocol (test/filters/protocol.exp)"
30 ./protocol.exp
31else
32 echo "TESTING SKIP: protocol, running only on x86_64"
33fi
34
35echo "TESTING: seccomp bad empty (test/filters/seccomp-bad-empty.exp)"
36./seccomp-bad-empty.exp
37
38echo "TESTING: seccomp debug (test/filters/seccomp-debug.exp)"
39./seccomp-debug.exp
40
41echo "TESTING: seccomp errno (test/filters/seccomp-errno.exp)"
42./seccomp-errno.exp
43
44echo "TESTING: seccomp su (test/filters/seccomp-su.exp)"
45./seccomp-su.exp
46
47which strace
48if [ $? -eq 0 ]; then
49 echo "TESTING: seccomp ptrace (test/filters/seccomp-ptrace.exp)"
50 ./seccomp-ptrace.exp
51else
52 echo "TESTING SKIP: ptrace, strace not found"
53fi
54
55echo "TESTING: seccomp chmod - seccomp lists (test/filters/seccomp-chmod.exp)"
56./seccomp-chmod.exp
57
58echo "TESTING: seccomp chmod profile - seccomp lists (test/filters/seccomp-chmod-profile.exp)"
59./seccomp-chmod-profile.exp
60
61# todo: fix pwd and add seccomp-chown.exp
62
63echo "TESTING: seccomp empty (test/filters/seccomp-empty.exp)"
64./seccomp-empty.exp
65
66if [ "$(uname -m)" = "x86_64" ]; then
67 echo "TESTING: seccomp dual filter (test/filters/seccomp-dualfilter.exp)"
68 ./seccomp-dualfilter.exp
69else
70 echo "TESTING SKIP: seccomp dual, not running on x86_64"
71fi
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/ip6.exp b/test/filters/seccomp-chmod-profile.exp
index fba47d095..463ce05e9 100755
--- a/test/ip6.exp
+++ b/test/filters/seccomp-chmod-profile.exp
@@ -1,43 +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 --debug --noprofile --net=br0 --ip6=2001:0db8:0:f101::1/64 --netfilter6=ipv6.net\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 "Installing network filter" 13 "Child process initialized"
11} 14}
15sleep 2
16
17send -- "cd ~; echo done\r"
12expect { 18expect {
13 timeout {puts "TESTING ERROR 1\n";exit} 19 timeout {puts "TESTING ERROR 1\n";exit}
14 "DROP" 20 "done"
15} 21}
22
23send -- "touch testfile; echo done\r"
16expect { 24expect {
17 timeout {puts "TESTING ERROR 2\n";exit} 25 timeout {puts "TESTING ERROR 2\n";exit}
18 "2001:db8:1f0a:3ec::2" 26 "done"
19} 27}
28
29send -- "ls -l testfile; echo done\r"
20expect { 30expect {
21 timeout {puts "TESTING ERROR 3\n";exit} 31 timeout {puts "TESTING ERROR 3\n";exit}
22 "Child process initialized" 32 "testfile"
23} 33}
24sleep 2
25
26send -- "/sbin/ifconfig\r"
27expect { 34expect {
28 timeout {puts "TESTING ERROR 4\n";exit} 35 timeout {puts "TESTING ERROR 4\n";exit}
29 "inet6" 36 "done"
30} 37}
38
39send -- "chmod +x testfile; echo done\r"
31expect { 40expect {
32 timeout {puts "TESTING ERROR 5\n";exit} 41 timeout {puts "TESTING ERROR 5\n";exit}
33 "2001:db8:0:f101::1" 42 "Bad system call"
34} 43}
35expect { 44expect {
36 timeout {puts "TESTING ERROR 6\n";exit} 45 timeout {puts "TESTING ERROR 6\n";exit}
37 "Scope:Global" { puts "Debian\n"} 46 "done"
38 "scopeid 0x0<global>" { puts "Arch\n"}
39} 47}
40 48
41 49send -- "exit\r"
50after 100
42puts "\nall done\n" 51puts "\nall done\n"
43
diff --git a/test/pid.exp b/test/filters/seccomp-chmod.exp
index cdeb9d5fb..b17990e3a 100755
--- a/test/pid.exp
+++ b/test/filters/seccomp-chmod.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 --seccomp=chmod,fchmod,fchmodat --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-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/firejail-in-firejail.exp b/test/firejail-in-firejail.exp
deleted file mode 100755
index 5ba18d1fa..000000000
--- a/test/firejail-in-firejail.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 1\n";exit}
10 "Child process initialized"
11}
12sleep 1
13
14send -- "firejail\r"
15expect {
16 timeout {puts "TESTING ERROR 1\n";exit}
17 "Warning: an existing sandbox was detected"
18}
19sleep 1
20
21puts "\nall done\n"
diff --git a/test/firejail-in-firejail2.exp b/test/firejail-in-firejail2.exp
deleted file mode 100755
index b0fed0dae..000000000
--- a/test/firejail-in-firejail2.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 --noprofile\r"
8expect {
9 timeout {puts "TESTING ERROR 1\n";exit}
10 "Child process initialized"
11}
12sleep 1
13
14send -- "firejail --force\r"
15expect {
16 timeout {puts "TESTING ERROR 1\n";exit}
17 "Child process initialized"
18}
19sleep 1
20
21puts "\nall done\n"
diff --git a/test/fs/fs.sh b/test/fs/fs.sh
new file mode 100755
index 000000000..611b62b09
--- /dev/null
+++ b/test/fs/fs.sh
@@ -0,0 +1,116 @@
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: whitelist ~/Downloads (test/fs/whitelist-downloads.exp)"
65./whitelist-downloads.exp
66
67echo "TESTING: invalid filename (test/fs/invalid_filename.exp)"
68./invalid_filename.exp
69
70echo "TESTING: blacklist directory (test/fs/option_blacklist.exp)"
71./option_blacklist.exp
72
73echo "TESTING: blacklist file (test/fs/option_blacklist_file.exp)"
74./option_blacklist_file.exp
75
76echo "TESTING: blacklist glob (test/fs/option_blacklist_glob.exp)"
77./option_blacklist_glob.exp
78
79echo "TESTING: bind as user (test/fs/option_bind_user.exp)"
80./option_bind_user.exp
81
82echo "TESTING: recursive mkdir (test/fs/mkdir.exp)"
83./mkdir.exp
84
85echo "TESTING: double whitelist (test/fs/whitelist-double.exp)"
86./whitelist-double.exp
87
88echo "TESTING: whitelist (test/fs/whitelist.exp)"
89./whitelist.exp
90
91echo "TESTING: whitelist dev, var(test/fs/whitelist-dev.exp)"
92./whitelist-dev.exp
93
94echo "TESTING: fscheck --bind non root (test/fs/fscheck-bindnoroot.exp)"
95./fscheck-bindnoroot.exp
96
97echo "TESTING: fscheck --tmpfs non root (test/fs/fscheck-tmpfs.exp)"
98./fscheck-tmpfs.exp
99
100echo "TESTING: fscheck --private= (test/fs/fscheck-private.exp)"
101./fscheck-private.exp
102
103echo "TESTING: fscheck --read-only= (test/fs/fscheck-readonly.exp)"
104./fscheck-readonly.exp
105
106#cleanup
107rm -fr ~/fjtest-dir
108rm -fr ~/fjtest-dir-lnk
109rm -f ~/fjtest-file
110rm -f ~/fjtest-file-lnk
111rm -f /tmp/fjtest-file
112rm -fr /tmp/fjtest-dir
113rm -fr ~/_firejail_test_*
114
115
116
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/fscheck-bindnoroot.exp b/test/fs/fscheck-bindnoroot.exp
index 796a7d975..8cbe2b8af 100755
--- a/test/fscheck-bindnoroot.exp
+++ b/test/fs/fscheck-bindnoroot.exp
@@ -5,10 +5,13 @@ spawn $env(SHELL)
5match_max 100000 5match_max 100000
6 6
7# dir 7# dir
8send -- "firejail --net=br0 --bind=fscheck-dir,/etc\r" 8send -- "firejail --net=br0 --bind=testdir1,/etc\r"
9expect { 9expect {
10 timeout {puts "TESTING ERROR 0\n";exit} 10 timeout {puts "TESTING ERROR 0\n";exit}
11 "Error" 11 "Error"
12} 12}
13after 100 13after 100
14 14
15puts "\nall done\n"
16
17
diff --git a/test/fs/fscheck-private.exp b/test/fs/fscheck-private.exp
new file mode 100755
index 000000000..28c921538
--- /dev/null
+++ b/test/fs/fscheck-private.exp
@@ -0,0 +1,50 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7
8
9# file link
10#send -- "firejail --private=fscheck-file-link\r"
11#expect {
12# timeout {puts "TESTING ERROR 2\n";exit}
13# "Error"
14#}
15#after 100
16
17# file
18send -- "firejail --private=testfile1\r"
19expect {
20 timeout {puts "TESTING ERROR 2.1\n";exit}
21 "Error"
22}
23after 100
24
25# ..
26send -- "firejail --private=../fs/testfile1\r"
27expect {
28 timeout {puts "TESTING ERROR 2.2\n";exit}
29 "Error"
30}
31after 100
32
33# no file
34send -- "firejail --private=../test/nodir\r"
35expect {
36 timeout {puts "TESTING ERROR 3\n";exit}
37 "Error"
38}
39after 100
40
41# same owner
42send -- "firejail --private=/etc\r"
43expect {
44 timeout {puts "TESTING ERROR 4\n";exit}
45 "Error"
46}
47after 100
48
49puts "\nall done\n"
50
diff --git a/test/fscheck-readonly.exp b/test/fs/fscheck-readonly.exp
index e0f0a8a1d..4d7528e50 100755
--- a/test/fscheck-readonly.exp
+++ b/test/fs/fscheck-readonly.exp
@@ -5,10 +5,11 @@ spawn $env(SHELL)
5match_max 100000 5match_max 100000
6 6
7# dir 7# dir
8send -- "firejail --net=br0 --read-only=../test/fscheck-dir\r" 8send -- "firejail --read-only=../test/testdir1\r"
9expect { 9expect {
10 timeout {puts "TESTING ERROR 0\n";exit} 10 timeout {puts "TESTING ERROR 0\n";exit}
11 "Error" 11 "Error"
12} 12}
13after 100 13after 100
14 14
15puts "\nall done\n"
diff --git a/test/fscheck-tmpfs.exp b/test/fs/fscheck-tmpfs.exp
index d5bbccd96..deac5a631 100755
--- a/test/fscheck-tmpfs.exp
+++ b/test/fs/fscheck-tmpfs.exp
@@ -5,7 +5,7 @@ spawn $env(SHELL)
5match_max 100000 5match_max 100000
6 6
7# .. 7# ..
8send -- "firejail --net=br0 --tmpfs=../test/fscheck-dir\r" 8send -- "firejail --tmpfs=fscheck-dir\r"
9expect { 9expect {
10 timeout {puts "TESTING ERROR 0.1\n";exit} 10 timeout {puts "TESTING ERROR 0.1\n";exit}
11 "Error" 11 "Error"
diff --git a/test/invalid_filename.exp b/test/fs/invalid_filename.exp
index fe8bd8c25..a6efc24b6 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)
@@ -125,6 +109,21 @@ expect {
125} 109}
126after 100 110after 100
127 111
112send -- "firejail --debug-check-filename --noprofile --private-home=\"bla&&bla\"\r"
113expect {
114 timeout {puts "TESTING ERROR 8.1\n";exit}
115 "Checking filename bla&&bla"
116}
117expect {
118 timeout {puts "TESTING ERROR 8.2\n";exit}
119 "Error:"
120}
121expect {
122 timeout {puts "TESTING ERROR 8.3\n";exit}
123 "is an invalid filename"
124}
125after 100
126
128send -- "firejail --debug-check-filename --noprofile --private-etc=\"bla&&bla\"\r" 127send -- "firejail --debug-check-filename --noprofile --private-etc=\"bla&&bla\"\r"
129expect { 128expect {
130 timeout {puts "TESTING ERROR 9.1\n";exit} 129 timeout {puts "TESTING ERROR 9.1\n";exit}
@@ -201,7 +200,5 @@ expect {
201} 200}
202after 100 201after 100
203 202
204
205
206puts "\nall done\n" 203puts "\nall done\n"
207 204
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..f7181d218 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)
@@ -62,10 +65,29 @@ expect {
62 "sh" 65 "sh"
63} 66}
64send -- "exit\r" 67send -- "exit\r"
68after 100
65 69
66 70
71send -- "firejail --private-bin=/etc/shadow\r"
72expect {
73 timeout {puts "TESTING ERROR 8\n";exit}
74 "invalid filename"
75}
76after 100
67 77
78send -- "firejail --private-bin=\"bla;bla\"\r"
79expect {
80 timeout {puts "TESTING ERROR 9\n";exit}
81 "is an invalid filename"
82}
83after 100
68 84
69sleep 1 85send -- "firejail --private-etc=../bin/ls\r"
86expect {
87 timeout {puts "TESTING ERROR 10\n";exit}
88 "is an invalid filename"
89}
90
91after 100
70puts "\nall done\n" 92puts "\nall done\n"
71 93
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/fs/private-etc.exp b/test/fs/private-etc.exp
new file mode 100755
index 000000000..36b5d247c
--- /dev/null
+++ b/test/fs/private-etc.exp
@@ -0,0 +1,73 @@
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# directory with ~
11send -- "firejail --private-etc=passwd,group,resolv.conf,X11\r"
12expect {
13 timeout {puts "TESTING ERROR 1\n";exit}
14 "Child process initialized"
15}
16sleep 1
17
18send -- "LC_ALL=C ls -al /etc\r"
19expect {
20 timeout {puts "TESTING ERROR 3\n";exit}
21 "X11"
22}
23expect {
24 timeout {puts "TESTING ERROR 4\n";exit}
25 "group"
26}
27expect {
28 timeout {puts "TESTING ERROR 5\n";exit}
29 "passwd"
30}
31expect {
32 timeout {puts "TESTING ERROR 6\n";exit}
33 "resolv.conf"
34}
35
36
37send -- "file /etc/shadow\r"
38expect {
39 timeout {puts "TESTING ERROR 7\n";exit}
40 "No such file or directory"
41}
42after 100
43send -- "exit\r"
44sleep 1
45
46send -- "firejail --private-etc=shadow\r"
47expect {
48 timeout {puts "TESTING ERROR 8\n";exit}
49 "invalid file type"
50}
51after 100
52
53send -- "firejail --private-etc=\"bla;bla\"\r"
54expect {
55 timeout {puts "TESTING ERROR 9\n";exit}
56 "is an invalid filename"
57}
58after 100
59
60send -- "firejail --private-etc=../bin/ls\r"
61expect {
62 timeout {puts "TESTING ERROR 10\n";exit}
63 "is an invalid filename"
64}
65after 100
66
67
68
69
70
71after 100
72puts "\nall done\n"
73
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..3840d1cb8
--- /dev/null
+++ b/test/fs/private-home.exp
@@ -0,0 +1,103 @@
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"
12after 100
13send -- "touch ~/_firejail_test_file2\r"
14after 100
15send -- "mkdir ~/_firejail_test_dir1\r"
16after 100
17send -- "mkdir ~/_firejail_test_dir1/_firejail_test_dir2\r"
18after 100
19send -- "touch ~/_firejail_test_dir1/_firejail_test_dir2/_firejail_test_file3\r"
20after 100
21send -- "ln -s /etc ~/_firejail_test_link1\r"
22after 100
23send -- "ln -s ~/_firejail_test_dir1 ~/_firejail_test_link2\r"
24after 100
25
26send -- "firejail --private-home=_firejail_test_file1,_firejail_test_file2,_firejail_test_dir1\r"
27expect {
28 timeout {puts "TESTING ERROR 1\n";exit}
29 "Child process initialized"
30}
31after 100
32
33send -- "find ~\r"
34expect {
35 timeout {puts "TESTING ERROR 2\n";exit}
36 "_firejail_test_file3"
37}
38expect {
39 timeout {puts "TESTING ERROR 3\n";exit}
40 "_firejail_test_file2"
41}
42expect {
43 timeout {puts "TESTING ERROR 4\n";exit}
44 "_firejail_test_file1"
45}
46after 100
47
48send -- "exit\r"
49sleep 1
50
51send -- "firejail --private-home=\"bla;bla\"\r"
52expect {
53 timeout {puts "TESTING ERROR 5\n";exit}
54 "is an invalid filename"
55}
56after 100
57
58send -- "firejail --private-home=/etc/shadow\r"
59expect {
60 timeout {puts "TESTING ERROR 6\n";exit}
61 "invalid file"
62}
63after 100
64
65send -- "firejail --private-home=/etc/passwd\r"
66expect {
67 timeout {puts "TESTING ERROR 7\n";exit}
68 "invalid file"
69}
70after 100
71
72send -- "firejail --private-home=../../etc/passwd\r"
73expect {
74 timeout {puts "TESTING ERROR 8\n";exit}
75 "invalid file"
76}
77after 100
78
79send -- "firejail --private-home=_firejail_test_link1\r"
80expect {
81 timeout {puts "TESTING ERROR 9\n";exit}
82 "to file or directory not owned by the user"
83}
84after 100
85
86send -- "firejail --private-home=_firejail_test_link2\r"
87expect {
88 timeout {puts "TESTING ERROR 10\n";exit}
89 "Child process initialized"
90}
91after 100
92send -- "file file ~/_firejail_test_link2\r"
93expect {
94 timeout {puts "TESTING ERROR 11\n";exit}
95 "broken symbolic link"
96}
97send -- "exit\r"
98
99send -- "rm -f ~/_firejail_test*\r"
100after 100
101
102puts "\nall done\n"
103
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..19a915f66
--- /dev/null
+++ b/test/fs/read-write.exp
@@ -0,0 +1,35 @@
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\r"
19expect {
20 timeout {puts "TESTING ERROR 5\n";exit}
21 "Read-only file system"
22}
23after 100
24
25send -- "echo mytest > ~/_firejail_test_dir/test1/b\r"
26sleep 1
27
28send -- "cat ~/_firejail_test_dir/test1/b\r"
29expect {
30 timeout {puts "TESTING ERROR 5\n";exit}
31 "mytest"
32}
33
34after 100
35puts "\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/testfile1 b/test/fs/testfile1
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/test/fs/testfile1
diff --git a/test/fs/user-dirs.dirs b/test/fs/user-dirs.dirs
new file mode 100644
index 000000000..0d19da4e4
--- /dev/null
+++ b/test/fs/user-dirs.dirs
@@ -0,0 +1,15 @@
1# This file is written by xdg-user-dirs-update
2# If you want to change or add directories, just edit the line you're
3# interested in. All local changes will be retained on the next run
4# Format is XDG_xxx_DIR="$HOME/yyy", where yyy is a shell-escaped
5# homedir-relative path, or XDG_xxx_DIR="/yyy", where /yyy is an
6# absolute path. No other format is supported.
7#
8XDG_DESKTOP_DIR="$HOME/Desktop"
9XDG_DOWNLOAD_DIR="$HOME/Downloads"
10XDG_TEMPLATES_DIR="$HOME/Templates"
11XDG_PUBLICSHARE_DIR="$HOME/Public"
12XDG_DOCUMENTS_DIR="$HOME/Documents"
13XDG_MUSIC_DIR="$HOME/Music"
14XDG_PICTURES_DIR="$HOME/Pictures"
15XDG_VIDEOS_DIR="$HOME/Videos"
diff --git a/test/fs/whitelist-dev.exp b/test/fs/whitelist-dev.exp
new file mode 100755
index 000000000..a19d5cedf
--- /dev/null
+++ b/test/fs/whitelist-dev.exp
@@ -0,0 +1,47 @@
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 --whitelist=/dev/null --debug\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Child process initialized"
14}
15sleep 1
16
17send -- "ls -l /dev | find /dev | wc -l\r"
18expect {
19 timeout {puts "TESTING ERROR 1\n";exit}
20 "2"
21}
22after 100
23send -- "exit\r"
24sleep 1
25
26send -- "firejail --whitelist=/var/tmp --debug\r"
27expect {
28 timeout {puts "TESTING ERROR 0\n";exit}
29 "Child process initialized"
30}
31sleep 1
32
33send -- "ls -l /dev | find /dev | wc -l\r"
34expect {
35 timeout {puts "TESTING ERROR 1\n";exit}
36 "2"
37}
38after 100
39send -- "exit\r"
40sleep 1
41
42
43
44
45after 100
46puts "\nall done\n"
47
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/fs/whitelist-downloads.exp b/test/fs/whitelist-downloads.exp
new file mode 100755
index 000000000..6af318d2b
--- /dev/null
+++ b/test/fs/whitelist-downloads.exp
@@ -0,0 +1,49 @@
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 -- "cp user-dirs.dirs /tmp/.\r"
11after 100
12
13send -- "firejail --private --noprofile\r"
14expect {
15 timeout {puts "TESTING ERROR 0\n";exit}
16 "Child process initialized"
17}
18after 100
19
20send -- "firejail --force --profile=/etc/firejail/firefox.profile\r"
21expect {
22 timeout {puts "TESTING ERROR 1\n";exit}
23 "cannot whitelist Downloads directory"
24}
25expect {
26 timeout {puts "TESTING ERROR 2\n";exit}
27 "Child process initialized"
28}
29after 100
30
31send -- "exit\r"
32after 100
33
34send -- "cp /tmp/user-dirs.dirs ~/.config/.\r"
35after 100
36
37send -- "firejail --force --profile=/etc/firejail/firefox.profile\r"
38expect {
39 timeout {puts "TESTING ERROR 3\n";exit}
40 "cannot whitelist Downloads directory"
41}
42expect {
43 timeout {puts "TESTING ERROR 4\n";exit}
44 "Child process initialized"
45}
46after 100
47
48puts "\nall done\n"
49
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..9b631b884
--- /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 --debug\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/fscheck-private.exp b/test/fscheck-private.exp
deleted file mode 100755
index 8e485cc03..000000000
--- a/test/fscheck-private.exp
+++ /dev/null
@@ -1,70 +0,0 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7
8# ..
9#send -- "firejail --net=br0 --private=../test/fscheck-dir\r"
10#expect {
11# timeout {puts "TESTING ERROR 0.1\n";exit}
12# "Error"
13#}
14#after 100
15
16# dir link
17#send -- "firejail --net=br0 --private=fscheck-dir-link\r"
18#expect {
19# timeout {puts "TESTING ERROR 1\n";exit}
20# "Error"
21#}
22#after 100
23
24# ..
25#send -- "firejail --net=br0 --private=../test/fscheck-dir-link\r"
26#expect {
27# timeout {puts "TESTING ERROR 1.1\n";exit}
28# "Error"
29#}
30#after 100
31
32# file link
33send -- "firejail --net=br0 --private=fscheck-file-link\r"
34expect {
35 timeout {puts "TESTING ERROR 2\n";exit}
36 "Error"
37}
38after 100
39
40# file
41send -- "firejail --net=br0 --private=fscheck-file\r"
42expect {
43 timeout {puts "TESTING ERROR 2.1\n";exit}
44 "Error"
45}
46after 100
47
48# ..
49send -- "firejail --net=br0 --private=../test/fscheck-file\r"
50expect {
51 timeout {puts "TESTING ERROR 2.2\n";exit}
52 "Error"
53}
54after 100
55
56# no file
57send -- "firejail --net=br0 --private=../test/nodir\r"
58expect {
59 timeout {puts "TESTING ERROR 3\n";exit}
60 "Error"
61}
62after 100
63
64# same owner
65send -- "firejail --net=br0 --private=/etc\r"
66expect {
67 timeout {puts "TESTING ERROR 4\n";exit}
68 "Error"
69}
70after 100
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/dns-print.exp b/test/network/dns-print.exp
new file mode 100755
index 000000000..9cdc14a6d
--- /dev/null
+++ b/test/network/dns-print.exp
@@ -0,0 +1,31 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "firejail --name=test-dns --net=eth0 --dns=1.2.3.4 --dns=2.3.4.5 --dns=3.4.5.6\r"
8expect {
9 timeout {puts "TESTING ERROR 1\n";exit}
10 "Child process initialized"
11}
12sleep 1
13
14spawn $env(SHELL)
15send -- "firejail --dns.print=test-dns\r"
16expect {
17 timeout {puts "TESTING ERROR 2\n";exit}
18 "nameserver 1.2.3.4"
19}
20expect {
21 timeout {puts "TESTING ERROR 2\n";exit}
22 "nameserver 2.3.4.5"
23}
24expect {
25 timeout {puts "TESTING ERROR 2\n";exit}
26 "nameserver 3.4.5.6"
27}
28
29after 100
30
31puts "\nall done\n"
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/network/ip6.exp b/test/network/ip6.exp
new file mode 100755
index 000000000..1db16c28a
--- /dev/null
+++ b/test/network/ip6.exp
@@ -0,0 +1,89 @@
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 --debug --noprofile --net=br0 --ip6=2001:0db8:0:f101::1/64 --netfilter6=ipv6.net\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Installing network filter"
14}
15expect {
16 timeout {puts "TESTING ERROR 1\n";exit}
17 "DROP"
18}
19expect {
20 timeout {puts "TESTING ERROR 2\n";exit}
21 "unable to initialize table 'filter'" {puts "\nTESTING SKIP 2: no IPv6 support\n"; exit}
22 "2001:db8:1f0a:3ec::2"
23}
24expect {
25 timeout {puts "TESTING ERROR 3\n";exit}
26 "Child process initialized"
27}
28sleep 2
29
30send -- "/sbin/ifconfig\r"
31expect {
32 timeout {puts "TESTING ERROR 4\n";exit}
33 "inet6"
34}
35expect {
36 timeout {puts "TESTING ERROR 5\n";exit}
37 "2001:db8:0:f101::1"
38}
39expect {
40 timeout {puts "TESTING ERROR 6\n";exit}
41 "Scope:Global" { puts "Debian\n"}
42 "scopeid 0x0<global>" { puts "Arch\n"}
43}
44
45send -- "exit\r"
46sleep 2
47
48
49send -- "firejail --debug --profile=ip6.profile\r"
50expect {
51 timeout {puts "TESTING ERROR 10\n";exit}
52 "Installing network filter"
53}
54expect {
55 timeout {puts "TESTING ERROR 11\n";exit}
56 "DROP"
57}
58expect {
59 timeout {puts "TESTING ERROR 12\n";exit}
60 "unable to initialize table 'filter'" {puts "\nTESTING SKIP 2: no IPv6 support\n"; exit}
61 "2001:db8:1f0a:3ec::2"
62}
63expect {
64 timeout {puts "TESTING ERROR 13\n";exit}
65 "Child process initialized"
66}
67sleep 2
68
69send -- "/sbin/ifconfig\r"
70expect {
71 timeout {puts "TESTING ERROR 14\n";exit}
72 "inet6"
73}
74expect {
75 timeout {puts "TESTING ERROR 15\n";exit}
76 "2001:db8:0:f101::1"
77}
78expect {
79 timeout {puts "TESTING ERROR 16\n";exit}
80 "Scope:Global" { puts "Debian\n"}
81 "scopeid 0x0<global>" { puts "Arch\n"}
82}
83
84send -- "exit\r"
85
86after 100
87
88puts "\nall done\n"
89
diff --git a/test/network/ip6.profile b/test/network/ip6.profile
new file mode 100644
index 000000000..87afa3941
--- /dev/null
+++ b/test/network/ip6.profile
@@ -0,0 +1,3 @@
1net br0
2ip6 2001:0db8:0:f101::1/64
3netfilter6 ipv6.net
diff --git a/test/network/iprange.exp b/test/network/iprange.exp
new file mode 100755
index 000000000..a1b2ccab4
--- /dev/null
+++ b/test/network/iprange.exp
@@ -0,0 +1,103 @@
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=br1 --iprange=10.10.30.50,10.10.30.55\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "eth0"
14}
15expect {
16 timeout {puts "TESTING ERROR 1\n";exit}
17 "10.10.30.50" {puts "10.10.30.50\n"}
18 "10.10.30.51" {puts "10.10.30.51\n"}
19 "10.10.30.52" {puts "10.10.30.52\n"}
20 "10.10.30.53" {puts "10.10.30.53\n"}
21 "10.10.30.54" {puts "10.10.30.54\n"}
22 "10.10.30.55" {puts "10.10.30.55\n"}
23}
24expect {
25 timeout {puts "TESTING ERROR 2\n";exit}
26 "255.255.255.0"
27}
28expect {
29 timeout {puts "TESTING ERROR 3\n";exit}
30 "Child process initialized"
31}
32sleep 1
33send -- "exit\r"
34sleep 2
35
36send -- "firejail --profile=iprange.profile\r"
37expect {
38 timeout {puts "TESTING ERROR 5\n";exit}
39 "eth0"
40}
41expect {
42 timeout {puts "TESTING ERROR 6\n";exit}
43 "10.10.30.50" {puts "10.10.30.50\n"}
44 "10.10.30.51" {puts "10.10.30.51\n"}
45 "10.10.30.52" {puts "10.10.30.52\n"}
46 "10.10.30.53" {puts "10.10.30.53\n"}
47 "10.10.30.54" {puts "10.10.30.54\n"}
48 "10.10.30.55" {puts "10.10.30.55\n"}
49}
50expect {
51 timeout {puts "TESTING ERROR 7\n";exit}
52 "255.255.255.0"
53}
54expect {
55 timeout {puts "TESTING ERROR 8\n";exit}
56 "Child process initialized"
57}
58sleep 1
59send -- "exit\r"
60sleep 2
61
62
63
64send -- "firejail --iprange=10.10.30.50,10.10.30.55\r"
65expect {
66 timeout {puts "TESTING ERROR 9\n";exit}
67 "no network device configured"
68}
69after 100
70
71send -- "firejail --net=br1 --iprange=10.10.30.50,10.10.30.55 --iprange=10.10.30.50,10.10.30.55\r"
72expect {
73 timeout {puts "TESTING ERROR 10\n";exit}
74 "cannot configure the IP range twice for the same interface"
75}
76after 100
77
78send -- "firejail --net=br1 --iprange=10.10.30.50\r"
79expect {
80 timeout {puts "TESTING ERROR 11\n";exit}
81 "invalid IP range"
82}
83after 100
84
85send -- "firejail --net=br0 --iprange=10.10.30.50,10.10.30.55\r"
86expect {
87 timeout {puts "TESTING ERROR 12\n";exit}
88 "IP range addresses not in network range"
89}
90after 100
91
92send -- "firejail --net=br1 --iprange=10.10.30.55,10.10.30.50\r"
93expect {
94 timeout {puts "TESTING ERROR 12\n";exit}
95 "invalid IP range"
96}
97after 100
98
99
100after 100
101
102puts "\nall done\n"
103
diff --git a/test/network/iprange.profile b/test/network/iprange.profile
new file mode 100644
index 000000000..ecc01cd93
--- /dev/null
+++ b/test/network/iprange.profile
@@ -0,0 +1,2 @@
1net br1
2iprange 10.10.30.50,10.10.30.55
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/network/net_macvlan2.exp b/test/network/net_macvlan2.exp
new file mode 100755
index 000000000..7f21fc083
--- /dev/null
+++ b/test/network/net_macvlan2.exp
@@ -0,0 +1,43 @@
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 --net=eth0 --net=eth0 --net=eth0\r"
11expect {
12 timeout {puts "TESTING ERROR 0.1\n";exit}
13 "eth0-"
14}
15expect {
16 timeout {puts "TESTING ERROR 0.2\n";exit}
17 "eth1-"
18}
19expect {
20 timeout {puts "TESTING ERROR 0.3\n";exit}
21 "eth2-"
22}
23expect {
24 timeout {puts "TESTING ERROR 0.4\n";exit}
25 "eth3-"
26}
27expect {
28 timeout {puts "TESTING ERROR 0.5\n";exit}
29 "Default gateway 192.168.1.1"
30}
31expect {
32 timeout {puts "TESTING ERROR 0.6\n";exit}
33 "Child process initialized"
34}
35after 100
36send -- "exit\r"
37sleep 1
38
39
40after 100
41
42puts "\nall done\n"
43
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..04091047b
--- /dev/null
+++ b/test/network/net_veth.exp
@@ -0,0 +1,142 @@
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"
126sleep 1
127
128send -- "firejail --net=eth0 --ip=10.10.20.1\r"
129expect {
130 timeout {puts "TESTING ERROR 27\n";exit}
131 "the IP address is not in the interface range"
132}
133
134
135
136
137
138
139after 100
140
141puts "\n"
142
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..94df9935e
--- /dev/null
+++ b/test/network/network.sh
@@ -0,0 +1,100 @@
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: print dns (dns-print.exp)"
15./dns-print.exp
16
17echo "TESTING: firemon arp (firemon-arp.exp)"
18./firemon-arp.exp
19
20echo "TESTING: firemon netstats (netstats.exp)"
21./netstats.exp
22
23echo "TESTING: firemon route (firemon-route.exp)"
24./firemon-route.exp
25
26echo "TESTING: network profile (net_profile.exp)"
27./net_profile.exp
28
29echo "TESTING: bandwidth (bandwidth.exp)"
30./bandwidth.exp
31
32echo "TESTING: IPv6 support (ip6.exp)"
33./ip6.exp
34
35echo "TESTING: local network (net_local.exp)"
36./net_local.exp
37
38echo "TESTING: no network (net_none.exp)"
39./net_none.exp
40
41echo "TESTING: network IP (net_ip.exp)"
42./net_ip.exp
43
44echo "TESTING: network MAC (net_mac.exp)"
45sleep 2
46./net_mac.exp
47
48echo "TESTING: network MTU (net_mtu.exp)"
49./net_mtu.exp
50
51echo "TESTING: network hostname (hostname.exp)"
52./hostname.exp
53
54echo "TESTING: network bad IP (net_badip.exp)"
55./net_badip.exp
56
57echo "TESTING: network no IP test 1 (net_noip.exp)"
58./net_noip.exp
59
60echo "TESTING: network no IP test 2 (net_noip2.exp)"
61./net_noip2.exp
62
63echo "TESTING: network default gateway test 1 (net_defaultgw.exp)"
64./net_defaultgw.exp
65
66echo "TESTING: network default gateway test 2 (net_defaultgw2.exp)"
67./net_defaultgw2.exp
68
69echo "TESTING: network default gateway test 3 (net_defaultgw3.exp)"
70./net_defaultgw3.exp
71
72echo "TESTING: scan (net_scan.exp)"
73./net_scan.exp
74
75echo "TESTING: mtu (mtu.exp)"
76./mtu.exp
77
78echo "TESTING: interface (interface.exp)"
79./interface.exp
80
81echo "TESTING: veth (net_veth.exp)"
82./net_veth.exp
83
84echo "TESTING: netfilter (net_netfilter.exp)"
85./net_netfilter.exp
86
87echo "TESTING: iprange (iprange.exp)"
88./iprange.exp
89
90echo "TESTING: veth-name (veth-name.exp)"
91./veth-name.exp
92
93echo "TESTING: macvlan2 (net_macvlan2.exp)"
94./net_macvlan2.exp
95
96echo "TESTING: 4 bridges ARP (4bridges_arp.exp)"
97./4bridges_arp.exp
98
99echo "TESTING: 4 bridges IP (4bridges_ip.exp)"
100./4bridges_ip.exp
diff --git a/test/network/veth-name.exp b/test/network/veth-name.exp
new file mode 100755
index 000000000..36ed41d92
--- /dev/null
+++ b/test/network/veth-name.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#
11send -- "firejail --net=br1 --ip=10.10.30.50 --veth-name=blablabla\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 -- "ip link show\r"
32expect {
33 timeout {puts "TESTING ERROR 4\n";exit}
34 "blablabla"
35}
36expect {
37 timeout {puts "TESTING ERROR 5\n";exit}
38 "master br1 state UP"
39}
40sleep 1
41
42
43send -- "firejail --profile=veth-name.profile\r"
44expect {
45 timeout {puts "TESTING ERROR 6\n";exit}
46 "eth0"
47}
48expect {
49 timeout {puts "TESTING ERROR 7\n";exit}
50 "10.10.60.51"
51}
52expect {
53 timeout {puts "TESTING ERROR 8\n";exit}
54 "255.255.255.0"
55}
56expect {
57 timeout {puts "TESTING ERROR 9\n";exit}
58 "Child process initialized"
59}
60sleep 1
61
62spawn $env(SHELL)
63send -- "ip link show\r"
64expect {
65 timeout {puts "TESTING ERROR 10\n";exit}
66 "bingo"
67}
68expect {
69 timeout {puts "TESTING ERROR 11\n";exit}
70 "master br4 state UP"
71}
72sleep 1
73
74
75after 100
76puts "\nall done\n"
77
diff --git a/test/network/veth-name.profile b/test/network/veth-name.profile
new file mode 100644
index 000000000..f00a74d63
--- /dev/null
+++ b/test/network/veth-name.profile
@@ -0,0 +1,3 @@
1net br4
2ip 10.10.60.51
3veth-name bingo
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-join-profile.exp b/test/option-join-profile.exp
deleted file mode 100755
index 9200980a1..000000000
--- a/test/option-join-profile.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 --profile=name.profile\r"
8expect {
9 timeout {puts "TESTING ERROR 0\n";exit}
10 "Child process initialized"
11}
12sleep 3
13
14spawn $env(SHELL)
15send -- "firejail --join=jointesting;pwd\r"
16expect {
17 timeout {puts "TESTING ERROR 1\n";exit}
18 "Switching to pid"
19}
20sleep 3
21
22
23spawn $env(SHELL)
24send -- "firejail --shutdown=jointesting;pwd\r"
25expect {
26 timeout {puts "TESTING ERROR 3\n";exit}
27 "home"
28}
29sleep 5
30
31send -- "firejail --list;pwd\r"
32expect {
33 timeout {puts "TESTING ERROR 4\n";exit}
34 "jointesting" {puts "TESTING ERROR 5\n";exit}
35 "home"
36}
37sleep 1
38
39puts "\nall done\n"
diff --git a/test/option-join.exp b/test/option-join.exp
deleted file mode 100755
index 6250e87a2..000000000
--- a/test/option-join.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=svntesting\r"
8expect {
9 timeout {puts "TESTING ERROR 0\n";exit}
10 "Child process initialized"
11}
12sleep 3
13
14spawn $env(SHELL)
15send -- "firejail --join=svntesting;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=svntesting;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 "svntesting" {puts "TESTING ERROR 5\n";exit}
35 "home"
36}
37sleep 1
38
39puts "\nall done\n"
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-shutdown.exp b/test/option-shutdown.exp
deleted file mode 100755
index e869f7611..000000000
--- a/test/option-shutdown.exp
+++ /dev/null
@@ -1,30 +0,0 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "firejail --name=shutdowntesting\r"
8expect {
9 timeout {puts "TESTING ERROR 0\n";exit}
10 "Child process initialized"
11}
12sleep 3
13
14spawn $env(SHELL)
15send -- "firejail --shutdown=shutdowntesting;pwd\r"
16expect {
17 timeout {puts "TESTING ERROR 4\n";exit}
18 "home"
19}
20sleep 1
21
22send -- "firejail --list;pwd\r"
23expect {
24 timeout {puts "TESTING ERROR 5\n";exit}
25 "shutdowntesting" {puts "TESTING ERROR 6\n";exit}
26 "home"
27}
28sleep 1
29
30puts "\nalldone\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-etc.exp b/test/private-etc.exp
deleted file mode 100755
index db1d1df3a..000000000
--- a/test/private-etc.exp
+++ /dev/null
@@ -1,42 +0,0 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7# directory with ~
8send -- "firejail --private-etc=passwd,group,resolv.conf,X11\r"
9expect {
10 timeout {puts "TESTING ERROR 1\n";exit}
11 "Child process initialized"
12}
13sleep 1
14
15send -- "ls -al /etc\r"
16expect {
17 timeout {puts "TESTING ERROR 3\n";exit}
18 "group"
19}
20expect {
21 timeout {puts "TESTING ERROR 4\n";exit}
22 "passwd"
23}
24expect {
25 timeout {puts "TESTING ERROR 5\n";exit}
26 "resolv.conf"
27}
28expect {
29 timeout {puts "TESTING ERROR 6\n";exit}
30 "X11"
31}
32
33send -- "ls -al /etc\r"
34expect {
35 timeout {puts "TESTING ERROR 7\n";exit}
36 "shadow" {puts "TESTING ERROR 8\n";exit}
37 "X11"
38}
39
40sleep 1
41puts "\nall done\n"
42
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/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/root/join.exp b/test/root/join.exp
new file mode 100755
index 000000000..e4a4e87af
--- /dev/null
+++ b/test/root/join.exp
@@ -0,0 +1,52 @@
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\r"
36sleep 1
37send -- "firejail --join-network=jointesting\r"
38expect {
39 timeout {puts "TESTING ERROR 4\n";exit}
40 "Child process initialized"
41}
42send -- "exit\r"
43sleep 1
44send -- "firejail --join-filesystem=jointesting\r"
45expect {
46 timeout {puts "TESTING ERROR 5\n";exit}
47 "Child process initialized"
48}
49
50after 100
51
52puts "\nall done\n"
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..9ce9716f9
--- /dev/null
+++ b/test/root/private.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 --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"
32sleep 1
33
34
35
36send -- "touch /opt/firejail-test-file\r"
37after 100
38send -- "mkdir /opt/firejail-test-dir\r"
39after 100
40send -- "touch /opt/firejail-test-dir/firejail-test-file\r"
41after 100
42send -- "firejail --private-opt=firejail-test-file,firejail-test-dir --debug\r"
43expect {
44 timeout {puts "TESTING ERROR 3\n";exit}
45 "Child process initialized"
46}
47sleep 1
48
49send -- "find /opt | wc -l\r"
50expect {
51 timeout {puts "TESTING ERROR 4\n";exit}
52 "4"
53}
54after 100
55send -- "exit\r"
56sleep 1
57
58
59send -- "touch /srv/firejail-test-file\r"
60after 100
61send -- "mkdir /srv/firejail-test-dir\r"
62after 100
63send -- "touch /srv/firejail-test-dir/firejail-test-file\r"
64after 100
65send -- "firejail --private-srv=firejail-test-file,firejail-test-dir --debug\r"
66expect {
67 timeout {puts "TESTING ERROR 5\n";exit}
68 "Child process initialized"
69}
70sleep 1
71
72send -- "find /srv | wc -l\r"
73expect {
74 timeout {puts "TESTING ERROR 6\n";exit}
75 "4"
76}
77after 100
78send -- "exit\r"
79sleep 1
80
81
82
83
84
85
86
87
88
89
90puts "\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..9764b3804
--- /dev/null
+++ b/test/root/root.sh
@@ -0,0 +1,114 @@
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
56echo "TESTING: fs whitelist mnt, opt, media (test/root/whitelist-mnt.exp)"
57./whitelist.exp
58
59#********************************
60# utils
61#********************************
62echo "TESTING: join (test/root/join.exp)"
63./join.exp
64
65#********************************
66# seccomp
67#********************************
68echo "TESTING: seccomp umount (test/root/seccomp-umount.exp)"
69./seccomp-umount.exp
70
71echo "TESTING: seccomp chmod (test/root/seccomp-chmod.exp)"
72./seccomp-chmod.exp
73
74echo "TESTING: seccomp chown (test/root/seccomp-chown.exp)"
75./seccomp-chown.exp
76
77#********************************
78# command line options
79#********************************
80echo "TESTING: tmpfs (test/root/option_tmpfs.exp)"
81./option_tmpfs.exp
82
83echo "TESTING: profile tmpfs (test/root/profile_tmpfs)"
84./profile_tmpfs.exp
85
86echo "TESTING: bind directory (test/root/option_bind_directory.exp)"
87./option_bind_directory.exp
88
89echo "TESTING: bind file (test/root/option_bind_file.exp)"
90echo hello > tmpfile
91./option_bind_file.exp
92rm -f tmpfile
93
94#********************************
95# firemon
96#********************************
97echo "TESTING: firemon events (test/root/firemon-events.exp)"
98./firemon-events.exp
99
100#********************************
101# firecfg
102#********************************
103which firefox
104if [ "$?" -eq 0 ];
105then
106 echo "TESTING: firecfg (test/root/firecfg.exp)"
107 ./firecfg.exp
108else
109 echo "TESTING SKIP: firecfg, firefox not found"
110fi
111
112# restore the default config file
113cp ../../etc/firejail.config /etc/firejail/firejail.config
114
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.exp b/test/root/seccomp-chown.exp
index b4a213206..a54d279f1 100755
--- a/test/seccomp-chmod.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 --seccomp=chmod,fchmod,fchmodat --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/root/whitelist.exp b/test/root/whitelist.exp
new file mode 100755
index 000000000..f6936c048
--- /dev/null
+++ b/test/root/whitelist.exp
@@ -0,0 +1,118 @@
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 /mnt/firejail-test-file\r"
11after 100
12send -- "mkdir /mnt/firejail-test-dir\r"
13after 100
14send -- "touch /mnt/firejail-test-dir/firejail-test-file\r"
15after 100
16send -- "firejail --whitelist=/mnt/firejail-test-file --whitelist=/mnt/firejail-test-dir --debug\r"
17expect {
18 timeout {puts "TESTING ERROR 0\n";exit}
19 "Child process initialized"
20}
21sleep 1
22
23send -- "find /mnt | wc -l\r"
24expect {
25 timeout {puts "TESTING ERROR 1\n";exit}
26 "4"
27}
28after 100
29send -- "exit\r"
30sleep 1
31
32
33send -- "touch /opt/firejail-test-file\r"
34after 100
35send -- "mkdir /opt/firejail-test-dir\r"
36after 100
37send -- "touch /opt/firejail-test-dir/firejail-test-file\r"
38after 100
39send -- "firejail --whitelist=/opt/firejail-test-file --whitelist=/opt/firejail-test-dir --debug\r"
40expect {
41 timeout {puts "TESTING ERROR 2\n";exit}
42 "Child process initialized"
43}
44sleep 1
45
46send -- "find /opt | wc -l\r"
47expect {
48 timeout {puts "TESTING ERROR 3\n";exit}
49 "4"
50}
51after 100
52send -- "exit\r"
53sleep 1
54
55send -- "touch /media/firejail-test-file\r"
56after 100
57send -- "mkdir /media/firejail-test-dir\r"
58after 100
59send -- "touch /media/firejail-test-dir/firejail-test-file\r"
60after 100
61send -- "firejail --whitelist=/media/firejail-test-file --whitelist=/media/firejail-test-dir --debug\r"
62expect {
63 timeout {puts "TESTING ERROR 4\n";exit}
64 "Child process initialized"
65}
66sleep 1
67
68send -- "find /media | wc -l\r"
69expect {
70 timeout {puts "TESTING ERROR 5\n";exit}
71 "4"
72}
73after 100
74send -- "exit\r"
75sleep 1
76
77
78send -- "firejail --whitelist=/var/run --whitelist=/var/lock --debug\r"
79expect {
80 timeout {puts "TESTING ERROR 6\n";exit}
81 "Child process initialized"
82}
83sleep 1
84
85send -- "find /var | wc -l\r"
86expect {
87 timeout {puts "TESTING ERROR 7\n";exit}
88 ""
89}
90after 100
91send -- "exit\r"
92sleep 1
93
94send -- "touch /srv/firejail-test-file\r"
95after 100
96send -- "mkdir /srv/firejail-test-dir\r"
97after 100
98send -- "touch /srv/firejail-test-dir/firejail-test-file\r"
99after 100
100send -- "firejail --whitelist=/srv/firejail-test-file --whitelist=/srv/firejail-test-dir --debug\r"
101expect {
102 timeout {puts "TESTING ERROR 8\n";exit}
103 "Child process initialized"
104}
105sleep 1
106
107send -- "find /srv | wc -l\r"
108expect {
109 timeout {puts "TESTING ERROR 9\n";exit}
110 "4"
111}
112after 100
113send -- "exit\r"
114
115
116after 100
117puts "\nall done\n"
118
diff --git a/test/seccomp-chmod-profile.exp b/test/seccomp-chmod-profile.exp
deleted file mode 100755
index 098328cea..000000000
--- a/test/seccomp-chmod-profile.exp
+++ /dev/null
@@ -1,46 +0,0 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "firejail --profile=seccomp.profile --private\r"
8expect {
9 timeout {puts "TESTING ERROR 0\n";exit}
10 "Child process initialized"
11}
12sleep 2
13
14send -- "touch testfile;pwd\r"
15expect {
16 timeout {puts "TESTING ERROR 1\n";exit}
17 "/root" {puts "running as root"}
18 "/home"
19}
20
21send -- "ls -l testfile;pwd\r"
22expect {
23 timeout {puts "TESTING ERROR 2\n";exit}
24 "testfile"
25}
26expect {
27 timeout {puts "TESTING ERROR 3\n";exit}
28 "/root" {puts "running as root"}
29 "/home"
30}
31
32send -- "chmod +x testfile;pwd\r"
33expect {
34 timeout {puts "TESTING ERROR 2\n";exit}
35 "Bad system call"
36}
37expect {
38 timeout {puts "TESTING ERROR 3\n";exit}
39 "/root" {puts "running as root"}
40 "/home"
41}
42
43
44send -- "exit\r"
45sleep 1
46puts "\n"
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/net_macvlan.exp b/test/stress/net_macvlan.exp
index 20d022de9..6ea4a6adf 100755
--- a/test/net_macvlan.exp
+++ b/test/stress/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)
@@ -9,7 +12,7 @@ spawn $env(SHELL)
9send -- "firejail --net=eth0 --ip=192.168.1.60\r" 12send -- "firejail --net=eth0 --ip=192.168.1.60\r"
10expect { 13expect {
11 timeout {puts "TESTING ERROR 1.1\n";puts "Please open a sandbox on 192.168.1.60\n";exit} 14 timeout {puts "TESTING ERROR 1.1\n";puts "Please open a sandbox on 192.168.1.60\n";exit}
12 "the address 192.168.1.60 is already in use" 15 "192.168.1.60 is interface eth0 address"
13} 16}
14 17
15 18
@@ -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/stress/stress.sh b/test/stress/stress.sh
new file mode 100755
index 000000000..35c846071
--- /dev/null
+++ b/test/stress/stress.sh
@@ -0,0 +1,11 @@
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: macvlan (net_macvlan.exp)"
10./net_macvlan.exp
11
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/utils/audit.exp b/test/utils/audit.exp
new file mode 100755
index 000000000..931b46981
--- /dev/null
+++ b/test/utils/audit.exp
@@ -0,0 +1,79 @@
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 --audit\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Firejail Audit"
14}
15expect {
16 timeout {puts "TESTING ERROR 1\n";exit}
17 "is running in a PID namespace"
18}
19expect {
20 timeout {puts "TESTING ERROR 2\n";exit}
21 "container/sandbox firejail"
22}
23expect {
24 timeout {puts "TESTING ERROR 3\n";exit}
25 "seccomp BPF enabled"
26}
27expect {
28 timeout {puts "TESTING ERROR 4\n";exit}
29 "all capabilities are disabled"
30}
31expect {
32 timeout {puts "TESTING ERROR 5\n";exit}
33 "dev directory seems to be fully populated"
34}
35after 100
36
37
38send -- "firejail --audit=/usr/lib/firejail/faudit\r"
39expect {
40 timeout {puts "TESTING ERROR 6\n";exit}
41 "Firejail Audit"
42}
43expect {
44 timeout {puts "TESTING ERROR 7\n";exit}
45 "is running in a PID namespace"
46}
47expect {
48 timeout {puts "TESTING ERROR 8\n";exit}
49 "container/sandbox firejail"
50}
51expect {
52 timeout {puts "TESTING ERROR 9\n";exit}
53 "seccomp BPF enabled"
54}
55expect {
56 timeout {puts "TESTING ERROR 10\n";exit}
57 "all capabilities are disabled"
58}
59expect {
60 timeout {puts "TESTING ERROR 11\n";exit}
61 "dev directory seems to be fully populated"
62}
63after 100
64
65send -- "firejail --audit=blablabla\r"
66expect {
67 timeout {puts "TESTING ERROR 12\n";exit}
68 "cannot find the audit program"
69}
70after 100
71
72send -- "firejail --audit=\r"
73expect {
74 timeout {puts "TESTING ERROR 12\n";exit}
75 "invalid audit program"
76}
77after 100
78
79puts "\nall done\n"
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..00156c909 100755
--- a/test/seccomp-dualfilter.exp
+++ b/test/utils/firemon-cpu.exp
@@ -1,38 +1,44 @@
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"
16expect { 27expect {
17 timeout {puts "TESTING ERROR 2\n";exit} 28 timeout {puts "TESTING ERROR 2\n";exit}
18 "after mount" {puts "TESTING ERROR 2.1\n";exit} 29 "need to be root" {puts "TESTING SKIP: /proc mounted as hidepid\n"; exit}
19 "Parent is shutting down" 30 "name=test1"
20} 31}
21sleep 1
22
23send -- "firejail ../src/tools/syscall_test32 mount\r"
24expect { 32expect {
25 timeout {puts "TESTING ERROR 3\n";exit} 33 timeout {puts "TESTING ERROR 3\n";exit}
26 "Child process initialized" 34 "Cpus_allowed_list"
27} 35}
28expect { 36expect {
29 timeout {puts "TESTING ERROR 4\n";exit} 37 timeout {puts "TESTING ERROR 4\n";exit}
30 "before mount" 38 "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} 39}
37 40
41after 100
42
38puts "\nall done\n" 43puts "\nall done\n"
44
diff --git a/test/utils/firemon-interface.exp b/test/utils/firemon-interface.exp
new file mode 100755
index 000000000..edafd1639
--- /dev/null
+++ b/test/utils/firemon-interface.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 -- "firemon --interface\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "you need to be root"
14}
15after 100
16
17puts "\nall done\n"
18
diff --git a/test/utils/firemon-name.exp b/test/utils/firemon-name.exp
new file mode 100755
index 000000000..c5dbfabab
--- /dev/null
+++ b/test/utils/firemon-name.exp
@@ -0,0 +1,28 @@
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\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Child process initialized"
14}
15sleep 1
16
17spawn $env(SHELL)
18send -- "firemon --cpu --name=test\r"
19expect {
20 timeout {puts "TESTING ERROR 2\n";exit}
21 "need to be root" {puts "TESTING SKIP: /proc mounted as hidepid\n"; exit}
22 "Cpus_allowed_list"
23}
24
25after 100
26
27puts "\nall done\n"
28
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/utils/firemon-version.exp b/test/utils/firemon-version.exp
new file mode 100755
index 000000000..639c15c29
--- /dev/null
+++ b/test/utils/firemon-version.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 -- "firemon --version\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "firemon version"
14}
15after 100
16
17puts "\nall done\n"
18
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..79fe99f2d
--- /dev/null
+++ b/test/utils/join.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
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\r"
36sleep 1
37send -- "firejail --join-network=jointesting\r"
38expect {
39 timeout {puts "TESTING ERROR 4\n";exit}
40 "is only available to root user"
41}
42after 100
43send -- "firejail --join-filesystem=jointesting\r"
44expect {
45 timeout {puts "TESTING ERROR 5\n";exit}
46 "is only available to root user"
47}
48
49after 100
50
51puts "\nall done\n"
diff --git a/test/utils/join2.exp b/test/utils/join2.exp
new file mode 100755
index 000000000..5895eb730
--- /dev/null
+++ b/test/utils/join2.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=\"join testing\"\r"
12expect {
13 timeout {puts "TESTING ERROR 0\n";exit}
14 "Child process initialized"
15}
16sleep 2
17
18spawn $env(SHELL)
19send -- "firejail --join=\"join testing\"\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/utils/join3.exp b/test/utils/join3.exp
new file mode 100755
index 000000000..3ccc47bf9
--- /dev/null
+++ b/test/utils/join3.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=join\\ testing\r"
12expect {
13 timeout {puts "TESTING ERROR 0\n";exit}
14 "Child process initialized"
15}
16sleep 2
17
18spawn $env(SHELL)
19send -- "firejail --join=join\\ testing\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/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/utils/shutdown.exp b/test/utils/shutdown.exp
new file mode 100755
index 000000000..1ab231bf4
--- /dev/null
+++ b/test/utils/shutdown.exp
@@ -0,0 +1,49 @@
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=shutdowntesting\r"
12expect {
13 timeout {puts "TESTING ERROR 0\n";exit}
14 "Child process initialized"
15}
16sleep 2
17
18spawn $env(SHELL)
19send -- "firejail --shutdown=shutdowntesting; echo done\r"
20expect {
21 timeout {puts "TESTING ERROR 4\n";exit}
22 "done"
23}
24sleep 5
25
26spawn $env(SHELL)
27send -- "firejail --list;echo done\r"
28expect {
29 timeout {puts "TESTING ERROR 5\n";exit}
30 "shutdowntesting" {puts "TESTING ERROR 6\n";exit}
31 "done"
32}
33sleep 1
34
35send -- "firejail --shutdown=sutdowntesting\r"
36expect {
37 timeout {puts "TESTING ERROR 5\n";exit}
38 "cannot find sandbox sutdowntesting"
39}
40after 100
41
42send -- "firejail --shutdown=10\r"
43expect {
44 timeout {puts "TESTING ERROR 5\n";exit}
45 "this is not a firejail sandbox"
46}
47after 100
48
49puts "\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..04702597f
--- /dev/null
+++ b/test/utils/utils.sh
@@ -0,0 +1,114 @@
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: audit (test/utils/audit.exp)"
10./audit.exp
11
12echo "TESTING: version (test/utils/version.exp)"
13./version.exp
14
15echo "TESTING: help (test/utils/help.exp)"
16./help.exp
17
18which man
19if [ "$?" -eq 0 ];
20then
21 echo "TESTING: man (test/utils/man.exp)"
22 ./man.exp
23else
24 echo "TESTING SKIP: man not found"
25fi
26
27echo "TESTING: list (test/utils/list.exp)"
28./list.exp
29
30echo "TESTING: tree (test/utils/tree.exp)"
31./tree.exp
32
33if [ $(grep -c ^processor /proc/cpuinfo) -gt 1 ];
34then
35 echo "TESTING: cpu.print (test/utils/cpu-print.exp)"
36 ./cpu-print.exp
37else
38 echo "TESTING SKIP: cpu.print, not enough CPUs"
39fi
40
41echo "TESTING: fs.print (test/utils/fs-print.exp)"
42./fs-print.exp
43
44echo "TESTING: dns.print (test/utils/dns-print.exp)"
45./dns-print.exp
46
47echo "TESTING: caps.print (test/utils/caps-print.exp)"
48./caps-print.exp
49
50echo "TESTING: seccomp.print (test/utils/seccomp-print.exp)"
51./seccomp-print.exp
52
53echo "TESTING: protocol.print (test/utils/protocol-print.exp)"
54./protocol-print.exp
55
56echo "TESTING: shutdown (test/utils/shutdown.exp)"
57./shutdown.exp
58
59echo "TESTING: shutdown2 (test/utils/shutdown2.exp)"
60./shutdown2.exp
61
62echo "TESTING: shutdown3 (test/utils/shutdown3.exp)"
63./shutdown3.exp
64
65echo "TESTING: shutdown4 (test/utils/shutdown4.exp)"
66./shutdown4.exp
67
68echo "TESTING: join (test/utils/join.exp)"
69./join.exp
70
71echo "TESTING: join2 (test/utils/join2.exp)"
72./join2.exp
73
74echo "TESTING: join3 (test/utils/join3.exp)"
75./join3.exp
76
77echo "TESTING: join3 (test/utils/join4.exp)"
78./join4.exp
79
80echo "TESTING: join profile (test/utils/join-profile.exp)"
81./join-profile.exp
82
83echo "TESTING: trace (test/utils/trace.exp)"
84rm -f index.html*
85./trace.exp
86rm -f index.html*
87
88echo "TESTING: top (test/utils/top.exp)"
89./top.exp
90
91echo "TESTING: file transfer (test/utils/ls.exp)"
92./ls.exp
93
94echo "TESTING: firemon seccomp (test/utils/firemon-seccomp.exp)"
95./firemon-seccomp.exp
96
97echo "TESTING: firemon caps (test/utils/firemon-caps.exp)"
98./firemon-caps.exp
99
100echo "TESTING: firemon cpu (test/utils/firemon-cpu.exp)"
101./firemon-cpu.exp
102
103echo "TESTING: firemon cgroup (test/utils/firemon-cgroup.exp)"
104./firemon-cgroup.exp
105
106echo "TESTING: firemon version (test/utils/firemon-version.exp)"
107./firemon-version.exp
108
109echo "TESTING: firemon interface (test/utils/firemon-interface.exp)"
110./firemon-interface.exp
111
112echo "TESTING: firemon name (test/utils/firemon-name.exp)"
113./firemon-name.exp
114
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..86917e6cd 100644
--- a/todo
+++ b/todo
@@ -74,11 +74,230 @@ 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.
290$ sudo firejail --fs.print=test
291[sudo] password for netblue:
292tmpfs /run/firejail/mnt << ????????????????
293sandbox name: test
294sandbox pid: 5790
295sandbox filesystem: local
296install mount namespace
297read-only /etc
298read-only /var
299read-only /bin
300
30131. --private and --allusers are coliding
302
30332. machine-id defined in rfc4122