aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar startx2017 <vradu.startx@yandex.com>2018-07-27 12:56:41 -0400
committerLibravatar startx2017 <vradu.startx@yandex.com>2018-07-27 12:56:41 -0400
commit3cf75fe9a34c0bb579502b106649a1fc58d39f35 (patch)
tree3c696691a48205e6c73987f562bcc7a80aac69e4
parentcompile time marker for LTS code (diff)
downloadfirejail-3cf75fe9a34c0bb579502b106649a1fc58d39f35.tar.gz
firejail-3cf75fe9a34c0bb579502b106649a1fc58d39f35.tar.zst
firejail-3cf75fe9a34c0bb579502b106649a1fc58d39f35.zip
phase 1
-rw-r--r--Makefile.in39
-rwxr-xr-xconfigure24
-rw-r--r--configure.ac14
-rwxr-xr-xcontrib/fix_private-bin.py157
-rwxr-xr-xcontrib/fj-mkdeb.py74
-rwxr-xr-xcontrib/fjclip.py35
-rwxr-xr-xcontrib/fjdisplay.py43
-rwxr-xr-xcontrib/fjresize.py25
-rwxr-xr-xcontrib/update_deb.sh12
-rw-r--r--src/faudit/Makefile.in14
-rw-r--r--src/faudit/caps.c78
-rw-r--r--src/faudit/dbus.c92
-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.c105
-rw-r--r--src/faudit/x11.c63
-rw-r--r--src/fbuilder/Makefile.in14
-rw-r--r--src/fbuilder/build_bin.c126
-rw-r--r--src/fbuilder/build_fs.c317
-rw-r--r--src/fbuilder/build_home.c199
-rw-r--r--src/fbuilder/build_profile.c170
-rw-r--r--src/fbuilder/build_seccomp.c192
-rw-r--r--src/fbuilder/fbuilder.h69
-rw-r--r--src/fbuilder/filedb.c79
-rw-r--r--src/fbuilder/main.c93
-rw-r--r--src/fbuilder/utils.c72
-rw-r--r--src/firejail/fs.c3
-rw-r--r--src/firejail/fs_bin.c309
-rw-r--r--src/firejail/fs_home.c2
-rw-r--r--src/firejail/fs_lib.c378
-rw-r--r--src/firejail/fs_lib2.c314
-rw-r--r--src/firejail/main.c23
-rw-r--r--src/firejail/profile.c8
-rw-r--r--src/firejail/sandbox.c13
-rw-r--r--src/firejail/x11.c1311
-rw-r--r--src/fldd/Makefile.in14
-rw-r--r--src/fldd/main.c353
-rw-r--r--status7
-rwxr-xr-xtest/apps-x11-xorg/apps-x11-xorg.sh34
-rwxr-xr-xtest/apps-x11-xorg/firefox.exp90
-rwxr-xr-xtest/apps-x11-xorg/thunderbird.exp85
-rwxr-xr-xtest/apps-x11-xorg/transmission-gtk.exp85
-rwxr-xr-xtest/apps-x11/apps-x11.sh87
-rwxr-xr-xtest/apps-x11/chromium.exp85
-rwxr-xr-xtest/apps-x11/firefox.exp90
-rwxr-xr-xtest/apps-x11/thunderbird.exp85
-rwxr-xr-xtest/apps-x11/transmission-gtk.exp85
-rwxr-xr-xtest/apps-x11/x11-none.exp47
-rwxr-xr-xtest/apps-x11/x11-xephyr.exp58
-rwxr-xr-xtest/apps-x11/xterm-xephyr.exp85
-rwxr-xr-xtest/apps-x11/xterm-xorg.exp85
-rwxr-xr-xtest/apps-x11/xterm-xpra.exp97
-rwxr-xr-xtest/chroot/chroot.sh21
-rwxr-xr-xtest/chroot/configure46
-rwxr-xr-xtest/chroot/fs_chroot.exp61
-rwxr-xr-xtest/chroot/unchroot-as-root.exp26
-rw-r--r--test/chroot/unchroot.c40
-rwxr-xr-xtest/overlay/firefox-x11-xorg.exp89
-rwxr-xr-xtest/overlay/firefox-x11.exp89
-rwxr-xr-xtest/overlay/firefox.exp98
-rwxr-xr-xtest/overlay/fs-named.exp69
-rwxr-xr-xtest/overlay/fs-tmpfs.exp67
-rwxr-xr-xtest/overlay/fs.exp59
-rwxr-xr-xtest/overlay/overlay.sh67
-rwxr-xr-xtest/private-lib/atril.exp83
-rwxr-xr-xtest/private-lib/eog.exp83
-rwxr-xr-xtest/private-lib/eom.exp83
-rwxr-xr-xtest/private-lib/evince.exp83
-rwxr-xr-xtest/private-lib/galculator.exp83
-rwxr-xr-xtest/private-lib/gedit.exp83
-rwxr-xr-xtest/private-lib/gnome-calculator.exp85
-rwxr-xr-xtest/private-lib/gpicview.exp83
-rwxr-xr-xtest/private-lib/leafpad.exp83
-rwxr-xr-xtest/private-lib/mousepad.exp83
-rwxr-xr-xtest/private-lib/pluma.exp83
-rwxr-xr-xtest/private-lib/private-lib.sh20
-rwxr-xr-xtest/private-lib/transmission-gtk.exp83
-rwxr-xr-xtest/private-lib/xcalc.exp83
-rwxr-xr-xtest/utils/audit.exp159
-rwxr-xr-xtest/utils/build.exp91
-rwxr-xr-xtest/utils/utils.sh12
86 files changed, 53 insertions, 8570 deletions
diff --git a/Makefile.in b/Makefile.in
index cbcf252df..c09b1cd4c 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,6 +1,6 @@
1all: apps man filters 1all: apps man filters
2MYLIBS = src/lib 2MYLIBS = src/lib
3APPS = src/firejail src/firemon src/fsec-print src/fsec-optimize src/firecfg src/fnetfilter src/libtrace src/libtracelog src/ftee src/faudit src/fnet src/fseccomp src/fbuilder src/fcopy src/fldd src/libpostexecseccomp 3APPS = src/firejail src/firemon src/fsec-print src/fsec-optimize src/firecfg src/fnetfilter src/libtrace src/libtracelog src/ftee src/fnet src/fseccomp src/fcopy src/libpostexecseccomp
4MANPAGES = firejail.1 firemon.1 firecfg.1 firejail-profile.5 firejail-login.5 firejail-users.5 4MANPAGES = firejail.1 firemon.1 firecfg.1 firejail-profile.5 firejail-login.5 firejail-users.5
5SECCOMP_FILTERS = seccomp seccomp.debug seccomp.32 seccomp.block_secondary seccomp.mdwx 5SECCOMP_FILTERS = seccomp seccomp.debug seccomp.32 seccomp.block_secondary seccomp.mdwx
6 6
@@ -93,12 +93,9 @@ endif
93 install -c -m 0755 src/fshaper/fshaper.sh $(DESTDIR)/$(libdir)/firejail/. 93 install -c -m 0755 src/fshaper/fshaper.sh $(DESTDIR)/$(libdir)/firejail/.
94 94
95 install -c -m 0644 src/firecfg/firecfg.config $(DESTDIR)/$(libdir)/firejail/. 95 install -c -m 0644 src/firecfg/firecfg.config $(DESTDIR)/$(libdir)/firejail/.
96 install -c -m 0755 src/faudit/faudit $(DESTDIR)/$(libdir)/firejail/.
97 install -c -m 0755 src/fnet/fnet $(DESTDIR)/$(libdir)/firejail/. 96 install -c -m 0755 src/fnet/fnet $(DESTDIR)/$(libdir)/firejail/.
98 install -c -m 0755 src/fnetfilter/fnetfilter $(DESTDIR)/$(libdir)/firejail/. 97 install -c -m 0755 src/fnetfilter/fnetfilter $(DESTDIR)/$(libdir)/firejail/.
99 install -c -m 0755 src/fcopy/fcopy $(DESTDIR)/$(libdir)/firejail/. 98 install -c -m 0755 src/fcopy/fcopy $(DESTDIR)/$(libdir)/firejail/.
100 install -c -m 0755 src/fldd/fldd $(DESTDIR)/$(libdir)/firejail/.
101 install -c -m 0755 src/fbuilder/fbuilder $(DESTDIR)/$(libdir)/firejail/.
102ifeq ($(HAVE_SECCOMP),-DHAVE_SECCOMP) 99ifeq ($(HAVE_SECCOMP),-DHAVE_SECCOMP)
103 install -c -m 0755 src/fsec-print/fsec-print $(DESTDIR)/$(libdir)/firejail/. 100 install -c -m 0755 src/fsec-print/fsec-print $(DESTDIR)/$(libdir)/firejail/.
104 install -c -m 0755 src/fsec-optimize/fsec-optimize $(DESTDIR)/$(libdir)/firejail/. 101 install -c -m 0755 src/fsec-optimize/fsec-optimize $(DESTDIR)/$(libdir)/firejail/.
@@ -109,13 +106,6 @@ ifeq ($(HAVE_SECCOMP),-DHAVE_SECCOMP)
109 install -c -m 0644 seccomp.block_secondary $(DESTDIR)/$(libdir)/firejail/. 106 install -c -m 0644 seccomp.block_secondary $(DESTDIR)/$(libdir)/firejail/.
110 install -c -m 0644 seccomp.mdwx $(DESTDIR)/$(libdir)/firejail/. 107 install -c -m 0644 seccomp.mdwx $(DESTDIR)/$(libdir)/firejail/.
111endif 108endif
112ifeq ($(HAVE_CONTRIB_INSTALL),yes)
113 install -c -m 0755 contrib/fix_private-bin.py $(DESTDIR)/$(libdir)/firejail/.
114 install -c -m 0755 contrib/fjclip.py $(DESTDIR)/$(libdir)/firejail/.
115 install -c -m 0755 contrib/fjdisplay.py $(DESTDIR)/$(libdir)/firejail/.
116 install -c -m 0755 contrib/fjresize.py $(DESTDIR)/$(libdir)/firejail/.
117 install -c -m 0755 contrib/fj-mkdeb.py $(DESTDIR)/$(libdir)/firejail/.
118endif
119 # documents 109 # documents
120 install -m 0755 -d $(DESTDIR)/$(DOCDIR) 110 install -m 0755 -d $(DESTDIR)/$(DOCDIR)
121 install -c -m 0644 COPYING $(DESTDIR)/$(DOCDIR)/. 111 install -c -m 0644 COPYING $(DESTDIR)/$(DOCDIR)/.
@@ -165,15 +155,12 @@ install-strip: all
165 strip src/libtracelog/libtracelog.so 155 strip src/libtracelog/libtracelog.so
166 strip src/libpostexecseccomp/libpostexecseccomp.so 156 strip src/libpostexecseccomp/libpostexecseccomp.so
167 strip src/ftee/ftee 157 strip src/ftee/ftee
168 strip src/faudit/faudit
169 strip src/fnet/fnet 158 strip src/fnet/fnet
170 strip src/fnetfilter/fnetfilter 159 strip src/fnetfilter/fnetfilter
171 strip src/fseccomp/fseccomp 160 strip src/fseccomp/fseccomp
172 strip src/fsec-print/fsec-print 161 strip src/fsec-print/fsec-print
173 strip src/fsec-optimize/fsec-optimize 162 strip src/fsec-optimize/fsec-optimize
174 strip src/fcopy/fcopy 163 strip src/fcopy/fcopy
175 strip src/fldd/fldd
176 strip src/fbuilder/fbuilder
177 $(MAKE) realinstall 164 $(MAKE) realinstall
178 165
179uninstall: 166uninstall:
@@ -190,7 +177,7 @@ uninstall:
190 rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firemon 177 rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firemon
191 rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firecfg 178 rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firecfg
192 179
193DISTFILES = "src etc platform contrib configure configure.ac dummy.c Makefile.in install.sh mkman.sh mketc.sh mkdeb.sh COPYING README RELNOTES" 180DISTFILES = "src etc platform configure configure.ac dummy.c Makefile.in install.sh mkman.sh mketc.sh mkdeb.sh COPYING README RELNOTES"
194DISTFILES_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 test/chroot" 181DISTFILES_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 test/chroot"
195 182
196dist: 183dist:
@@ -214,9 +201,6 @@ deb: dist
214snap: all 201snap: all
215 cd platform/snap; ./snap.sh 202 cd platform/snap; ./snap.sh
216 203
217install-snap: snap
218 sudo snap remove faudit; sudo snap install faudit*.snap
219
220test-compile: dist 204test-compile: dist
221 cd test/compile; ./compile.sh $(NAME)-$(VERSION) 205 cd test/compile; ./compile.sh $(NAME)-$(VERSION)
222 206
@@ -242,18 +226,9 @@ scan-build: clean
242test-profiles: 226test-profiles:
243 cd test/profiles; ./profiles.sh | grep TESTING 227 cd test/profiles; ./profiles.sh | grep TESTING
244 228
245test-private-lib:
246 cd test/private-lib; ./private-lib.sh | grep TESTING
247
248test-apps: 229test-apps:
249 cd test/apps; ./apps.sh | grep TESTING 230 cd test/apps; ./apps.sh | grep TESTING
250 231
251test-apps-x11:
252 cd test/apps-x11; ./apps-x11.sh | grep TESTING
253
254test-apps-x11-xorg:
255 cd test/apps-x11-xorg; ./apps-x11-xorg.sh | grep TESTING
256
257test-sysutils: 232test-sysutils:
258 cd test/sysutils; ./sysutils.sh | grep TESTING 233 cd test/sysutils; ./sysutils.sh | grep TESTING
259 234
@@ -280,7 +255,7 @@ test-fcopy:
280test-fnetfilter: 255test-fnetfilter:
281 cd test/fnetfilter; ./fnetfilter.sh | grep TESTING 256 cd test/fnetfilter; ./fnetfilter.sh | grep TESTING
282 257
283test: test-profiles test-private-lib test-fcopy test-fnetfilter test-fs test-utils test-sysutils test-environment test-apps test-apps-x11 test-apps-x11-xorg test-filters test-arguments 258test: test-profiles test-fcopy test-fnetfilter test-fs test-utils test-sysutils test-environment test-apps test-filters test-arguments
284 echo "TEST COMPLETE" 259 echo "TEST COMPLETE"
285 260
286test-travis: test-profiles test-fcopy test-fnetfilter test-fs test-utils test-sysutils test-environment test-filters test-arguments 261test-travis: test-profiles test-fcopy test-fnetfilter test-fs test-utils test-sysutils test-environment test-filters test-arguments
@@ -296,10 +271,6 @@ test-travis: test-profiles test-fcopy test-fnetfilter test-fs test-utils test-sy
296test-ssh: 271test-ssh:
297 cd test/ssh; ./ssh.sh | grep TESTING 272 cd test/ssh; ./ssh.sh | grep TESTING
298 273
299# requires root access
300test-chroot:
301 cd test/chroot; ./chroot.sh | grep testing
302
303# Huge appimage files, not included in "make dist" archive 274# Huge appimage files, not included in "make dist" archive
304test-appimage: 275test-appimage:
305 cd test/appimage; ./appimage.sh | grep TESTING 276 cd test/appimage; ./appimage.sh | grep TESTING
@@ -317,10 +288,6 @@ test-stress:
317test-root: 288test-root:
318 cd test/root; su -c ./root.sh | grep TESTING 289 cd test/root; su -c ./root.sh | grep TESTING
319 290
320# OverlayFS is not available on all platforms
321test-overlay:
322 cd test/overlay; ./overlay.sh | grep TESTING
323
324# For testing hidepid system, the command to set it up is "mount -o remount,rw,hidepid=2 /proc" 291# For testing hidepid system, the command to set it up is "mount -o remount,rw,hidepid=2 /proc"
325 292
326test-all: test-root test-chroot test-network test-appimage test-overlay 293test-all: test-root test-chroot test-network test-appimage test-overlay
diff --git a/configure b/configure
index bad17d97d..bc86756ff 100755
--- a/configure
+++ b/configure
@@ -625,7 +625,6 @@ ac_includes_default="\
625ac_subst_vars='LTLIBOBJS 625ac_subst_vars='LTLIBOBJS
626LIBOBJS 626LIBOBJS
627HAVE_SECCOMP_H 627HAVE_SECCOMP_H
628HAVE_CONTRIB_INSTALL
629HAVE_GCOV 628HAVE_GCOV
630BUSYBOX_WORKAROUND 629BUSYBOX_WORKAROUND
631HAVE_FATAL_WARNINGS 630HAVE_FATAL_WARNINGS
@@ -716,7 +715,6 @@ enable_suid
716enable_fatal_warnings 715enable_fatal_warnings
717enable_busybox_workaround 716enable_busybox_workaround
718enable_gcov 717enable_gcov
719enable_contrib_install
720' 718'
721 ac_precious_vars='build_alias 719 ac_precious_vars='build_alias
722host_alias 720host_alias
@@ -1365,8 +1363,6 @@ Optional Features:
1365 --enable-busybox-workaround 1363 --enable-busybox-workaround
1366 enable busybox workaround 1364 enable busybox workaround
1367 --enable-gcov Gcov instrumentation 1365 --enable-gcov Gcov instrumentation
1368 --enable-contrib-install
1369 install contrib scripts
1370 1366
1371Some influential environment variables: 1367Some influential environment variables:
1372 CC C compiler command 1368 CC C compiler command
@@ -3776,20 +3772,6 @@ if test "x$enable_gcov" = "xyes"; then :
3776 3772
3777fi 3773fi
3778 3774
3779HAVE_CONTRIB_INSTALL="yes"
3780# Check whether --enable-contrib-install was given.
3781if test "${enable_contrib_install+set}" = set; then :
3782 enableval=$enable_contrib_install;
3783fi
3784
3785if test "x$enable_contrib_install" = "xno"; then :
3786 HAVE_CONTRIB_INSTALL="no"
3787else
3788 HAVE_CONTRIB_INSTALL="yes"
3789
3790fi
3791
3792
3793# checking pthread library 3775# checking pthread library
3794{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpthread" >&5 3776{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpthread" >&5
3795$as_echo_n "checking for main in -lpthread... " >&6; } 3777$as_echo_n "checking for main in -lpthread... " >&6; }
@@ -3855,7 +3837,7 @@ if test "$prefix" = /usr; then
3855 sysconfdir="/etc" 3837 sysconfdir="/etc"
3856fi 3838fi
3857 3839
3858ac_config_files="$ac_config_files Makefile src/common.mk src/lib/Makefile src/fcopy/Makefile src/fnet/Makefile src/firejail/Makefile src/fnetfilter/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/fbuilder/Makefile src/fsec-print/Makefile src/ftee/Makefile src/faudit/Makefile src/fseccomp/Makefile src/fldd/Makefile src/libpostexecseccomp/Makefile src/fsec-optimize/Makefile" 3840ac_config_files="$ac_config_files Makefile src/common.mk src/lib/Makefile src/fcopy/Makefile src/fnet/Makefile src/firejail/Makefile src/fnetfilter/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/fsec-print/Makefile src/ftee/Makefile src/fseccomp/Makefile src/libpostexecseccomp/Makefile src/fsec-optimize/Makefile"
3859 3841
3860cat >confcache <<\_ACEOF 3842cat >confcache <<\_ACEOF
3861# This file is a shell script that caches the results of configure 3843# This file is a shell script that caches the results of configure
@@ -4575,12 +4557,9 @@ do
4575 "src/libtrace/Makefile") CONFIG_FILES="$CONFIG_FILES src/libtrace/Makefile" ;; 4557 "src/libtrace/Makefile") CONFIG_FILES="$CONFIG_FILES src/libtrace/Makefile" ;;
4576 "src/libtracelog/Makefile") CONFIG_FILES="$CONFIG_FILES src/libtracelog/Makefile" ;; 4558 "src/libtracelog/Makefile") CONFIG_FILES="$CONFIG_FILES src/libtracelog/Makefile" ;;
4577 "src/firecfg/Makefile") CONFIG_FILES="$CONFIG_FILES src/firecfg/Makefile" ;; 4559 "src/firecfg/Makefile") CONFIG_FILES="$CONFIG_FILES src/firecfg/Makefile" ;;
4578 "src/fbuilder/Makefile") CONFIG_FILES="$CONFIG_FILES src/fbuilder/Makefile" ;;
4579 "src/fsec-print/Makefile") CONFIG_FILES="$CONFIG_FILES src/fsec-print/Makefile" ;; 4560 "src/fsec-print/Makefile") CONFIG_FILES="$CONFIG_FILES src/fsec-print/Makefile" ;;
4580 "src/ftee/Makefile") CONFIG_FILES="$CONFIG_FILES src/ftee/Makefile" ;; 4561 "src/ftee/Makefile") CONFIG_FILES="$CONFIG_FILES src/ftee/Makefile" ;;
4581 "src/faudit/Makefile") CONFIG_FILES="$CONFIG_FILES src/faudit/Makefile" ;;
4582 "src/fseccomp/Makefile") CONFIG_FILES="$CONFIG_FILES src/fseccomp/Makefile" ;; 4562 "src/fseccomp/Makefile") CONFIG_FILES="$CONFIG_FILES src/fseccomp/Makefile" ;;
4583 "src/fldd/Makefile") CONFIG_FILES="$CONFIG_FILES src/fldd/Makefile" ;;
4584 "src/libpostexecseccomp/Makefile") CONFIG_FILES="$CONFIG_FILES src/libpostexecseccomp/Makefile" ;; 4563 "src/libpostexecseccomp/Makefile") CONFIG_FILES="$CONFIG_FILES src/libpostexecseccomp/Makefile" ;;
4585 "src/fsec-optimize/Makefile") CONFIG_FILES="$CONFIG_FILES src/fsec-optimize/Makefile" ;; 4564 "src/fsec-optimize/Makefile") CONFIG_FILES="$CONFIG_FILES src/fsec-optimize/Makefile" ;;
4586 4565
@@ -5061,6 +5040,5 @@ echo " EXTRA_LDFLAGS: $EXTRA_LDFLAGS"
5061echo " EXTRA_CFLAGS: $EXTRA_CFLAGS" 5040echo " EXTRA_CFLAGS: $EXTRA_CFLAGS"
5062echo " fatal warnings: $HAVE_FATAL_WARNINGS" 5041echo " fatal warnings: $HAVE_FATAL_WARNINGS"
5063echo " Gcov instrumentation: $HAVE_GCOV" 5042echo " Gcov instrumentation: $HAVE_GCOV"
5064echo " Install contrib scripts: $HAVE_CONTRIB_INSTALL"
5065echo " Install as a SUID executable: $HAVE_SUID" 5043echo " Install as a SUID executable: $HAVE_SUID"
5066echo 5044echo
diff --git a/configure.ac b/configure.ac
index ea569eb2f..9dc01bc8f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -178,15 +178,6 @@ AS_IF([test "x$enable_gcov" = "xyes"], [
178 AC_SUBST(HAVE_GCOV) 178 AC_SUBST(HAVE_GCOV)
179]) 179])
180 180
181HAVE_CONTRIB_INSTALL="yes"
182AC_ARG_ENABLE([contrib-install],
183 AS_HELP_STRING([--enable-contrib-install], [install contrib scripts]))
184AS_IF([test "x$enable_contrib_install" = "xno"],
185 [HAVE_CONTRIB_INSTALL="no"],
186 [HAVE_CONTRIB_INSTALL="yes"]
187)
188AC_SUBST(HAVE_CONTRIB_INSTALL)
189
190# checking pthread library 181# checking pthread library
191AC_CHECK_LIB([pthread], [main], [], AC_MSG_ERROR([*** POSIX thread support not installed ***])) 182AC_CHECK_LIB([pthread], [main], [], AC_MSG_ERROR([*** POSIX thread support not installed ***]))
192AC_CHECK_HEADER(pthread.h,,AC_MSG_ERROR([*** POSIX thread support not installed ***])) 183AC_CHECK_HEADER(pthread.h,,AC_MSG_ERROR([*** POSIX thread support not installed ***]))
@@ -199,8 +190,8 @@ if test "$prefix" = /usr; then
199fi 190fi
200 191
201AC_OUTPUT(Makefile src/common.mk src/lib/Makefile src/fcopy/Makefile src/fnet/Makefile src/firejail/Makefile src/fnetfilter/Makefile \ 192AC_OUTPUT(Makefile src/common.mk src/lib/Makefile src/fcopy/Makefile src/fnet/Makefile src/firejail/Makefile src/fnetfilter/Makefile \
202src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/fbuilder/Makefile src/fsec-print/Makefile \ 193src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/fsec-print/Makefile \
203src/ftee/Makefile src/faudit/Makefile src/fseccomp/Makefile src/fldd/Makefile src/libpostexecseccomp/Makefile src/fsec-optimize/Makefile) 194src/ftee/Makefile src/fseccomp/Makefile src/libpostexecseccomp/Makefile src/fsec-optimize/Makefile)
204 195
205echo 196echo
206echo "Configuration options:" 197echo "Configuration options:"
@@ -225,6 +216,5 @@ echo " EXTRA_LDFLAGS: $EXTRA_LDFLAGS"
225echo " EXTRA_CFLAGS: $EXTRA_CFLAGS" 216echo " EXTRA_CFLAGS: $EXTRA_CFLAGS"
226echo " fatal warnings: $HAVE_FATAL_WARNINGS" 217echo " fatal warnings: $HAVE_FATAL_WARNINGS"
227echo " Gcov instrumentation: $HAVE_GCOV" 218echo " Gcov instrumentation: $HAVE_GCOV"
228echo " Install contrib scripts: $HAVE_CONTRIB_INSTALL"
229echo " Install as a SUID executable: $HAVE_SUID" 219echo " Install as a SUID executable: $HAVE_SUID"
230echo 220echo
diff --git a/contrib/fix_private-bin.py b/contrib/fix_private-bin.py
deleted file mode 100755
index 86fd3d16b..000000000
--- a/contrib/fix_private-bin.py
+++ /dev/null
@@ -1,157 +0,0 @@
1#!/usr/bin/python3
2
3__author__ = "KOLANICH"
4__copyright__ = """This is free and unencumbered software released into the public domain.
5
6Anyone is free to copy, modify, publish, use, compile, sell, or
7distribute this software, either in source code form or as a compiled
8binary, for any purpose, commercial or non-commercial, and by any
9means.
10
11In jurisdictions that recognize copyright laws, the author or authors
12of this software dedicate any and all copyright interest in the
13software to the public domain. We make this dedication for the benefit
14of the public at large and to the detriment of our heirs and
15successors. We intend this dedication to be an overt act of
16relinquishment in perpetuity of all present and future rights to this
17software under copyright law.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25OTHER DEALINGS IN THE SOFTWARE.
26
27For more information, please refer to <http://unlicense.org/>"""
28__license__ = "Unlicense"
29
30import sys, os, glob, re
31
32privRx=re.compile("^(?:#\s*)?private-bin")
33
34def fixSymlinkedBins(files, replMap):
35 """
36 Used to add filenames to private-bin directives of files if the ones present are mentioned in replMap
37 replMap is a dict where key is the marker filename and value is the filename to add
38 """
39
40 rxs=dict()
41 for (old,new) in replMap.items():
42 rxs[old]=re.compile("\\b"+old+"\\b")
43 rxs[new]=re.compile("\\b"+new+"\\b")
44 #print(rxs)
45
46 for filename in files:
47 lines=None
48 with open(filename,"r") as file:
49 lines=file.readlines()
50
51 shouldUpdate=False
52 for (i,line) in enumerate(lines):
53 if privRx.search(line):
54 for (old,new) in replMap.items():
55 if rxs[old].search(line) and not rxs[new].search(line):
56 lines[i]=rxs[old].sub(old+","+new, line)
57 shouldUpdate=True
58 print(lines[i])
59
60 if shouldUpdate:
61 with open(filename,"w") as file:
62 file.writelines(lines)
63 pass
64
65def createSetOfBinaries(files):
66 """
67 Creates a set of binaries mentioned in private-bin directives of files.
68 """
69 s=set()
70 for filename in files:
71 lines=None
72 with open(filename,"r") as file:
73 for line in file:
74 if privRx.search(line):
75 bins=line.split(",")
76 bins[0]=bins[0].split(" ")[-1]
77 bins = [n.strip() for n in bins]
78 s=s|set(bins)
79 return s
80
81def createSymlinkTable(binDirs, binariesSet):
82 """
83 creates a dict of symlinked binaries in the system where a key is a symlink name and value is a symlinked binary.
84 binDirs are folders to look into for binaries symlinks
85 binariesSet is a set of binaries to be checked if they are actually a symlinks
86 """
87 m=dict()
88 toProcess=binariesSet
89 while len(toProcess)!=0:
90 additional=set()
91 for sh in toProcess:
92 for bD in binDirs:
93 p=bD+os.path.sep+sh
94 if os.path.exists(p):
95 if os.path.islink(p):
96 m[sh]=os.readlink(p)
97 additional.add(m[sh].split(" ")[0])
98 else:
99 pass
100 break
101 toProcess=additional
102 return m
103
104def doTheFixes(profilesPath, binDirs):
105 """
106 Fixes private-bin in .profiles for firejail. The pipeline is as follows:
107 discover files -> discover mentioned binaries ->
108 discover the ones which are symlinks ->
109 make a look-up table for fix ->
110 filter the ones can be fixed (we cannot fix the ones which are not in directories for binaries) ->
111 apply fix
112 """
113 files=glob.glob(profilesPath+os.path.sep+"*.profile")
114 bins=createSetOfBinaries(files)
115 #print("The binaries used are:")
116 #print(bins)
117 stbl=createSymlinkTable(binDirs,bins)
118 print("The replacement table is:")
119 print(stbl)
120 stbl={a[0]:a[1] for a in stbl.items() if a[0].find(os.path.sep) < 0 and a[1].find(os.path.sep)<0}
121 print("Filtered replacement table is:")
122 print(stbl)
123 fixSymlinkedBins(files,stbl)
124
125def printHelp():
126 print("python3 "+os.path.basename(__file__)+" <dir with .profile files>\nThe default dir is "+defaultProfilesPath+"\n"+doTheFixes.__doc__)
127
128def main():
129 """The main function. Parses the commandline args, shows messages and calles the function actually doing the work."""
130 print(repr(sys.argv))
131 defaultProfilesPath="../etc"
132 if len(sys.argv)>2 or (len(sys.argv)==2 and (sys.argv[1] == '-h' or sys.argv[1] == '--help') ):
133 printHelp()
134 exit(1)
135
136 profilesPath=None
137 if len(sys.argv)==2:
138 if os.path.isdir(sys.argv[1]):
139 profilesPath=os.path.abspath(sys.argv[1])
140 else:
141 if os.path.exists(sys.argv[1]):
142 print(sys.argv[1]+" is not a dir")
143 else:
144 print(sys.argv[1]+" does not exist")
145 printHelp()
146 exit(1)
147 else:
148 print("Using default profiles dir: " + defaultProfilesPath)
149 profilesPath=defaultProfilesPath
150
151 binDirs=["/bin","/usr/bin","/usr/sbin","/usr/local/bin","/usr/local/sbin"]
152 print("Binaries dirs are:")
153 print(binDirs)
154 doTheFixes(profilesPath, binDirs)
155
156if __name__ == "__main__":
157 main()
diff --git a/contrib/fj-mkdeb.py b/contrib/fj-mkdeb.py
deleted file mode 100755
index 3cc13b758..000000000
--- a/contrib/fj-mkdeb.py
+++ /dev/null
@@ -1,74 +0,0 @@
1#!/usr/bin/env python3
2
3# This script is automate the workaround for https://github.com/netblue30/firejail/issues/772
4
5import os, re, shlex, subprocess, sys
6
7def run(srcdir, args):
8 if srcdir: os.chdir(srcdir)
9
10 dry_run=False
11 escaped_args=[]
12 # We need to modify the list as we go. So be sure to copy the list to be iterated!
13 for a in args[:]:
14 if a.startswith('--prefix'):
15 # prefix should ALWAYS be /usr here. Discard user-set values
16 args.remove(a)
17 elif a == '--only-fix-mkdeb':
18 # for us, not configure
19 dry_run=True
20 args.remove(a)
21 else:
22 escaped_args.append(shlex.quote(a))
23
24 # Fix up mkdeb.sh to include custom configure options.
25 with open('mkdeb.sh', 'rb') as f:
26 sh=str(f.read(), 'utf_8')
27 rx=re.compile(r'^\./configure\s.*$', re.M)
28 with open('mkdeb.sh', 'wb') as f:
29 f.write(bytes(rx.sub('./configure --prefix=/usr '+(' '.join(escaped_args)), sh), 'utf_8'))
30
31 if dry_run: return 0
32
33 # now run configure && make
34 if subprocess.call(['./configure', '--prefix=/usr']+args) == 0:
35 subprocess.call(['make', 'deb'])
36
37 return 0
38
39
40if __name__ == '__main__':
41 if len(sys.argv) == 2 and sys.argv[1] == '--help':
42 print('''Build a .deb of firejail with custom configure options
43
44usage:
45{script} [--fj-src=SRCDIR] [--only-fix-mkdeb] [CONFIGURE_OPTIONS [...]]
46
47 --fj-src=SRCDIR: manually specify the location of firejail source tree
48 as SRCDIR. If not specified, looks in the parent directory
49 of the directory where this script is located, and then the
50 current working directory, in that order.
51 --only-fix-mkdeb: don't run configure or make after modifying mkdeb.sh
52 CONFIGURE_OPTIONS: arguments for configure
53'''.format(script=sys.argv[0]))
54 sys.exit(0)
55 else:
56 # Find the source directory
57 srcdir=None
58 args=sys.argv[1:]
59 for a in args:
60 if a.startswith('--fj-src='):
61 args.remove(a)
62 srcdir=a[9:]
63 break
64 if not(srcdir):
65 # srcdir not manually specified, try to auto-detect
66 srcdir=os.path.dirname(os.path.abspath(sys.argv[0]+'/..'))
67 if not(os.path.isfile(srcdir+'/mkdeb.sh')):
68 # Script is probably installed. Check the cwd.
69 if os.path.isfile('./mkdeb.sh'):
70 srcdir=None
71 else:
72 print('Error: Could not find the firejail source tree. Exiting.')
73 sys.exit(1)
74 sys.exit(run(srcdir, args))
diff --git a/contrib/fjclip.py b/contrib/fjclip.py
deleted file mode 100755
index b45959841..000000000
--- a/contrib/fjclip.py
+++ /dev/null
@@ -1,35 +0,0 @@
1#!/usr/bin/env python
2
3import re
4import sys
5import subprocess
6import fjdisplay
7
8usage = """fjclip.py src dest. src or dest can be named firejails or - for stdin or stdout.
9firemon --x11 to see available running x11 firejails. firejail names can be shortened
10to least ambiguous. for example 'work-libreoffice' can be shortened to 'work' if no
11other firejails name starts with 'work'.
12warning: browsers are dangerous. clipboards from browsers are dangerous. see
13https://github.com/dxa4481/Pastejacking
14fjclip.py strips whitespace from both
15ends, but does nothing else to protect you. use a simple gui text editor like
16gedit if you want to see what your pasting."""
17
18if len(sys.argv) != 3 or sys.argv == '-h' or sys.argv == '--help':
19 print(usage)
20 exit(1)
21
22if sys.argv[1] == '-':
23 clipin_raw = sys.stdin.read()
24else:
25 display = fjdisplay.getdisplay(sys.argv[1])
26 clipin_raw = subprocess.check_output(['xsel','-b','--display',display])
27
28clipin = clipin_raw.strip()
29
30if sys.argv[2] == '-':
31 print(clipin)
32else:
33 display = fjdisplay.getdisplay(sys.argv[2])
34 clipout = subprocess.Popen(['xsel','-b','-i','--display',display],stdin=subprocess.PIPE)
35 clipout.communicate(clipin)
diff --git a/contrib/fjdisplay.py b/contrib/fjdisplay.py
deleted file mode 100755
index 3f409545f..000000000
--- a/contrib/fjdisplay.py
+++ /dev/null
@@ -1,43 +0,0 @@
1#!/usr/bin/env python
2
3import re
4import sys
5import subprocess
6
7usage = """fjdisplay.py name-of-firejail
8returns the display in the form of ':NNN'
9"""
10
11def getfirejails():
12 output = subprocess.check_output(['firemon','--x11'])
13 firejails = {}
14 name = ''
15 for line in output.split('\n'):
16 namematch = re.search('--name=(\w+\S*)',line)
17 if namematch:
18 name = namematch.group(1)
19 displaymatch = re.search('DISPLAY (:\d+)',line)
20 if displaymatch:
21 firejails[name] = displaymatch.group(1)
22 return firejails
23
24def getdisplay(name):
25 firejails = getfirejails()
26 fjlist = '\n'.join(firejails.keys())
27 namere = re.compile('^'+name+'.*', re.MULTILINE)
28 matchingjails = namere.findall(fjlist)
29 if len(matchingjails) == 1:
30 return firejails[matchingjails[0]]
31 if len(matchingjails) == 0:
32 raise NameError("firejail {} does not exist".format(name))
33 else:
34 raise NameError("ambiguous firejail name")
35
36if __name__ == '__main__':
37 if '-h' in sys.argv or '--help' in sys.argv or len(sys.argv) > 2:
38 print(usage)
39 exit()
40 if len(sys.argv) == 1:
41 print(getfirejails())
42 if len(sys.argv) == 2:
43 print (getdisplay(sys.argv[1]))
diff --git a/contrib/fjresize.py b/contrib/fjresize.py
deleted file mode 100755
index 3997cf280..000000000
--- a/contrib/fjresize.py
+++ /dev/null
@@ -1,25 +0,0 @@
1#!/usr/bin/env python
2
3import sys
4import fjdisplay
5import subprocess
6
7usage = """usage: fjresize.py firejail-name displaysize
8resize firejail xephyr windows.
9fjdisplay.py with no other arguments will list running named firejails with displays.
10fjresize.py with only a firejail name will list valid resolutions.
11names can be shortend as long its unambiguous.
12note: you may need to move the xephyr window for the resize to take effect
13example:
14 fjresize.py browser 1280x800
15"""
16
17
18if len(sys.argv) == 2:
19 out = subprocess.check_output(['xrandr','--display',fjdisplay.getdisplay(sys.argv[1])])
20 print(out)
21elif len(sys.argv) == 3:
22 out = subprocess.check_output(['xrandr','--display',fjdisplay.getdisplay(sys.argv[1]),'--output','default','--mode',sys.argv[2]])
23 print(out)
24else:
25 print(usage)
diff --git a/contrib/update_deb.sh b/contrib/update_deb.sh
deleted file mode 100755
index fa1b2d692..000000000
--- a/contrib/update_deb.sh
+++ /dev/null
@@ -1,12 +0,0 @@
1#!/bin/sh
2# Purpose: Fetch, compile, and install firejail from GitHub source. For
3# Debian-based distros only (Ubuntu, Mint, etc).
4set -e
5git clone --depth=1 https://github.com/netblue30/firejail.git
6cd firejail
7./configure --prefix=/usr
8make deb
9sudo dpkg -i firejail*.deb
10echo "Firejail was updated!"
11cd ..
12rm -rf firejail
diff --git a/src/faudit/Makefile.in b/src/faudit/Makefile.in
deleted file mode 100644
index 26df0fe51..000000000
--- a/src/faudit/Makefile.in
+++ /dev/null
@@ -1,14 +0,0 @@
1all: faudit
2
3include ../common.mk
4
5%.o : %.c $(H_FILE_LIST)
6 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@
7
8faudit: $(OBJS)
9 $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTRA_LDFLAGS)
10
11clean:; rm -f *.o faudit *.gcov *.gcda *.gcno
12
13distclean: clean
14 rm -fr Makefile
diff --git a/src/faudit/caps.c b/src/faudit/caps.c
deleted file mode 100644
index 46c262c89..000000000
--- a/src/faudit/caps.c
+++ /dev/null
@@ -1,78 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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}
diff --git a/src/faudit/dbus.c b/src/faudit/dbus.c
deleted file mode 100644
index cb08b9b0b..000000000
--- a/src/faudit/dbus.c
+++ /dev/null
@@ -1,92 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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}
diff --git a/src/faudit/dev.c b/src/faudit/dev.c
deleted file mode 100644
index 7bf4b279c..000000000
--- a/src/faudit/dev.c
+++ /dev/null
@@ -1,47 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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
deleted file mode 100644
index 180121ec1..000000000
--- a/src/faudit/faudit.h
+++ /dev/null
@@ -1,68 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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
deleted file mode 100644
index 1ba18f2ab..000000000
--- a/src/faudit/files.c
+++ /dev/null
@@ -1,75 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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
deleted file mode 100644
index d73986843..000000000
--- a/src/faudit/main.c
+++ /dev/null
@@ -1,98 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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") == 0) {
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
deleted file mode 100644
index 54eef2b2a..000000000
--- a/src/faudit/network.c
+++ /dev/null
@@ -1,101 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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
deleted file mode 100644
index 22bb68c1a..000000000
--- a/src/faudit/pid.c
+++ /dev/null
@@ -1,99 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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
deleted file mode 100644
index 85a883618..000000000
--- a/src/faudit/seccomp.c
+++ /dev/null
@@ -1,101 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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 allowed.\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
deleted file mode 100644
index 3650590f3..000000000
--- a/src/faudit/syscall.c
+++ /dev/null
@@ -1,105 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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 (argc < 3)
38 return;
39
40 if (strcmp(argv[2], "mount") == 0) {
41 int rv = mount(NULL, NULL, NULL, 0, NULL);
42 (void) rv;
43 printf("\nUGLY: mount syscall permitted.\n");
44 }
45 else if (strcmp(argv[2], "umount2") == 0) {
46 umount2(NULL, 0);
47 printf("\nUGLY: umount2 syscall permitted.\n");
48 }
49 else if (strcmp(argv[2], "ptrace") == 0) {
50 ptrace(0, 0, NULL, NULL);
51 printf("\nUGLY: ptrace syscall permitted.\n");
52 }
53 else if (strcmp(argv[2], "swapon") == 0) {
54 swapon(NULL, 0);
55 printf("\nUGLY: swapon syscall permitted.\n");
56 }
57 else if (strcmp(argv[2], "swapoff") == 0) {
58 swapoff(NULL);
59 printf("\nUGLY: swapoff syscall permitted.\n");
60 }
61 else if (strcmp(argv[2], "init_module") == 0) {
62 init_module(NULL, 0, NULL);
63 printf("\nUGLY: init_module syscall permitted.\n");
64 }
65 else if (strcmp(argv[2], "delete_module") == 0) {
66 delete_module(NULL, 0);
67 printf("\nUGLY: delete_module syscall permitted.\n");
68 }
69 else if (strcmp(argv[2], "chroot") == 0) {
70 int rv = chroot("/blablabla-57281292");
71 (void) rv;
72 printf("\nUGLY: chroot syscall permitted.\n");
73 }
74 else if (strcmp(argv[2], "pivot_root") == 0) {
75 pivot_root(NULL, NULL);
76 printf("\nUGLY: pivot_root syscall permitted.\n");
77 }
78#if defined(__i386__) || defined(__x86_64__)
79 else if (strcmp(argv[2], "iopl") == 0) {
80 iopl(0L);
81 printf("\nUGLY: iopl syscall permitted.\n");
82 }
83 else if (strcmp(argv[2], "ioperm") == 0) {
84 ioperm(0, 0, 0);
85 printf("\nUGLY: ioperm syscall permitted.\n");
86 }
87#endif
88 exit(0);
89}
90
91void syscall_run(const char *name) {
92 assert(prog);
93
94 pid_t child = fork();
95 if (child < 0)
96 errExit("fork");
97 if (child == 0) {
98 execl(prog, prog, "syscall", name, NULL);
99 perror("execl");
100 _exit(1);
101 }
102
103 // wait for the child to finish
104 waitpid(child, NULL, 0);
105}
diff --git a/src/faudit/x11.c b/src/faudit/x11.c
deleted file mode 100644
index bb763b110..000000000
--- a/src/faudit/x11.c
+++ /dev/null
@@ -1,63 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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/fbuilder/Makefile.in b/src/fbuilder/Makefile.in
deleted file mode 100644
index 7a606c872..000000000
--- a/src/fbuilder/Makefile.in
+++ /dev/null
@@ -1,14 +0,0 @@
1all: fbuilder
2
3include ../common.mk
4
5%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/syscall.h
6 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@
7
8fbuilder: $(OBJS)
9 $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTRA_LDFLAGS)
10
11clean:; rm -f *.o fbuilder *.gcov *.gcda *.gcno
12
13distclean: clean
14 rm -fr Makefile
diff --git a/src/fbuilder/build_bin.c b/src/fbuilder/build_bin.c
deleted file mode 100644
index 1230fb780..000000000
--- a/src/fbuilder/build_bin.c
+++ /dev/null
@@ -1,126 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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 "fbuilder.h"
21
22static FileDB *bin_out = NULL;
23
24static void process_bin(const char *fname) {
25 assert(fname);
26
27 // process trace file
28 FILE *fp = fopen(fname, "r");
29 if (!fp) {
30 fprintf(stderr, "Error: cannot open %s\n", fname);
31 exit(1);
32 }
33
34 char buf[MAX_BUF];
35 while (fgets(buf, MAX_BUF, fp)) {
36 // remove \n
37 char *ptr = strchr(buf, '\n');
38 if (ptr)
39 *ptr = '\0';
40
41 // parse line: 4:galculator:access /etc/fonts/conf.d:0
42 // number followed by :
43 ptr = buf;
44 if (!isdigit(*ptr))
45 continue;
46 while (isdigit(*ptr))
47 ptr++;
48 if (*ptr != ':')
49 continue;
50 ptr++;
51
52 // next :
53 ptr = strchr(ptr, ':');
54 if (!ptr)
55 continue;
56 ptr++;
57 if (strncmp(ptr, "exec ", 5) == 0)
58 ptr += 5;
59 else
60 continue;
61 if (strncmp(ptr, "/bin/", 5) == 0)
62 ptr += 5;
63 else if (strncmp(ptr, "/sbin/", 6) == 0)
64 ptr += 6;
65 else if (strncmp(ptr, "/usr/bin/", 9) == 0)
66 ptr += 9;
67 else if (strncmp(ptr, "/usr/sbin/", 10) == 0)
68 ptr += 10;
69 else if (strncmp(ptr, "/usr/local/bin/", 15) == 0)
70 ptr += 15;
71 else if (strncmp(ptr, "/usr/local/sbin/", 16) == 0)
72 ptr += 16;
73 else if (strncmp(ptr, "/usr/games/", 11) == 0)
74 ptr += 12;
75 else if (strncmp(ptr, "/usr/local/games/", 17) == 0)
76 ptr += 17;
77 else
78 continue;
79
80 // end of filename
81 char *ptr2 = strchr(ptr, ':');
82 if (!ptr2)
83 continue;
84 *ptr2 = '\0';
85
86 // skip strace
87 if (strcmp(ptr, "strace") == 0)
88 continue;
89
90 bin_out = filedb_add(bin_out, ptr);
91 }
92
93 fclose(fp);
94}
95
96
97// process fname, fname.1, fname.2, fname.3, fname.4, fname.5
98void build_bin(const char *fname, FILE *fp) {
99 assert(fname);
100
101 // run fname
102 process_bin(fname);
103
104 // run all the rest
105 struct stat s;
106 int i;
107 for (i = 1; i <= 5; i++) {
108 char *newname;
109 if (asprintf(&newname, "%s.%d", fname, i) == -1)
110 errExit("asprintf");
111 if (stat(newname, &s) == 0)
112 process_bin(newname);
113 free(newname);
114 }
115
116 if (bin_out) {
117 fprintf(fp, "private-bin ");
118 FileDB *ptr = bin_out;
119 while (ptr) {
120 fprintf(fp, "%s,", ptr->fname);
121 ptr = ptr->next;
122 }
123 fprintf(fp, "\n");
124 fprintf(fp, "# private-lib\n");
125 }
126}
diff --git a/src/fbuilder/build_fs.c b/src/fbuilder/build_fs.c
deleted file mode 100644
index 771dc94cb..000000000
--- a/src/fbuilder/build_fs.c
+++ /dev/null
@@ -1,317 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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 "fbuilder.h"
22
23// common file processing function, using the callback for each line in the file
24static void process_file(const char *fname, const char *dir, void (*callback)(char *)) {
25 assert(fname);
26 assert(dir);
27 assert(callback);
28
29 int dir_len = strlen(dir);
30
31 // process trace file
32 FILE *fp = fopen(fname, "r");
33 if (!fp) {
34 fprintf(stderr, "Error: cannot open %s\n", fname);
35 exit(1);
36 }
37
38 char buf[MAX_BUF];
39 while (fgets(buf, MAX_BUF, fp)) {
40 // remove \n
41 char *ptr = strchr(buf, '\n');
42 if (ptr)
43 *ptr = '\0';
44
45 // parse line: 4:galculator:access /etc/fonts/conf.d:0
46 // number followed by :
47 ptr = buf;
48 if (!isdigit(*ptr))
49 continue;
50 while (isdigit(*ptr))
51 ptr++;
52 if (*ptr != ':')
53 continue;
54 ptr++;
55
56 // next :
57 ptr = strchr(ptr, ':');
58 if (!ptr)
59 continue;
60 ptr++;
61 if (strncmp(ptr, "access ", 7) == 0)
62 ptr += 7;
63 else if (strncmp(ptr, "fopen ", 6) == 0)
64 ptr += 6;
65 else if (strncmp(ptr, "fopen64 ", 8) == 0)
66 ptr += 8;
67 else if (strncmp(ptr, "open64 ", 7) == 0)
68 ptr += 7;
69 else if (strncmp(ptr, "open ", 5) == 0)
70 ptr += 5;
71 else
72 continue;
73 if (strncmp(ptr, dir, dir_len) != 0)
74 continue;
75
76 // end of filename
77 char *ptr2 = strchr(ptr, ':');
78 if (!ptr2)
79 continue;
80 *ptr2 = '\0';
81
82 callback(ptr);
83 }
84
85 fclose(fp);
86}
87
88// process fname, fname.1, fname.2, fname.3, fname.4, fname.5
89static void process_files(const char *fname, const char *dir, void (*callback)(char *)) {
90 assert(fname);
91 assert(dir);
92 assert(callback);
93
94 // run fname
95 process_file(fname, dir, callback);
96
97 // run all the rest
98 struct stat s;
99 int i;
100 for (i = 1; i <= 5; i++) {
101 char *newname;
102 if (asprintf(&newname, "%s.%d", fname, i) == -1)
103 errExit("asprintf");
104 if (stat(newname, &s) == 0)
105 process_file(newname, dir, callback);
106 free(newname);
107 }
108}
109
110//*******************************************
111// etc directory
112//*******************************************
113static FileDB *etc_out = NULL;
114
115static void etc_callback(char *ptr) {
116 // skip firejail directory
117 if (strncmp(ptr, "/etc/firejail", 13) == 0)
118 return;
119
120 // add only top files and directories
121 ptr += 5; // skip "/etc/"
122 char *end = strchr(ptr, '/');
123 if (end)
124 *end = '\0';
125 etc_out = filedb_add(etc_out, ptr);
126}
127
128void build_etc(const char *fname, FILE *fp) {
129 assert(fname);
130
131 process_files(fname, "/etc", etc_callback);
132
133 fprintf(fp, "private-etc ");
134 if (etc_out == NULL)
135 fprintf(fp, "none\n");
136 else {
137 FileDB *ptr = etc_out;
138 while (ptr) {
139 fprintf(fp, "%s,", ptr->fname);
140 ptr = ptr->next;
141 }
142 fprintf(fp, "\n");
143 }
144}
145
146//*******************************************
147// var directory
148//*******************************************
149static FileDB *var_out = NULL;
150static void var_callback(char *ptr) {
151 if (strcmp(ptr, "/var/lib") == 0)
152 ;
153 else if (strcmp(ptr, "/var/cache") == 0)
154 ;
155 else if (strncmp(ptr, "/var/lib/menu-xdg", 17) == 0)
156 var_out = filedb_add(var_out, "/var/lib/menu-xdg");
157 else if (strncmp(ptr, "/var/cache/fontconfig", 21) == 0)
158 var_out = filedb_add(var_out, "/var/cache/fontconfig");
159 else
160 var_out = filedb_add(var_out, ptr);
161}
162
163void build_var(const char *fname, FILE *fp) {
164 assert(fname);
165
166 process_files(fname, "/var", var_callback);
167
168 if (var_out == NULL)
169 fprintf(fp, "blacklist /var\n");
170 else
171 filedb_print(var_out, "whitelist ", fp);
172}
173
174
175//*******************************************
176// usr/share directory
177//*******************************************
178static FileDB *share_out = NULL;
179static void share_callback(char *ptr) {
180 // extract the directory:
181 assert(strncmp(ptr, "/usr/share", 10) == 0);
182 char *p1 = ptr + 10;
183 if (*p1 != '/')
184 return;
185 p1++;
186 if (*p1 == '/') // double '/'
187 p1++;
188 if (*p1 == '\0')
189 return;
190
191 // "/usr/share/bash-completion/bash_completion" becomes "/usr/share/bash-completion"
192 char *p2 = strchr(p1, '/');
193 if (p2)
194 *p2 = '\0';
195
196 // store the file
197 share_out = filedb_add(share_out, ptr);
198}
199
200void build_share(const char *fname, FILE *fp) {
201 assert(fname);
202
203 process_files(fname, "/usr/share", share_callback);
204
205 if (share_out == NULL)
206 fprintf(fp, "blacklist /usr/share\n");
207 else
208 filedb_print(share_out, "whitelist ", fp);
209}
210
211//*******************************************
212// tmp directory
213//*******************************************
214static FileDB *tmp_out = NULL;
215static void tmp_callback(char *ptr) {
216 filedb_add(tmp_out, ptr);
217}
218
219void build_tmp(const char *fname, FILE *fp) {
220 assert(fname);
221
222 process_files(fname, "/tmp", tmp_callback);
223
224 if (tmp_out == NULL)
225 fprintf(fp, "private-tmp\n");
226 else {
227 fprintf(fp, "\n");
228 fprintf(fp, "# private-tmp\n");
229 fprintf(fp, "# File accessed in /tmp directory:\n");
230 fprintf(fp, "# ");
231 FileDB *ptr = tmp_out;
232 while (ptr) {
233 fprintf(fp, "%s,", ptr->fname);
234 ptr = ptr->next;
235 }
236 printf("\n");
237 }
238}
239
240//*******************************************
241// dev directory
242//*******************************************
243static char *dev_skip[] = {
244 "/dev/zero",
245 "/dev/null",
246 "/dev/full",
247 "/dev/random",
248 "/dev/urandom",
249 "/dev/tty",
250 "/dev/snd",
251 "/dev/dri",
252 "/dev/pts",
253 "/dev/nvidia0",
254 "/dev/nvidia1",
255 "/dev/nvidia2",
256 "/dev/nvidia3",
257 "/dev/nvidia4",
258 "/dev/nvidia5",
259 "/dev/nvidia6",
260 "/dev/nvidia7",
261 "/dev/nvidia8",
262 "/dev/nvidia9",
263 "/dev/nvidiactl",
264 "/dev/nvidia-modeset",
265 "/dev/nvidia-uvm",
266 "/dev/video0",
267 "/dev/video1",
268 "/dev/video2",
269 "/dev/video3",
270 "/dev/video4",
271 "/dev/video5",
272 "/dev/video6",
273 "/dev/video7",
274 "/dev/video8",
275 "/dev/video9",
276 "/dev/dvb",
277 "/dev/sr0",
278 NULL
279};
280
281static FileDB *dev_out = NULL;
282static void dev_callback(char *ptr) {
283 // skip private-dev devices
284 int i = 0;
285 int found = 0;
286 while (dev_skip[i]) {
287 if (strcmp(ptr, dev_skip[i]) == 0) {
288 found = 1;
289 break;
290 }
291 i++;
292 }
293 if (!found)
294 filedb_add(dev_out, ptr);
295}
296
297void build_dev(const char *fname, FILE *fp) {
298 assert(fname);
299
300 process_files(fname, "/dev", dev_callback);
301
302 if (dev_out == NULL)
303 fprintf(fp, "private-dev\n");
304 else {
305 fprintf(fp, "\n");
306 fprintf(fp, "# private-dev\n");
307 fprintf(fp, "# This is the list of devices accessed (on top of regular private-dev devices:\n");
308 fprintf(fp, "# ");
309 FileDB *ptr = dev_out;
310 while (ptr) {
311 fprintf(fp, "%s,", ptr->fname);
312 ptr = ptr->next;
313 }
314 fprintf(fp, "\n");
315 }
316}
317
diff --git a/src/fbuilder/build_home.c b/src/fbuilder/build_home.c
deleted file mode 100644
index 7470a8d10..000000000
--- a/src/fbuilder/build_home.c
+++ /dev/null
@@ -1,199 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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 "fbuilder.h"
22
23static FileDB *db_skip = NULL;
24static FileDB *db_out = NULL;
25
26static void load_whitelist_common(void) {
27 FILE *fp = fopen("/etc/firejail/whitelist-common.inc", "r");
28 if (!fp) {
29 fprintf(stderr, "Error: cannot open whitelist-common.inc\n");
30 exit(1);
31 }
32
33 char buf[MAX_BUF];
34 while (fgets(buf, MAX_BUF, fp)) {
35 if (strncmp(buf, "whitelist ~/", 12) != 0)
36 continue;
37 char *fn = buf + 12;
38 char *ptr = strchr(buf, '\n');
39 if (!ptr)
40 continue;
41 *ptr = '\0';
42
43 // add the file to skip list
44 db_skip = filedb_add(db_skip, fn);
45 }
46
47 fclose(fp);
48}
49
50void process_home(const char *fname, char *home, int home_len) {
51 assert(fname);
52 assert(home);
53 assert(home_len);
54
55 // process trace file
56 FILE *fp = fopen(fname, "r");
57 if (!fp) {
58 fprintf(stderr, "Error: cannot open %s\n", fname);
59 exit(1);
60 }
61
62 char buf[MAX_BUF];
63 while (fgets(buf, MAX_BUF, fp)) {
64 // remove \n
65 char *ptr = strchr(buf, '\n');
66 if (ptr)
67 *ptr = '\0';
68
69 // parse line: 4:galculator:access /etc/fonts/conf.d:0
70 // number followed by :
71 ptr = buf;
72 if (!isdigit(*ptr))
73 continue;
74 while (isdigit(*ptr))
75 ptr++;
76 if (*ptr != ':')
77 continue;
78 ptr++;
79
80 // next :
81 ptr = strchr(ptr, ':');
82 if (!ptr)
83 continue;
84 ptr++;
85 if (strncmp(ptr, "access /home", 12) == 0)
86 ptr += 7;
87 else if (strncmp(ptr, "fopen /home", 11) == 0)
88 ptr += 6;
89 else if (strncmp(ptr, "fopen64 /home", 13) == 0)
90 ptr += 8;
91 else if (strncmp(ptr, "open64 /home", 12) == 0)
92 ptr += 7;
93 else if (strncmp(ptr, "open /home", 10) == 0)
94 ptr += 5;
95 else
96 continue;
97
98 // end of filename
99 char *ptr2 = strchr(ptr, ':');
100 if (!ptr2)
101 continue;
102 *ptr2 = '\0';
103
104 // check home directory
105 if (strncmp(ptr, home, home_len) != 0)
106 continue;
107 if (strcmp(ptr, home) == 0)
108 continue;
109 ptr += home_len + 1;
110
111 // skip files handled automatically by firejail
112 if (strcmp(ptr, ".Xauthority") == 0 ||
113 strcmp(ptr, ".Xdefaults-debian") == 0 ||
114 strncmp(ptr, ".config/pulse/", 13) == 0 ||
115 strncmp(ptr, ".pulse/", 7) == 0 ||
116 strncmp(ptr, ".bash_hist", 10) == 0 ||
117 strcmp(ptr, ".bashrc") == 0)
118 continue;
119
120
121 // try to find the relevant directory for this file
122 char *dir = extract_dir(ptr);
123 char *toadd = (dir)? dir: ptr;
124
125 // skip some dot directories
126 if (strcmp(toadd, ".config") == 0 ||
127 strcmp(toadd, ".local") == 0 ||
128 strcmp(toadd, ".local/share") == 0 ||
129 strcmp(toadd, ".cache") == 0) {
130 if (dir)
131 free(dir);
132 continue;
133 }
134
135 // clean .cache entries
136 if (strncmp(toadd, ".cache/", 7) == 0) {
137 char *ptr2 = toadd + 7;
138 ptr2 = strchr(ptr2, '/');
139 if (ptr2)
140 *ptr2 = '\0';
141 }
142
143 // skip files and directories in whitelist-common.inc
144 if (filedb_find(db_skip, toadd)) {
145 if (dir)
146 free(dir);
147 continue;
148 }
149
150 // add the file to out list
151 db_out = filedb_add(db_out, toadd);
152 if (dir)
153 free(dir);
154
155 }
156 fclose(fp);
157}
158
159
160// process fname, fname.1, fname.2, fname.3, fname.4, fname.5
161void build_home(const char *fname, FILE *fp) {
162 assert(fname);
163
164 // load whitelist common
165 load_whitelist_common();
166
167 // find user home directory
168 struct passwd *pw = getpwuid(getuid());
169 if (!pw)
170 errExit("getpwuid");
171 char *home = pw->pw_dir;
172 if (!home)
173 errExit("getpwuid");
174 int home_len = strlen(home);
175
176 // run fname
177 process_home(fname, home, home_len);
178
179 // run all the rest
180 struct stat s;
181 int i;
182 for (i = 1; i <= 5; i++) {
183 char *newname;
184 if (asprintf(&newname, "%s.%d", fname, i) == -1)
185 errExit("asprintf");
186 if (stat(newname, &s) == 0)
187 process_home(newname, home, home_len);
188 free(newname);
189 }
190
191 // print the out list if any
192 if (db_out) {
193 filedb_print(db_out, "whitelist ~/", fp);
194 fprintf(fp, "include /etc/firejail/whitelist-common.inc\n");
195 }
196 else
197 fprintf(fp, "private\n");
198
199} \ No newline at end of file
diff --git a/src/fbuilder/build_profile.c b/src/fbuilder/build_profile.c
deleted file mode 100644
index 125487c41..000000000
--- a/src/fbuilder/build_profile.c
+++ /dev/null
@@ -1,170 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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 "fbuilder.h"
22#include <sys/wait.h>
23#include <fcntl.h>
24
25#define TRACE_OUTPUT "/tmp/firejail-trace"
26#define STRACE_OUTPUT "/tmp/firejail-strace"
27
28static char *cmdlist[] = {
29 "/usr/bin/firejail",
30 "--quiet",
31 "--output=" TRACE_OUTPUT,
32 "--noprofile",
33 "--caps.drop=all",
34 "--nonewprivs",
35 "--trace",
36 "--shell=none",
37 "/usr/bin/strace", // also used as a marker in build_profile()
38 "-c",
39 "-f",
40 "-o" STRACE_OUTPUT,
41};
42
43static void clear_tmp_files(void) {
44 unlink(STRACE_OUTPUT);
45 unlink(TRACE_OUTPUT);
46
47 // run all the rest
48 int i;
49 for (i = 1; i <= 5; i++) {
50 char *newname;
51 if (asprintf(&newname, "%s.%d", TRACE_OUTPUT, i) == -1)
52 errExit("asprintf");
53 unlink(newname);
54 free(newname);
55 }
56
57}
58
59void build_profile(int argc, char **argv, int index, FILE *fp) {
60 // next index is the application name
61 if (index >= argc) {
62 fprintf(stderr, "Error: application name missing\n");
63 exit(1);
64 }
65
66 // clean /tmp files
67 clear_tmp_files();
68
69 // detect strace
70 int have_strace = 0;
71 if (access("/usr/bin/strace", X_OK) == 0)
72 have_strace = 1;
73
74 // calculate command length
75 unsigned len = (int) sizeof(cmdlist) / sizeof(char*) + argc - index + 1;
76 if (arg_debug)
77 printf("command len %d + %d + 1\n", (int) (sizeof(cmdlist) / sizeof(char*)), argc - index);
78 char *cmd[len];
79 cmd[0] = cmdlist[0]; // explicit assignemnt to clean scan-build error
80
81 // build command
82 unsigned i = 0;
83 for (i = 0; i < (int) sizeof(cmdlist) / sizeof(char*); i++) {
84 // skip strace if not installed
85 if (have_strace == 0 && strcmp(cmdlist[i], "/usr/bin/strace") == 0)
86 break;
87 cmd[i] = cmdlist[i];
88 }
89
90 int i2 = index;
91 for (; i < (len - 1); i++, i2++)
92 cmd[i] = argv[i2];
93 assert(i < len);
94 cmd[i] = NULL;
95
96 if (arg_debug) {
97 for (i = 0; i < len; i++)
98 printf("\t%s\n", cmd[i]);
99 }
100
101 // fork and execute
102 pid_t child = fork();
103 if (child == -1)
104 errExit("fork");
105 if (child == 0) {
106 assert(cmd[0]);
107 int rv = execvp(cmd[0], cmd);
108 (void) rv;
109 errExit("execv");
110 }
111
112 // wait for all processes to finish
113 int status;
114 if (waitpid(child, &status, 0) != child)
115 errExit("waitpid");
116
117 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
118 printf("\n\n\n");
119 fprintf(fp, "############################################\n");
120 fprintf(fp, "# %s profile\n", argv[index]);
121 fprintf(fp, "############################################\n");
122 fprintf(fp, "# Persistent global definitions\n");
123 fprintf(fp, "# include /etc/firejail/globals.local\n");
124 fprintf(fp, "\n");
125
126 fprintf(fp, "### basic blacklisting\n");
127 fprintf(fp, "include /etc/firejail/disable-common.inc\n");
128 fprintf(fp, "# include /etc/firejail/disable-devel.inc\n");
129 fprintf(fp, "include /etc/firejail/disable-passwdmgr.inc\n");
130 fprintf(fp, "# include /etc/firejail/disable-programs.inc\n");
131 fprintf(fp, "\n");
132
133 fprintf(fp, "### home directory whitelisting\n");
134 build_home(TRACE_OUTPUT, fp);
135 fprintf(fp, "\n");
136
137 fprintf(fp, "### filesystem\n");
138 build_tmp(TRACE_OUTPUT, fp);
139 build_dev(TRACE_OUTPUT, fp);
140 build_etc(TRACE_OUTPUT, fp);
141 build_var(TRACE_OUTPUT, fp);
142 build_bin(TRACE_OUTPUT, fp);
143 build_share(TRACE_OUTPUT, fp);
144 fprintf(fp, "\n");
145
146 fprintf(fp, "### security filters\n");
147 fprintf(fp, "caps.drop all\n");
148 fprintf(fp, "nonewprivs\n");
149 fprintf(fp, "seccomp\n");
150 if (have_strace)
151 build_seccomp(STRACE_OUTPUT, fp);
152 else {
153 fprintf(fp, "# If you install strace on your system, Firejail will also create a\n");
154 fprintf(fp, "# whitelisted seccomp filter.\n");
155 }
156 fprintf(fp, "\n");
157
158 fprintf(fp, "### network\n");
159 build_protocol(TRACE_OUTPUT, fp);
160 fprintf(fp, "\n");
161
162 fprintf(fp, "### environment\n");
163 fprintf(fp, "shell none\n");
164
165 }
166 else {
167 fprintf(stderr, "Error: cannot run the sandbox\n");
168 exit(1);
169 }
170}
diff --git a/src/fbuilder/build_seccomp.c b/src/fbuilder/build_seccomp.c
deleted file mode 100644
index fbc0e06f4..000000000
--- a/src/fbuilder/build_seccomp.c
+++ /dev/null
@@ -1,192 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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 "fbuilder.h"
22
23void build_seccomp(const char *fname, FILE *fp) {
24 assert(fname);
25 assert(fp);
26
27 FILE *fp2 = fopen(fname, "r");
28 if (!fp2) {
29 fprintf(stderr, "Error: cannot open %s\n", fname);
30 exit(1);
31 }
32
33 char buf[MAX_BUF];
34 int line = 1;
35 int position = 0;
36 int cnt = 0;
37 while (fgets(buf, MAX_BUF, fp2)) {
38 // remove \n
39 char *ptr = strchr(buf, '\n');
40 if (ptr)
41 *ptr = '\0';
42
43 // first line:
44 //% time seconds usecs/call calls errors syscall
45 if (line == 1) {
46 // extract syscall position
47 ptr = strstr(buf, "syscall");
48 if (*buf != '%' || ptr == NULL) {
49 // skip this line, it could be garbage from strace
50 continue;
51 }
52 position = (int) (ptr - buf);
53 }
54 else if (line == 2) {
55 if (*buf != '-') {
56 fprintf(stderr, "Error: invalid strace output\n%s\n", buf);
57 exit(1);
58 }
59 }
60 else {
61 // get out on the next "----" line
62 if (*buf == '-')
63 break;
64
65 if (line == 3)
66 fprintf(fp, "# seccomp.keep %s", buf + position);
67 else
68 fprintf(fp, ",%s", buf + position);
69 cnt++;
70 }
71 line++;
72 }
73 fprintf(fp, "\n");
74 fprintf(fp, "# %d syscalls total\n", cnt);
75 fprintf(fp, "# Probably you will need to add more syscalls to seccomp.keep. Look for\n");
76 fprintf(fp, "# seccomp errors in /var/log/syslog or /var/log/audit/audit.log while\n");
77 fprintf(fp, "# running your sandbox.\n");
78
79 fclose(fp2);
80}
81
82//***************************************
83// protocol
84//***************************************
85int unix_s = 0;
86int inet = 0;
87int inet6 = 0;
88int netlink = 0;
89int packet = 0;
90static void process_protocol(const char *fname) {
91 assert(fname);
92
93 // process trace file
94 FILE *fp = fopen(fname, "r");
95 if (!fp) {
96 fprintf(stderr, "Error: cannot open %s\n", fname);
97 exit(1);
98 }
99
100 char buf[MAX_BUF];
101 while (fgets(buf, MAX_BUF, fp)) {
102 // remove \n
103 char *ptr = strchr(buf, '\n');
104 if (ptr)
105 *ptr = '\0';
106
107 // parse line: 4:galculator:access /etc/fonts/conf.d:0
108 // number followed by :
109 ptr = buf;
110 if (!isdigit(*ptr))
111 continue;
112 while (isdigit(*ptr))
113 ptr++;
114 if (*ptr != ':')
115 continue;
116 ptr++;
117
118 // next :
119 ptr = strchr(ptr, ':');
120 if (!ptr)
121 continue;
122 ptr++;
123 if (strncmp(ptr, "socket ", 7) == 0)
124 ptr += 7;
125 else
126 continue;
127
128 if (strncmp(ptr, "AF_LOCAL ", 9) == 0)
129 unix_s = 1;
130 else if (strncmp(ptr, "AF_INET ", 8) == 0)
131 inet = 1;
132 else if (strncmp(ptr, "AF_INET6 ", 9) == 0)
133 inet6 = 1;
134 else if (strncmp(ptr, "AF_NETLINK ", 9) == 0)
135 netlink = 1;
136 else if (strncmp(ptr, "AF_PACKET ", 9) == 0)
137 packet = 1;
138 }
139
140 fclose(fp);
141}
142
143
144// process fname, fname.1, fname.2, fname.3, fname.4, fname.5
145void build_protocol(const char *fname, FILE *fp) {
146 assert(fname);
147
148 // run fname
149 process_protocol(fname);
150
151 // run all the rest
152 struct stat s;
153 int i;
154 for (i = 1; i <= 5; i++) {
155 char *newname;
156 if (asprintf(&newname, "%s.%d", fname, i) == -1)
157 errExit("asprintf");
158 if (stat(newname, &s) == 0)
159 process_protocol(newname);
160 free(newname);
161 }
162
163 int net = 0;
164 if (unix_s || inet || inet6 || netlink || packet) {
165 fprintf(fp, "protocol ");
166 if (unix_s)
167 fprintf(fp, "unix,");
168 if (inet) {
169 fprintf(fp, "inet,");
170 net = 1;
171 }
172 if (inet6) {
173 fprintf(fp, "inet6,");
174 net = 1;
175 }
176 if (netlink)
177 fprintf(fp, "netlink,");
178 if (packet) {
179 fprintf(fp, "packet");
180 net = 1;
181 }
182 fprintf(fp, "\n");
183 }
184
185 if (net == 0)
186 fprintf(fp, "net none\n");
187 else {
188 fprintf(fp, "# net eth0\n");
189 fprintf(fp, "netfilter\n");
190 }
191}
192
diff --git a/src/fbuilder/fbuilder.h b/src/fbuilder/fbuilder.h
deleted file mode 100644
index 0a0fd42c9..000000000
--- a/src/fbuilder/fbuilder.h
+++ /dev/null
@@ -1,69 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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 FBUILDER_H
22#define FBUILDER_H
23#include "../include/common.h"
24#include <sys/types.h>
25#include <pwd.h>
26#include <sys/types.h>
27#include <sys/stat.h>
28
29
30#define MAX_BUF 4096
31// main.c
32extern int arg_debug;
33
34// build_profile.c
35void build_profile(int argc, char **argv, int index, FILE *fp);
36
37// build_seccomp.c
38void build_seccomp(const char *fname, FILE *fp);
39void build_protocol(const char *fname, FILE *fp);
40
41// build_fs.c
42void build_etc(const char *fname, FILE *fp);
43void build_var(const char *fname, FILE *fp);
44void build_tmp(const char *fname, FILE *fp);
45void build_dev(const char *fname, FILE *fp);
46void build_share(const char *fname, FILE *fp);
47
48// build_bin.c
49void build_bin(const char *fname, FILE *fp);
50
51// build_home.c
52void build_home(const char *fname, FILE *fp);
53
54// utils.c
55int is_dir(const char *fname);
56char *extract_dir(char *fname);
57
58// filedb.c
59typedef struct filedb_t {
60 struct filedb_t *next;
61 char *fname; // file name
62 int len; // length of file name
63} FileDB;
64
65FileDB *filedb_add(FileDB *head, const char *fname);
66FileDB *filedb_find(FileDB *head, const char *fname);
67void filedb_print(FileDB *head, const char *prefix, FILE *fp);
68
69#endif \ No newline at end of file
diff --git a/src/fbuilder/filedb.c b/src/fbuilder/filedb.c
deleted file mode 100644
index 7af3724e8..000000000
--- a/src/fbuilder/filedb.c
+++ /dev/null
@@ -1,79 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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 "fbuilder.h"
22
23FileDB *filedb_find(FileDB *head, const char *fname) {
24 FileDB *ptr = head;
25 int found = 0;
26 int len = strlen(fname);
27
28 while (ptr) {
29 // exact name
30 if (strcmp(fname, ptr->fname) == 0) {
31 found = 1;
32 break;
33 }
34
35 // parent directory in the list
36 if (len > ptr->len &&
37 fname[ptr->len] == '/' &&
38 strncmp(ptr->fname, fname, ptr->len) == 0) {
39 found = 1;
40 break;
41 }
42
43 ptr = ptr->next;
44 }
45
46 if (found)
47 return ptr;
48
49 return NULL;
50}
51
52FileDB *filedb_add(FileDB *head, const char *fname) {
53 assert(fname);
54
55 // don't add it if it is already there or if the parent directory is already in the list
56 if (filedb_find(head, fname))
57 return head;
58
59 // add a new entry
60 FileDB *entry = malloc(sizeof(FileDB));
61 if (!entry)
62 errExit("malloc");
63 memset(entry, 0, sizeof(FileDB));
64 entry->fname = strdup(fname);
65 if (!entry->fname)
66 errExit("strdup");
67 entry->len = strlen(entry->fname);
68 entry->next = head;
69 return entry;
70};
71
72void filedb_print(FileDB *head, const char *prefix, FILE *fp) {
73 FileDB *ptr = head;
74 while (ptr) {
75 fprintf(fp, "%s%s\n", prefix, ptr->fname);
76 ptr = ptr->next;
77 }
78}
79
diff --git a/src/fbuilder/main.c b/src/fbuilder/main.c
deleted file mode 100644
index ef5dee7d9..000000000
--- a/src/fbuilder/main.c
+++ /dev/null
@@ -1,93 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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 "fbuilder.h"
21int arg_debug = 0;
22
23static void usage(void) {
24 printf("Firejail profile builder\n");
25 printf("Usage: firejail [--debug] --build[=profile-file] program-and-arguments\n");
26}
27
28int main(int argc, char **argv) {
29#if 0
30{
31system("cat /proc/self/status");
32int i;
33for (i = 0; i < argc; i++)
34 printf("*%s* ", argv[i]);
35printf("\n");
36}
37#endif
38
39 int i;
40 int prog_index = 0;
41 FILE *fp = stdout;
42 int prof_file = 0;
43
44 // parse arguments and extract program index
45 for (i = 1; i < argc; i++) {
46 if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-?") ==0) {
47 usage();
48 return 0;
49 }
50 else if (strcmp(argv[i], "--debug") == 0)
51 arg_debug = 1;
52 else if (strcmp(argv[i], "--build") == 0)
53 ; // do nothing, this is passed down from firejail
54 else if (strncmp(argv[i], "--build=", 8) == 0) {
55 // this option is only supported for non-root users
56 if (getuid() == 0) {
57 fprintf(stderr, "Error fbuild: --build=profile-name is not supported for root user.\n");
58 exit(1);
59 }
60
61 // check file access
62 fp = fopen(argv[i] + 8, "w");
63 if (!fp) {
64 fprintf(stderr, "Error fbuild: cannot open profile file.\n");
65 exit(1);
66 }
67 prof_file = 1;
68 // do nothing, this is passed down from firejail
69 }
70 else {
71 if (*argv[i] == '-') {
72 fprintf(stderr, "Error fbuilder: invalid program\n");
73 usage();
74 exit(1);
75 }
76 prog_index = i;
77 break;
78 }
79 }
80
81 if (prog_index == 0) {
82 fprintf(stderr, "Error fbuilder: program and arguments required\n");
83 usage();
84 if (prof_file)
85 fclose(fp);
86 exit(1);
87 }
88
89 build_profile(argc, argv, prog_index, fp);
90 if (prof_file)
91 fclose(fp);
92 return 0;
93}
diff --git a/src/fbuilder/utils.c b/src/fbuilder/utils.c
deleted file mode 100644
index 1d490b07e..000000000
--- a/src/fbuilder/utils.c
+++ /dev/null
@@ -1,72 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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 "fbuilder.h"
22
23// todo: duplicated from src/firejail/util.c - remove dplication
24// return 1 if the file is a directory
25int is_dir(const char *fname) {
26 assert(fname);
27 if (*fname == '\0')
28 return 0;
29
30 // if fname doesn't end in '/', add one
31 int rv;
32 struct stat s;
33 if (fname[strlen(fname) - 1] == '/')
34 rv = stat(fname, &s);
35 else {
36 char *tmp;
37 if (asprintf(&tmp, "%s/", fname) == -1) {
38 fprintf(stderr, "Error: cannot allocate memory, %s:%d\n", __FILE__, __LINE__);
39 errExit("asprintf");
40 }
41 rv = stat(tmp, &s);
42 free(tmp);
43 }
44
45 if (rv == -1)
46 return 0;
47
48 if (S_ISDIR(s.st_mode))
49 return 1;
50
51 return 0;
52}
53
54// return NULL if fname is already a directory, or if no directory found
55char *extract_dir(char *fname) {
56 assert(fname);
57 if (is_dir(fname))
58 return NULL;
59
60 char *name = strdup(fname);
61 if (!name)
62 errExit("strdup");
63
64 char *ptr = strrchr(name, '/');
65 if (!ptr) {
66 free(name);
67 return NULL;
68 }
69 *ptr = '\0';
70
71 return name;
72}
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index 24ff553d7..ba2f8e284 100644
--- a/src/firejail/fs.c
+++ b/src/firejail/fs.c
@@ -740,7 +740,7 @@ void fs_basic_fs(void) {
740} 740}
741 741
742 742
743 743#ifndef LTS
744#ifdef HAVE_OVERLAYFS 744#ifdef HAVE_OVERLAYFS
745char *fs_check_overlay_dir(const char *subdirname, int allow_reuse) { 745char *fs_check_overlay_dir(const char *subdirname, int allow_reuse) {
746 struct stat s; 746 struct stat s;
@@ -1292,6 +1292,7 @@ void fs_chroot(const char *rootdir) {
1292 disable_config(); 1292 disable_config();
1293} 1293}
1294#endif 1294#endif
1295#endif // LTS
1295 1296
1296// this function is called from sandbox.c before blacklist/whitelist functions 1297// this function is called from sandbox.c before blacklist/whitelist functions
1297void fs_private_tmp(void) { 1298void fs_private_tmp(void) {
diff --git a/src/firejail/fs_bin.c b/src/firejail/fs_bin.c
deleted file mode 100644
index 5625ed356..000000000
--- a/src/firejail/fs_bin.c
+++ /dev/null
@@ -1,309 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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#include <sys/types.h>
24#include <sys/wait.h>
25#include <unistd.h>
26#include <glob.h>
27
28static int prog_cnt = 0;
29
30static char *paths[] = {
31 "/usr/local/bin",
32 "/usr/bin",
33 "/bin",
34 "/usr/games",
35 "/usr/local/games",
36 "/usr/local/sbin",
37 "/usr/sbin",
38 "/sbin",
39 NULL
40};
41
42// return 1 if found, 0 if not found
43static char *check_dir_or_file(const char *name) {
44 assert(name);
45 struct stat s;
46 char *fname = NULL;
47
48 int i = 0;
49 while (paths[i]) {
50 // private-bin-no-local can be disabled in /etc/firejail/firejail.config
51 if (checkcfg(CFG_PRIVATE_BIN_NO_LOCAL) && strstr(paths[i], "local/")) {
52 i++;
53 continue;
54 }
55
56 // check file
57 if (asprintf(&fname, "%s/%s", paths[i], name) == -1)
58 errExit("asprintf");
59 if (arg_debug)
60 printf("Checking %s/%s\n", paths[i], name);
61 if (stat(fname, &s) == 0 && !S_ISDIR(s.st_mode)) { // do not allow directories
62 // check symlink to firejail executable in /usr/local/bin
63 if (strcmp(paths[i], "/usr/local/bin") == 0 && is_link(fname)) {
64 /* coverity[toctou] */
65 char *actual_path = realpath(fname, NULL);
66 if (actual_path) {
67 char *ptr = strstr(actual_path, "/firejail");
68 if (ptr && strlen(ptr) == strlen("/firejail")) {
69 if (arg_debug)
70 printf("firejail exec symlink detected\n");
71 free(actual_path);
72 free(fname);
73 fname = NULL;
74 i++;
75 continue;
76 }
77 free(actual_path);
78 }
79
80 }
81 break; // file found
82 }
83
84 free(fname);
85 fname = NULL;
86 i++;
87 }
88
89 if (!fname) {
90 if (arg_debug)
91 fwarning("file %s not found\n", name);
92 return NULL;
93 }
94
95 free(fname);
96 return paths[i];
97}
98
99// return 1 if the file is in paths[]
100static int valid_full_path_file(const char *name) {
101 assert(name);
102
103 if (*name != '/')
104 return 0;
105 if (strstr(name, ".."))
106 return 0;
107
108 // do we have a file?
109 struct stat s;
110 if (stat(name, &s) == -1)
111 return 0;
112 // directories not allowed
113 if (S_ISDIR(s.st_mode))
114 return 0;
115 // checking access
116 if (access(name, X_OK) == -1)
117 return 0;
118
119 // check standard paths
120 int i = 0;
121 while (paths[i]) {
122 // private-bin-no-local can be disabled in /etc/firejail/firejail.config
123 if (checkcfg(CFG_PRIVATE_BIN_NO_LOCAL) && strstr(paths[i], "local/")) {
124 i++;
125 continue;
126 }
127
128 int len = strlen(paths[i]);
129 if (strncmp(name, paths[i], len) == 0 && name[len] == '/' && name[len + 1] != '\0')
130 return 1;
131 i++;
132 }
133 if (arg_debug)
134 printf("file %s not found\n", name);
135 return 0;
136}
137
138static void report_duplication(const char *fname) {
139 // report the file on all bin paths
140 int i = 0;
141 while (paths[i]) {
142 char *p;
143 if (asprintf(&p, "%s/%s", paths[i], fname) == -1)
144 errExit("asprintf");
145 fs_logger2("clone", p);
146 free(p);
147 i++;
148 }
149}
150
151static void duplicate(char *fname) {
152 assert(fname);
153
154 if (*fname == '~' || strstr(fname, "..")) {
155 fprintf(stderr, "Error: \"%s\" is an invalid filename\n", fname);
156 exit(1);
157 }
158 invalid_filename(fname, 0); // no globbing
159
160 char *full_path;
161 if (*fname == '/') {
162 // If the absolute filename is indicated, directly use it. This
163 // is required for the following cases:
164 // - if user's $PATH order is not the same as the above
165 // paths[] variable order
166 if (!valid_full_path_file(fname)) {
167 fwarning("invalid private-bin path %s\n", fname);
168 return;
169 }
170
171 full_path = strdup(fname);
172 if (!full_path)
173 errExit("strdup");
174 }
175 else {
176 // Find the standard directory (by looping through paths[])
177 // where the filename fname is located
178 char *path = check_dir_or_file(fname);
179 if (!path)
180 return;
181 if (asprintf(&full_path, "%s/%s", path, fname) == -1)
182 errExit("asprintf");
183 }
184
185 // add to private-lib list
186 if (cfg.bin_private_lib == NULL) {
187 if (asprintf(&cfg.bin_private_lib, "%s,%s",fname, full_path) == -1)
188 errExit("asprinf");
189 }
190 else {
191 char *tmp;
192 if (asprintf(&tmp, "%s,%s,%s", cfg.bin_private_lib, fname, full_path) == -1)
193 errExit("asprinf");
194 free(cfg.bin_private_lib);
195 cfg.bin_private_lib = tmp;
196 }
197
198 // if full_path is symlink, and the link is in our path, copy both the file and the symlink
199 if (is_link(full_path)) {
200 char *actual_path = realpath(full_path, NULL);
201 if (actual_path) {
202 if (valid_full_path_file(actual_path)) {
203 // solving problems such as /bin/sh -> /bin/dash
204 // copy the real file pointed by symlink
205 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, actual_path, RUN_BIN_DIR);
206 prog_cnt++;
207 char *f = strrchr(actual_path, '/');
208 if (f && *(++f) !='\0')
209 report_duplication(f);
210 }
211 free(actual_path);
212 }
213 }
214
215 // copy a file or a symlink
216 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, full_path, RUN_BIN_DIR);
217 prog_cnt++;
218 free(full_path);
219 report_duplication(fname);
220}
221
222static void globbing(char *fname) {
223 assert(fname);
224
225 // go directly to duplicate() if no globbing char is present - see man 7 glob
226 if (strrchr(fname, '*') == NULL &&
227 strrchr(fname, '[') == NULL &&
228 strrchr(fname, '?') == NULL)
229 return duplicate(fname);
230
231 // loop through paths[]
232 int i = 0;
233 while (paths[i]) {
234 // private-bin-no-local can be disabled in /etc/firejail/firejail.config
235 if (checkcfg(CFG_PRIVATE_BIN_NO_LOCAL) && strstr(paths[i], "local/")) {
236 i++;
237 continue;
238 }
239
240 // check file
241 char *pattern;
242 if (asprintf(&pattern, "%s/%s", paths[i], fname) == -1)
243 errExit("asprintf");
244
245 // globbing
246 glob_t globbuf;
247 int globerr = glob(pattern, GLOB_NOCHECK | GLOB_NOSORT | GLOB_PERIOD, NULL, &globbuf);
248 if (globerr) {
249 fprintf(stderr, "Error: failed to glob private-bin pattern %s\n", pattern);
250 exit(1);
251 }
252
253 size_t j;
254 for (j = 0; j < globbuf.gl_pathc; j++) {
255 assert(globbuf.gl_pathv[j]);
256 // testing for GLOB_NOCHECK - no pattern matched returns the original pattern
257 if (strcmp(globbuf.gl_pathv[j], pattern) == 0)
258 continue;
259
260 duplicate(globbuf.gl_pathv[j]);
261 }
262
263 globfree(&globbuf);
264 free(pattern);
265 i++;
266 }
267}
268
269void fs_private_bin_list(void) {
270 char *private_list = cfg.bin_private_keep;
271 assert(private_list);
272
273 // start timetrace
274 timetrace_start();
275
276 // create /run/firejail/mnt/bin directory
277 mkdir_attr(RUN_BIN_DIR, 0755, 0, 0);
278
279 if (arg_debug)
280 printf("Copying files in the new bin directory\n");
281
282 // copy the list of files in the new home directory
283 char *dlist = strdup(private_list);
284 if (!dlist)
285 errExit("strdup");
286
287 char *ptr = strtok(dlist, ",");
288 globbing(ptr);
289 while ((ptr = strtok(NULL, ",")) != NULL)
290 globbing(ptr);
291 free(dlist);
292 fs_logger_print();
293
294 // mount-bind
295 int i = 0;
296 while (paths[i]) {
297 struct stat s;
298 if (stat(paths[i], &s) == 0) {
299 if (arg_debug)
300 printf("Mount-bind %s on top of %s\n", RUN_BIN_DIR, paths[i]);
301 if (mount(RUN_BIN_DIR, paths[i], NULL, MS_BIND|MS_REC, NULL) < 0)
302 errExit("mount bind");
303 fs_logger2("tmpfs", paths[i]);
304 fs_logger2("mount", paths[i]);
305 }
306 i++;
307 }
308 fmessage("%d %s installed in %0.2f ms\n", prog_cnt, (prog_cnt == 1)? "program": "programs", timetrace_end());
309}
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c
index 3afa3bf0c..f8e7e6e74 100644
--- a/src/firejail/fs_home.c
+++ b/src/firejail/fs_home.c
@@ -364,6 +364,7 @@ void fs_check_private_dir(void) {
364 } 364 }
365} 365}
366 366
367#ifndef LTS
367//*********************************************************************************** 368//***********************************************************************************
368// --private-home 369// --private-home
369//*********************************************************************************** 370//***********************************************************************************
@@ -531,3 +532,4 @@ void fs_private_home_list(void) {
531 fprintf(stderr, "Home directory installed in %0.2f ms\n", timetrace_end()); 532 fprintf(stderr, "Home directory installed in %0.2f ms\n", timetrace_end());
532 533
533} 534}
535#endif //LTS \ No newline at end of file
diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c
deleted file mode 100644
index 77c9a0cf5..000000000
--- a/src/firejail/fs_lib.c
+++ /dev/null
@@ -1,378 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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 "../include/ldd_utils.h"
22#include <sys/mount.h>
23#include <sys/stat.h>
24#include <sys/types.h>
25#include <unistd.h>
26#include <dirent.h>
27#include <glob.h>
28#define MAXBUF 4096
29
30extern void fslib_install_stdc(void);
31extern void fslib_install_system(void);
32
33static int lib_cnt = 0;
34static int dir_cnt = 0;
35
36static void report_duplication(const char *full_path) {
37 char *fname = strrchr(full_path, '/');
38 if (fname && *(++fname) != '\0') {
39 // report the file on all bin paths
40 int i = 0;
41 while (default_lib_paths[i]) {
42 char *p;
43 if (asprintf(&p, "%s/%s", default_lib_paths[i], fname) == -1)
44 errExit("asprintf");
45 fs_logger2("clone", p);
46 free(p);
47 i++;
48 }
49 }
50}
51
52static char *build_dest_dir(const char *full_path) {
53 assert(full_path);
54 if (strstr(full_path, "/x86_64-linux-gnu/"))
55 return RUN_LIB_DIR "/x86_64-linux-gnu";
56 return RUN_LIB_DIR;
57}
58
59// copy fname in private_run_dir
60void fslib_duplicate(const char *full_path) {
61 assert(full_path);
62
63 struct stat s;
64 if (stat(full_path, &s) != 0 || s.st_uid != 0 || access(full_path, R_OK))
65 return;
66
67 char *dest_dir = build_dest_dir(full_path);
68
69 // don't copy it if the file is already there
70 char *ptr = strrchr(full_path, '/');
71 if (!ptr)
72 return;
73 ptr++;
74 if (*ptr == '\0')
75 return;
76
77 char *name;
78 if (asprintf(&name, "%s/%s", dest_dir, ptr) == -1)
79 errExit("asprintf");
80 if (stat(name, &s) == 0) {
81 free(name);
82 return;
83 }
84 free(name);
85
86 if (arg_debug || arg_debug_private_lib)
87 printf(" copying %s to private %s\n", full_path, dest_dir);
88
89 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 4, PATH_FCOPY, "--follow-link", full_path, dest_dir);
90 report_duplication(full_path);
91 lib_cnt++;
92}
93
94
95// requires full path for lib
96// it could be a library or an executable
97// lib is not copied, only libraries used by it
98void fslib_copy_libs(const char *full_path) {
99 assert(full_path);
100 if (arg_debug || arg_debug_private_lib)
101 printf(" fslib_copy_libs %s\n", full_path);
102
103 // if library/executable does not exist or the user does not have read access to it
104 // print a warning and exit the function.
105 if (access(full_path, R_OK)) {
106 if (arg_debug || arg_debug_private_lib)
107 printf("cannot find %s for private-lib, skipping...\n", full_path);
108 return;
109 }
110
111 // create an empty RUN_LIB_FILE and allow the user to write to it
112 unlink(RUN_LIB_FILE); // in case is there
113 create_empty_file_as_root(RUN_LIB_FILE, 0644);
114 if (chown(RUN_LIB_FILE, getuid(), getgid()))
115 errExit("chown");
116
117 // run fldd to extact the list of files
118 if (arg_debug || arg_debug_private_lib)
119 printf(" running fldd %s\n", full_path);
120 sbox_run(SBOX_USER | SBOX_SECCOMP | SBOX_CAPS_NONE, 3, PATH_FLDD, full_path, RUN_LIB_FILE);
121
122 // open the list of libraries and install them on by one
123 FILE *fp = fopen(RUN_LIB_FILE, "r");
124 if (!fp)
125 errExit("fopen");
126
127 char buf[MAXBUF];
128 while (fgets(buf, MAXBUF, fp)) {
129 // remove \n
130 char *ptr = strchr(buf, '\n');
131 if (ptr)
132 *ptr = '\0';
133 fslib_duplicate(buf);
134 }
135 fclose(fp);
136}
137
138
139void fslib_copy_dir(const char *full_path) {
140 assert(full_path);
141 if (arg_debug || arg_debug_private_lib)
142 printf(" fslib_copy_dir %s\n", full_path);
143
144 // do nothing if the directory does not exist or is not owned by root
145 struct stat s;
146 if (stat(full_path, &s) != 0 || s.st_uid != 0 || !S_ISDIR(s.st_mode) || access(full_path, R_OK))
147 return;
148
149 char *dir_name = strrchr(full_path, '/');
150 assert(dir_name);
151 dir_name++;
152 assert(*dir_name != '\0');
153
154 // do nothing if the directory is already there
155 char *dest;
156 if (asprintf(&dest, "%s/%s", build_dest_dir(full_path), dir_name) == -1)
157 errExit("asprintf");
158 if (stat(dest, &s) == 0) {
159 free(dest);
160 return;
161 }
162
163 // create new directory and mount the original on top of it
164 mkdir_attr(dest, 0755, 0, 0);
165
166 if (mount(full_path, dest, NULL, MS_BIND|MS_REC, NULL) < 0 ||
167 mount(NULL, dest, NULL, MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0)
168 errExit("mount bind");
169 fs_logger2("clone", full_path);
170 fs_logger2("mount", full_path);
171 dir_cnt++;
172 free(dest);
173}
174
175// fname should be a vallid full path at this point
176static void load_library(const char *fname) {
177 assert(fname);
178 assert(*fname == '/');
179
180 // existing file owned by root, read access
181 struct stat s;
182 if (stat(fname, &s) == 0 && s.st_uid == 0 && !access(fname, R_OK)) {
183 // load directories, regular 64 bit libraries, and 64 bit executables
184 if (is_dir(fname) || is_lib_64(fname)) {
185 if (is_dir(fname))
186 fslib_copy_dir(fname);
187 else {
188 if (strstr(fname, ".so") ||
189 access(fname, X_OK) != 0) // don't duplicate executables, just install the libraries
190 fslib_duplicate(fname);
191
192 fslib_copy_libs(fname);
193 }
194 }
195 }
196}
197
198static void install_list_entry(const char *lib) {
199 // filename check
200 int len = strlen(lib);
201 if (strcspn(lib, "\\&!?\"'<>%^(){}[];,") != (size_t)len ||
202 strstr(lib, "..")) {
203 fprintf(stderr, "Error: \"%s\" is an invalid library\n", lib);
204 exit(1);
205 }
206
207 // if this is a full path, use it as is
208 if (*lib == '/')
209 return load_library(lib);
210
211
212 // find the library
213 int i;
214 for (i = 0; default_lib_paths[i]; i++) {
215 char *fname = NULL;
216 if (asprintf(&fname, "%s/%s", default_lib_paths[i], lib) == -1)
217 errExit("asprintf");
218
219#define DO_GLOBBING
220#ifdef DO_GLOBBING
221 // globbing
222 glob_t globbuf;
223 int globerr = glob(fname, GLOB_NOCHECK | GLOB_NOSORT | GLOB_PERIOD, NULL, &globbuf);
224 if (globerr) {
225 fprintf(stderr, "Error: failed to glob private-lib pattern %s\n", fname);
226 exit(1);
227 }
228 size_t j;
229 for (j = 0; j < globbuf.gl_pathc; j++) {
230 assert(globbuf.gl_pathv[j]);
231//printf("glob %s\n", globbuf.gl_pathv[j]);
232 // GLOB_NOCHECK - no pattern matched returns the original pattern; try to load it anyway
233 load_library(globbuf.gl_pathv[j]);
234 }
235
236 globfree(&globbuf);
237#else
238 load_library(fname);
239#endif
240 free(fname);
241 }
242
243// fwarning("%s library not found, skipping...\n", lib);
244 return;
245}
246
247
248void fslib_install_list(const char *lib_list) {
249 assert(lib_list);
250 if (arg_debug || arg_debug_private_lib)
251 printf(" fslib_install_list %s\n", lib_list);
252
253 char *dlist = strdup(lib_list);
254 if (!dlist)
255 errExit("strdup");
256
257 char *ptr = strtok(dlist, ",");
258 install_list_entry(ptr);
259
260 while ((ptr = strtok(NULL, ",")) != NULL)
261 install_list_entry(ptr);
262 free(dlist);
263 fs_logger_print();
264}
265
266
267
268static void mount_directories(void) {
269 if (arg_debug || arg_debug_private_lib)
270 printf("Mount-bind %s on top of /lib /lib64 /usr/lib\n", RUN_LIB_DIR);
271
272 if (is_dir("/lib")) {
273 if (mount(RUN_LIB_DIR, "/lib", NULL, MS_BIND|MS_REC, NULL) < 0 ||
274 mount(NULL, "/lib", NULL, MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0)
275 errExit("mount bind");
276 fs_logger2("tmpfs", "/lib");
277 fs_logger("mount /lib");
278 }
279
280 if (is_dir("/lib64")) {
281 if (mount(RUN_LIB_DIR, "/lib64", NULL, MS_BIND|MS_REC, NULL) < 0 ||
282 mount(NULL, "/lib64", NULL, MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0)
283 errExit("mount bind");
284 fs_logger2("tmpfs", "/lib64");
285 fs_logger("mount /lib64");
286 }
287
288 if (is_dir("/usr/lib")) {
289 if (mount(RUN_LIB_DIR, "/usr/lib", NULL, MS_BIND|MS_REC, NULL) < 0 ||
290 mount(NULL, "/usr/lib", NULL, MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0)
291 errExit("mount bind");
292 fs_logger2("tmpfs", "/usr/lib");
293 fs_logger("mount /usr/lib");
294 }
295
296 // for amd64 only - we'll deal with i386 later
297 if (is_dir("/lib32")) {
298 if (mount(RUN_RO_DIR, "/lib32", "none", MS_BIND, "mode=400,gid=0") < 0)
299 errExit("disable file");
300 fs_logger("blacklist-nolog /lib32");
301 }
302 if (is_dir("/libx32")) {
303 if (mount(RUN_RO_DIR, "/libx32", "none", MS_BIND, "mode=400,gid=0") < 0)
304 errExit("disable file");
305 fs_logger("blacklist-nolog /libx32");
306 }
307}
308
309void fs_private_lib(void) {
310#ifndef __x86_64__
311 fwarning("private-lib feature is currently available only on amd64 platforms\n");
312 return;
313#endif
314 char *private_list = cfg.lib_private_keep;
315 if (arg_debug || arg_debug_private_lib)
316 printf("Starting private-lib processing: program %s, shell %s\n",
317 (cfg.original_program_index > 0)? cfg.original_argv[cfg.original_program_index]: "none",
318 (arg_shell_none)? "none": cfg.shell);
319
320 // create /run/firejail/mnt/lib directory
321 mkdir_attr(RUN_LIB_DIR, 0755, 0, 0);
322
323 // install standard C libraries
324 if (arg_debug || arg_debug_private_lib)
325 printf("Installing standard C library\n");
326 fslib_install_stdc();
327
328 // start timetrace
329 timetrace_start();
330
331 // copy the libs in the new lib directory for the main exe
332 if (cfg.original_program_index > 0) {
333 if (arg_debug || arg_debug_private_lib)
334 printf("Installing sandboxed program libraries\n");
335 fslib_install_list(cfg.original_argv[cfg.original_program_index]);
336 }
337
338 // for the shell
339 if (!arg_shell_none) {
340 if (arg_debug || arg_debug_private_lib)
341 printf("Installing shell libraries\n");
342
343 fslib_install_list(cfg.shell);
344 // a shell is useless without some basic commands
345 fslib_install_list("/bin/ls,/bin/cat,/bin/mv,/bin/rm");
346
347 }
348
349 // for the listed libs and directories
350 if (private_list && *private_list != '\0') {
351 if (arg_debug || arg_debug_private_lib)
352 printf("Processing private-lib files\n");
353 fslib_install_list(private_list);
354 }
355
356 // for private-bin files
357 if (arg_private_bin && cfg.bin_private_lib && *cfg.bin_private_lib != '\0') {
358 if (arg_debug || arg_debug_private_lib)
359 printf("Processing private-bin files\n");
360 fslib_install_list(cfg.bin_private_lib);
361 }
362 fmessage("Program libraries installed in %0.2f ms\n", timetrace_end());
363
364 // install the reset of the system libraries
365 if (arg_debug || arg_debug_private_lib)
366 printf("Installing system libraries\n");
367 fslib_install_system();
368
369 // bring in firejail directory for --trace and seccomp post exec
370 // bring in firejail executable libraries in case we are redirected here by a firejail symlink from /usr/local/bin/firejail
371 fslib_install_list("/usr/bin/firejail,firejail"); // todo: use the installed path for the executable
372
373 fmessage("Installed %d %s and %d %s\n", lib_cnt, (lib_cnt == 1)? "library": "libraries",
374 dir_cnt, (dir_cnt == 1)? "directory": "directories");
375
376 // mount lib filesystem
377 mount_directories();
378}
diff --git a/src/firejail/fs_lib2.c b/src/firejail/fs_lib2.c
deleted file mode 100644
index ea5edfabe..000000000
--- a/src/firejail/fs_lib2.c
+++ /dev/null
@@ -1,314 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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 <dirent.h>
22#include <sys/stat.h>
23
24extern void fslib_duplicate(const char *full_path);
25extern void fslib_copy_libs(const char *full_path);
26extern void fslib_copy_dir(const char *full_path);
27
28//***************************************************************
29// Standard C library
30//***************************************************************
31// standard libc libraries based on Debian's libc6 package
32// selinux seems to be linked in most command line utilities
33// locale (/usr/lib/locale) - without it, the program will default to "C" locale
34typedef struct liblist_t {
35 const char *name;
36 int len;
37} LibList;
38
39static LibList libc_list[] = {
40 { "libselinux.so.", 0 },
41 { "ld-linux-x86-64.so.", 0 },
42 { "libanl.so.", 0 },
43 { "libc.so.", 0 },
44 { "libcidn.so.", 0 },
45 { "libcrypt.so.", 0 },
46 { "libdl.so.", 0 },
47 { "libm.so.", 0 },
48 { "libmemusage.so", 0 },
49 { "libmvec.so.", 0 },
50 { "libnsl.so.", 0 },
51 { "libnss_compat.so.", 0 },
52 { "libnss_dns.so.", 0 },
53 { "libnss_files.so.", 0 },
54 { "libnss_hesiod.so.", 0 },
55 { "libnss_nisplus.so.", 0 },
56 { "libnss_nis.so.", 0 },
57 { "libpthread.so.", 0 },
58 { "libresolv.so.", 0 },
59 { "librt.so.", 0 },
60 { "libthread_db.so.", 0 },
61 { "libutil.so.", 0 },
62 { NULL, 0}
63};
64
65static int find_libc_list(const char *name) {
66 assert(name);
67
68 int i = 0;
69 while (libc_list[i].name) {
70 if (libc_list[i].len == 0)
71 libc_list[i].len = strlen(libc_list[i].name);
72 if (strncmp(name, libc_list[i].name, libc_list[i].len) == 0)
73 return 1;
74 i++;
75 }
76 return 0;
77}
78
79// compare the files in dirname against liblist above
80static void stdc(const char *dirname) {
81 assert(dirname);
82
83 DIR *dir = opendir(dirname);
84 if (dir) {
85 struct dirent *entry;
86 while ((entry = readdir(dir)) != NULL) {
87 if (strcmp(entry->d_name, ".") == 0)
88 continue;
89 if (strcmp(entry->d_name, "..") == 0)
90 continue;
91
92 if (find_libc_list(entry->d_name)) {
93 char *fname;
94 if (asprintf(&fname, "%s/%s", dirname, entry->d_name) == -1)
95 errExit("asprintf");
96
97 fslib_duplicate(fname);
98 }
99 }
100 closedir(dir);
101 }
102}
103
104void fslib_install_stdc(void) {
105 // install standard C libraries
106 struct stat s;
107 char *stdclib = "/lib64"; // CentOS, Fedora, Arch
108
109 if (stat("/lib/x86_64-linux-gnu", &s) == 0) { // Debian & friends
110 mkdir_attr(RUN_LIB_DIR "/x86_64-linux-gnu", 0755, 0, 0);
111 stdclib = "/lib/x86_64-linux-gnu";
112 }
113
114 timetrace_start();
115 stdc(stdclib);
116
117 // install locale
118 if (stat("/usr/lib/locale", &s) == 0)
119 fslib_copy_dir("/usr/lib/locale");
120
121 fmessage("Standard C library installed in %0.2f ms\n", timetrace_end());
122}
123
124
125//***************************************************************
126// various system libraries
127//***************************************************************
128
129// look for library in the new filesystem, and install one or two more directories, dir1 and dir2
130typedef struct syslib_t {
131 const char *library; // look in the system for this library
132 int len; // length of library string, 0 by default
133 int found; // library found, 0 by default
134 const char *dir1; // directory to install
135 const char *dir2; // directory to install
136 const char *message; // message to print on the screen
137} SysLib;
138
139SysLib syslibs[] = {
140#if 0
141 {
142 "", // library
143 0, 0, // len and found flag
144 "", // dir1
145 "", // dir2
146 "" // message
147 },
148#endif
149 { // pixmaps - libraries used by GTK to display application menu icons
150 "libgdk_pixbuf-2.0", // library
151 0, 0, // len and found flag
152 "gdk-pixbuf-2.0", // dir1
153 "", // dir2
154 "GdkPixbuf" // message
155 },
156 { // GTK2
157 "libgtk-x11-2.0", // library
158 0, 0, // len and found flag
159 "gtk-2.0", // dir1
160 "libgtk2.0-0", // dir2
161 "GTK2" // message
162 },
163 { // GTK3
164 "libgtk-3", // library
165 0, 0, // len and found flag
166 "gtk-3.0", // dir1
167 "libgtk-3-0", // dir2
168 "GTK3" // message
169 },
170 { // Pango - text internationalization, found on older GTK2-based systems
171 "libpango", // library
172 0, 0, // len and found flag
173 "pango", // dir1
174 "", // dir2
175 "Pango" // message
176 },
177 { // Library for handling GObject introspection data on GTK systems
178 "libgirepository-1.0", // library
179 0, 0, // len and found flag
180 "girepository-1.0", // dir1
181 "", // dir2
182 "GIRepository" // message
183 },
184 { // GIO
185 "libgio", // library
186 0, 0, // len and found flag
187 "gio", // dir1
188 "", // dir2
189 "GIO" // message
190 },
191 { // Enchant speller
192 "libenchant.so.", // library
193 0, 0, // len and found flag
194 "enchant", // dir1
195 "", // dir2
196 "Enchant (speller)" // message
197 },
198 { // Qt5 - lots of problems on Arch Linux, Qt5 version 5.9.1 - disabled in all apps profiles
199 "libQt5", // library
200 0, 0, // len and found flag
201 "qt5", // dir1
202 "gdk-pixbuf-2.0", // dir2
203 "Qt5, GdkPixbuf" // message
204 },
205 { // Qt4
206 "libQtCore", // library
207 0, 0, // len and found flag
208 "qt4", // dir1
209 "gdk-pixbuf-2.0", // dir2
210 "Qt4" // message
211 },
212
213 { // NULL terminated list
214 NULL, // library
215 0, 0, // len and found flag
216 "", // dir1
217 "", // dir2
218 "" // message
219 }
220};
221
222void fslib_install_system(void) {
223 // look for installed libraries
224 DIR *dir = opendir(RUN_LIB_DIR "/x86_64-linux-gnu");
225 if (!dir)
226 dir = opendir(RUN_LIB_DIR);
227
228 if (dir) {
229 struct dirent *entry;
230 while ((entry = readdir(dir)) != NULL) {
231 if (strcmp(entry->d_name, ".") == 0)
232 continue;
233 if (strcmp(entry->d_name, "..") == 0)
234 continue;
235
236 SysLib *ptr = &syslibs[0];
237 while (ptr->library) {
238 if (ptr->len == 0)
239 ptr->len = strlen(ptr->library);
240
241 if (strncmp(entry->d_name, ptr->library, ptr->len) == 0) {
242 ptr->found = 1;
243 break;
244 }
245
246 ptr++;
247 }
248
249 }
250 closedir(dir);
251 }
252 else
253 assert(0);
254
255 // install required directories
256 SysLib *ptr = &syslibs[0];
257 while (ptr->library) {
258 if (ptr->found) {
259 assert(*ptr->message != '\0');
260 timetrace_start();
261
262 // bring in all libraries
263 assert(ptr->dir1);
264 char *name;
265 // Debian & friends
266 if (asprintf(&name, "/usr/lib/x86_64-linux-gnu/%s", ptr->dir1) == -1)
267 errExit("asprintf");
268 if (access(name, R_OK) == 0) {
269 fslib_copy_libs(name);
270 fslib_copy_dir(name);
271 }
272 else {
273 free(name);
274 // CentOS, Fedora, Arch
275 if (asprintf(&name, "/usr/lib64/%s", ptr->dir1) == -1)
276 errExit("asprintf");
277 if (access(name, R_OK) == 0) {
278 fslib_copy_libs(name);
279 fslib_copy_dir(name);
280 }
281 }
282 free(name);
283
284 if (*ptr->dir2 != '\0') {
285 // Debian & friends
286 if (asprintf(&name, "/usr/lib/x86_64-linux-gnu/%s", ptr->dir2) == -1)
287 errExit("asprintf");
288 if (access(name, R_OK) == 0) {
289 fslib_copy_libs(name);
290 fslib_copy_dir(name);
291 }
292 else {
293 free(name);
294 // CentOS, Fedora, Arch
295 if (asprintf(&name, "/usr/lib64/%s", ptr->dir2) == -1)
296 errExit("asprintf");
297 if (access(name, R_OK) == 0) {
298 fslib_copy_libs(name);
299 fslib_copy_dir(name);
300 }
301 }
302 free(name);
303 }
304
305 fmessage("%s installed in %0.2f ms\n", ptr->message, timetrace_end());
306 }
307 ptr++;
308 }
309}
310
311
312
313
314
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 3e092a3cc..ba5e8cdfd 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -339,6 +339,7 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
339 exit(0); 339 exit(0);
340 } 340 }
341#endif 341#endif
342#ifndef LTS
342#ifdef HAVE_X11 343#ifdef HAVE_X11
343 else if (strcmp(argv[i], "--x11") == 0) { 344 else if (strcmp(argv[i], "--x11") == 0) {
344 if (checkcfg(CFG_X11)) { 345 if (checkcfg(CFG_X11)) {
@@ -373,6 +374,7 @@ static void run_cmd_and_exit(int i, int argc, char **argv) {
373 exit_err_feature("x11"); 374 exit_err_feature("x11");
374 } 375 }
375#endif 376#endif
377#endif // LTS
376#ifdef HAVE_NETWORK 378#ifdef HAVE_NETWORK
377 else if (strncmp(argv[i], "--bandwidth=", 12) == 0) { 379 else if (strncmp(argv[i], "--bandwidth=", 12) == 0) {
378 if (checkcfg(CFG_NETWORK)) { 380 if (checkcfg(CFG_NETWORK)) {
@@ -825,6 +827,7 @@ static int check_arg(int argc, char **argv, const char *argument, int strict) {
825 return found; 827 return found;
826} 828}
827 829
830#ifndef LTS
828static void run_builder(int argc, char **argv) { 831static void run_builder(int argc, char **argv) {
829 EUID_ASSERT(); 832 EUID_ASSERT();
830 (void) argc; 833 (void) argc;
@@ -844,7 +847,7 @@ static void run_builder(int argc, char **argv) {
844 perror("execvp"); 847 perror("execvp");
845 exit(1); 848 exit(1);
846} 849}
847 850#endif // LTS
848 851
849//******************************************* 852//*******************************************
850// Main program 853// Main program
@@ -920,10 +923,11 @@ int main(int argc, char **argv) {
920 profile_add(cmd); 923 profile_add(cmd);
921 } 924 }
922 925
926#ifndef LTS
923 // profile builder 927 // profile builder
924 if (check_arg(argc, argv, "--build", 0)) // supports both --build and --build=filename 928 if (check_arg(argc, argv, "--build", 0)) // supports both --build and --build=filename
925 run_builder(argc, argv); // this function will not return 929 run_builder(argc, argv); // this function will not return
926 930#endif // LTS
927 // check argv[0] symlink wrapper if this is not a login shell 931 // check argv[0] symlink wrapper if this is not a login shell
928 if (*argv[0] != '-') 932 if (*argv[0] != '-')
929 run_symlink(argc, argv, 0); // if symlink detected, this function will not return 933 run_symlink(argc, argv, 0); // if symlink detected, this function will not return
@@ -1354,6 +1358,7 @@ int main(int argc, char **argv) {
1354 } 1358 }
1355 else if (strcmp(argv[i], "--disable-mnt") == 0) 1359 else if (strcmp(argv[i], "--disable-mnt") == 0)
1356 arg_disable_mnt = 1; 1360 arg_disable_mnt = 1;
1361#ifndef LTS
1357#ifdef HAVE_OVERLAYFS 1362#ifdef HAVE_OVERLAYFS
1358 else if (strcmp(argv[i], "--overlay") == 0) { 1363 else if (strcmp(argv[i], "--overlay") == 0) {
1359 if (checkcfg(CFG_OVERLAYFS)) { 1364 if (checkcfg(CFG_OVERLAYFS)) {
@@ -1441,6 +1446,7 @@ int main(int argc, char **argv) {
1441 exit_err_feature("overlayfs"); 1446 exit_err_feature("overlayfs");
1442 } 1447 }
1443#endif 1448#endif
1449#endif //LTS
1444 else if (strncmp(argv[i], "--profile=", 10) == 0) { 1450 else if (strncmp(argv[i], "--profile=", 10) == 0) {
1445 // multiple profile files are allowed! 1451 // multiple profile files are allowed!
1446 1452
@@ -1489,6 +1495,7 @@ int main(int argc, char **argv) {
1489 else 1495 else
1490 cfg.profile_ignore[j] = argv[i] + 9; 1496 cfg.profile_ignore[j] = argv[i] + 9;
1491 } 1497 }
1498#ifndef LTS
1492#ifdef HAVE_CHROOT 1499#ifdef HAVE_CHROOT
1493 else if (strncmp(argv[i], "--chroot=", 9) == 0) { 1500 else if (strncmp(argv[i], "--chroot=", 9) == 0) {
1494 if (checkcfg(CFG_CHROOT)) { 1501 if (checkcfg(CFG_CHROOT)) {
@@ -1537,6 +1544,7 @@ int main(int argc, char **argv) {
1537 exit_err_feature("chroot"); 1544 exit_err_feature("chroot");
1538 } 1545 }
1539#endif 1546#endif
1547#endif // LTS
1540 else if (strcmp(argv[i], "--writable-etc") == 0) { 1548 else if (strcmp(argv[i], "--writable-etc") == 0) {
1541 if (cfg.etc_private_keep) { 1549 if (cfg.etc_private_keep) {
1542 fprintf(stderr, "Error: --private-etc and --writable-etc are mutually exclusive\n"); 1550 fprintf(stderr, "Error: --private-etc and --writable-etc are mutually exclusive\n");
@@ -1583,6 +1591,7 @@ int main(int argc, char **argv) {
1583 } 1591 }
1584 arg_private = 1; 1592 arg_private = 1;
1585 } 1593 }
1594#ifndef LTS
1586#ifdef HAVE_PRIVATE_HOME 1595#ifdef HAVE_PRIVATE_HOME
1587 else if (strncmp(argv[i], "--private-home=", 15) == 0) { 1596 else if (strncmp(argv[i], "--private-home=", 15) == 0) {
1588 if (checkcfg(CFG_PRIVATE_HOME)) { 1597 if (checkcfg(CFG_PRIVATE_HOME)) {
@@ -1607,6 +1616,7 @@ int main(int argc, char **argv) {
1607 exit_err_feature("private-home"); 1616 exit_err_feature("private-home");
1608 } 1617 }
1609#endif 1618#endif
1619#endif //LTS
1610 else if (strcmp(argv[i], "--private-dev") == 0) { 1620 else if (strcmp(argv[i], "--private-dev") == 0) {
1611 arg_private_dev = 1; 1621 arg_private_dev = 1;
1612 } 1622 }
@@ -1657,6 +1667,7 @@ int main(int argc, char **argv) {
1657 cfg.srv_private_keep = argv[i] + 14; 1667 cfg.srv_private_keep = argv[i] + 14;
1658 arg_private_srv = 1; 1668 arg_private_srv = 1;
1659 } 1669 }
1670#ifndef LTS
1660 else if (strncmp(argv[i], "--private-bin=", 14) == 0) { 1671 else if (strncmp(argv[i], "--private-bin=", 14) == 0) {
1661 // extract private bin list 1672 // extract private bin list
1662 if (*(argv[i] + 14) == '\0') { 1673 if (*(argv[i] + 14) == '\0') {
@@ -1685,6 +1696,7 @@ int main(int argc, char **argv) {
1685 else 1696 else
1686 exit_err_feature("private-lib"); 1697 exit_err_feature("private-lib");
1687 } 1698 }
1699#endif // LTS
1688 else if (strcmp(argv[i], "--private-tmp") == 0) { 1700 else if (strcmp(argv[i], "--private-tmp") == 0) {
1689 arg_private_tmp = 1; 1701 arg_private_tmp = 1;
1690 } 1702 }
@@ -2100,6 +2112,7 @@ int main(int argc, char **argv) {
2100 //************************************* 2112 //*************************************
2101 else if (strncmp(argv[i], "--timeout=", 10) == 0) 2113 else if (strncmp(argv[i], "--timeout=", 10) == 0)
2102 cfg.timeout = extract_timeout(argv[i] + 10); 2114 cfg.timeout = extract_timeout(argv[i] + 10);
2115#ifndef LTS
2103 else if (strcmp(argv[i], "--audit") == 0) { 2116 else if (strcmp(argv[i], "--audit") == 0) {
2104 arg_audit_prog = LIBDIR "/firejail/faudit"; 2117 arg_audit_prog = LIBDIR "/firejail/faudit";
2105 arg_audit = 1; 2118 arg_audit = 1;
@@ -2120,6 +2133,7 @@ int main(int argc, char **argv) {
2120 } 2133 }
2121 arg_audit = 1; 2134 arg_audit = 1;
2122 } 2135 }
2136#endif // LTS
2123 else if (strcmp(argv[i], "--appimage") == 0) 2137 else if (strcmp(argv[i], "--appimage") == 0)
2124 arg_appimage = 1; 2138 arg_appimage = 1;
2125 else if (strcmp(argv[i], "--shell=none") == 0) { 2139 else if (strcmp(argv[i], "--shell=none") == 0) {
@@ -2364,10 +2378,11 @@ int main(int argc, char **argv) {
2364 } 2378 }
2365 EUID_ASSERT(); 2379 EUID_ASSERT();
2366 2380
2381#ifndef LTS
2367 // block X11 sockets 2382 // block X11 sockets
2368 if (arg_x11_block) 2383 if (arg_x11_block)
2369 x11_block(); 2384 x11_block();
2370 2385#endif //LTS
2371 // check network configuration options - it will exit if anything went wrong 2386 // check network configuration options - it will exit if anything went wrong
2372 net_check_cfg(); 2387 net_check_cfg();
2373 2388
@@ -2422,9 +2437,11 @@ int main(int argc, char **argv) {
2422 } 2437 }
2423 if (cfg.name) 2438 if (cfg.name)
2424 set_name_run_file(sandbox_pid); 2439 set_name_run_file(sandbox_pid);
2440#ifndef LTS
2425 int display = x11_display(); 2441 int display = x11_display();
2426 if (display > 0) 2442 if (display > 0)
2427 set_x11_run_file(sandbox_pid, display); 2443 set_x11_run_file(sandbox_pid, display);
2444#endif
2428 flock(lockfd_directory, LOCK_UN); 2445 flock(lockfd_directory, LOCK_UN);
2429 close(lockfd_directory); 2446 close(lockfd_directory);
2430 EUID_USER(); 2447 EUID_USER();
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 4b2fb3abd..c3ef2f2f5 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -198,6 +198,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
198 arg_private = 1; 198 arg_private = 1;
199 return 0; 199 return 0;
200 } 200 }
201#ifndef LTS
201 if (strncmp(ptr, "private-home ", 13) == 0) { 202 if (strncmp(ptr, "private-home ", 13) == 0) {
202#ifdef HAVE_PRIVATE_HOME 203#ifdef HAVE_PRIVATE_HOME
203 if (checkcfg(CFG_PRIVATE_HOME)) { 204 if (checkcfg(CFG_PRIVATE_HOME)) {
@@ -213,6 +214,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
213#endif 214#endif
214 return 0; 215 return 0;
215 } 216 }
217#endif //LTS
216 else if (strcmp(ptr, "allusers") == 0) { 218 else if (strcmp(ptr, "allusers") == 0) {
217 arg_allusers = 1; 219 arg_allusers = 1;
218 return 0; 220 return 0;
@@ -790,6 +792,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
790 return 0; 792 return 0;
791 } 793 }
792 794
795#ifndef LTS
793 if (strcmp(ptr, "x11 xephyr") == 0) { 796 if (strcmp(ptr, "x11 xephyr") == 0) {
794#ifdef HAVE_X11 797#ifdef HAVE_X11
795 if (checkcfg(CFG_X11)) { 798 if (checkcfg(CFG_X11)) {
@@ -875,7 +878,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
875#endif 878#endif
876 return 0; 879 return 0;
877 } 880 }
878 881#endif //LTS
879 // private /etc list of files and directories 882 // private /etc list of files and directories
880 if (strncmp(ptr, "private-etc ", 12) == 0) { 883 if (strncmp(ptr, "private-etc ", 12) == 0) {
881 if (arg_writable_etc) { 884 if (arg_writable_etc) {
@@ -949,7 +952,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
949 return 0; 952 return 0;
950 } 953 }
951 954
952 955#ifndef LTS
953#ifdef HAVE_OVERLAYFS 956#ifdef HAVE_OVERLAYFS
954 if (strncmp(ptr, "overlay-named ", 14) == 0) { 957 if (strncmp(ptr, "overlay-named ", 14) == 0) {
955 if (checkcfg(CFG_OVERLAYFS)) { 958 if (checkcfg(CFG_OVERLAYFS)) {
@@ -1034,6 +1037,7 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
1034 } 1037 }
1035 } 1038 }
1036#endif 1039#endif
1040#endif // LTS
1037 1041
1038 // filesystem bind 1042 // filesystem bind
1039 if (strncmp(ptr, "bind ", 5) == 0) { 1043 if (strncmp(ptr, "bind ", 5) == 0) {
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 66881c040..06c2dbf5b 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -391,6 +391,7 @@ void start_application(int no_sandbox) {
391 //**************************************** 391 //****************************************
392 // audit 392 // audit
393 //**************************************** 393 //****************************************
394#ifndef LTS
394 if (arg_audit) { 395 if (arg_audit) {
395 assert(arg_audit_prog); 396 assert(arg_audit_prog);
396#ifdef HAVE_GCOV 397#ifdef HAVE_GCOV
@@ -404,7 +405,9 @@ void start_application(int no_sandbox) {
404 //**************************************** 405 //****************************************
405 // start the program without using a shell 406 // start the program without using a shell
406 //**************************************** 407 //****************************************
407 else if (arg_shell_none) { 408 else
409#endif // LTS
410 if (arg_shell_none) {
408 if (arg_debug) { 411 if (arg_debug) {
409 int i; 412 int i;
410 for (i = cfg.original_program_index; i < cfg.original_argc; i++) { 413 for (i = cfg.original_program_index; i < cfg.original_argc; i++) {
@@ -732,6 +735,7 @@ int sandbox(void* sandbox_arg) {
732 if (arg_appimage) 735 if (arg_appimage)
733 enforce_filters(); 736 enforce_filters();
734 737
738#ifndef LTS
735#ifdef HAVE_CHROOT 739#ifdef HAVE_CHROOT
736 if (cfg.chrootdir) { 740 if (cfg.chrootdir) {
737 fs_chroot(cfg.chrootdir); 741 fs_chroot(cfg.chrootdir);
@@ -761,6 +765,7 @@ int sandbox(void* sandbox_arg) {
761 } 765 }
762 else 766 else
763#endif 767#endif
768#endif // LTS
764 fs_basic_fs(); 769 fs_basic_fs();
765 770
766 //**************************** 771 //****************************
@@ -775,6 +780,7 @@ int sandbox(void* sandbox_arg) {
775 else 780 else
776 fs_private_homedir(); 781 fs_private_homedir();
777 } 782 }
783#ifndef LTS
778 else if (cfg.home_private_keep) { // --private-home= 784 else if (cfg.home_private_keep) { // --private-home=
779 if (cfg.chrootdir) 785 if (cfg.chrootdir)
780 fwarning("private-home= feature is disabled in chroot\n"); 786 fwarning("private-home= feature is disabled in chroot\n");
@@ -784,6 +790,7 @@ int sandbox(void* sandbox_arg) {
784 fs_private_home_list(); 790 fs_private_home_list();
785 } 791 }
786 else // --private 792 else // --private
793#endif //LTS
787 fs_private(); 794 fs_private();
788 } 795 }
789 796
@@ -823,6 +830,7 @@ int sandbox(void* sandbox_arg) {
823 } 830 }
824 } 831 }
825 832
833#ifndef LTS
826 // private-bin is disabled for appimages 834 // private-bin is disabled for appimages
827 if (arg_private_bin && !arg_appimage) { 835 if (arg_private_bin && !arg_appimage) {
828 if (cfg.chrootdir) 836 if (cfg.chrootdir)
@@ -853,6 +861,7 @@ int sandbox(void* sandbox_arg) {
853 fs_private_lib(); 861 fs_private_lib();
854 } 862 }
855 } 863 }
864#endif // LTS
856 865
857 if (arg_private_cache) { 866 if (arg_private_cache) {
858 if (cfg.chrootdir) 867 if (cfg.chrootdir)
@@ -1001,10 +1010,12 @@ int sandbox(void* sandbox_arg) {
1001 } 1010 }
1002 } 1011 }
1003 1012
1013#ifndef LTS
1004 // clean /tmp/.X11-unix sockets 1014 // clean /tmp/.X11-unix sockets
1005 fs_x11(); 1015 fs_x11();
1006 if (arg_x11_xorg) 1016 if (arg_x11_xorg)
1007 x11_xorg(); 1017 x11_xorg();
1018#endif //LTS
1008 1019
1009 //**************************** 1020 //****************************
1010 // set security filters 1021 // set security filters
diff --git a/src/firejail/x11.c b/src/firejail/x11.c
deleted file mode 100644
index 9cbe6598e..000000000
--- a/src/firejail/x11.c
+++ /dev/null
@@ -1,1311 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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 <sys/socket.h>
24#include <sys/un.h>
25#include <unistd.h>
26#include <signal.h>
27#include <stdlib.h>
28#include <dirent.h>
29#include <sys/mount.h>
30#include <sys/wait.h>
31#include <errno.h>
32#include <limits.h>
33
34// on Debian 7 we are missing O_PATH definition
35#include <fcntl.h>
36#ifndef O_PATH
37#define O_PATH 010000000
38#endif
39
40
41// Parse the DISPLAY environment variable and return a display number.
42// Returns -1 if DISPLAY is not set, or is set to anything other than :ddd.
43int x11_display(void) {
44 const char *display_str = getenv("DISPLAY");
45 char *endp;
46 unsigned long display;
47
48 if (!display_str) {
49 if (arg_debug)
50 fputs("DISPLAY is not set\n", stderr);
51 return -1;
52 }
53
54 if (display_str[0] != ':' || display_str[1] < '0' || display_str[1] > '9') {
55 if (arg_debug)
56 fprintf(stderr, "unsupported DISPLAY form '%s'\n", display_str);
57 return -1;
58 }
59
60 errno = 0;
61 display = strtoul(display_str+1, &endp, 10);
62 // handling DISPLAY=:0 and also :0.0
63 if (endp == display_str+1 || (*endp != '\0' && *endp != '.')) {
64 if (arg_debug)
65 fprintf(stderr, "unsupported DISPLAY form '%s'\n", display_str);
66 return -1;
67 }
68 if (errno || display > (unsigned long)INT_MAX) {
69 if (arg_debug)
70 fprintf(stderr, "display number %s is outside the valid range\n",
71 display_str+1);
72 return -1;
73 }
74
75 if (arg_debug)
76 fprintf(stderr, "DISPLAY=%s parsed as %lu\n", display_str, display);
77
78 return (int)display;
79}
80
81
82#ifdef HAVE_X11
83// check for X11 abstract sockets
84static int x11_abstract_sockets_present(void) {
85
86 EUID_ROOT(); // grsecurity fix
87 FILE *fp = fopen("/proc/net/unix", "r");
88 if (!fp)
89 errExit("fopen");
90 EUID_USER();
91
92 char *linebuf = 0;
93 size_t bufsz = 0;
94 int found = 0;
95 errno = 0;
96
97 for (;;) {
98 if (getline(&linebuf, &bufsz, fp) == -1) {
99 if (errno)
100 errExit("getline");
101 break;
102 }
103 // The last space-separated field in 'linebuf' is the
104 // pathname of the socket. Abstract sockets' pathnames
105 // all begin with '@/', normal ones begin with '/'.
106 char *p = strrchr(linebuf, ' ');
107 if (!p) {
108 fputs("error parsing /proc/net/unix\n", stderr);
109 exit(1);
110 }
111 if (strncmp(p+1, "@/tmp/.X11-unix/", 16) == 0) {
112 found = 1;
113 break;
114 }
115 }
116
117 free(linebuf);
118 fclose(fp);
119 return found;
120}
121
122
123// Choose a random, unallocated display number. This has an inherent
124// and unavoidable TOCTOU race, since we cannot create either the
125// socket or a lockfile ourselves.
126static int random_display_number(void) {
127 int display;
128 int found = 0;
129 int i;
130
131 struct sockaddr_un sa;
132 // The -1 here is because we need space to inject a
133 // leading nul byte.
134 int sun_pathmax = (int)(sizeof sa.sun_path - 1);
135 assert((size_t)sun_pathmax == sizeof sa.sun_path - 1);
136 int sun_pathlen;
137
138 int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
139 if (sockfd == -1)
140 errExit("socket");
141
142 for (i = 0; i < 100; i++) {
143 display = rand() % (X11_DISPLAY_END - X11_DISPLAY_START) + X11_DISPLAY_START;
144
145 // The display number might be claimed by a server listening
146 // in _either_ the normal or the abstract namespace; they
147 // don't necessarily do both. The easiest way to check is
148 // to try to connect, both ways.
149 memset(&sa, 0, sizeof sa);
150 sa.sun_family = AF_UNIX;
151 sun_pathlen = snprintf(sa.sun_path, sun_pathmax,
152 "/tmp/.X11-unix/X%d", display);
153 if (sun_pathlen >= sun_pathmax) {
154 fprintf(stderr, "sun_path too small for display :%d"
155 " (only %d bytes usable)\n", display, sun_pathmax);
156 exit(1);
157 }
158
159 if (connect(sockfd, (struct sockaddr *)&sa,
160 offsetof(struct sockaddr_un, sun_path) + sun_pathlen + 1) == 0) {
161 close(sockfd);
162 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
163 if (sockfd == -1)
164 errExit("socket");
165 continue;
166 }
167 if (errno != ECONNREFUSED && errno != ENOENT)
168 errExit("connect");
169
170 // Name not claimed in the normal namespace; now try it
171 // in the abstract namespace. Note that abstract-namespace
172 // names are NOT nul-terminated; they extend to the length
173 // specified as the third argument to 'connect'.
174 memmove(sa.sun_path + 1, sa.sun_path, sun_pathlen + 1);
175 sa.sun_path[0] = '\0';
176 if (connect(sockfd, (struct sockaddr *)&sa,
177 offsetof(struct sockaddr_un, sun_path) + 1 + sun_pathlen) == 0) {
178 close(sockfd);
179 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
180 if (sockfd == -1)
181 errExit("socket");
182 continue;
183 }
184 if (errno != ECONNREFUSED && errno != ENOENT)
185 errExit("connect");
186
187 // This display number is unclaimed. Of course, it could
188 // be claimed before we get around to doing it...
189 found = 1;
190 break;
191 }
192 close(sockfd);
193
194 if (!found) {
195 fputs("Error: cannot find an unallocated X11 display number, "
196 "exiting...\n", stderr);
197 exit(1);
198 }
199 return display;
200}
201#endif
202
203#ifdef HAVE_X11
204void x11_start_xvfb(int argc, char **argv) {
205 EUID_ASSERT();
206 int i;
207 struct stat s;
208 pid_t jail = 0;
209 pid_t server = 0;
210
211 setenv("FIREJAIL_X11", "yes", 1);
212
213 // mever try to run X servers as root!!!
214 if (getuid() == 0) {
215 fprintf(stderr, "Error: X11 sandboxing is not available when running as root\n");
216 exit(1);
217 }
218 drop_privs(0);
219
220 // check xvfb
221 if (!program_in_path("Xvfb")) {
222 fprintf(stderr, "\nError: Xvfb program was not found in /usr/bin directory, please install it:\n");
223 fprintf(stderr, " Debian/Ubuntu/Mint: sudo apt-get install xvfb\n");
224 fprintf(stderr, " Arch: sudo pacman -S xorg-server-xvfb\n");
225 exit(0);
226 }
227
228 int display = random_display_number();
229 char *display_str;
230 if (asprintf(&display_str, ":%d", display) == -1)
231 errExit("asprintf");
232
233 assert(xvfb_screen);
234
235 char *server_argv[256] = { // rest initialyzed to NULL
236 "Xvfb", display_str, "-screen", "0", xvfb_screen
237 };
238 unsigned pos = 0;
239 while (server_argv[pos] != NULL) pos++;
240 assert(xvfb_extra_params); // should be "" if empty
241
242 // parse xvfb_extra_params
243 // very basic quoting support
244 char *temp = strdup(xvfb_extra_params);
245 if (*xvfb_extra_params != '\0') {
246 if (!temp)
247 errExit("strdup");
248 bool dquote = false;
249 bool squote = false;
250 for (i = 0; i < (int) strlen(xvfb_extra_params); i++) {
251 if (temp[i] == '\"') {
252 dquote = !dquote;
253 // replace closing quote by \0
254 if (dquote) temp[i] = '\0';
255 }
256 if (temp[i] == '\'') {
257 squote = !squote;
258 // replace closing quote by \0
259 if (squote) temp[i] = '\0';
260 }
261 if (!dquote && !squote && temp[i] == ' ') temp[i] = '\0';
262 if (dquote && squote) {
263 fprintf(stderr, "Error: mixed quoting found while parsing xvfb_extra_params\n");
264 exit(1);
265 }
266 }
267 if (dquote) {
268 fprintf(stderr, "Error: unclosed quote found while parsing xvfb_extra_params\n");
269 exit(1);
270 }
271
272 server_argv[pos++] = temp;
273 for (i = 0; i < (int) strlen(xvfb_extra_params)-1; i++) {
274 if (pos >= (sizeof(server_argv)/sizeof(*server_argv)) - 2) {
275 fprintf(stderr, "Error: arg count limit exceeded while parsing xvfb_extra_params\n");
276 exit(1);
277 }
278 if (temp[i] == '\0' && (temp[i+1] == '\"' || temp[i+1] == '\'')) server_argv[pos++] = temp + i + 2;
279 else if (temp[i] == '\0' && temp[i+1] != '\0') server_argv[pos++] = temp + i + 1;
280 }
281 }
282
283 server_argv[pos++] = NULL;
284
285 assert(pos < (sizeof(server_argv)/sizeof(*server_argv))); // no overrun
286 assert(server_argv[pos-1] == NULL); // last element is null
287
288 if (arg_debug) {
289 size_t i = 0;
290 printf("\n*** Starting xvfb server:");
291 while (server_argv[i]!=NULL) {
292 printf(" \"%s\"", server_argv[i]);
293 i++;
294 }
295 printf(" ***\n\n");
296 }
297
298 // remove --x11 arg
299 char *jail_argv[argc+2];
300 int j = 0;
301 for (i = 0; i < argc; i++) {
302 if (strncmp(argv[i], "--x11", 5) == 0)
303 continue;
304 jail_argv[j] = argv[i];
305 j++;
306 }
307 jail_argv[j] = NULL;
308
309 assert(j < argc+2); // no overrun
310
311 if (arg_debug) {
312 size_t i = 0;
313 printf("\n*** Stating xvfb client:");
314 while (jail_argv[i]!=NULL) {
315 printf(" \"%s\"", jail_argv[i]);
316 i++;
317 }
318 printf(" ***\n\n");
319 }
320
321 server = fork();
322 if (server < 0)
323 errExit("fork");
324 if (server == 0) {
325 if (arg_debug)
326 printf("Starting xvfb...\n");
327
328 // running without privileges - see drop_privs call above
329 assert(getenv("LD_PRELOAD") == NULL);
330 execvp(server_argv[0], server_argv);
331 perror("execvp");
332 _exit(1);
333 }
334
335 if (arg_debug)
336 printf("xvfb server pid %d\n", server);
337
338 // check X11 socket
339 char *fname;
340 if (asprintf(&fname, "/tmp/.X11-unix/X%d", display) == -1)
341 errExit("asprintf");
342 int n = 0;
343 // wait for x11 server to start
344 while (++n < 10) {
345 sleep(1);
346 if (stat(fname, &s) == 0)
347 break;
348 };
349
350 if (n == 10) {
351 fprintf(stderr, "Error: failed to start xvfb\n");
352 exit(1);
353 }
354 free(fname);
355
356 assert(display_str);
357 setenv("DISPLAY", display_str, 1);
358 // run attach command
359 jail = fork();
360 if (jail < 0)
361 errExit("fork");
362 if (jail == 0) {
363 fmessage("\n*** Attaching to Xvfb display %d ***\n\n", display);
364
365 // running without privileges - see drop_privs call above
366 assert(getenv("LD_PRELOAD") == NULL);
367 execvp(jail_argv[0], jail_argv);
368 perror("execvp");
369 _exit(1);
370 }
371
372 // cleanup
373 free(display_str);
374 free(temp);
375
376 // wait for either server or jail termination
377 pid_t pid = wait(NULL);
378
379 // see which process terminated and kill other
380 if (pid == server) {
381 kill(jail, SIGTERM);
382 }
383 else if (pid == jail) {
384 kill(server, SIGTERM);
385 }
386
387 // without this closing Xephyr window may mess your terminal:
388 // "monitoring" process will release terminal before
389 // jail process ends and releases terminal
390 wait(NULL); // fulneral
391
392 exit(0);
393}
394
395
396static char *extract_setting(int argc, char **argv, const char *argument) {
397 int i;
398 int len = strlen(argument);
399
400 for (i = 1; i < argc; i++) {
401 if (strncmp(argv[i], argument, len) == 0) {
402 return argv[i] + len;
403 }
404
405 // detect end of firejail params
406 if (strcmp(argv[i], "--") == 0)
407 break;
408 if (strncmp(argv[i], "--", 2) != 0)
409 break;
410 }
411
412 return NULL;
413}
414
415
416//$ Xephyr -ac -br -noreset -screen 800x600 :22 &
417//$ DISPLAY=:22 firejail --net=eth0 --blacklist=/tmp/.X11-unix/x0 firefox
418void x11_start_xephyr(int argc, char **argv) {
419 EUID_ASSERT();
420 int i;
421 struct stat s;
422 pid_t jail = 0;
423 pid_t server = 0;
424
425 // default xephyr screen can be overwriten by a --xephyr-screen= command line option
426 char *newscreen = extract_setting(argc, argv, "--xephyr-screen=");
427 if (newscreen)
428 xephyr_screen = newscreen;
429
430 setenv("FIREJAIL_X11", "yes", 1);
431
432 // unfortunately, xephyr does a number of weird things when started by root user!!!
433 if (getuid() == 0) {
434 fprintf(stderr, "Error: X11 sandboxing is not available when running as root\n");
435 exit(1);
436 }
437 drop_privs(0);
438
439 // check xephyr
440 if (!program_in_path("Xephyr")) {
441 fprintf(stderr, "\nError: Xephyr program was not found in /usr/bin directory, please install it:\n");
442 fprintf(stderr, " Debian/Ubuntu/Mint: sudo apt-get install xserver-xephyr\n");
443 fprintf(stderr, " Arch: sudo pacman -S xorg-server-xephyr\n");
444 exit(0);
445 }
446
447 int display = random_display_number();
448 char *display_str;
449 if (asprintf(&display_str, ":%d", display) == -1)
450 errExit("asprintf");
451
452 assert(xephyr_screen);
453 char *server_argv[256] = { // rest initialyzed to NULL
454 "Xephyr", "-ac", "-br", "-noreset", "-screen", xephyr_screen
455 };
456 unsigned pos = 0;
457 while (server_argv[pos] != NULL) pos++;
458 if (checkcfg(CFG_XEPHYR_WINDOW_TITLE)) {
459 server_argv[pos++] = "-title";
460 server_argv[pos++] = "firejail x11 sandbox";
461 }
462
463 assert(xephyr_extra_params); // should be "" if empty
464
465 // parse xephyr_extra_params
466 // very basic quoting support
467 char *temp = strdup(xephyr_extra_params);
468 if (*xephyr_extra_params != '\0') {
469 if (!temp)
470 errExit("strdup");
471 bool dquote = false;
472 bool squote = false;
473 for (i = 0; i < (int) strlen(xephyr_extra_params); i++) {
474 if (temp[i] == '\"') {
475 dquote = !dquote;
476 // replace closing quote by \0
477 if (dquote) temp[i] = '\0';
478 }
479 if (temp[i] == '\'') {
480 squote = !squote;
481 // replace closing quote by \0
482 if (squote) temp[i] = '\0';
483 }
484 if (!dquote && !squote && temp[i] == ' ') temp[i] = '\0';
485 if (dquote && squote) {
486 fprintf(stderr, "Error: mixed quoting found while parsing xephyr_extra_params\n");
487 exit(1);
488 }
489 }
490 if (dquote) {
491 fprintf(stderr, "Error: unclosed quote found while parsing xephyr_extra_params\n");
492 exit(1);
493 }
494
495 server_argv[pos++] = temp;
496 for (i = 0; i < (int) strlen(xephyr_extra_params)-1; i++) {
497 if (pos >= (sizeof(server_argv)/sizeof(*server_argv)) - 2) {
498 fprintf(stderr, "Error: arg count limit exceeded while parsing xephyr_extra_params\n");
499 exit(1);
500 }
501 if (temp[i] == '\0' && (temp[i+1] == '\"' || temp[i+1] == '\'')) {
502 server_argv[pos++] = temp + i + 2;
503 }
504 else if (temp[i] == '\0' && temp[i+1] != '\0') {
505 server_argv[pos++] = temp + i + 1;
506 }
507 }
508 }
509
510 server_argv[pos++] = display_str;
511 server_argv[pos++] = NULL;
512
513 // no overrun
514 assert(pos < (sizeof(server_argv)/sizeof(*server_argv)));
515 assert(server_argv[pos-1] == NULL); // last element is null
516
517 {
518 size_t i = 0;
519 printf("\n*** Starting xephyr server:");
520 while (server_argv[i]!=NULL) {
521 printf(" \"%s\"", server_argv[i]);
522 i++;
523 }
524 printf(" ***\n\n");
525 }
526
527 // remove --x11 arg
528 char *jail_argv[argc+2];
529 int j = 0;
530 for (i = 0; i < argc; i++) {
531 if (strncmp(argv[i], "--x11", 5) == 0)
532 continue;
533 jail_argv[j] = argv[i];
534 j++;
535 }
536 jail_argv[j] = NULL;
537
538 assert(j < argc+2); // no overrun
539
540 if (arg_debug) {
541 size_t i = 0;
542 printf("*** Starting xephyr client:");
543 while (jail_argv[i]!=NULL) {
544 printf(" \"%s\"", jail_argv[i]);
545 i++;
546 }
547 printf(" ***\n\n");
548 }
549
550 server = fork();
551 if (server < 0)
552 errExit("fork");
553 if (server == 0) {
554 if (arg_debug)
555 printf("Starting xephyr...\n");
556
557 // running without privileges - see drop_privs call above
558 assert(getenv("LD_PRELOAD") == NULL);
559 execvp(server_argv[0], server_argv);
560 perror("execvp");
561 _exit(1);
562 }
563
564 if (arg_debug)
565 printf("xephyr server pid %d\n", server);
566
567 // check X11 socket
568 char *fname;
569 if (asprintf(&fname, "/tmp/.X11-unix/X%d", display) == -1)
570 errExit("asprintf");
571 int n = 0;
572 // wait for x11 server to start
573 while (++n < 10) {
574 sleep(1);
575 if (stat(fname, &s) == 0)
576 break;
577 };
578
579 if (n == 10) {
580 fprintf(stderr, "Error: failed to start xephyr\n");
581 exit(1);
582 }
583 free(fname);
584
585 assert(display_str);
586 setenv("DISPLAY", display_str, 1);
587 // run attach command
588 jail = fork();
589 if (jail < 0)
590 errExit("fork");
591 if (jail == 0) {
592 if (!arg_quiet)
593 printf("\n*** Attaching to Xephyr display %d ***\n\n", display);
594
595 // running without privileges - see drop_privs call above
596 assert(getenv("LD_PRELOAD") == NULL);
597 execvp(jail_argv[0], jail_argv);
598 perror("execvp");
599 _exit(1);
600 }
601
602 // cleanup
603 free(display_str);
604 free(temp);
605
606 // wait for either server or jail termination
607 pid_t pid = wait(NULL);
608
609 // see which process terminated and kill other
610 if (pid == server) {
611 kill(jail, SIGTERM);
612 }
613 else if (pid == jail) {
614 kill(server, SIGTERM);
615 }
616
617 // without this closing Xephyr window may mess your terminal:
618 // "monitoring" process will release terminal before
619 // jail process ends and releases terminal
620 wait(NULL); // fulneral
621
622 exit(0);
623}
624
625
626void x11_start_xpra_old(int argc, char **argv, int display, char *display_str) {
627 EUID_ASSERT();
628 int i;
629 struct stat s;
630 pid_t client = 0;
631 pid_t server = 0;
632
633 // build the start command
634 char *server_argv[256] = { // rest initialyzed to NULL
635 "xpra", "start", display_str, "--no-daemon",
636 };
637 unsigned pos = 0;
638 while (server_argv[pos] != NULL) pos++;
639
640 assert(xpra_extra_params); // should be "" if empty
641
642 // parse xephyr_extra_params
643 // very basic quoting support
644 char *temp = strdup(xpra_extra_params);
645 if (*xpra_extra_params != '\0') {
646 if (!temp)
647 errExit("strdup");
648 bool dquote = false;
649 bool squote = false;
650 for (i = 0; i < (int) strlen(xpra_extra_params); i++) {
651 if (temp[i] == '\"') {
652 dquote = !dquote;
653 // replace closing quote by \0
654 if (dquote) temp[i] = '\0';
655 }
656 if (temp[i] == '\'') {
657 squote = !squote;
658 // replace closing quote by \0
659 if (squote) temp[i] = '\0';
660 }
661 if (!dquote && !squote && temp[i] == ' ') temp[i] = '\0';
662 if (dquote && squote) {
663 fprintf(stderr, "Error: mixed quoting found while parsing xpra_extra_params\n");
664 exit(1);
665 }
666 }
667 if (dquote) {
668 fprintf(stderr, "Error: unclosed quote found while parsing xpra_extra_params\n");
669 exit(1);
670 }
671
672 server_argv[pos++] = temp;
673 for (i = 0; i < (int) strlen(xpra_extra_params)-1; i++) {
674 if (pos >= (sizeof(server_argv)/sizeof(*server_argv)) - 2) {
675 fprintf(stderr, "Error: arg count limit exceeded while parsing xpra_extra_params\n");
676 exit(1);
677 }
678 if (temp[i] == '\0' && (temp[i+1] == '\"' || temp[i+1] == '\'')) {
679 server_argv[pos++] = temp + i + 2;
680 }
681 else if (temp[i] == '\0' && temp[i+1] != '\0') {
682 server_argv[pos++] = temp + i + 1;
683 }
684 }
685 }
686
687 server_argv[pos++] = NULL;
688
689 // no overrun
690 assert(pos < (sizeof(server_argv)/sizeof(*server_argv)));
691 assert(server_argv[pos-1] == NULL); // last element is null
692
693 if (arg_debug) {
694 size_t i = 0;
695 printf("\n*** Starting xpra server: ");
696 while (server_argv[i]!=NULL) {
697 printf(" \"%s\"", server_argv[i]);
698 i++;
699 }
700 printf(" ***\n\n");
701 }
702
703 int fd_null = -1;
704 if (arg_quiet) {
705 fd_null = open("/dev/null", O_RDWR);
706 if (fd_null == -1)
707 errExit("open");
708 }
709
710 // start
711 server = fork();
712 if (server < 0)
713 errExit("fork");
714 if (server == 0) {
715 if (arg_debug)
716 printf("Starting xpra...\n");
717
718 if (arg_quiet && fd_null != -1) {
719 dup2(fd_null,0);
720 dup2(fd_null,1);
721 dup2(fd_null,2);
722 }
723
724 // running without privileges - see drop_privs call above
725 assert(getenv("LD_PRELOAD") == NULL);
726 execvp(server_argv[0], server_argv);
727 perror("execvp");
728 _exit(1);
729 }
730
731 // add a small delay, on some systems it takes some time for the server to start
732 sleep(5);
733
734 // check X11 socket
735 char *fname;
736 if (asprintf(&fname, "/tmp/.X11-unix/X%d", display) == -1)
737 errExit("asprintf");
738 int n = 0;
739 // wait for x11 server to start
740 while (++n < 10) {
741 sleep(1);
742 if (stat(fname, &s) == 0)
743 break;
744 }
745
746 if (n == 10) {
747 fprintf(stderr, "Error: failed to start xpra\n");
748 exit(1);
749 }
750 free(fname);
751
752 // build attach command
753 char *attach_argv[] = { "xpra", "--title=\"firejail x11 sandbox\"", "attach", display_str, NULL };
754
755 // run attach command
756 client = fork();
757 if (client < 0)
758 errExit("fork");
759 if (client == 0) {
760 if (arg_quiet && fd_null != -1) {
761 dup2(fd_null,0);
762 dup2(fd_null,1);
763 dup2(fd_null,2);
764 }
765
766 fmessage("\n*** Attaching to xpra display %d ***\n\n", display);
767
768 // running without privileges - see drop_privs call above
769 assert(getenv("LD_PRELOAD") == NULL);
770 execvp(attach_argv[0], attach_argv);
771 perror("execvp");
772 _exit(1);
773 }
774
775 assert(display_str);
776 setenv("DISPLAY", display_str, 1);
777
778 // build jail command
779 char *firejail_argv[argc+2];
780 pos = 0;
781 for (i = 0; i < argc; i++) {
782 if (strncmp(argv[i], "--x11", 5) == 0)
783 continue;
784 firejail_argv[pos] = argv[i];
785 pos++;
786 }
787 firejail_argv[pos] = NULL;
788
789 assert((int) pos < (argc+2));
790 assert(!firejail_argv[pos]);
791
792 // start jail
793 pid_t jail = fork();
794 if (jail < 0)
795 errExit("fork");
796 if (jail == 0) {
797 // running without privileges - see drop_privs call above
798 assert(getenv("LD_PRELOAD") == NULL);
799 if (firejail_argv[0]) // shut up llvm scan-build
800 execvp(firejail_argv[0], firejail_argv);
801 perror("execvp");
802 exit(1);
803 }
804
805 fmessage("Xpra server pid %d, xpra client pid %d, jail %d\n", server, client, jail);
806
807 sleep(1); // adding a delay in order to let the server start
808
809 // wait for jail or server to end
810 while (1) {
811 pid_t pid = wait(NULL);
812
813 if (pid == jail) {
814 char *stop_argv[] = { "xpra", "stop", display_str, NULL };
815 pid_t stop = fork();
816 if (stop < 0)
817 errExit("fork");
818 if (stop == 0) {
819 if (arg_quiet && fd_null != -1) {
820 dup2(fd_null,0);
821 dup2(fd_null,1);
822 dup2(fd_null,2);
823 }
824 // running without privileges - see drop_privs call above
825 assert(getenv("LD_PRELOAD") == NULL);
826 execvp(stop_argv[0], stop_argv);
827 perror("execvp");
828 _exit(1);
829 }
830
831 // wait for xpra server to stop, 10 seconds limit
832 while (++n < 10) {
833 sleep(1);
834 pid = waitpid(server, NULL, WNOHANG);
835 if (pid == server)
836 break;
837 }
838
839 if (arg_debug) {
840 if (n == 10)
841 printf("failed to stop xpra server gratefully\n");
842 else
843 printf("xpra server successfully stopped in %d secs\n", n);
844 }
845
846 // kill xpra server and xpra client
847 kill(client, SIGTERM);
848 kill(server, SIGTERM);
849 exit(0);
850 }
851 else if (pid == server) {
852 // kill firejail process
853 kill(jail, SIGTERM);
854 // kill xpra client (should die with server, but...)
855 kill(client, SIGTERM);
856 exit(0);
857 }
858 }
859}
860
861
862void x11_start_xpra_new(int argc, char **argv, char *display_str) {
863 EUID_ASSERT();
864 int i;
865 pid_t server = 0;
866
867 // build the start command
868 char *server_argv[256] = { // rest initialyzed to NULL
869 "xpra", "start", display_str, "--daemon=no", "--attach=yes", "--exit-with-children=yes"
870 };
871 unsigned spos = 0;
872 unsigned fpos = 0;
873 while (server_argv[spos] != NULL) spos++;
874
875 // build jail command
876 char *firejail_argv[argc+2];
877 size_t total_length = 0;
878 for (i = 0; i < argc; i++) {
879 if (strncmp(argv[i], "--x11", 5) == 0)
880 continue;
881 firejail_argv[fpos] = argv[i];
882 fpos++;
883 total_length += strlen(argv[i]);
884 }
885
886 char *start_child_prefix = "--start-child=";
887 char *start_child;
888 start_child = malloc(total_length + strlen(start_child_prefix) + fpos + 2);
889 if (start_child == NULL) {
890 fprintf(stderr, "Error: unable to allocate start_child to assemble command\n");
891 exit(1);
892 }
893
894 strcpy(start_child,start_child_prefix);
895 for(i = 0; (unsigned) i < fpos; i++) {
896 strncat(start_child,firejail_argv[i],strlen(firejail_argv[i]));
897 if((unsigned) i != fpos - 1)
898 strncat(start_child," ",strlen(" "));
899 }
900
901 server_argv[spos++] = start_child;
902
903 server_argv[spos++] = NULL;
904 firejail_argv[fpos] = NULL;
905
906 assert(xpra_extra_params); // should be "" if empty
907
908 // parse xephyr_extra_params
909 // very basic quoting support
910 char *temp = strdup(xpra_extra_params);
911 if (*xpra_extra_params != '\0') {
912 if (!temp)
913 errExit("strdup");
914 bool dquote = false;
915 bool squote = false;
916 for (i = 0; i < (int) strlen(xpra_extra_params); i++) {
917 if (temp[i] == '\"') {
918 dquote = !dquote;
919 // replace closing quote by \0
920 if (dquote) temp[i] = '\0';
921 }
922 if (temp[i] == '\'') {
923 squote = !squote;
924 // replace closing quote by \0
925 if (squote) temp[i] = '\0';
926 }
927 if (!dquote && !squote && temp[i] == ' ') temp[i] = '\0';
928 if (dquote && squote) {
929 fprintf(stderr, "Error: mixed quoting found while parsing xpra_extra_params\n");
930 exit(1);
931 }
932 }
933 if (dquote) {
934 fprintf(stderr, "Error: unclosed quote found while parsing xpra_extra_params\n");
935 exit(1);
936 }
937
938 server_argv[spos++] = temp;
939 for (i = 0; i < (int) strlen(xpra_extra_params)-1; i++) {
940 if (spos >= (sizeof(server_argv)/sizeof(*server_argv)) - 2) {
941 fprintf(stderr, "Error: arg count limit exceeded while parsing xpra_extra_params\n");
942 exit(1);
943 }
944 if (temp[i] == '\0' && (temp[i+1] == '\"' || temp[i+1] == '\'')) {
945 server_argv[spos++] = temp + i + 2;
946 }
947 else if (temp[i] == '\0' && temp[i+1] != '\0') {
948 server_argv[spos++] = temp + i + 1;
949 }
950 }
951 }
952
953 server_argv[spos++] = NULL;
954
955 assert((int) fpos < (argc+2));
956 assert(!firejail_argv[fpos]);
957 // no overrun
958 assert(spos < (sizeof(server_argv)/sizeof(*server_argv)));
959 assert(server_argv[spos-1] == NULL); // last element is null
960
961 if (arg_debug) {
962 size_t i = 0;
963 printf("\n*** Starting xpra server: ");
964 while (server_argv[i]!=NULL) {
965 printf(" \"%s\"", server_argv[i]);
966 i++;
967 }
968 printf(" ***\n\n");
969 }
970
971 int fd_null = -1;
972 if (arg_quiet) {
973 fd_null = open("/dev/null", O_RDWR);
974 if (fd_null == -1)
975 errExit("open");
976 }
977
978 // start
979 server = fork();
980 if (server < 0)
981 errExit("fork");
982 if (server == 0) {
983 if (arg_debug)
984 printf("Starting xpra...\n");
985
986 if (arg_quiet && fd_null != -1) {
987 dup2(fd_null,0);
988 dup2(fd_null,1);
989 dup2(fd_null,2);
990 }
991
992 // running without privileges - see drop_privs call above
993 assert(getenv("LD_PRELOAD") == NULL);
994 execvp(server_argv[0], server_argv);
995 perror("execvp");
996 _exit(1);
997 }
998
999 // wait for server to end
1000 while (1) {
1001 pid_t pid = wait(NULL);
1002 if (pid == server) {
1003 free(start_child);
1004 exit(0);
1005 }
1006 }
1007}
1008
1009
1010void x11_start_xpra(int argc, char **argv) {
1011 EUID_ASSERT();
1012
1013 setenv("FIREJAIL_X11", "yes", 1);
1014
1015 // unfortunately, xpra does a number of weird things when started by root user!!!
1016 if (getuid() == 0) {
1017 fprintf(stderr, "Error: X11 sandboxing is not available when running as root\n");
1018 exit(1);
1019 }
1020 drop_privs(0);
1021
1022 // check xpra
1023 if (!program_in_path("xpra")) {
1024 fprintf(stderr, "\nError: Xpra program was not found in /usr/bin directory, please install it:\n");
1025 fprintf(stderr, " Debian/Ubuntu/Mint: sudo apt-get install xpra\n");
1026 exit(0);
1027 }
1028
1029 int display = random_display_number();
1030 char *display_str;
1031 if (asprintf(&display_str, ":%d", display) == -1)
1032 errExit("asprintf");
1033
1034 if (checkcfg(CFG_XPRA_ATTACH))
1035 x11_start_xpra_new(argc, argv, display_str);
1036 else
1037 x11_start_xpra_old(argc, argv, display, display_str);
1038}
1039
1040
1041void x11_start(int argc, char **argv) {
1042 EUID_ASSERT();
1043
1044 // unfortunately, xpra does a number of weird things when started by root user!!!
1045 if (getuid() == 0) {
1046 fprintf(stderr, "Error: X11 sandboxing is not available when running as root\n");
1047 exit(1);
1048 }
1049
1050 // check xpra
1051 if (program_in_path("xpra"))
1052 x11_start_xpra(argc, argv);
1053 else if (program_in_path("Xephyr"))
1054 x11_start_xephyr(argc, argv);
1055 else {
1056 fprintf(stderr, "\nError: Xpra or Xephyr not found in /usr/bin directory, please install one of them:\n");
1057 fprintf(stderr, " Debian/Ubuntu/Mint: sudo apt-get install xpra\n");
1058 fprintf(stderr, " Debian/Ubuntu/Mint: sudo apt-get install xserver-xephyr\n");
1059 exit(0);
1060 }
1061}
1062#endif
1063
1064// Porting notes:
1065//
1066// 1. merge #1100 from zackw:
1067// Attempting to run xauth -f directly on a file in /run/firejail/mnt/ directory fails on Debian 8
1068// with this message:
1069// xauth: timeout in locking authority file /run/firejail/mnt/sec.Xauthority-Qt5Mu4
1070// Failed to create untrusted X cookie: xauth: exit 1
1071// For this reason we run xauth on a file in a tmpfs filesystem mounted on /tmp. This was
1072// a partial merge.
1073//
1074// 2. Since we cannot deal with the TOCTOU condition when mounting .Xauthority in user home
1075// directory, we need to make sure /usr/bin/xauth executable is the real thing, and not
1076// something picked up on $PATH.
1077//
1078// 3. If for any reason xauth command fails, we exit the sandbox. On Debian 8 this happens
1079// when using a network namespace. Somehow, xauth tries to connect to the abstract socket,
1080// and it fails because of the network namespace - it should try to connect to the regular
1081// Unix socket! If we ignore the fail condition, the program will be started on X server without
1082// the security extension loaded.
1083void x11_xorg(void) {
1084#ifdef HAVE_X11
1085
1086 // check xauth utility is present in the system
1087 struct stat s;
1088 if (stat("/usr/bin/xauth", &s) == -1) {
1089 fprintf(stderr, "Error: xauth utility not found in /usr/bin. Please install it:\n"
1090 " Debian/Ubuntu/Mint: sudo apt-get install xauth\n");
1091 exit(1);
1092 }
1093 if (s.st_uid != 0 && s.st_gid != 0) {
1094 fprintf(stderr, "Error: invalid /usr/bin/xauth executable\n");
1095 exit(1);
1096 }
1097
1098 // get DISPLAY env
1099 char *display = getenv("DISPLAY");
1100 if (!display) {
1101 fputs("Error: --x11=xorg requires an 'outer' X11 server to use.\n", stderr);
1102 exit(1);
1103 }
1104
1105 // temporarily mount a tempfs on top of /tmp directory
1106 if (mount("tmpfs", "/tmp", "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=1777,gid=0") < 0)
1107 errExit("mounting /tmp");
1108
1109 // create the temporary .Xauthority file
1110 if (arg_debug)
1111 printf("Generating a new .Xauthority file\n");
1112 char tmpfname[] = "/tmp/.tmpXauth-XXXXXX";
1113 int fd = mkstemp(tmpfname);
1114 if (fd == -1) {
1115 fprintf(stderr, "Error: cannot create .Xauthority file\n");
1116 exit(1);
1117 }
1118 if (fchown(fd, getuid(), getgid()) == -1)
1119 errExit("chown");
1120 close(fd);
1121
1122 pid_t child = fork();
1123 if (child < 0)
1124 errExit("fork");
1125 if (child == 0) {
1126 drop_privs(1);
1127 clearenv();
1128#ifdef HAVE_GCOV
1129 __gcov_flush();
1130#endif
1131 execlp("/usr/bin/xauth", "/usr/bin/xauth", "-v", "-f", tmpfname,
1132 "generate", display, "MIT-MAGIC-COOKIE-1", "untrusted", NULL);
1133
1134 _exit(127);
1135 }
1136
1137 // wait for the xauth process to finish
1138 int status;
1139 if (waitpid(child, &status, 0) != child)
1140 errExit("waitpid");
1141 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
1142 /* success */
1143 }
1144 else if (WIFEXITED(status)) {
1145 fprintf(stderr, "Failed to create untrusted X cookie: xauth: exit %d\n",
1146 WEXITSTATUS(status));
1147 exit(1);
1148 }
1149 else if (WIFSIGNALED(status)) {
1150 fprintf(stderr, "Failed to create untrusted X cookie: xauth: %s\n",
1151 strsignal(WTERMSIG(status)));
1152 exit(1);
1153 }
1154 else {
1155 fprintf(stderr, "Failed to create untrusted X cookie: "
1156 "xauth: un-decodable exit status %04x\n", status);
1157 exit(1);
1158 }
1159
1160 // move the temporary file in RUN_XAUTHORITY_SEC_FILE in order to have it deleted
1161 // automatically when the sandbox is closed (rename doesn't work)
1162 // root needed
1163 if (copy_file(tmpfname, RUN_XAUTHORITY_SEC_FILE, getuid(), getgid(), 0600)) {
1164 fprintf(stderr, "Error: cannot create the new .Xauthority file\n");
1165 exit(1);
1166 }
1167 /* coverity[toctou] */
1168 unlink(tmpfname);
1169 umount("/tmp");
1170
1171 // Ensure there is already a file in the usual location, so that bind-mount below will work.
1172 char *dest;
1173 if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1)
1174 errExit("asprintf");
1175 if (lstat(dest, &s) == -1)
1176 touch_file_as_user(dest, getuid(), getgid(), 0600);
1177
1178 // get a file descriptor for .Xauthority
1179 fd = safe_fd(dest, O_PATH|O_NOFOLLOW|O_CLOEXEC);
1180 if (fd == -1)
1181 errExit("safe_fd");
1182 // check if the actual mount destination is a user owned regular file
1183 if (fstat(fd, &s) == -1)
1184 errExit("fstat");
1185 if (!S_ISREG(s.st_mode) || s.st_uid != getuid()) {
1186 if (S_ISLNK(s.st_mode))
1187 fprintf(stderr, "Error: .Xauthority is a symbolic link\n");
1188 else
1189 fprintf(stderr, "Error: .Xauthority is not a user owned regular file\n");
1190 exit(1);
1191 }
1192
1193 // mount via the link in /proc/self/fd
1194 char *proc;
1195 if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1)
1196 errExit("asprintf");
1197 if (mount(RUN_XAUTHORITY_SEC_FILE, proc, "none", MS_BIND, "mode=0600") == -1) {
1198 fprintf(stderr, "Error: cannot mount the new .Xauthority file\n");
1199 exit(1);
1200 }
1201 free(proc);
1202 close(fd);
1203 // check /proc/self/mountinfo to confirm the mount is ok
1204 MountData *mptr = get_last_mount();
1205 if (strcmp(mptr->dir, dest) != 0 || strcmp(mptr->fstype, "tmpfs") != 0)
1206 errLogExit("invalid .Xauthority mount");
1207
1208 ASSERT_PERMS(dest, getuid(), getgid(), 0600);
1209 free(dest);
1210#endif
1211}
1212
1213
1214void fs_x11(void) {
1215#ifdef HAVE_X11
1216 int display = x11_display();
1217 if (display <= 0)
1218 return;
1219
1220 char *x11file;
1221 if (asprintf(&x11file, "/tmp/.X11-unix/X%d", display) == -1)
1222 errExit("asprintf");
1223 struct stat x11stat;
1224 if (stat(x11file, &x11stat) == -1 || !S_ISSOCK(x11stat.st_mode)) {
1225 free(x11file);
1226 return;
1227 }
1228
1229 if (arg_debug || arg_debug_whitelists)
1230 fprintf(stderr, "Masking all X11 sockets except %s\n", x11file);
1231
1232 // Move the real /tmp/.X11-unix to a scratch location
1233 // so we can still access x11file after we mount a
1234 // tmpfs over /tmp/.X11-unix.
1235 int rv = mkdir(RUN_WHITELIST_X11_DIR, 0700);
1236 if (rv == -1)
1237 errExit("mkdir");
1238 if (set_perms(RUN_WHITELIST_X11_DIR, 0, 0, 0700))
1239 errExit("set_perms");
1240
1241 if (mount("/tmp/.X11-unix", RUN_WHITELIST_X11_DIR, 0, MS_BIND|MS_REC, 0) < 0)
1242 errExit("mount bind");
1243
1244 // This directory must be mode 1777, or Xlib will barf.
1245 if (mount("tmpfs", "/tmp/.X11-unix", "tmpfs",
1246 MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC,
1247 "mode=1777,uid=0,gid=0") < 0)
1248 errExit("mounting tmpfs on /tmp/.X11-unix");
1249 fs_logger("tmpfs /tmp/.X11-unix");
1250
1251 // create an empty file which will have the desired socket bind-mounted over it
1252 int fd = open(x11file, O_RDWR|O_CREAT|O_EXCL, x11stat.st_mode & ~S_IFMT);
1253 if (fd < 0)
1254 errExit(x11file);
1255 if (fchown(fd, x11stat.st_uid, x11stat.st_gid))
1256 errExit("fchown");
1257 close(fd);
1258
1259 // do the mount
1260 char *wx11file;
1261 if (asprintf(&wx11file, "%s/X%d", RUN_WHITELIST_X11_DIR, display) == -1)
1262 errExit("asprintf");
1263 if (mount(wx11file, x11file, NULL, MS_BIND|MS_REC, NULL) < 0)
1264 errExit("mount bind");
1265 fs_logger2("whitelist", x11file);
1266
1267 free(x11file);
1268 free(wx11file);
1269
1270 // block access to RUN_WHITELIST_X11_DIR
1271 if (mount(RUN_RO_DIR, RUN_WHITELIST_X11_DIR, 0, MS_BIND, 0) < 0)
1272 errExit("mount");
1273 fs_logger2("blacklist", RUN_WHITELIST_X11_DIR);
1274#endif
1275}
1276
1277
1278void x11_block(void) {
1279#ifdef HAVE_X11
1280 // check abstract socket presence and network namespace options
1281 if ((!arg_nonetwork && !cfg.bridge0.configured && !cfg.interface0.configured)
1282 && x11_abstract_sockets_present()) {
1283 fprintf(stderr, "ERROR: --x11=none specified, but abstract X11 socket still accessible.\n"
1284 "Additional setup required. To block abstract X11 socket you can either:\n"
1285 " * use network namespace in firejail (--net=none, --net=...)\n"
1286 " * add \"-nolisten local\" to xserver options\n"
1287 " (eg. to your display manager config, or /etc/X11/xinit/xserverrc)\n");
1288 exit(1);
1289 }
1290
1291 // blacklist sockets
1292 profile_check_line("blacklist /tmp/.X11-unix", 0, NULL);
1293 profile_add(strdup("blacklist /tmp/.X11-unix"));
1294
1295 // blacklist .Xauthority
1296 profile_check_line("blacklist ${HOME}/.Xauthority", 0, NULL);
1297 profile_add(strdup("blacklist ${HOME}/.Xauthority"));
1298 char *xauthority = getenv("XAUTHORITY");
1299 if (xauthority) {
1300 char *line;
1301 if (asprintf(&line, "blacklist %s", xauthority) == -1)
1302 errExit("asprintf");
1303 profile_check_line(line, 0, NULL);
1304 profile_add(line);
1305 }
1306
1307 // clear environment
1308 env_store("DISPLAY", RMENV);
1309 env_store("XAUTHORITY", RMENV);
1310#endif
1311}
diff --git a/src/fldd/Makefile.in b/src/fldd/Makefile.in
deleted file mode 100644
index 5af37cfbd..000000000
--- a/src/fldd/Makefile.in
+++ /dev/null
@@ -1,14 +0,0 @@
1all: fldd
2
3include ../common.mk
4
5%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/syscall.h ../include/ldd_utils.h
6 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@
7
8fldd: $(OBJS) ../lib/ldd_utils.o
9 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/ldd_utils.o $(LIBS) $(EXTRA_LDFLAGS)
10
11clean:; rm -f *.o fldd *.gcov *.gcda *.gcno
12
13distclean: clean
14 rm -fr Makefile
diff --git a/src/fldd/main.c b/src/fldd/main.c
deleted file mode 100644
index 4658e82fb..000000000
--- a/src/fldd/main.c
+++ /dev/null
@@ -1,353 +0,0 @@
1/*
2 * Copyright (C) 2014-2018 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 "../include/ldd_utils.h"
23
24#include <fcntl.h>
25#include <sys/mman.h>
26#include <sys/mount.h>
27#include <sys/stat.h>
28#include <sys/types.h>
29#include <unistd.h>
30#include <dirent.h>
31
32
33static int arg_quiet = 0;
34static void copy_libs_for_lib(const char *lib);
35
36typedef struct storage_t {
37 struct storage_t *next;
38 const char *name;
39} Storage;
40static Storage *libs = NULL;
41static Storage *lib_paths = NULL;
42
43// return 1 if found
44static int storage_find(Storage *ptr, const char *name) {
45 while (ptr) {
46 if (strcmp(ptr->name, name) == 0)
47 return 1;
48 ptr = ptr->next;
49 }
50
51 return 0;
52}
53
54static void storage_add(Storage **head, const char *name) {
55 if (storage_find(*head, name))
56 return;
57
58 Storage *s = malloc(sizeof(Storage));
59 if (!s)
60 errExit("malloc");
61 s->next = *head;
62 *head = s;
63 s->name = strdup(name);
64 if (!s->name)
65 errExit("strdup");
66}
67
68
69static void storage_print(Storage *ptr, int fd) {
70 while (ptr) {
71 dprintf(fd, "%s\n", ptr->name);
72 ptr = ptr->next;
73 }
74}
75
76static bool ptr_ok(const void *ptr, const void *base, const void *end, const char *name) {
77 bool r;
78 (void) name;
79
80 r = (ptr >= base && ptr < end);
81 return r;
82}
83
84
85static void parse_elf(const char *exe) {
86 int f;
87 f = open(exe, O_RDONLY);
88 if (f < 0) {
89 if (!arg_quiet)
90 fprintf(stderr, "Warning fldd: cannot open %s, skipping...\n", exe);
91 return;
92 }
93
94 struct stat s;
95 char *base = NULL, *end;
96 if (fstat(f, &s) == -1)
97 goto error_close;
98 base = mmap(0, s.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, f, 0);
99 if (base == MAP_FAILED)
100 goto error_close;
101
102 end = base + s.st_size;
103
104 Elf_Ehdr *ebuf = (Elf_Ehdr *)base;
105 if (strncmp((const char *)ebuf->e_ident, ELFMAG, SELFMAG) != 0) {
106 if (!arg_quiet)
107 fprintf(stderr, "Warning fldd: %s is not an ELF executable or library\n", exe);
108 goto close;
109 }
110//unsigned char elfclass = ebuf->e_ident[EI_CLASS];
111//if (elfclass == ELFCLASS32)
112//printf("%s 32bit\n", exe);
113//else if (elfclass == ELFCLASS64)
114//printf("%s 64bit\n", exe);
115
116
117 Elf_Phdr *pbuf = (Elf_Phdr *)(base + sizeof(*ebuf));
118 while (ebuf->e_phnum-- > 0 && ptr_ok(pbuf, base, end, "pbuf")) {
119 switch (pbuf->p_type) {
120 case PT_INTERP:
121 // dynamic loader ld-linux.so
122 if (!ptr_ok(base + pbuf->p_offset, base, end, "base + pbuf->p_offset"))
123 goto close;
124
125 storage_add(&libs, base + pbuf->p_offset);
126 break;
127 }
128 pbuf++;
129 }
130
131 Elf_Shdr *sbuf = (Elf_Shdr *)(base + ebuf->e_shoff);
132 if (!ptr_ok(sbuf, base, end, "sbuf"))
133 goto close;
134
135 // Find strings section
136 char *strbase = NULL;
137 int sections = ebuf->e_shnum;
138 while (sections-- > 0 && ptr_ok(sbuf, base, end, "sbuf")) {
139 if (sbuf->sh_type == SHT_STRTAB) {
140 strbase = base + sbuf->sh_offset;
141 if (!ptr_ok(strbase, base, end, "strbase"))
142 goto close;
143 break;
144 }
145 sbuf++;
146 }
147 if (strbase == NULL)
148 goto error_close;
149
150 // Find dynamic section
151 sections = ebuf->e_shnum;
152 while (sections-- > 0 && ptr_ok(sbuf, base, end, "sbuf")) {
153// TODO: running fldd on large gui programs (fldd /usr/bin/transmission-qt)
154// crash on accessing memory location sbuf->sh_type if sbuf->sh_type in the previous section was 0 (SHT_NULL)
155// for now we just exit the while loop - this is probably incorrect
156// printf("sbuf %p #%s#, sections %d, type %u\n", sbuf, exe, sections, sbuf->sh_type);
157 if (!ptr_ok(sbuf, base, end, "sbuf"))
158 goto close;
159
160 if (sbuf->sh_type == SHT_NULL)
161 break;
162 if (sbuf->sh_type == SHT_DYNAMIC) {
163 Elf_Dyn *dbuf = (Elf_Dyn *)(base + sbuf->sh_offset);
164 if (!ptr_ok(dbuf, base, end, "dbuf"))
165 goto close;
166 // Find DT_RPATH/DT_RUNPATH tags first
167 unsigned long size = sbuf->sh_size;
168 while (size >= sizeof(*dbuf) && ptr_ok(dbuf, base, end, "dbuf")) {
169 if (dbuf->d_tag == DT_RPATH || dbuf->d_tag == DT_RUNPATH) {
170 const char *searchpath = strbase + dbuf->d_un.d_ptr;
171 if (!ptr_ok(searchpath, base, end, "searchpath"))
172 goto close;
173 storage_add(&lib_paths, searchpath);
174 }
175 size -= sizeof(*dbuf);
176 dbuf++;
177 }
178 // Find DT_NEEDED tags
179 dbuf = (Elf_Dyn *)(base + sbuf->sh_offset);
180 size = sbuf->sh_size;
181 while (size >= sizeof(*dbuf) && ptr_ok(dbuf, base, end, "dbuf")) {
182 if (dbuf->d_tag == DT_NEEDED) {
183 const char *lib = strbase + dbuf->d_un.d_ptr;
184 if (!ptr_ok(lib, base, end, "lib"))
185 goto close;
186 copy_libs_for_lib(lib);
187 }
188 size -= sizeof(*dbuf);
189 dbuf++;
190 }
191 }
192 sbuf++;
193 }
194 goto close;
195
196 error_close:
197 perror("copy libs");
198 close:
199 if (base)
200 munmap(base, s.st_size);
201
202 close(f);
203}
204
205static void copy_libs_for_lib(const char *lib) {
206 Storage *lib_path;
207 for (lib_path = lib_paths; lib_path; lib_path = lib_path->next) {
208 char *fname;
209 if (asprintf(&fname, "%s/%s", lib_path->name, lib) == -1)
210 errExit("asprintf");
211 if (access(fname, R_OK) == 0 && is_lib_64(fname)) {
212 if (!storage_find(libs, fname)) {
213 storage_add(&libs, fname);
214 // libs may need other libs
215 parse_elf(fname);
216 }
217 free(fname);
218 return;
219 }
220 free(fname);
221 }
222
223 // log a warning and continue
224 if (!arg_quiet)
225 fprintf(stderr, "Warning fldd: cannot find %s, skipping...\n", lib);
226}
227
228static void lib_paths_init(void) {
229 int i;
230 for (i = 0; default_lib_paths[i]; i++)
231 storage_add(&lib_paths, default_lib_paths[i]);
232}
233
234
235static void walk_directory(const char *dirname) {
236 assert(dirname);
237
238 DIR *dir = opendir(dirname);
239 if (dir) {
240 struct dirent *entry;
241 while ((entry = readdir(dir)) != NULL) {
242 if (strcmp(entry->d_name, ".") == 0)
243 continue;
244 if (strcmp(entry->d_name, "..") == 0)
245 continue;
246
247 // build full path
248 char *path;
249 if (asprintf(&path, "%s/%s", dirname, entry->d_name) == -1)
250 errExit("asprintf");
251
252 // check regular so library
253 char *ptr = strstr(entry->d_name, ".so");
254 if (ptr && is_lib_64(path)) {
255 if (*(ptr + 3) == '\0' || *(ptr + 3) == '.') {
256 parse_elf(path);
257 free(path);
258 continue;
259 }
260 }
261
262 // check directory
263 // entry->d_type field is supported in glibc since version 2.19 (Feb 2014)
264 // we'll use stat to check for directories
265 struct stat s;
266 if (stat(path, &s) == -1)
267 errExit("stat");
268 if (S_ISDIR(s.st_mode))
269 walk_directory(path);
270 }
271 closedir(dir);
272 }
273}
274
275
276
277static void usage(void) {
278 printf("Usage: fldd program_or_directory [file]\n");
279 printf("Print a list of libraries used by program or store it in the file.\n");
280 printf("Print a list of libraries used by all .so files in a directory or store it in the file.\n");
281}
282
283int main(int argc, char **argv) {
284#if 0
285{
286//system("cat /proc/self/status");
287int i;
288for (i = 0; i < argc; i++)
289 printf("*%s* ", argv[i]);
290printf("\n");
291}
292#endif
293 if (argc < 2) {
294 fprintf(stderr, "Error fldd: invalid arguments\n");
295 usage();
296 exit(1);
297 }
298
299
300 if (strcmp(argv[1], "--help") == 0) {
301 usage();
302 return 0;
303 }
304
305 // check program access
306 if (access(argv[1], R_OK)) {
307 fprintf(stderr, "Error fldd: cannot access %s\n", argv[1]);
308 exit(1);
309 }
310
311 char *quiet = getenv("FIREJAIL_QUIET");
312 if (quiet && strcmp(quiet, "yes") == 0)
313 arg_quiet = 1;
314
315 if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") ==0) {
316 usage();
317 return 0;
318 }
319
320 int fd = STDOUT_FILENO;
321 // attempt to open the file
322 if (argc == 3) {
323 fd = open(argv[2], O_CREAT | O_TRUNC | O_WRONLY, 0644);
324 if (!fd) {
325 fprintf(stderr, "Error fldd: invalid arguments\n");
326 usage();
327 exit(1);
328 }
329 }
330
331 // initialize local storage
332 lib_paths_init();
333
334 // process files
335 struct stat s;
336 if (stat(argv[1], &s) == -1)
337 errExit("stat");
338 if (S_ISDIR(s.st_mode))
339 walk_directory(argv[1]);
340 else {
341 if (is_lib_64(argv[1]))
342 parse_elf(argv[1]);
343 else
344 fprintf(stderr, "Warning fldd: %s is not a 64bit program/library\n", argv[1]);
345 }
346
347
348 // print libraries and exit
349 storage_print(libs, fd);
350 if (argc == 3)
351 close(fd);
352 return 0;
353}
diff --git a/status b/status
index 533ccc69e..f59f8e5a2 100644
--- a/status
+++ b/status
@@ -1,2 +1,5 @@
1starting from main as of Jul 27 1Phase 1
2removing chroot, overlayfs, x11, private-bin, private-lib 2- starting from main as of Jul 27
3- removing chroot, overlayfs, x11, private-bin, private-lib
4- removing private-home, audit, build
5
diff --git a/test/apps-x11-xorg/apps-x11-xorg.sh b/test/apps-x11-xorg/apps-x11-xorg.sh
deleted file mode 100755
index ea07d3713..000000000
--- a/test/apps-x11-xorg/apps-x11-xorg.sh
+++ /dev/null
@@ -1,34 +0,0 @@
1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6export MALLOC_CHECK_=3
7export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
8
9which firefox 2>/dev/null
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 2>/dev/null
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 thunderbird 2>/dev/null
28if [ "$?" -eq 0 ];
29then
30 echo "TESTING: thunderbird x11 xorg"
31 ./thunderbird.exp
32else
33 echo "TESTING SKIP: thunderbird not found"
34fi
diff --git a/test/apps-x11-xorg/firefox.exp b/test/apps-x11-xorg/firefox.exp
deleted file mode 100755
index 10575b277..000000000
--- a/test/apps-x11-xorg/firefox.exp
+++ /dev/null
@@ -1,90 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --name=test --x11=xorg --ignore=net --ignore=netfilter --ignore=iprange 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 --nowrap\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 --nowrap\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"
diff --git a/test/apps-x11-xorg/thunderbird.exp b/test/apps-x11-xorg/thunderbird.exp
deleted file mode 100755
index 6706cc321..000000000
--- a/test/apps-x11-xorg/thunderbird.exp
+++ /dev/null
@@ -1,85 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --name=test --x11=xorg --ignore=net --ignore=netfilter --ignore=iprange thunderbird\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 "thunderbird"
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 --nowrap\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 "thunderbird"
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 --nowrap\r"
61expect {
62 timeout {puts "TESTING ERROR 6\n";exit}
63 ":firejail"
64}
65expect {
66 timeout {puts "TESTING ERROR 6.0\n";exit}
67 "thunderbird"
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"
diff --git a/test/apps-x11-xorg/transmission-gtk.exp b/test/apps-x11-xorg/transmission-gtk.exp
deleted file mode 100755
index 75c302764..000000000
--- a/test/apps-x11-xorg/transmission-gtk.exp
+++ /dev/null
@@ -1,85 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --name=test --x11=xorg --ignore=net --ignore=netfilter --ignore=iprange 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 --nowrap\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 --nowrap\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"
diff --git a/test/apps-x11/apps-x11.sh b/test/apps-x11/apps-x11.sh
deleted file mode 100755
index c12b11f3e..000000000
--- a/test/apps-x11/apps-x11.sh
+++ /dev/null
@@ -1,87 +0,0 @@
1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 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 2>/dev/null
14if [ "$?" -eq 0 ];
15then
16 echo "TESTING: xterm x11 xorg"
17 ./xterm-xorg.exp
18
19 which xpra 2>/dev/null
20 if [ "$?" -eq 0 ];
21 then
22 echo "TESTING: xterm x11 xpra"
23 ./xterm-xpra.exp
24 fi
25
26 which Xephyr 2>/dev/null
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 2>/dev/null
38if [ "$?" -eq 0 ];
39then
40 echo "xpra found"
41else
42 echo "xpra not found"
43 which Xephyr 2>/dev/null
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 2>/dev/null
54if [ "$?" -eq 0 ];
55then
56 echo "TESTING: firefox x11"
57 ./firefox.exp
58else
59 echo "TESTING SKIP: firefox not found"
60fi
61
62which chromium 2>/dev/null
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 2>/dev/null
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 thunderbird 2>/dev/null
81if [ "$?" -eq 0 ];
82then
83 echo "TESTING: thunderbird x11"
84 ./thunderbird.exp
85else
86 echo "TESTING SKIP: thunderbird not found"
87fi
diff --git a/test/apps-x11/chromium.exp b/test/apps-x11/chromium.exp
deleted file mode 100755
index f72b86dde..000000000
--- a/test/apps-x11/chromium.exp
+++ /dev/null
@@ -1,85 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --name=test --x11 chromium 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 "chromium"
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}
32send -- "firejail --name=blablabla\r"
33expect {
34 timeout {puts "TESTING ERROR 4\n";exit}
35 "Child process initialized"
36}
37sleep 2
38
39spawn $env(SHELL)
40send -- "firemon --seccomp\r"
41expect {
42 timeout {puts "TESTING ERROR 5\n";exit}
43 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
44 ":firejail"
45}
46expect {
47 timeout {puts "TESTING ERROR 5.0\n";exit}
48 "chromium"
49}
50expect {
51 timeout {puts "TESTING ERROR 5.1\n";exit}
52 "Seccomp: 0"
53}
54expect {
55 timeout {puts "TESTING ERROR 5.1\n";exit}
56 "name=blablabla"
57}
58sleep 1
59send -- "firemon --caps\r"
60expect {
61 timeout {puts "TESTING ERROR 6\n";exit}
62 ":firejail"
63}
64expect {
65 timeout {puts "TESTING ERROR 6.0\n";exit}
66 "chromium"
67}
68expect {
69 timeout {puts "TESTING ERROR 6.1\n";exit}
70 "CapBnd:"
71}
72expect {
73 timeout {puts "TESTING ERROR 6.2\n";exit}
74 "00240000"
75}
76expect {
77 timeout {puts "TESTING ERROR 6.3\n";exit}
78 "name=blablabla"
79}
80sleep 1
81send -- "firejail --shutdown=test\r"
82sleep 3
83
84
85puts "\nall done\n"
diff --git a/test/apps-x11/firefox.exp b/test/apps-x11/firefox.exp
deleted file mode 100755
index 8021042e5..000000000
--- a/test/apps-x11/firefox.exp
+++ /dev/null
@@ -1,90 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 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"
diff --git a/test/apps-x11/thunderbird.exp b/test/apps-x11/thunderbird.exp
deleted file mode 100755
index 5994ab15e..000000000
--- a/test/apps-x11/thunderbird.exp
+++ /dev/null
@@ -1,85 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --name=test --x11 thunderbird\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 "thunderbird"
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 "thunderbird"
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 "thunderbird"
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"
diff --git a/test/apps-x11/transmission-gtk.exp b/test/apps-x11/transmission-gtk.exp
deleted file mode 100755
index 48c685cf0..000000000
--- a/test/apps-x11/transmission-gtk.exp
+++ /dev/null
@@ -1,85 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --name=test --x11 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"
diff --git a/test/apps-x11/x11-none.exp b/test/apps-x11/x11-none.exp
deleted file mode 100755
index e6e515966..000000000
--- a/test/apps-x11/x11-none.exp
+++ /dev/null
@@ -1,47 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 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"
diff --git a/test/apps-x11/x11-xephyr.exp b/test/apps-x11/x11-xephyr.exp
deleted file mode 100755
index 68f981096..000000000
--- a/test/apps-x11/x11-xephyr.exp
+++ /dev/null
@@ -1,58 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 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"
diff --git a/test/apps-x11/xterm-xephyr.exp b/test/apps-x11/xterm-xephyr.exp
deleted file mode 100755
index 63fa03fbb..000000000
--- a/test/apps-x11/xterm-xephyr.exp
+++ /dev/null
@@ -1,85 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 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"
diff --git a/test/apps-x11/xterm-xorg.exp b/test/apps-x11/xterm-xorg.exp
deleted file mode 100755
index a31925383..000000000
--- a/test/apps-x11/xterm-xorg.exp
+++ /dev/null
@@ -1,85 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 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"
diff --git a/test/apps-x11/xterm-xpra.exp b/test/apps-x11/xterm-xpra.exp
deleted file mode 100755
index 8830bb003..000000000
--- a/test/apps-x11/xterm-xpra.exp
+++ /dev/null
@@ -1,97 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 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"
diff --git a/test/chroot/chroot.sh b/test/chroot/chroot.sh
deleted file mode 100755
index 0f0fdab22..000000000
--- a/test/chroot/chroot.sh
+++ /dev/null
@@ -1,21 +0,0 @@
1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 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
deleted file mode 100755
index 26a516931..000000000
--- a/test/chroot/configure
+++ /dev/null
@@ -1,46 +0,0 @@
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,sys}
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/chroot/fs_chroot.exp b/test/chroot/fs_chroot.exp
deleted file mode 100755
index a071027e5..000000000
--- a/test/chroot/fs_chroot.exp
+++ /dev/null
@@ -1,61 +0,0 @@
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 /home;pwd\r"
16expect {
17 timeout {puts "TESTING ERROR 0.1\n";exit}
18 "home"
19}
20sleep 1
21send -- "bash\r"
22sleep 1
23send -- "ls /\r"
24expect {
25 timeout {puts "TESTING ERROR 0.2\n";exit}
26 "this-is-my-chroot"
27}
28after 100
29
30send -- "ps aux\r"
31expect {
32 timeout {puts "TESTING ERROR 1\n";exit}
33 "/bin/bash"
34}
35expect {
36 timeout {puts "TESTING ERROR 2\n";exit}
37 "bash"
38}
39expect {
40 timeout {puts "TESTING ERROR 3\n";exit}
41 "ps aux"
42}
43after 100
44
45send -- "ps aux | wc -l; pwd\r"
46expect {
47 timeout {puts "TESTING ERROR 5\n";exit}
48 "6"
49}
50after 100
51
52# check /sys directory
53send -- "ls /sys\r"
54expect {
55 timeout {puts "TESTING ERROR 6\n";exit}
56 "block"
57}
58after 100
59
60
61puts "all done\n"
diff --git a/test/chroot/unchroot-as-root.exp b/test/chroot/unchroot-as-root.exp
deleted file mode 100755
index e4bedd539..000000000
--- a/test/chroot/unchroot-as-root.exp
+++ /dev/null
@@ -1,26 +0,0 @@
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"
diff --git a/test/chroot/unchroot.c b/test/chroot/unchroot.c
deleted file mode 100644
index 4919637d6..000000000
--- a/test/chroot/unchroot.c
+++ /dev/null
@@ -1,40 +0,0 @@
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/overlay/firefox-x11-xorg.exp b/test/overlay/firefox-x11-xorg.exp
deleted file mode 100755
index ec24b23af..000000000
--- a/test/overlay/firefox-x11-xorg.exp
+++ /dev/null
@@ -1,89 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 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"
diff --git a/test/overlay/firefox-x11.exp b/test/overlay/firefox-x11.exp
deleted file mode 100755
index 1b7034af0..000000000
--- a/test/overlay/firefox-x11.exp
+++ /dev/null
@@ -1,89 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --overlay --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 --overlay\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"
diff --git a/test/overlay/firefox.exp b/test/overlay/firefox.exp
deleted file mode 100755
index 5bdd6751f..000000000
--- a/test/overlay/firefox.exp
+++ /dev/null
@@ -1,98 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 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"
diff --git a/test/overlay/fs-named.exp b/test/overlay/fs-named.exp
deleted file mode 100755
index 0356720bc..000000000
--- a/test/overlay/fs-named.exp
+++ /dev/null
@@ -1,69 +0,0 @@
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
15send -- "stty -echo\r"
16after 100
17
18send -- "echo xyzxyzxyz > ~/_firejail_test_file; echo done\r"
19expect {
20 timeout {puts "TESTING ERROR 3\n";exit}
21 "done"
22}
23after 100
24
25send -- "cat ~/_firejail_test_file; echo done\r"
26expect {
27 timeout {puts "TESTING ERROR 4\n";exit}
28 "xyzxyzxyz"
29}
30expect {
31 timeout {puts "TESTING ERROR 4.1\n";exit}
32 "done"
33}
34after 100
35
36send -- "exit\r"
37sleep 2
38
39send -- "cat ~/_firejail_test_file; echo done\r"
40expect {
41 timeout {puts "TESTING ERROR 5\n";exit}
42 "xyzxyzxyz" {puts "TESTING ERROR 5.1\n";exit}
43 "done"
44}
45after 100
46
47send -- "firejail --overlay-named=firejail-test\r"
48expect {
49 timeout {puts "TESTING ERROR 2\n";exit}
50 "not available for kernels older than 3.18" {puts "\nTESTING: overlayfs not available\n"; exit}
51 "Error: --overlay option is not available on Grsecurity systems" {puts "\nTESTING: overlayfs not available\n"; exit}
52 "Child process initialized" {puts "found\n"}
53}
54sleep 1
55
56send -- "stty -echo\r"
57after 100
58send -- "cat ~/_firejail_test_file; echo done\r"
59expect {
60 timeout {puts "TESTING ERROR 4\n";exit}
61 "xyzxyzxyz"
62}
63expect {
64 timeout {puts "TESTING ERROR 4.1\n";exit}
65 "done"
66}
67after 100
68
69puts "\nall done\n"
diff --git a/test/overlay/fs-tmpfs.exp b/test/overlay/fs-tmpfs.exp
deleted file mode 100755
index 20fa315b6..000000000
--- a/test/overlay/fs-tmpfs.exp
+++ /dev/null
@@ -1,67 +0,0 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "firejail --overlay-clean\r"
8after 100
9send -- "file ~/.firejail\r"
10expect {
11 timeout {puts "TESTING ERROR 0\n";exit}
12 "cannot open"
13}
14after 100
15
16send -- "firejail --overlay-tmpfs\r"
17expect {
18 timeout {puts "TESTING ERROR 1\n";exit}
19 "not available for kernels older than 3.18" {puts "\nTESTING: overlayfs not available\n"; exit}
20 "Error: --overlay option is not available on Grsecurity systems" {puts "\nTESTING: overlayfs not available\n"; exit}
21 "Child process initialized" {puts "found\n"}
22}
23sleep 1
24send -- "stty -echo\r"
25after 100
26
27send -- "echo xyzxyzxyz > ~/_firejail_test_file; echo done\r"
28expect {
29 timeout {puts "TESTING ERROR 2\n";exit}
30 "done"
31}
32after 100
33
34send -- "stty -echo\r"
35after 100
36send -- "cat ~/_firejail_test_file; echo done\r"
37expect {
38 timeout {puts "TESTING ERROR 3\n";exit}
39 "xyzxyzxyz"
40}
41expect {
42 timeout {puts "TESTING ERROR 4\n";exit}
43 "done"
44}
45after 100
46
47send -- "exit\r"
48sleep 1
49
50send -- "stty -echo\r"
51after 100
52send -- "cat ~/_firejail_test_file; echo done\r"
53expect {
54 timeout {puts "TESTING ERROR 5\n";exit}
55 "xyzxyzxyz" {puts "TESTING ERROR 6\n";exit}
56 "done"
57}
58after 100
59
60send -- "file ~/.firejail\r"
61expect {
62 timeout {puts "TESTING ERROR 7\n";exit}
63 "cannot open"
64}
65after 100
66
67puts "\nall done\n"
diff --git a/test/overlay/fs.exp b/test/overlay/fs.exp
deleted file mode 100755
index 9debe6536..000000000
--- a/test/overlay/fs.exp
+++ /dev/null
@@ -1,59 +0,0 @@
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 -- "stty -echo\r"
17after 100
18send -- "echo xyzxyzxyz > ~/_firejail_test_file; echo done\r"
19expect {
20 timeout {puts "TESTING ERROR 3\n";exit}
21 "done"
22}
23after 100
24
25send -- "stty -echo\r"
26after 100
27send -- "cat ~/_firejail_test_file; echo done\r"
28expect {
29 timeout {puts "TESTING ERROR 4\n";exit}
30 "xyzxyzxyz"
31}
32expect {
33 timeout {puts "TESTING ERROR 4.1\n";exit}
34 "done"
35}
36after 100
37
38send -- "exit\r"
39sleep 2
40
41send -- "stty -echo\r"
42after 100
43send -- "cat ~/_firejail_test_file; echo done\r"
44expect {
45 timeout {puts "TESTING ERROR 5\n";exit}
46 "xyzxyzxyz" {puts "TESTING ERROR 5.1\n";exit}
47 "done"
48}
49after 100
50
51# check /sys directory
52send -- "ls /sys\r"
53expect {
54 timeout {puts "TESTING ERROR 6\n";exit}
55 "block"
56}
57after 100
58
59puts "\nall done\n"
diff --git a/test/overlay/overlay.sh b/test/overlay/overlay.sh
deleted file mode 100755
index 9daf1f5f6..000000000
--- a/test/overlay/overlay.sh
+++ /dev/null
@@ -1,67 +0,0 @@
1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 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 2>/dev/null
25if [ "$?" -eq 0 ];
26then
27 echo "TESTING: overlay firefox"
28 ./firefox.exp
29else
30 echo "TESTING SKIP: firefox not found"
31fi
32
33which firefox 2>/dev/null
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 2>/dev/null
45if [ "$?" -eq 0 ];
46then
47 echo "xpra found"
48else
49 echo "xpra not found"
50 which Xephyr 2>/dev/null
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 2>/dev/null
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-lib/atril.exp b/test/private-lib/atril.exp
deleted file mode 100755
index 04b11a646..000000000
--- a/test/private-lib/atril.exp
+++ /dev/null
@@ -1,83 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail atril\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Reading profile /etc/firejail/atril.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 "atril"
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 atril"
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 atril"
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"
diff --git a/test/private-lib/eog.exp b/test/private-lib/eog.exp
deleted file mode 100755
index 1b5406add..000000000
--- a/test/private-lib/eog.exp
+++ /dev/null
@@ -1,83 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail eog\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Reading profile /etc/firejail/eog.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 "eog"
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 eog"
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 eog"
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"
diff --git a/test/private-lib/eom.exp b/test/private-lib/eom.exp
deleted file mode 100755
index a8b74de98..000000000
--- a/test/private-lib/eom.exp
+++ /dev/null
@@ -1,83 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail eom\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Reading profile /etc/firejail/eom.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 "eom"
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 eom"
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 eom"
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"
diff --git a/test/private-lib/evince.exp b/test/private-lib/evince.exp
deleted file mode 100755
index 94ed826db..000000000
--- a/test/private-lib/evince.exp
+++ /dev/null
@@ -1,83 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail evince\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Reading profile /etc/firejail/evince.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 "evince"
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 evince"
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 evince"
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"
diff --git a/test/private-lib/galculator.exp b/test/private-lib/galculator.exp
deleted file mode 100755
index c18c07571..000000000
--- a/test/private-lib/galculator.exp
+++ /dev/null
@@ -1,83 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail galculator\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Reading profile /etc/firejail/galculator.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 "galculator"
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 galculator"
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 galculator"
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"
diff --git a/test/private-lib/gedit.exp b/test/private-lib/gedit.exp
deleted file mode 100755
index 00fa934e7..000000000
--- a/test/private-lib/gedit.exp
+++ /dev/null
@@ -1,83 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail /usr/bin/gedit\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Reading profile /etc/firejail/gedit.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 "gedit"
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 /usr/bin/gedit"
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 /usr/bin/gedit"
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"
diff --git a/test/private-lib/gnome-calculator.exp b/test/private-lib/gnome-calculator.exp
deleted file mode 100755
index e9d2c8208..000000000
--- a/test/private-lib/gnome-calculator.exp
+++ /dev/null
@@ -1,85 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10# gnome-calculator uses quiet at the top of the profile
11# we need to use --ignore
12send -- "firejail --ignore=quiet gnome-calculator\r"
13expect {
14 timeout {puts "TESTING ERROR 0\n";exit}
15 "Reading profile /etc/firejail/gnome-calculator.profile"
16}
17expect {
18 timeout {puts "TESTING ERROR 1\n";exit}
19 "Child process initialized"
20}
21sleep 3
22
23spawn $env(SHELL)
24send -- "firejail --list\r"
25expect {
26 timeout {puts "TESTING ERROR 3\n";exit}
27 ":firejail"
28}
29expect {
30 timeout {puts "TESTING ERROR 3.1\n";exit}
31 "gnome-calculator"
32}
33after 100
34
35# grsecurity exit
36send -- "file /proc/sys/kernel/grsecurity\r"
37expect {
38 timeout {puts "TESTING ERROR - grsecurity detection\n";exit}
39 "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit}
40 "cannot open" {puts "grsecurity not present\n"}
41}
42
43send -- "firejail --name=blablabla\r"
44expect {
45 timeout {puts "TESTING ERROR 4\n";exit}
46 "Child process initialized"
47}
48sleep 2
49
50spawn $env(SHELL)
51send -- "firemon --seccomp\r"
52expect {
53 timeout {puts "TESTING ERROR 5\n";exit}
54 "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit}
55 ":firejail --ignore=quiet gnome-calculator"
56}
57expect {
58 timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit}
59 "Seccomp: 2"
60}
61expect {
62 timeout {puts "TESTING ERROR 5.1\n";exit}
63 "name=blablabla"
64}
65after 100
66send -- "firemon --caps\r"
67expect {
68 timeout {puts "TESTING ERROR 6\n";exit}
69 ":firejail --ignore=quiet gnome-calculator"
70}
71expect {
72 timeout {puts "TESTING ERROR 6.1\n";exit}
73 "CapBnd:"
74}
75expect {
76 timeout {puts "TESTING ERROR 6.2\n";exit}
77 "0000000000000000"
78}
79expect {
80 timeout {puts "TESTING ERROR 6.3\n";exit}
81 "name=blablabla"
82}
83after 100
84
85puts "\nall done\n"
diff --git a/test/private-lib/gpicview.exp b/test/private-lib/gpicview.exp
deleted file mode 100755
index 8d36a9d11..000000000
--- a/test/private-lib/gpicview.exp
+++ /dev/null
@@ -1,83 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail gpicview\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Reading profile /etc/firejail/gpicview.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 "gpicview"
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 gpicview"
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 gpicview"
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"
diff --git a/test/private-lib/leafpad.exp b/test/private-lib/leafpad.exp
deleted file mode 100755
index 2a1b07f94..000000000
--- a/test/private-lib/leafpad.exp
+++ /dev/null
@@ -1,83 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail leafpad\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Reading profile /etc/firejail/leafpad.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 "leafpad"
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 leafpad"
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 leafpad"
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"
diff --git a/test/private-lib/mousepad.exp b/test/private-lib/mousepad.exp
deleted file mode 100755
index 2e8f5e92b..000000000
--- a/test/private-lib/mousepad.exp
+++ /dev/null
@@ -1,83 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail mousepad\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Reading profile /etc/firejail/mousepad.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 "mousepad"
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 mousepad"
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 mousepad"
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"
diff --git a/test/private-lib/pluma.exp b/test/private-lib/pluma.exp
deleted file mode 100755
index 92ae0a345..000000000
--- a/test/private-lib/pluma.exp
+++ /dev/null
@@ -1,83 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail pluma\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Reading profile /etc/firejail/pluma.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 "pluma"
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 pluma"
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 pluma"
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"
diff --git a/test/private-lib/private-lib.sh b/test/private-lib/private-lib.sh
deleted file mode 100755
index edf81917a..000000000
--- a/test/private-lib/private-lib.sh
+++ /dev/null
@@ -1,20 +0,0 @@
1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6export MALLOC_CHECK_=3
7export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
8LIST="evince galculator gnome-calculator gedit leafpad mousepad pluma transmission-gtk xcalc atril gpicview eom eog"
9
10
11for app in $LIST; do
12 which $app 2>/dev/null
13 if [ "$?" -eq 0 ];
14 then
15 echo "TESTING: private-lib $app"
16 ./$app.exp
17 else
18 echo "TESTING SKIP: $app not found"
19 fi
20done
diff --git a/test/private-lib/transmission-gtk.exp b/test/private-lib/transmission-gtk.exp
deleted file mode 100755
index 06559293b..000000000
--- a/test/private-lib/transmission-gtk.exp
+++ /dev/null
@@ -1,83 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail transmission-gtk\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Reading profile /etc/firejail/transmission-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 "transmission-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 transmission-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 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}
81after 100
82
83puts "\nall done\n"
diff --git a/test/private-lib/xcalc.exp b/test/private-lib/xcalc.exp
deleted file mode 100755
index 12bd73b51..000000000
--- a/test/private-lib/xcalc.exp
+++ /dev/null
@@ -1,83 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail xcalc\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Reading profile /etc/firejail/xcalc.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 "xcalc"
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 xcalc"
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 xcalc"
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"
diff --git a/test/utils/audit.exp b/test/utils/audit.exp
deleted file mode 100755
index 6352dc62d..000000000
--- a/test/utils/audit.exp
+++ /dev/null
@@ -1,159 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 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\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
79# run audit executable without a sandbox
80send -- "faudit\r"
81expect {
82 timeout {puts "TESTING ERROR 13\n";exit}
83 "is not running in a PID namespace"
84}
85expect {
86 timeout {puts "TESTING ERROR 14\n";exit}
87 "BAD: seccomp disabled"
88}
89expect {
90 timeout {puts "TESTING ERROR 15\n";exit}
91 "BAD: the capability map is"
92}
93expect {
94 timeout {puts "TESTING ERROR 16\n";exit}
95 "MAYBE: /dev directory seems to be fully populated"
96}
97after 100
98
99# test seccomp
100send -- "firejail --seccomp.drop=mkdir --audit\r"
101expect {
102 timeout {puts "TESTING ERROR 17\n";exit}
103 "Firejail Audit"
104}
105expect {
106 timeout {puts "TESTING ERROR 18\n";exit}
107 "GOOD: seccomp BPF enabled"
108}
109expect {
110 timeout {puts "TESTING ERROR 19\n";exit}
111 "UGLY: mount syscall permitted"
112}
113expect {
114 timeout {puts "TESTING ERROR 20\n";exit}
115 "UGLY: umount2 syscall permitted"
116}
117expect {
118 timeout {puts "TESTING ERROR 21\n";exit}
119 "UGLY: ptrace syscall permitted"
120}
121expect {
122 timeout {puts "TESTING ERROR 22\n";exit}
123 "UGLY: swapon syscall permitted"
124}
125expect {
126 timeout {puts "TESTING ERROR 23\n";exit}
127 "UGLY: swapoff syscall permitted"
128}
129expect {
130 timeout {puts "TESTING ERROR 24\n";exit}
131 "UGLY: init_module syscall permitted"
132}
133expect {
134 timeout {puts "TESTING ERROR 25\n";exit}
135 "UGLY: delete_module syscall permitted"
136}
137expect {
138 timeout {puts "TESTING ERROR 26\n";exit}
139 "UGLY: chroot syscall permitted"
140}
141expect {
142 timeout {puts "TESTING ERROR 27\n";exit}
143 "UGLY: pivot_root syscall permitted"
144}
145expect {
146 timeout {puts "TESTING ERROR 28\n";exit}
147 "UGLY: iopl syscall permitted"
148}
149expect {
150 timeout {puts "TESTING ERROR 29\n";exit}
151 "UGLY: ioperm syscall permitted"
152}
153expect {
154 timeout {puts "TESTING ERROR 30\n";exit}
155 "GOOD: all capabilities are disabled"
156}
157after 100
158
159puts "\nall done\n"
diff --git a/test/utils/build.exp b/test/utils/build.exp
deleted file mode 100755
index 5e883e4ba..000000000
--- a/test/utils/build.exp
+++ /dev/null
@@ -1,91 +0,0 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2018 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --build cat ~/firejail-test-file-7699\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "whitelist ~/firejail-test-file-7699"
14}
15expect {
16 timeout {puts "TESTING ERROR 0.1\n";exit}
17 "include /etc/firejail/whitelist-common.inc"
18}
19expect {
20 timeout {puts "TESTING ERROR 1\n";exit}
21 "private-tmp"
22}
23expect {
24 timeout {puts "TESTING ERROR 2\n";exit}
25 "private-dev"
26}
27expect {
28 timeout {puts "TESTING ERROR 3\n";exit}
29 "blacklist /var"
30}
31expect {
32 timeout {puts "TESTING ERROR 4\n";exit}
33 "private-bin cat,"
34}
35expect {
36 timeout {puts "TESTING ERROR 5\n";exit}
37 "caps.drop all"
38}
39expect {
40 timeout {puts "TESTING ERROR 6\n";exit}
41 "nonewprivs"
42}
43expect {
44 timeout {puts "TESTING ERROR 7\n";exit}
45 "seccomp"
46}
47expect {
48 timeout {puts "TESTING ERROR 8\n";exit}
49 "net none"
50}
51expect {
52 timeout {puts "TESTING ERROR 9\n";exit}
53 "shell none"
54}
55after 100
56
57send -- "firejail --build cat /etc/passwd\r"
58expect {
59 timeout {puts "TESTING ERROR 10\n";exit}
60 "private-etc passwd,"
61}
62after 100
63
64send -- "firejail --build cat /var/tmp/firejail-test-file-7699\r"
65expect {
66 timeout {puts "TESTING ERROR 11\n";exit}
67 "whitelist /var/tmp/firejail-test-file-7699"
68}
69after 100
70
71send -- "firejail --build man firejail\r"
72expect {
73 timeout {puts "TESTING ERROR 12\n";exit}
74 "whitelist /usr/share/man"
75}
76after 100
77
78send -- "firejail --build wget blablabla\r"
79expect {
80 timeout {puts "TESTING ERROR 13\n";exit}
81 "protocol inet"
82}
83after 100
84
85
86send -- "firejail --build cat /tmp/firejail-test-file-7699\r"
87#todo - bug: it comes back with private-tmp
88sleep 1
89
90
91puts "all done\n"
diff --git a/test/utils/utils.sh b/test/utils/utils.sh
index d98e4c2e4..82d00007b 100755
--- a/test/utils/utils.sh
+++ b/test/utils/utils.sh
@@ -12,18 +12,6 @@ if [ -f /etc/debian_version ]; then
12fi 12fi
13export PATH="$PATH:/usr/lib/firejail:/usr/lib64/firejail" 13export PATH="$PATH:/usr/lib/firejail:/usr/lib64/firejail"
14 14
15echo "testing" > ~/firejail-test-file-7699
16echo "testing" > /tmp/firejail-test-file-7699
17echo "testing" > /var/tmp/firejail-test-file-7699
18echo "TESTING: build (test/utils/build.exp)"
19./build.exp
20rm -f ~/firejail-test-file-7699
21rm -f /tmp/firejail-test-file-7699
22rm -f /var/tmp/firejail-test-file-7699
23
24echo "TESTING: audit (test/utils/audit.exp)"
25./audit.exp
26
27echo "TESTING: name (test/utils/name.exp)" 15echo "TESTING: name (test/utils/name.exp)"
28./name.exp 16./name.exp
29 17