diff options
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 @@ | |||
1 | all: apps man filters | 1 | all: apps man filters |
2 | MYLIBS = src/lib | 2 | MYLIBS = src/lib |
3 | APPS = 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 | 3 | APPS = 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 |
4 | MANPAGES = firejail.1 firemon.1 firecfg.1 firejail-profile.5 firejail-login.5 firejail-users.5 | 4 | MANPAGES = firejail.1 firemon.1 firecfg.1 firejail-profile.5 firejail-login.5 firejail-users.5 |
5 | SECCOMP_FILTERS = seccomp seccomp.debug seccomp.32 seccomp.block_secondary seccomp.mdwx | 5 | SECCOMP_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/. | ||
102 | ifeq ($(HAVE_SECCOMP),-DHAVE_SECCOMP) | 99 | ifeq ($(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/. |
111 | endif | 108 | endif |
112 | ifeq ($(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/. | ||
118 | endif | ||
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 | ||
179 | uninstall: | 166 | uninstall: |
@@ -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 | ||
193 | DISTFILES = "src etc platform contrib configure configure.ac dummy.c Makefile.in install.sh mkman.sh mketc.sh mkdeb.sh COPYING README RELNOTES" | 180 | DISTFILES = "src etc platform configure configure.ac dummy.c Makefile.in install.sh mkman.sh mketc.sh mkdeb.sh COPYING README RELNOTES" |
194 | DISTFILES_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" | 181 | DISTFILES_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 | ||
196 | dist: | 183 | dist: |
@@ -214,9 +201,6 @@ deb: dist | |||
214 | snap: all | 201 | snap: all |
215 | cd platform/snap; ./snap.sh | 202 | cd platform/snap; ./snap.sh |
216 | 203 | ||
217 | install-snap: snap | ||
218 | sudo snap remove faudit; sudo snap install faudit*.snap | ||
219 | |||
220 | test-compile: dist | 204 | test-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 | |||
242 | test-profiles: | 226 | test-profiles: |
243 | cd test/profiles; ./profiles.sh | grep TESTING | 227 | cd test/profiles; ./profiles.sh | grep TESTING |
244 | 228 | ||
245 | test-private-lib: | ||
246 | cd test/private-lib; ./private-lib.sh | grep TESTING | ||
247 | |||
248 | test-apps: | 229 | test-apps: |
249 | cd test/apps; ./apps.sh | grep TESTING | 230 | cd test/apps; ./apps.sh | grep TESTING |
250 | 231 | ||
251 | test-apps-x11: | ||
252 | cd test/apps-x11; ./apps-x11.sh | grep TESTING | ||
253 | |||
254 | test-apps-x11-xorg: | ||
255 | cd test/apps-x11-xorg; ./apps-x11-xorg.sh | grep TESTING | ||
256 | |||
257 | test-sysutils: | 232 | test-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: | |||
280 | test-fnetfilter: | 255 | test-fnetfilter: |
281 | cd test/fnetfilter; ./fnetfilter.sh | grep TESTING | 256 | cd test/fnetfilter; ./fnetfilter.sh | grep TESTING |
282 | 257 | ||
283 | test: 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 | 258 | test: 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 | ||
286 | test-travis: test-profiles test-fcopy test-fnetfilter test-fs test-utils test-sysutils test-environment test-filters test-arguments | 261 | test-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 | |||
296 | test-ssh: | 271 | test-ssh: |
297 | cd test/ssh; ./ssh.sh | grep TESTING | 272 | cd test/ssh; ./ssh.sh | grep TESTING |
298 | 273 | ||
299 | # requires root access | ||
300 | test-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 |
304 | test-appimage: | 275 | test-appimage: |
305 | cd test/appimage; ./appimage.sh | grep TESTING | 276 | cd test/appimage; ./appimage.sh | grep TESTING |
@@ -317,10 +288,6 @@ test-stress: | |||
317 | test-root: | 288 | test-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 | ||
321 | test-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 | ||
326 | test-all: test-root test-chroot test-network test-appimage test-overlay | 293 | test-all: test-root test-chroot test-network test-appimage test-overlay |
@@ -625,7 +625,6 @@ ac_includes_default="\ | |||
625 | ac_subst_vars='LTLIBOBJS | 625 | ac_subst_vars='LTLIBOBJS |
626 | LIBOBJS | 626 | LIBOBJS |
627 | HAVE_SECCOMP_H | 627 | HAVE_SECCOMP_H |
628 | HAVE_CONTRIB_INSTALL | ||
629 | HAVE_GCOV | 628 | HAVE_GCOV |
630 | BUSYBOX_WORKAROUND | 629 | BUSYBOX_WORKAROUND |
631 | HAVE_FATAL_WARNINGS | 630 | HAVE_FATAL_WARNINGS |
@@ -716,7 +715,6 @@ enable_suid | |||
716 | enable_fatal_warnings | 715 | enable_fatal_warnings |
717 | enable_busybox_workaround | 716 | enable_busybox_workaround |
718 | enable_gcov | 717 | enable_gcov |
719 | enable_contrib_install | ||
720 | ' | 718 | ' |
721 | ac_precious_vars='build_alias | 719 | ac_precious_vars='build_alias |
722 | host_alias | 720 | host_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 | ||
1371 | Some influential environment variables: | 1367 | Some 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 | ||
3777 | fi | 3773 | fi |
3778 | 3774 | ||
3779 | HAVE_CONTRIB_INSTALL="yes" | ||
3780 | # Check whether --enable-contrib-install was given. | ||
3781 | if test "${enable_contrib_install+set}" = set; then : | ||
3782 | enableval=$enable_contrib_install; | ||
3783 | fi | ||
3784 | |||
3785 | if test "x$enable_contrib_install" = "xno"; then : | ||
3786 | HAVE_CONTRIB_INSTALL="no" | ||
3787 | else | ||
3788 | HAVE_CONTRIB_INSTALL="yes" | ||
3789 | |||
3790 | fi | ||
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" |
3856 | fi | 3838 | fi |
3857 | 3839 | ||
3858 | ac_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" | 3840 | ac_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 | ||
3860 | cat >confcache <<\_ACEOF | 3842 | cat >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" | |||
5061 | echo " EXTRA_CFLAGS: $EXTRA_CFLAGS" | 5040 | echo " EXTRA_CFLAGS: $EXTRA_CFLAGS" |
5062 | echo " fatal warnings: $HAVE_FATAL_WARNINGS" | 5041 | echo " fatal warnings: $HAVE_FATAL_WARNINGS" |
5063 | echo " Gcov instrumentation: $HAVE_GCOV" | 5042 | echo " Gcov instrumentation: $HAVE_GCOV" |
5064 | echo " Install contrib scripts: $HAVE_CONTRIB_INSTALL" | ||
5065 | echo " Install as a SUID executable: $HAVE_SUID" | 5043 | echo " Install as a SUID executable: $HAVE_SUID" |
5066 | echo | 5044 | echo |
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 | ||
181 | HAVE_CONTRIB_INSTALL="yes" | ||
182 | AC_ARG_ENABLE([contrib-install], | ||
183 | AS_HELP_STRING([--enable-contrib-install], [install contrib scripts])) | ||
184 | AS_IF([test "x$enable_contrib_install" = "xno"], | ||
185 | [HAVE_CONTRIB_INSTALL="no"], | ||
186 | [HAVE_CONTRIB_INSTALL="yes"] | ||
187 | ) | ||
188 | AC_SUBST(HAVE_CONTRIB_INSTALL) | ||
189 | |||
190 | # checking pthread library | 181 | # checking pthread library |
191 | AC_CHECK_LIB([pthread], [main], [], AC_MSG_ERROR([*** POSIX thread support not installed ***])) | 182 | AC_CHECK_LIB([pthread], [main], [], AC_MSG_ERROR([*** POSIX thread support not installed ***])) |
192 | AC_CHECK_HEADER(pthread.h,,AC_MSG_ERROR([*** POSIX thread support not installed ***])) | 183 | AC_CHECK_HEADER(pthread.h,,AC_MSG_ERROR([*** POSIX thread support not installed ***])) |
@@ -199,8 +190,8 @@ if test "$prefix" = /usr; then | |||
199 | fi | 190 | fi |
200 | 191 | ||
201 | AC_OUTPUT(Makefile src/common.mk src/lib/Makefile src/fcopy/Makefile src/fnet/Makefile src/firejail/Makefile src/fnetfilter/Makefile \ | 192 | AC_OUTPUT(Makefile src/common.mk src/lib/Makefile src/fcopy/Makefile src/fnet/Makefile src/firejail/Makefile src/fnetfilter/Makefile \ |
202 | src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/fbuilder/Makefile src/fsec-print/Makefile \ | 193 | src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/fsec-print/Makefile \ |
203 | src/ftee/Makefile src/faudit/Makefile src/fseccomp/Makefile src/fldd/Makefile src/libpostexecseccomp/Makefile src/fsec-optimize/Makefile) | 194 | src/ftee/Makefile src/fseccomp/Makefile src/libpostexecseccomp/Makefile src/fsec-optimize/Makefile) |
204 | 195 | ||
205 | echo | 196 | echo |
206 | echo "Configuration options:" | 197 | echo "Configuration options:" |
@@ -225,6 +216,5 @@ echo " EXTRA_LDFLAGS: $EXTRA_LDFLAGS" | |||
225 | echo " EXTRA_CFLAGS: $EXTRA_CFLAGS" | 216 | echo " EXTRA_CFLAGS: $EXTRA_CFLAGS" |
226 | echo " fatal warnings: $HAVE_FATAL_WARNINGS" | 217 | echo " fatal warnings: $HAVE_FATAL_WARNINGS" |
227 | echo " Gcov instrumentation: $HAVE_GCOV" | 218 | echo " Gcov instrumentation: $HAVE_GCOV" |
228 | echo " Install contrib scripts: $HAVE_CONTRIB_INSTALL" | ||
229 | echo " Install as a SUID executable: $HAVE_SUID" | 219 | echo " Install as a SUID executable: $HAVE_SUID" |
230 | echo | 220 | echo |
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 | |||
6 | Anyone is free to copy, modify, publish, use, compile, sell, or | ||
7 | distribute this software, either in source code form or as a compiled | ||
8 | binary, for any purpose, commercial or non-commercial, and by any | ||
9 | means. | ||
10 | |||
11 | In jurisdictions that recognize copyright laws, the author or authors | ||
12 | of this software dedicate any and all copyright interest in the | ||
13 | software to the public domain. We make this dedication for the benefit | ||
14 | of the public at large and to the detriment of our heirs and | ||
15 | successors. We intend this dedication to be an overt act of | ||
16 | relinquishment in perpetuity of all present and future rights to this | ||
17 | software under copyright law. | ||
18 | |||
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
22 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
23 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
24 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
25 | OTHER DEALINGS IN THE SOFTWARE. | ||
26 | |||
27 | For more information, please refer to <http://unlicense.org/>""" | ||
28 | __license__ = "Unlicense" | ||
29 | |||
30 | import sys, os, glob, re | ||
31 | |||
32 | privRx=re.compile("^(?:#\s*)?private-bin") | ||
33 | |||
34 | def 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 | |||
65 | def 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 | |||
81 | def 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 | |||
104 | def 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 | |||
125 | def printHelp(): | ||
126 | print("python3 "+os.path.basename(__file__)+" <dir with .profile files>\nThe default dir is "+defaultProfilesPath+"\n"+doTheFixes.__doc__) | ||
127 | |||
128 | def 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 | |||
156 | if __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 | |||
5 | import os, re, shlex, subprocess, sys | ||
6 | |||
7 | def 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 | |||
40 | if __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 | |||
44 | usage: | ||
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 | |||
3 | import re | ||
4 | import sys | ||
5 | import subprocess | ||
6 | import fjdisplay | ||
7 | |||
8 | usage = """fjclip.py src dest. src or dest can be named firejails or - for stdin or stdout. | ||
9 | firemon --x11 to see available running x11 firejails. firejail names can be shortened | ||
10 | to least ambiguous. for example 'work-libreoffice' can be shortened to 'work' if no | ||
11 | other firejails name starts with 'work'. | ||
12 | warning: browsers are dangerous. clipboards from browsers are dangerous. see | ||
13 | https://github.com/dxa4481/Pastejacking | ||
14 | fjclip.py strips whitespace from both | ||
15 | ends, but does nothing else to protect you. use a simple gui text editor like | ||
16 | gedit if you want to see what your pasting.""" | ||
17 | |||
18 | if len(sys.argv) != 3 or sys.argv == '-h' or sys.argv == '--help': | ||
19 | print(usage) | ||
20 | exit(1) | ||
21 | |||
22 | if sys.argv[1] == '-': | ||
23 | clipin_raw = sys.stdin.read() | ||
24 | else: | ||
25 | display = fjdisplay.getdisplay(sys.argv[1]) | ||
26 | clipin_raw = subprocess.check_output(['xsel','-b','--display',display]) | ||
27 | |||
28 | clipin = clipin_raw.strip() | ||
29 | |||
30 | if sys.argv[2] == '-': | ||
31 | print(clipin) | ||
32 | else: | ||
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 | |||
3 | import re | ||
4 | import sys | ||
5 | import subprocess | ||
6 | |||
7 | usage = """fjdisplay.py name-of-firejail | ||
8 | returns the display in the form of ':NNN' | ||
9 | """ | ||
10 | |||
11 | def 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 | |||
24 | def 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 | |||
36 | if __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 | |||
3 | import sys | ||
4 | import fjdisplay | ||
5 | import subprocess | ||
6 | |||
7 | usage = """usage: fjresize.py firejail-name displaysize | ||
8 | resize firejail xephyr windows. | ||
9 | fjdisplay.py with no other arguments will list running named firejails with displays. | ||
10 | fjresize.py with only a firejail name will list valid resolutions. | ||
11 | names can be shortend as long its unambiguous. | ||
12 | note: you may need to move the xephyr window for the resize to take effect | ||
13 | example: | ||
14 | fjresize.py browser 1280x800 | ||
15 | """ | ||
16 | |||
17 | |||
18 | if len(sys.argv) == 2: | ||
19 | out = subprocess.check_output(['xrandr','--display',fjdisplay.getdisplay(sys.argv[1])]) | ||
20 | print(out) | ||
21 | elif 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) | ||
24 | else: | ||
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). | ||
4 | set -e | ||
5 | git clone --depth=1 https://github.com/netblue30/firejail.git | ||
6 | cd firejail | ||
7 | ./configure --prefix=/usr | ||
8 | make deb | ||
9 | sudo dpkg -i firejail*.deb | ||
10 | echo "Firejail was updated!" | ||
11 | cd .. | ||
12 | rm -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 @@ | |||
1 | all: faudit | ||
2 | |||
3 | include ../common.mk | ||
4 | |||
5 | %.o : %.c $(H_FILE_LIST) | ||
6 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@ | ||
7 | |||
8 | faudit: $(OBJS) | ||
9 | $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTRA_LDFLAGS) | ||
10 | |||
11 | clean:; rm -f *.o faudit *.gcov *.gcda *.gcno | ||
12 | |||
13 | distclean: 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 | ||
25 | static 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 | ||
47 | static 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 | |||
59 | void 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 | ||
25 | int 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 | |||
49 | void 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 | |||
23 | void 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 | ||
37 | extern char *prog; | ||
38 | |||
39 | // pid.c | ||
40 | void pid_test(void); | ||
41 | |||
42 | // caps.c | ||
43 | void caps_test(void); | ||
44 | |||
45 | // seccomp.c | ||
46 | void seccomp_test(void); | ||
47 | |||
48 | // syscall.c | ||
49 | void syscall_helper(int argc, char **argv); | ||
50 | void syscall_run(const char *name); | ||
51 | |||
52 | // files.c | ||
53 | void files_test(void); | ||
54 | |||
55 | // network.c | ||
56 | void network_test(void); | ||
57 | |||
58 | // dbus.c | ||
59 | int check_unix(const char *sockfile); | ||
60 | void dbus_test(void); | ||
61 | |||
62 | // dev.c | ||
63 | void dev_test(void); | ||
64 | |||
65 | // x11.c | ||
66 | void 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 | |||
24 | static char *username = NULL; | ||
25 | static char *homedir = NULL; | ||
26 | |||
27 | static 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 | |||
44 | void 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" | ||
21 | char *prog; | ||
22 | |||
23 | int 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 | |||
26 | static 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 | |||
50 | static 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 | |||
74 | void 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 | |||
97 | void 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 | |||
22 | void 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 | ||
23 | static 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 | |||
44 | void 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> | ||
27 | extern int init_module(void *module_image, unsigned long len, | ||
28 | const char *param_values); | ||
29 | extern int finit_module(int fd, const char *param_values, | ||
30 | int flags); | ||
31 | extern int delete_module(const char *name, int flags); | ||
32 | extern int pivot_root(const char *new_root, const char *put_old); | ||
33 | |||
34 | void 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 | |||
91 | void 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 | |||
25 | void 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 @@ | |||
1 | all: fbuilder | ||
2 | |||
3 | include ../common.mk | ||
4 | |||
5 | %.o : %.c $(H_FILE_LIST) ../include/common.h ../include/syscall.h | ||
6 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@ | ||
7 | |||
8 | fbuilder: $(OBJS) | ||
9 | $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTRA_LDFLAGS) | ||
10 | |||
11 | clean:; rm -f *.o fbuilder *.gcov *.gcda *.gcno | ||
12 | |||
13 | distclean: 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 | |||
22 | static FileDB *bin_out = NULL; | ||
23 | |||
24 | static 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 | ||
98 | void 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 | ||
24 | static 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 | ||
89 | static 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 | //******************************************* | ||
113 | static FileDB *etc_out = NULL; | ||
114 | |||
115 | static 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 | |||
128 | void 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 | //******************************************* | ||
149 | static FileDB *var_out = NULL; | ||
150 | static 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 | |||
163 | void 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 | //******************************************* | ||
178 | static FileDB *share_out = NULL; | ||
179 | static 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 | |||
200 | void 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 | //******************************************* | ||
214 | static FileDB *tmp_out = NULL; | ||
215 | static void tmp_callback(char *ptr) { | ||
216 | filedb_add(tmp_out, ptr); | ||
217 | } | ||
218 | |||
219 | void 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 | //******************************************* | ||
243 | static 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 | |||
281 | static FileDB *dev_out = NULL; | ||
282 | static 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 | |||
297 | void 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 | |||
23 | static FileDB *db_skip = NULL; | ||
24 | static FileDB *db_out = NULL; | ||
25 | |||
26 | static 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 | |||
50 | void 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 | ||
161 | void 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 | |||
28 | static 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 | |||
43 | static 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 | |||
59 | void 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 | |||
23 | void 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 | //*************************************** | ||
85 | int unix_s = 0; | ||
86 | int inet = 0; | ||
87 | int inet6 = 0; | ||
88 | int netlink = 0; | ||
89 | int packet = 0; | ||
90 | static 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 | ||
145 | void 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 | ||
32 | extern int arg_debug; | ||
33 | |||
34 | // build_profile.c | ||
35 | void build_profile(int argc, char **argv, int index, FILE *fp); | ||
36 | |||
37 | // build_seccomp.c | ||
38 | void build_seccomp(const char *fname, FILE *fp); | ||
39 | void build_protocol(const char *fname, FILE *fp); | ||
40 | |||
41 | // build_fs.c | ||
42 | void build_etc(const char *fname, FILE *fp); | ||
43 | void build_var(const char *fname, FILE *fp); | ||
44 | void build_tmp(const char *fname, FILE *fp); | ||
45 | void build_dev(const char *fname, FILE *fp); | ||
46 | void build_share(const char *fname, FILE *fp); | ||
47 | |||
48 | // build_bin.c | ||
49 | void build_bin(const char *fname, FILE *fp); | ||
50 | |||
51 | // build_home.c | ||
52 | void build_home(const char *fname, FILE *fp); | ||
53 | |||
54 | // utils.c | ||
55 | int is_dir(const char *fname); | ||
56 | char *extract_dir(char *fname); | ||
57 | |||
58 | // filedb.c | ||
59 | typedef struct filedb_t { | ||
60 | struct filedb_t *next; | ||
61 | char *fname; // file name | ||
62 | int len; // length of file name | ||
63 | } FileDB; | ||
64 | |||
65 | FileDB *filedb_add(FileDB *head, const char *fname); | ||
66 | FileDB *filedb_find(FileDB *head, const char *fname); | ||
67 | void 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 | |||
23 | FileDB *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 | |||
52 | FileDB *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 | |||
72 | void 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" | ||
21 | int arg_debug = 0; | ||
22 | |||
23 | static void usage(void) { | ||
24 | printf("Firejail profile builder\n"); | ||
25 | printf("Usage: firejail [--debug] --build[=profile-file] program-and-arguments\n"); | ||
26 | } | ||
27 | |||
28 | int main(int argc, char **argv) { | ||
29 | #if 0 | ||
30 | { | ||
31 | system("cat /proc/self/status"); | ||
32 | int i; | ||
33 | for (i = 0; i < argc; i++) | ||
34 | printf("*%s* ", argv[i]); | ||
35 | printf("\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 | ||
25 | int 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 | ||
55 | char *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 |
745 | char *fs_check_overlay_dir(const char *subdirname, int allow_reuse) { | 745 | char *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 |
1297 | void fs_private_tmp(void) { | 1298 | void 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 | |||
28 | static int prog_cnt = 0; | ||
29 | |||
30 | static 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 | ||
43 | static 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[] | ||
100 | static 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 | |||
138 | static 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 | |||
151 | static 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 | |||
222 | static 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 | |||
269 | void 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 | |||
30 | extern void fslib_install_stdc(void); | ||
31 | extern void fslib_install_system(void); | ||
32 | |||
33 | static int lib_cnt = 0; | ||
34 | static int dir_cnt = 0; | ||
35 | |||
36 | static 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 | |||
52 | static 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 | ||
60 | void 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 | ||
98 | void 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 | |||
139 | void 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 | ||
176 | static 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 | |||
198 | static 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 | |||
248 | void 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 | |||
268 | static 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 | |||
309 | void 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 | |||
24 | extern void fslib_duplicate(const char *full_path); | ||
25 | extern void fslib_copy_libs(const char *full_path); | ||
26 | extern 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 | ||
34 | typedef struct liblist_t { | ||
35 | const char *name; | ||
36 | int len; | ||
37 | } LibList; | ||
38 | |||
39 | static 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 | |||
65 | static 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 | ||
80 | static 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 | |||
104 | void 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 | ||
130 | typedef 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 | |||
139 | SysLib 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 | |||
222 | void 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 | ||
828 | static void run_builder(int argc, char **argv) { | 831 | static 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. | ||
43 | int 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 | ||
84 | static 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. | ||
126 | static 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 | ||
204 | void 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 | |||
396 | static 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 | ||
418 | void 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 | |||
626 | void 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 | |||
862 | void 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 | |||
1010 | void 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 | |||
1041 | void 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. | ||
1083 | void 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 | |||
1214 | void 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 | |||
1278 | void 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 @@ | |||
1 | all: fldd | ||
2 | |||
3 | include ../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 | |||
8 | fldd: $(OBJS) ../lib/ldd_utils.o | ||
9 | $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/ldd_utils.o $(LIBS) $(EXTRA_LDFLAGS) | ||
10 | |||
11 | clean:; rm -f *.o fldd *.gcov *.gcda *.gcno | ||
12 | |||
13 | distclean: 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 | |||
33 | static int arg_quiet = 0; | ||
34 | static void copy_libs_for_lib(const char *lib); | ||
35 | |||
36 | typedef struct storage_t { | ||
37 | struct storage_t *next; | ||
38 | const char *name; | ||
39 | } Storage; | ||
40 | static Storage *libs = NULL; | ||
41 | static Storage *lib_paths = NULL; | ||
42 | |||
43 | // return 1 if found | ||
44 | static 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 | |||
54 | static 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 | |||
69 | static void storage_print(Storage *ptr, int fd) { | ||
70 | while (ptr) { | ||
71 | dprintf(fd, "%s\n", ptr->name); | ||
72 | ptr = ptr->next; | ||
73 | } | ||
74 | } | ||
75 | |||
76 | static 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 | |||
85 | static 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 | |||
205 | static 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 | |||
228 | static 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 | |||
235 | static 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 | |||
277 | static 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 | |||
283 | int main(int argc, char **argv) { | ||
284 | #if 0 | ||
285 | { | ||
286 | //system("cat /proc/self/status"); | ||
287 | int i; | ||
288 | for (i = 0; i < argc; i++) | ||
289 | printf("*%s* ", argv[i]); | ||
290 | printf("\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 | } | ||
@@ -1,2 +1,5 @@ | |||
1 | starting from main as of Jul 27 | 1 | Phase 1 |
2 | removing 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 | |||
6 | export MALLOC_CHECK_=3 | ||
7 | export MALLOC_PERTURB_=$(($RANDOM % 255 + 1)) | ||
8 | |||
9 | which firefox 2>/dev/null | ||
10 | if [ "$?" -eq 0 ]; | ||
11 | then | ||
12 | echo "TESTING: firefox x11 xorg" | ||
13 | ./firefox.exp | ||
14 | else | ||
15 | echo "TESTING SKIP: firefox not found" | ||
16 | fi | ||
17 | |||
18 | which transmission-gtk 2>/dev/null | ||
19 | if [ "$?" -eq 0 ]; | ||
20 | then | ||
21 | echo "TESTING: transmission-gtk x11 xorg" | ||
22 | ./transmission-gtk.exp | ||
23 | else | ||
24 | echo "TESTING SKIP: transmission-gtk not found" | ||
25 | fi | ||
26 | |||
27 | which thunderbird 2>/dev/null | ||
28 | if [ "$?" -eq 0 ]; | ||
29 | then | ||
30 | echo "TESTING: thunderbird x11 xorg" | ||
31 | ./thunderbird.exp | ||
32 | else | ||
33 | echo "TESTING SKIP: thunderbird not found" | ||
34 | fi | ||
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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail --name=test --x11=xorg --ignore=net --ignore=netfilter --ignore=iprange firefox -no-remote www.gentoo.org\r" | ||
11 | sleep 10 | ||
12 | |||
13 | spawn $env(SHELL) | ||
14 | send -- "firejail --list\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 3\n";exit} | ||
17 | ":firejail" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
21 | "firefox" {puts "firefox detected\n";} | ||
22 | "iceweasel" {puts "iceweasel detected\n";} | ||
23 | } | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 3.2\n";exit} | ||
26 | "no-remote" | ||
27 | } | ||
28 | sleep 1 | ||
29 | # grsecurity exit | ||
30 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
31 | expect { | ||
32 | timeout {puts "TESTING ERROR - grsecurity detection\n";exit} | ||
33 | "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit} | ||
34 | "cannot open" {puts "grsecurity not present\n"} | ||
35 | } | ||
36 | send -- "firejail --name=blablabla\r" | ||
37 | expect { | ||
38 | timeout {puts "TESTING ERROR 4\n";exit} | ||
39 | "Child process initialized" | ||
40 | } | ||
41 | sleep 2 | ||
42 | |||
43 | spawn $env(SHELL) | ||
44 | send -- "firemon --seccomp --nowrap\r" | ||
45 | expect { | ||
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 | } | ||
51 | expect { | ||
52 | timeout {puts "TESTING ERROR 5.0\n";exit} | ||
53 | "no-remote" | ||
54 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
57 | "Seccomp: 2" | ||
58 | } | ||
59 | expect { | ||
60 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
61 | "name=blablabla" | ||
62 | } | ||
63 | sleep 1 | ||
64 | send -- "firemon --caps --nowrap\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6\n";exit} | ||
67 | " firefox" {puts "firefox detected\n";} | ||
68 | " iceweasel" {puts "iceweasel detected\n";} | ||
69 | } | ||
70 | expect { | ||
71 | timeout {puts "TESTING ERROR 6.0\n";exit} | ||
72 | "no-remote" | ||
73 | } | ||
74 | expect { | ||
75 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
76 | "CapBnd:" | ||
77 | } | ||
78 | expect { | ||
79 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
80 | "0000000000000000" | ||
81 | } | ||
82 | expect { | ||
83 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
84 | "name=blablabla" | ||
85 | } | ||
86 | sleep 1 | ||
87 | send -- "firejail --shutdown=test\r" | ||
88 | sleep 3 | ||
89 | |||
90 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail --name=test --x11=xorg --ignore=net --ignore=netfilter --ignore=iprange thunderbird\r" | ||
11 | sleep 10 | ||
12 | |||
13 | spawn $env(SHELL) | ||
14 | send -- "firejail --list\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 3\n";exit} | ||
17 | ":firejail" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
21 | "thunderbird" | ||
22 | } | ||
23 | sleep 1 | ||
24 | |||
25 | # grsecurity exit | ||
26 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
27 | expect { | ||
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 | |||
33 | send -- "firejail --name=blablabla\r" | ||
34 | expect { | ||
35 | timeout {puts "TESTING ERROR 4\n";exit} | ||
36 | "Child process initialized" | ||
37 | } | ||
38 | sleep 2 | ||
39 | |||
40 | spawn $env(SHELL) | ||
41 | send -- "firemon --seccomp --nowrap\r" | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 5\n";exit} | ||
44 | "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit} | ||
45 | ":firejail" | ||
46 | } | ||
47 | expect { | ||
48 | timeout {puts "TESTING ERROR 5.0\n";exit} | ||
49 | "thunderbird" | ||
50 | } | ||
51 | expect { | ||
52 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
53 | "Seccomp: 2" | ||
54 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
57 | "name=blablabla" | ||
58 | } | ||
59 | sleep 2 | ||
60 | send -- "firemon --caps --nowrap\r" | ||
61 | expect { | ||
62 | timeout {puts "TESTING ERROR 6\n";exit} | ||
63 | ":firejail" | ||
64 | } | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6.0\n";exit} | ||
67 | "thunderbird" | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
71 | "CapBnd" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
75 | "0000000000000000" | ||
76 | } | ||
77 | expect { | ||
78 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
79 | "name=blablabla" | ||
80 | } | ||
81 | sleep 1 | ||
82 | send -- "firejail --shutdown=test\r" | ||
83 | sleep 3 | ||
84 | |||
85 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail --name=test --x11=xorg --ignore=net --ignore=netfilter --ignore=iprange transmission-gtk\r" | ||
11 | sleep 10 | ||
12 | |||
13 | spawn $env(SHELL) | ||
14 | send -- "firejail --list\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 3\n";exit} | ||
17 | ":firejail" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
21 | "transmission-gtk" | ||
22 | } | ||
23 | sleep 1 | ||
24 | |||
25 | # grsecurity exit | ||
26 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
27 | expect { | ||
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 | |||
33 | send -- "firejail --name=blablabla\r" | ||
34 | expect { | ||
35 | timeout {puts "TESTING ERROR 4\n";exit} | ||
36 | "Child process initialized" | ||
37 | } | ||
38 | sleep 2 | ||
39 | |||
40 | spawn $env(SHELL) | ||
41 | send -- "firemon --seccomp --nowrap\r" | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 5\n";exit} | ||
44 | "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit} | ||
45 | ":firejail" | ||
46 | } | ||
47 | expect { | ||
48 | timeout {puts "TESTING ERROR 5.0\n";exit} | ||
49 | "transmission-gtk" | ||
50 | } | ||
51 | expect { | ||
52 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
53 | "Seccomp: 2" | ||
54 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
57 | "name=blablabla" | ||
58 | } | ||
59 | sleep 1 | ||
60 | send -- "firemon --caps --nowrap\r" | ||
61 | expect { | ||
62 | timeout {puts "TESTING ERROR 6\n";exit} | ||
63 | ":firejail" | ||
64 | } | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6.0\n";exit} | ||
67 | "transmission-gtk" | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
71 | "CapBnd" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
75 | "0000000000000000" | ||
76 | } | ||
77 | expect { | ||
78 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
79 | "name=blablabla" | ||
80 | } | ||
81 | sleep 1 | ||
82 | send -- "firejail --shutdown=test\r" | ||
83 | sleep 3 | ||
84 | |||
85 | puts "\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 | |||
6 | export MALLOC_CHECK_=3 | ||
7 | export MALLOC_PERTURB_=$(($RANDOM % 255 + 1)) | ||
8 | |||
9 | echo "TESTING: no x11 (test/apps-x11/x11-none.exp)" | ||
10 | ./x11-none.exp | ||
11 | |||
12 | |||
13 | which xterm 2>/dev/null | ||
14 | if [ "$?" -eq 0 ]; | ||
15 | then | ||
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 | ||
32 | else | ||
33 | echo "TESTING SKIP: xterm not found" | ||
34 | fi | ||
35 | |||
36 | # check xpra/xephyr | ||
37 | which xpra 2>/dev/null | ||
38 | if [ "$?" -eq 0 ]; | ||
39 | then | ||
40 | echo "xpra found" | ||
41 | else | ||
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 | ||
51 | fi | ||
52 | |||
53 | which firefox 2>/dev/null | ||
54 | if [ "$?" -eq 0 ]; | ||
55 | then | ||
56 | echo "TESTING: firefox x11" | ||
57 | ./firefox.exp | ||
58 | else | ||
59 | echo "TESTING SKIP: firefox not found" | ||
60 | fi | ||
61 | |||
62 | which chromium 2>/dev/null | ||
63 | if [ "$?" -eq 0 ]; | ||
64 | then | ||
65 | echo "TESTING: chromium x11" | ||
66 | ./chromium.exp | ||
67 | else | ||
68 | echo "TESTING SKIP: chromium not found" | ||
69 | fi | ||
70 | |||
71 | which transmission-gtk 2>/dev/null | ||
72 | if [ "$?" -eq 0 ]; | ||
73 | then | ||
74 | echo "TESTING: transmission-gtk x11" | ||
75 | ./transmission-gtk.exp | ||
76 | else | ||
77 | echo "TESTING SKIP: transmission-gtk not found" | ||
78 | fi | ||
79 | |||
80 | which thunderbird 2>/dev/null | ||
81 | if [ "$?" -eq 0 ]; | ||
82 | then | ||
83 | echo "TESTING: thunderbird x11" | ||
84 | ./thunderbird.exp | ||
85 | else | ||
86 | echo "TESTING SKIP: thunderbird not found" | ||
87 | fi | ||
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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail --name=test --x11 chromium www.gentoo.org\r" | ||
11 | sleep 10 | ||
12 | |||
13 | spawn $env(SHELL) | ||
14 | send -- "firejail --list\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 3\n";exit} | ||
17 | ":firejail" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
21 | "chromium" | ||
22 | } | ||
23 | sleep 1 | ||
24 | |||
25 | # grsecurity exit | ||
26 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
27 | expect { | ||
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 | send -- "firejail --name=blablabla\r" | ||
33 | expect { | ||
34 | timeout {puts "TESTING ERROR 4\n";exit} | ||
35 | "Child process initialized" | ||
36 | } | ||
37 | sleep 2 | ||
38 | |||
39 | spawn $env(SHELL) | ||
40 | send -- "firemon --seccomp\r" | ||
41 | expect { | ||
42 | timeout {puts "TESTING ERROR 5\n";exit} | ||
43 | "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit} | ||
44 | ":firejail" | ||
45 | } | ||
46 | expect { | ||
47 | timeout {puts "TESTING ERROR 5.0\n";exit} | ||
48 | "chromium" | ||
49 | } | ||
50 | expect { | ||
51 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
52 | "Seccomp: 0" | ||
53 | } | ||
54 | expect { | ||
55 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
56 | "name=blablabla" | ||
57 | } | ||
58 | sleep 1 | ||
59 | send -- "firemon --caps\r" | ||
60 | expect { | ||
61 | timeout {puts "TESTING ERROR 6\n";exit} | ||
62 | ":firejail" | ||
63 | } | ||
64 | expect { | ||
65 | timeout {puts "TESTING ERROR 6.0\n";exit} | ||
66 | "chromium" | ||
67 | } | ||
68 | expect { | ||
69 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
70 | "CapBnd:" | ||
71 | } | ||
72 | expect { | ||
73 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
74 | "00240000" | ||
75 | } | ||
76 | expect { | ||
77 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
78 | "name=blablabla" | ||
79 | } | ||
80 | sleep 1 | ||
81 | send -- "firejail --shutdown=test\r" | ||
82 | sleep 3 | ||
83 | |||
84 | |||
85 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail --name=test --x11 firefox -no-remote www.gentoo.org\r" | ||
11 | sleep 10 | ||
12 | |||
13 | spawn $env(SHELL) | ||
14 | send -- "firejail --list\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 3\n";exit} | ||
17 | ":firejail" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
21 | "firefox" {puts "firefox detected\n";} | ||
22 | "iceweasel" {puts "iceweasel detected\n";} | ||
23 | } | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 3.2\n";exit} | ||
26 | "no-remote" | ||
27 | } | ||
28 | sleep 1 | ||
29 | # grsecurity exit | ||
30 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
31 | expect { | ||
32 | timeout {puts "TESTING ERROR - grsecurity detection\n";exit} | ||
33 | "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit} | ||
34 | "cannot open" {puts "grsecurity not present\n"} | ||
35 | } | ||
36 | send -- "firejail --name=blablabla\r" | ||
37 | expect { | ||
38 | timeout {puts "TESTING ERROR 4\n";exit} | ||
39 | "Child process initialized" | ||
40 | } | ||
41 | sleep 2 | ||
42 | |||
43 | spawn $env(SHELL) | ||
44 | send -- "firemon --seccomp\r" | ||
45 | expect { | ||
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 | } | ||
51 | expect { | ||
52 | timeout {puts "TESTING ERROR 5.0\n";exit} | ||
53 | "no-remote" | ||
54 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
57 | "Seccomp: 2" | ||
58 | } | ||
59 | expect { | ||
60 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
61 | "name=blablabla" | ||
62 | } | ||
63 | sleep 1 | ||
64 | send -- "firemon --caps\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6\n";exit} | ||
67 | " firefox" {puts "firefox detected\n";} | ||
68 | " iceweasel" {puts "iceweasel detected\n";} | ||
69 | } | ||
70 | expect { | ||
71 | timeout {puts "TESTING ERROR 6.0\n";exit} | ||
72 | "no-remote" | ||
73 | } | ||
74 | expect { | ||
75 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
76 | "CapBnd:" | ||
77 | } | ||
78 | expect { | ||
79 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
80 | "0000000000000000" | ||
81 | } | ||
82 | expect { | ||
83 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
84 | "name=blablabla" | ||
85 | } | ||
86 | sleep 1 | ||
87 | send -- "firejail --shutdown=test\r" | ||
88 | sleep 3 | ||
89 | |||
90 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail --name=test --x11 thunderbird\r" | ||
11 | sleep 10 | ||
12 | |||
13 | spawn $env(SHELL) | ||
14 | send -- "firejail --list\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 3\n";exit} | ||
17 | ":firejail" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
21 | "thunderbird" | ||
22 | } | ||
23 | sleep 1 | ||
24 | |||
25 | # grsecurity exit | ||
26 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
27 | expect { | ||
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 | |||
33 | send -- "firejail --name=blablabla\r" | ||
34 | expect { | ||
35 | timeout {puts "TESTING ERROR 4\n";exit} | ||
36 | "Child process initialized" | ||
37 | } | ||
38 | sleep 2 | ||
39 | |||
40 | spawn $env(SHELL) | ||
41 | send -- "firemon --seccomp\r" | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 5\n";exit} | ||
44 | "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit} | ||
45 | ":firejail" | ||
46 | } | ||
47 | expect { | ||
48 | timeout {puts "TESTING ERROR 5.0\n";exit} | ||
49 | "thunderbird" | ||
50 | } | ||
51 | expect { | ||
52 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
53 | "Seccomp: 2" | ||
54 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
57 | "name=blablabla" | ||
58 | } | ||
59 | sleep 2 | ||
60 | send -- "firemon --caps\r" | ||
61 | expect { | ||
62 | timeout {puts "TESTING ERROR 6\n";exit} | ||
63 | ":firejail" | ||
64 | } | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6.0\n";exit} | ||
67 | "thunderbird" | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
71 | "CapBnd" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
75 | "0000000000000000" | ||
76 | } | ||
77 | expect { | ||
78 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
79 | "name=blablabla" | ||
80 | } | ||
81 | sleep 1 | ||
82 | send -- "firejail --shutdown=test\r" | ||
83 | sleep 3 | ||
84 | |||
85 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail --name=test --x11 transmission-gtk\r" | ||
11 | sleep 10 | ||
12 | |||
13 | spawn $env(SHELL) | ||
14 | send -- "firejail --list\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 3\n";exit} | ||
17 | ":firejail" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
21 | "transmission-gtk" | ||
22 | } | ||
23 | sleep 1 | ||
24 | |||
25 | # grsecurity exit | ||
26 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
27 | expect { | ||
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 | |||
33 | send -- "firejail --name=blablabla\r" | ||
34 | expect { | ||
35 | timeout {puts "TESTING ERROR 4\n";exit} | ||
36 | "Child process initialized" | ||
37 | } | ||
38 | sleep 2 | ||
39 | |||
40 | spawn $env(SHELL) | ||
41 | send -- "firemon --seccomp\r" | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 5\n";exit} | ||
44 | "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit} | ||
45 | ":firejail" | ||
46 | } | ||
47 | expect { | ||
48 | timeout {puts "TESTING ERROR 5.0\n";exit} | ||
49 | "transmission-gtk" | ||
50 | } | ||
51 | expect { | ||
52 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
53 | "Seccomp: 2" | ||
54 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
57 | "name=blablabla" | ||
58 | } | ||
59 | sleep 1 | ||
60 | send -- "firemon --caps\r" | ||
61 | expect { | ||
62 | timeout {puts "TESTING ERROR 6\n";exit} | ||
63 | ":firejail" | ||
64 | } | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6.0\n";exit} | ||
67 | "transmission-gtk" | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
71 | "CapBnd" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
75 | "0000000000000000" | ||
76 | } | ||
77 | expect { | ||
78 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
79 | "name=blablabla" | ||
80 | } | ||
81 | sleep 1 | ||
82 | send -- "firejail --shutdown=test\r" | ||
83 | sleep 3 | ||
84 | |||
85 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail --name=test --x11=none\r" | ||
11 | expect { | ||
12 | timeout {puts "TESTING ERROR 0\n";exit} | ||
13 | "use network namespace in firejail" | ||
14 | } | ||
15 | sleep 1 | ||
16 | |||
17 | send -- "firejail --name=test --net=none --x11=none\r" | ||
18 | expect { | ||
19 | timeout {puts "TESTING ERROR 1\n";exit} | ||
20 | "Child process initialized" | ||
21 | } | ||
22 | sleep 1 | ||
23 | |||
24 | send -- "ls -al /tmp/.X11-unix\r" | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 2\n";exit} | ||
27 | "cannot open directory" | ||
28 | } | ||
29 | after 100 | ||
30 | |||
31 | send -- "xterm\r" | ||
32 | expect { | ||
33 | timeout {puts "TESTING ERROR 3\n";exit} | ||
34 | "DISPLAY is not set" | ||
35 | } | ||
36 | after 100 | ||
37 | |||
38 | send -- "export DISPLAY=:0.0\r" | ||
39 | after 100 | ||
40 | send -- "xterm\r" | ||
41 | expect { | ||
42 | timeout {puts "TESTING ERROR 4\n";exit} | ||
43 | "Xt error" | ||
44 | } | ||
45 | after 100 | ||
46 | |||
47 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail --name=test --x11=xephyr xterm\r" | ||
11 | expect { | ||
12 | timeout {puts "TESTING ERROR 1\n";exit} | ||
13 | "Child process initialized" | ||
14 | } | ||
15 | |||
16 | exit | ||
17 | |||
18 | |||
19 | sleep 5 | ||
20 | |||
21 | |||
22 | expect { | ||
23 | timeout {puts "TESTING ERROR 0\n";exit} | ||
24 | "use network namespace in firejail" | ||
25 | } | ||
26 | sleep 1 | ||
27 | |||
28 | send -- "firejail --name=test --net=none --x11=none\r" | ||
29 | expect { | ||
30 | timeout {puts "TESTING ERROR 1\n";exit} | ||
31 | "Child process initialized" | ||
32 | } | ||
33 | sleep 1 | ||
34 | |||
35 | send -- "ls -al /tmp/.X11-unix\r" | ||
36 | expect { | ||
37 | timeout {puts "TESTING ERROR 2\n";exit} | ||
38 | "cannot open directory" | ||
39 | } | ||
40 | after 100 | ||
41 | |||
42 | send -- "xterm\r" | ||
43 | expect { | ||
44 | timeout {puts "TESTING ERROR 3\n";exit} | ||
45 | "DISPLAY is not set" | ||
46 | } | ||
47 | after 100 | ||
48 | |||
49 | send -- "export DISPLAY=:0.0\r" | ||
50 | after 100 | ||
51 | send -- "xterm\r" | ||
52 | expect { | ||
53 | timeout {puts "TESTING ERROR 4\n";exit} | ||
54 | "Xt error" | ||
55 | } | ||
56 | after 100 | ||
57 | |||
58 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail --name=test --x11=xephyr xterm\r" | ||
11 | sleep 10 | ||
12 | |||
13 | spawn $env(SHELL) | ||
14 | send -- "firejail --list\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 3\n";exit} | ||
17 | ":firejail" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
21 | "xterm" | ||
22 | } | ||
23 | sleep 1 | ||
24 | |||
25 | # grsecurity exit | ||
26 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
27 | expect { | ||
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 | |||
33 | send -- "firejail --name=blablabla\r" | ||
34 | expect { | ||
35 | timeout {puts "TESTING ERROR 4\n";exit} | ||
36 | "Child process initialized" | ||
37 | } | ||
38 | sleep 2 | ||
39 | |||
40 | spawn $env(SHELL) | ||
41 | send -- "firemon --seccomp\r" | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 5\n";exit} | ||
44 | "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit} | ||
45 | ":firejail" | ||
46 | } | ||
47 | expect { | ||
48 | timeout {puts "TESTING ERROR 5.0\n";exit} | ||
49 | "xterm" | ||
50 | } | ||
51 | expect { | ||
52 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
53 | "Seccomp: 2" | ||
54 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
57 | "name=blablabla" | ||
58 | } | ||
59 | sleep 1 | ||
60 | send -- "firemon --caps\r" | ||
61 | expect { | ||
62 | timeout {puts "TESTING ERROR 6\n";exit} | ||
63 | ":firejail" | ||
64 | } | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6.0\n";exit} | ||
67 | "xterm" | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
71 | "CapBnd" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
75 | "0000000000000000" | ||
76 | } | ||
77 | expect { | ||
78 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
79 | "name=blablabla" | ||
80 | } | ||
81 | sleep 1 | ||
82 | send -- "firejail --shutdown=test\r" | ||
83 | sleep 3 | ||
84 | |||
85 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail --name=test --x11=xorg xterm\r" | ||
11 | sleep 10 | ||
12 | |||
13 | spawn $env(SHELL) | ||
14 | send -- "firejail --list\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 3\n";exit} | ||
17 | ":firejail" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
21 | "xterm" | ||
22 | } | ||
23 | sleep 1 | ||
24 | |||
25 | # grsecurity exit | ||
26 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
27 | expect { | ||
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 | |||
33 | send -- "firejail --name=blablabla\r" | ||
34 | expect { | ||
35 | timeout {puts "TESTING ERROR 4\n";exit} | ||
36 | "Child process initialized" | ||
37 | } | ||
38 | sleep 2 | ||
39 | |||
40 | spawn $env(SHELL) | ||
41 | send -- "firemon --seccomp\r" | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 5\n";exit} | ||
44 | "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit} | ||
45 | ":firejail" | ||
46 | } | ||
47 | expect { | ||
48 | timeout {puts "TESTING ERROR 5.0\n";exit} | ||
49 | "xterm" | ||
50 | } | ||
51 | expect { | ||
52 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
53 | "Seccomp: 2" | ||
54 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
57 | "name=blablabla" | ||
58 | } | ||
59 | sleep 1 | ||
60 | send -- "firemon --caps\r" | ||
61 | expect { | ||
62 | timeout {puts "TESTING ERROR 6\n";exit} | ||
63 | ":firejail" | ||
64 | } | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6.0\n";exit} | ||
67 | "xterm" | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
71 | "CapBnd" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
75 | "0000000000000000" | ||
76 | } | ||
77 | expect { | ||
78 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
79 | "name=blablabla" | ||
80 | } | ||
81 | sleep 1 | ||
82 | send -- "firejail --shutdown=test\r" | ||
83 | sleep 3 | ||
84 | |||
85 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail --name=test --x11=xpra xterm\r" | ||
11 | sleep 10 | ||
12 | |||
13 | spawn $env(SHELL) | ||
14 | send -- "firejail --list\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 3\n";exit} | ||
17 | ":firejail" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
21 | "xterm" | ||
22 | } | ||
23 | sleep 1 | ||
24 | |||
25 | # grsecurity exit | ||
26 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
27 | expect { | ||
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 | |||
33 | send -- "firejail --name=blablabla\r" | ||
34 | expect { | ||
35 | timeout {puts "TESTING ERROR 4\n";exit} | ||
36 | "Child process initialized" | ||
37 | } | ||
38 | sleep 2 | ||
39 | |||
40 | spawn $env(SHELL) | ||
41 | send -- "firemon --seccomp\r" | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 5\n";exit} | ||
44 | "need to be root" {puts "/proc mounted as hidepid, exiting...\n"; exit} | ||
45 | ":firejail" | ||
46 | } | ||
47 | expect { | ||
48 | timeout {puts "TESTING ERROR 5.0\n";exit} | ||
49 | "xterm" | ||
50 | } | ||
51 | expect { | ||
52 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
53 | "Seccomp: 2" | ||
54 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
57 | "name=blablabla" | ||
58 | } | ||
59 | sleep 1 | ||
60 | send -- "firemon --caps\r" | ||
61 | expect { | ||
62 | timeout {puts "TESTING ERROR 6\n";exit} | ||
63 | ":firejail" | ||
64 | } | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6.0\n";exit} | ||
67 | "xterm" | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
71 | "CapBnd" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
75 | "0000000000000000" | ||
76 | } | ||
77 | expect { | ||
78 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
79 | "name=blablabla" | ||
80 | } | ||
81 | sleep 1 | ||
82 | |||
83 | send -- "firemon --x11\r" | ||
84 | expect { | ||
85 | timeout {puts "TESTING ERROR 7\n";exit} | ||
86 | "name=test xterm" | ||
87 | } | ||
88 | expect { | ||
89 | timeout {puts "TESTING ERROR 7.1\n";exit} | ||
90 | "DISPLAY" | ||
91 | } | ||
92 | sleep 1 | ||
93 | |||
94 | send -- "firejail --shutdown=test\r" | ||
95 | sleep 3 | ||
96 | |||
97 | puts "\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 | |||
6 | export MALLOC_CHECK_=3 | ||
7 | export MALLOC_PERTURB_=$(($RANDOM % 255 + 1)) | ||
8 | |||
9 | rm -f unchroot | ||
10 | gcc -o unchroot unchroot.c | ||
11 | sudo ./configure | ||
12 | |||
13 | echo "TESTING: chroot (test/chroot/fs_chroot.exp)" | ||
14 | ./fs_chroot.exp | ||
15 | |||
16 | echo "TESTING: unchroot as root (test/chroot/unchroot-as-root.exp)" | ||
17 | sudo ./unchroot-as-root.exp | ||
18 | |||
19 | |||
20 | |||
21 | rm -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 | ||
4 | ROOTDIR="/tmp/chroot" # default chroot directory | ||
5 | DEFAULT_FILES="/bin/bash /bin/sh " # basic chroot files | ||
6 | DEFAULT_FILES+="/etc/passwd /etc/nsswitch.conf /etc/group " | ||
7 | DEFAULT_FILES+=`find /lib -name libnss*` # files required by glibc | ||
8 | DEFAULT_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 | |||
10 | rm -fr $ROOTDIR | ||
11 | mkdir -p $ROOTDIR/{root,bin,lib,lib64,usr,home,etc,dev/shm,tmp,var/run,var/tmp,var/lock,var/log,proc,sys} | ||
12 | chmod 777 $ROOTDIR/tmp | ||
13 | mkdir -p $ROOTDIR/etc/firejail | ||
14 | mkdir -p $ROOTDIR/home/netblue/.config/firejail | ||
15 | chown netblue:netblue $ROOTDIR/home/netblue | ||
16 | chown netblue:netblue $ROOTDIR/home/netblue/.config | ||
17 | cp /home/netblue/.Xauthority $ROOTDIR/home/netblue/. | ||
18 | cp -a /etc/skel $ROOTDIR/etc/. | ||
19 | mkdir $ROOTDIR/home/someotheruser | ||
20 | mkdir $ROOTDIR/boot | ||
21 | mkdir $ROOTDIR/selinux | ||
22 | cp /etc/passwd $ROOTDIR/etc/. | ||
23 | cp /etc/group $ROOTDIR/etc/. | ||
24 | cp /etc/hosts $ROOTDIR/etc/. | ||
25 | cp /etc/hostname $ROOTDIR/etc/. | ||
26 | mkdir -p $ROOTDIR/usr/lib/x86_64-linux-gnu | ||
27 | cp -a /usr/lib/x86_64-linux-gnu/openssl-1.0.0 $ROOTDIR/usr/lib/x86_64-linux-gnu/. | ||
28 | cp -a /usr/lib/ssl $ROOTDIR/usr/lib/. | ||
29 | touch $ROOTDIR/var/log/syslog | ||
30 | touch $ROOTDIR/var/tmp/somefile | ||
31 | SORTED=`for FILE in $* $DEFAULT_FILES; do echo " $FILE "; ldd $FILE | grep -v dynamic | cut -d " " -f 3; done | sort -u` | ||
32 | for FILE in $SORTED | ||
33 | do | ||
34 | cp --parents $FILE $ROOTDIR | ||
35 | done | ||
36 | cp --parents /lib64/ld-linux-x86-64.so.2 $ROOTDIR | ||
37 | cp --parents /lib/ld-linux.so.2 $ROOTDIR | ||
38 | cp unchroot $ROOTDIR/. | ||
39 | touch $ROOTDIR/this-is-my-chroot | ||
40 | |||
41 | cd $ROOTDIR; find . | ||
42 | mkdir -p usr/lib/firejail/ | ||
43 | cp /usr/lib/firejail/libtrace.so usr/lib/firejail/. | ||
44 | |||
45 | |||
46 | echo "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 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --chroot=/tmp/chroot\r" | ||
8 | expect { | ||
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 | } | ||
13 | sleep 1 | ||
14 | |||
15 | send -- "cd /home;pwd\r" | ||
16 | expect { | ||
17 | timeout {puts "TESTING ERROR 0.1\n";exit} | ||
18 | "home" | ||
19 | } | ||
20 | sleep 1 | ||
21 | send -- "bash\r" | ||
22 | sleep 1 | ||
23 | send -- "ls /\r" | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 0.2\n";exit} | ||
26 | "this-is-my-chroot" | ||
27 | } | ||
28 | after 100 | ||
29 | |||
30 | send -- "ps aux\r" | ||
31 | expect { | ||
32 | timeout {puts "TESTING ERROR 1\n";exit} | ||
33 | "/bin/bash" | ||
34 | } | ||
35 | expect { | ||
36 | timeout {puts "TESTING ERROR 2\n";exit} | ||
37 | "bash" | ||
38 | } | ||
39 | expect { | ||
40 | timeout {puts "TESTING ERROR 3\n";exit} | ||
41 | "ps aux" | ||
42 | } | ||
43 | after 100 | ||
44 | |||
45 | send -- "ps aux | wc -l; pwd\r" | ||
46 | expect { | ||
47 | timeout {puts "TESTING ERROR 5\n";exit} | ||
48 | "6" | ||
49 | } | ||
50 | after 100 | ||
51 | |||
52 | # check /sys directory | ||
53 | send -- "ls /sys\r" | ||
54 | expect { | ||
55 | timeout {puts "TESTING ERROR 6\n";exit} | ||
56 | "block" | ||
57 | } | ||
58 | after 100 | ||
59 | |||
60 | |||
61 | puts "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 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --chroot=/tmp/chroot\r" | ||
8 | expect { | ||
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 | } | ||
13 | sleep 1 | ||
14 | |||
15 | send -- "cd /\r" | ||
16 | after 100 | ||
17 | |||
18 | |||
19 | send -- "./unchroot\r" | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 1\n";exit} | ||
22 | "Bad system call" | ||
23 | } | ||
24 | after 100 | ||
25 | |||
26 | puts "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 | |||
8 | void die(char *msg) { | ||
9 | perror(msg); | ||
10 | exit(1); | ||
11 | } | ||
12 | |||
13 | int 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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail --overlay --name=test --x11=xorg firefox -no-remote www.gentoo.org\r" | ||
11 | sleep 10 | ||
12 | |||
13 | spawn $env(SHELL) | ||
14 | send -- "firejail --list\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 3\n";exit} | ||
17 | ":firejail" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
21 | "firefox" {puts "firefox detected\n";} | ||
22 | "iceweasel" {puts "iceweasel detected\n";} | ||
23 | } | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 3.2\n";exit} | ||
26 | "no-remote" | ||
27 | } | ||
28 | sleep 1 | ||
29 | # grsecurity exit | ||
30 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
31 | expect { | ||
32 | timeout {puts "TESTING ERROR - grsecurity detection\n";exit} | ||
33 | "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit} | ||
34 | "cannot open" {puts "grsecurity not present\n"} | ||
35 | } | ||
36 | send -- "firejail --overlay --name=blablabla\r" | ||
37 | expect { | ||
38 | timeout {puts "TESTING ERROR 4\n";exit} | ||
39 | "Child process initialized" | ||
40 | } | ||
41 | sleep 2 | ||
42 | |||
43 | spawn $env(SHELL) | ||
44 | send -- "firemon --seccomp\r" | ||
45 | expect { | ||
46 | timeout {puts "TESTING ERROR 5\n";exit} | ||
47 | " firefox" {puts "firefox detected\n";} | ||
48 | " iceweasel" {puts "iceweasel detected\n";} | ||
49 | } | ||
50 | expect { | ||
51 | timeout {puts "TESTING ERROR 5.0\n";exit} | ||
52 | "no-remote" | ||
53 | } | ||
54 | expect { | ||
55 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
56 | "Seccomp: 2" | ||
57 | } | ||
58 | expect { | ||
59 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
60 | "name=blablabla" | ||
61 | } | ||
62 | sleep 1 | ||
63 | send -- "firemon --caps\r" | ||
64 | expect { | ||
65 | timeout {puts "TESTING ERROR 6\n";exit} | ||
66 | " firefox" {puts "firefox detected\n";} | ||
67 | " iceweasel" {puts "iceweasel detected\n";} | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 6.0\n";exit} | ||
71 | "no-remote" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
75 | "CapBnd:" | ||
76 | } | ||
77 | expect { | ||
78 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
79 | "0000000000000000" | ||
80 | } | ||
81 | expect { | ||
82 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
83 | "name=blablabla" | ||
84 | } | ||
85 | sleep 1 | ||
86 | send -- "firejail --shutdown=test\r" | ||
87 | sleep 3 | ||
88 | |||
89 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail --overlay --name=test --x11 firefox -no-remote www.gentoo.org\r" | ||
11 | sleep 10 | ||
12 | |||
13 | spawn $env(SHELL) | ||
14 | send -- "firejail --list\r" | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 3\n";exit} | ||
17 | ":firejail" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
21 | "firefox" {puts "firefox detected\n";} | ||
22 | "iceweasel" {puts "iceweasel detected\n";} | ||
23 | } | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 3.2\n";exit} | ||
26 | "no-remote" | ||
27 | } | ||
28 | sleep 1 | ||
29 | # grsecurity exit | ||
30 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
31 | expect { | ||
32 | timeout {puts "TESTING ERROR - grsecurity detection\n";exit} | ||
33 | "grsecurity: directory" {puts "grsecurity present, exiting...\n";exit} | ||
34 | "cannot open" {puts "grsecurity not present\n"} | ||
35 | } | ||
36 | send -- "firejail --name=blablabla --overlay\r" | ||
37 | expect { | ||
38 | timeout {puts "TESTING ERROR 4\n";exit} | ||
39 | "Child process initialized" | ||
40 | } | ||
41 | sleep 2 | ||
42 | |||
43 | spawn $env(SHELL) | ||
44 | send -- "firemon --seccomp\r" | ||
45 | expect { | ||
46 | timeout {puts "TESTING ERROR 5\n";exit} | ||
47 | " firefox" {puts "firefox detected\n";} | ||
48 | " iceweasel" {puts "iceweasel detected\n";} | ||
49 | } | ||
50 | expect { | ||
51 | timeout {puts "TESTING ERROR 5.0\n";exit} | ||
52 | "no-remote" | ||
53 | } | ||
54 | expect { | ||
55 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
56 | "Seccomp: 2" | ||
57 | } | ||
58 | expect { | ||
59 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
60 | "name=blablabla" | ||
61 | } | ||
62 | sleep 1 | ||
63 | send -- "firemon --caps\r" | ||
64 | expect { | ||
65 | timeout {puts "TESTING ERROR 6\n";exit} | ||
66 | " firefox" {puts "firefox detected\n";} | ||
67 | " iceweasel" {puts "iceweasel detected\n";} | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 6.0\n";exit} | ||
71 | "no-remote" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
75 | "CapBnd:" | ||
76 | } | ||
77 | expect { | ||
78 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
79 | "0000000000000000" | ||
80 | } | ||
81 | expect { | ||
82 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
83 | "name=blablabla" | ||
84 | } | ||
85 | sleep 1 | ||
86 | send -- "firejail --shutdown=test\r" | ||
87 | sleep 3 | ||
88 | |||
89 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail --overlay firefox -no-remote www.gentoo.org\r" | ||
11 | expect { | ||
12 | timeout {puts "TESTING ERROR 0\n";exit} | ||
13 | "Reading profile /etc/firejail/firefox.profile" | ||
14 | } | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "Child process initialized" | ||
18 | } | ||
19 | sleep 10 | ||
20 | |||
21 | spawn $env(SHELL) | ||
22 | send -- "firejail --list\r" | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 3\n";exit} | ||
25 | ":firejail" | ||
26 | } | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
29 | "firefox" {puts "firefox detected\n";} | ||
30 | "iceweasel" {puts "iceweasel detected\n";} | ||
31 | } | ||
32 | expect { | ||
33 | timeout {puts "TESTING ERROR 3.2\n";exit} | ||
34 | "no-remote" | ||
35 | } | ||
36 | after 100 | ||
37 | |||
38 | # grsecurity exit | ||
39 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
40 | expect { | ||
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 | |||
47 | send -- "firejail --name=blablabla --overlay\r" | ||
48 | expect { | ||
49 | timeout {puts "TESTING ERROR 4\n";exit} | ||
50 | "Child process initialized" | ||
51 | } | ||
52 | sleep 2 | ||
53 | |||
54 | spawn $env(SHELL) | ||
55 | send -- "firemon --seccomp\r" | ||
56 | expect { | ||
57 | timeout {puts "TESTING ERROR 5\n";exit} | ||
58 | " firefox" {puts "firefox detected\n";} | ||
59 | " iceweasel" {puts "iceweasel detected\n";} | ||
60 | } | ||
61 | expect { | ||
62 | timeout {puts "TESTING ERROR 5.0\n";exit} | ||
63 | "no-remote" | ||
64 | } | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
67 | "Seccomp: 2" | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
71 | "name=blablabla" | ||
72 | } | ||
73 | after 100 | ||
74 | send -- "firemon --caps\r" | ||
75 | expect { | ||
76 | timeout {puts "TESTING ERROR 6\n";exit} | ||
77 | " firefox" {puts "firefox detected\n";} | ||
78 | " iceweasel" {puts "iceweasel detected\n";} | ||
79 | } | ||
80 | expect { | ||
81 | timeout {puts "TESTING ERROR 6.0\n";exit} | ||
82 | "no-remote" | ||
83 | } | ||
84 | expect { | ||
85 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
86 | "CapBnd:" | ||
87 | } | ||
88 | expect { | ||
89 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
90 | "0000000000000000" | ||
91 | } | ||
92 | expect { | ||
93 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
94 | "name=blablabla" | ||
95 | } | ||
96 | after 100 | ||
97 | |||
98 | puts "\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 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --overlay-named=firejail-test\r" | ||
8 | expect { | ||
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 | } | ||
14 | sleep 1 | ||
15 | send -- "stty -echo\r" | ||
16 | after 100 | ||
17 | |||
18 | send -- "echo xyzxyzxyz > ~/_firejail_test_file; echo done\r" | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 3\n";exit} | ||
21 | "done" | ||
22 | } | ||
23 | after 100 | ||
24 | |||
25 | send -- "cat ~/_firejail_test_file; echo done\r" | ||
26 | expect { | ||
27 | timeout {puts "TESTING ERROR 4\n";exit} | ||
28 | "xyzxyzxyz" | ||
29 | } | ||
30 | expect { | ||
31 | timeout {puts "TESTING ERROR 4.1\n";exit} | ||
32 | "done" | ||
33 | } | ||
34 | after 100 | ||
35 | |||
36 | send -- "exit\r" | ||
37 | sleep 2 | ||
38 | |||
39 | send -- "cat ~/_firejail_test_file; echo done\r" | ||
40 | expect { | ||
41 | timeout {puts "TESTING ERROR 5\n";exit} | ||
42 | "xyzxyzxyz" {puts "TESTING ERROR 5.1\n";exit} | ||
43 | "done" | ||
44 | } | ||
45 | after 100 | ||
46 | |||
47 | send -- "firejail --overlay-named=firejail-test\r" | ||
48 | expect { | ||
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 | } | ||
54 | sleep 1 | ||
55 | |||
56 | send -- "stty -echo\r" | ||
57 | after 100 | ||
58 | send -- "cat ~/_firejail_test_file; echo done\r" | ||
59 | expect { | ||
60 | timeout {puts "TESTING ERROR 4\n";exit} | ||
61 | "xyzxyzxyz" | ||
62 | } | ||
63 | expect { | ||
64 | timeout {puts "TESTING ERROR 4.1\n";exit} | ||
65 | "done" | ||
66 | } | ||
67 | after 100 | ||
68 | |||
69 | puts "\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 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --overlay-clean\r" | ||
8 | after 100 | ||
9 | send -- "file ~/.firejail\r" | ||
10 | expect { | ||
11 | timeout {puts "TESTING ERROR 0\n";exit} | ||
12 | "cannot open" | ||
13 | } | ||
14 | after 100 | ||
15 | |||
16 | send -- "firejail --overlay-tmpfs\r" | ||
17 | expect { | ||
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 | } | ||
23 | sleep 1 | ||
24 | send -- "stty -echo\r" | ||
25 | after 100 | ||
26 | |||
27 | send -- "echo xyzxyzxyz > ~/_firejail_test_file; echo done\r" | ||
28 | expect { | ||
29 | timeout {puts "TESTING ERROR 2\n";exit} | ||
30 | "done" | ||
31 | } | ||
32 | after 100 | ||
33 | |||
34 | send -- "stty -echo\r" | ||
35 | after 100 | ||
36 | send -- "cat ~/_firejail_test_file; echo done\r" | ||
37 | expect { | ||
38 | timeout {puts "TESTING ERROR 3\n";exit} | ||
39 | "xyzxyzxyz" | ||
40 | } | ||
41 | expect { | ||
42 | timeout {puts "TESTING ERROR 4\n";exit} | ||
43 | "done" | ||
44 | } | ||
45 | after 100 | ||
46 | |||
47 | send -- "exit\r" | ||
48 | sleep 1 | ||
49 | |||
50 | send -- "stty -echo\r" | ||
51 | after 100 | ||
52 | send -- "cat ~/_firejail_test_file; echo done\r" | ||
53 | expect { | ||
54 | timeout {puts "TESTING ERROR 5\n";exit} | ||
55 | "xyzxyzxyz" {puts "TESTING ERROR 6\n";exit} | ||
56 | "done" | ||
57 | } | ||
58 | after 100 | ||
59 | |||
60 | send -- "file ~/.firejail\r" | ||
61 | expect { | ||
62 | timeout {puts "TESTING ERROR 7\n";exit} | ||
63 | "cannot open" | ||
64 | } | ||
65 | after 100 | ||
66 | |||
67 | puts "\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 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | send -- "firejail --overlay\r" | ||
8 | expect { | ||
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 | } | ||
14 | sleep 1 | ||
15 | |||
16 | send -- "stty -echo\r" | ||
17 | after 100 | ||
18 | send -- "echo xyzxyzxyz > ~/_firejail_test_file; echo done\r" | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 3\n";exit} | ||
21 | "done" | ||
22 | } | ||
23 | after 100 | ||
24 | |||
25 | send -- "stty -echo\r" | ||
26 | after 100 | ||
27 | send -- "cat ~/_firejail_test_file; echo done\r" | ||
28 | expect { | ||
29 | timeout {puts "TESTING ERROR 4\n";exit} | ||
30 | "xyzxyzxyz" | ||
31 | } | ||
32 | expect { | ||
33 | timeout {puts "TESTING ERROR 4.1\n";exit} | ||
34 | "done" | ||
35 | } | ||
36 | after 100 | ||
37 | |||
38 | send -- "exit\r" | ||
39 | sleep 2 | ||
40 | |||
41 | send -- "stty -echo\r" | ||
42 | after 100 | ||
43 | send -- "cat ~/_firejail_test_file; echo done\r" | ||
44 | expect { | ||
45 | timeout {puts "TESTING ERROR 5\n";exit} | ||
46 | "xyzxyzxyz" {puts "TESTING ERROR 5.1\n";exit} | ||
47 | "done" | ||
48 | } | ||
49 | after 100 | ||
50 | |||
51 | # check /sys directory | ||
52 | send -- "ls /sys\r" | ||
53 | expect { | ||
54 | timeout {puts "TESTING ERROR 6\n";exit} | ||
55 | "block" | ||
56 | } | ||
57 | after 100 | ||
58 | |||
59 | puts "\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 | |||
6 | export MALLOC_CHECK_=3 | ||
7 | export MALLOC_PERTURB_=$(($RANDOM % 255 + 1)) | ||
8 | |||
9 | echo "TESTING: overlay fs (test/overlay/fs.exp)" | ||
10 | rm -fr ~/_firejail_test_* | ||
11 | ./fs.exp | ||
12 | rm -fr ~/_firejail_test_* | ||
13 | |||
14 | echo "TESTING: overlay named fs (test/overlay/fs-named.exp)" | ||
15 | rm -fr ~/_firejail_test_* | ||
16 | ./fs-named.exp | ||
17 | rm -fr ~/_firejail_test_* | ||
18 | |||
19 | echo "TESTING: overlay tmpfs fs (test/overlay/fs-tmpfs.exp)" | ||
20 | rm -fr ~/_firejail_test_* | ||
21 | ./fs-tmpfs.exp | ||
22 | rm -fr ~/_firejail_test_* | ||
23 | |||
24 | which firefox 2>/dev/null | ||
25 | if [ "$?" -eq 0 ]; | ||
26 | then | ||
27 | echo "TESTING: overlay firefox" | ||
28 | ./firefox.exp | ||
29 | else | ||
30 | echo "TESTING SKIP: firefox not found" | ||
31 | fi | ||
32 | |||
33 | which firefox 2>/dev/null | ||
34 | if [ "$?" -eq 0 ]; | ||
35 | then | ||
36 | echo "TESTING: overlay firefox x11 xorg" | ||
37 | ./firefox.exp | ||
38 | else | ||
39 | echo "TESTING SKIP: firefox not found" | ||
40 | fi | ||
41 | |||
42 | |||
43 | # check xpra/xephyr | ||
44 | which xpra 2>/dev/null | ||
45 | if [ "$?" -eq 0 ]; | ||
46 | then | ||
47 | echo "xpra found" | ||
48 | else | ||
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 | ||
58 | fi | ||
59 | |||
60 | which firefox 2>/dev/null | ||
61 | if [ "$?" -eq 0 ]; | ||
62 | then | ||
63 | echo "TESTING: overlay firefox x11" | ||
64 | ./firefox-x11.exp | ||
65 | else | ||
66 | echo "TESTING SKIP: firefox not found" | ||
67 | fi | ||
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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail atril\r" | ||
11 | expect { | ||
12 | timeout {puts "TESTING ERROR 0\n";exit} | ||
13 | "Reading profile /etc/firejail/atril.profile" | ||
14 | } | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "Child process initialized" | ||
18 | } | ||
19 | sleep 3 | ||
20 | |||
21 | spawn $env(SHELL) | ||
22 | send -- "firejail --list\r" | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 3\n";exit} | ||
25 | ":firejail" | ||
26 | } | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
29 | "atril" | ||
30 | } | ||
31 | after 100 | ||
32 | |||
33 | # grsecurity exit | ||
34 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
35 | expect { | ||
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 | |||
41 | send -- "firejail --name=blablabla\r" | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 4\n";exit} | ||
44 | "Child process initialized" | ||
45 | } | ||
46 | sleep 2 | ||
47 | |||
48 | spawn $env(SHELL) | ||
49 | send -- "firemon --seccomp\r" | ||
50 | expect { | ||
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 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
57 | "Seccomp: 2" | ||
58 | } | ||
59 | expect { | ||
60 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
61 | "name=blablabla" | ||
62 | } | ||
63 | after 100 | ||
64 | send -- "firemon --caps\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6\n";exit} | ||
67 | ":firejail atril" | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
71 | "CapBnd:" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
75 | "0000000000000000" | ||
76 | } | ||
77 | expect { | ||
78 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
79 | "name=blablabla" | ||
80 | } | ||
81 | after 100 | ||
82 | |||
83 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail eog\r" | ||
11 | expect { | ||
12 | timeout {puts "TESTING ERROR 0\n";exit} | ||
13 | "Reading profile /etc/firejail/eog.profile" | ||
14 | } | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "Child process initialized" | ||
18 | } | ||
19 | sleep 3 | ||
20 | |||
21 | spawn $env(SHELL) | ||
22 | send -- "firejail --list\r" | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 3\n";exit} | ||
25 | ":firejail" | ||
26 | } | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
29 | "eog" | ||
30 | } | ||
31 | after 100 | ||
32 | |||
33 | # grsecurity exit | ||
34 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
35 | expect { | ||
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 | |||
41 | send -- "firejail --name=blablabla\r" | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 4\n";exit} | ||
44 | "Child process initialized" | ||
45 | } | ||
46 | sleep 2 | ||
47 | |||
48 | spawn $env(SHELL) | ||
49 | send -- "firemon --seccomp\r" | ||
50 | expect { | ||
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 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
57 | "Seccomp: 2" | ||
58 | } | ||
59 | expect { | ||
60 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
61 | "name=blablabla" | ||
62 | } | ||
63 | after 100 | ||
64 | send -- "firemon --caps\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6\n";exit} | ||
67 | ":firejail eog" | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
71 | "CapBnd:" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
75 | "0000000000000000" | ||
76 | } | ||
77 | expect { | ||
78 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
79 | "name=blablabla" | ||
80 | } | ||
81 | after 100 | ||
82 | |||
83 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail eom\r" | ||
11 | expect { | ||
12 | timeout {puts "TESTING ERROR 0\n";exit} | ||
13 | "Reading profile /etc/firejail/eom.profile" | ||
14 | } | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "Child process initialized" | ||
18 | } | ||
19 | sleep 3 | ||
20 | |||
21 | spawn $env(SHELL) | ||
22 | send -- "firejail --list\r" | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 3\n";exit} | ||
25 | ":firejail" | ||
26 | } | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
29 | "eom" | ||
30 | } | ||
31 | after 100 | ||
32 | |||
33 | # grsecurity exit | ||
34 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
35 | expect { | ||
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 | |||
41 | send -- "firejail --name=blablabla\r" | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 4\n";exit} | ||
44 | "Child process initialized" | ||
45 | } | ||
46 | sleep 2 | ||
47 | |||
48 | spawn $env(SHELL) | ||
49 | send -- "firemon --seccomp\r" | ||
50 | expect { | ||
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 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
57 | "Seccomp: 2" | ||
58 | } | ||
59 | expect { | ||
60 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
61 | "name=blablabla" | ||
62 | } | ||
63 | after 100 | ||
64 | send -- "firemon --caps\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6\n";exit} | ||
67 | ":firejail eom" | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
71 | "CapBnd:" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
75 | "0000000000000000" | ||
76 | } | ||
77 | expect { | ||
78 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
79 | "name=blablabla" | ||
80 | } | ||
81 | after 100 | ||
82 | |||
83 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail evince\r" | ||
11 | expect { | ||
12 | timeout {puts "TESTING ERROR 0\n";exit} | ||
13 | "Reading profile /etc/firejail/evince.profile" | ||
14 | } | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "Child process initialized" | ||
18 | } | ||
19 | sleep 3 | ||
20 | |||
21 | spawn $env(SHELL) | ||
22 | send -- "firejail --list\r" | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 3\n";exit} | ||
25 | ":firejail" | ||
26 | } | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
29 | "evince" | ||
30 | } | ||
31 | after 100 | ||
32 | |||
33 | # grsecurity exit | ||
34 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
35 | expect { | ||
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 | |||
41 | send -- "firejail --name=blablabla\r" | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 4\n";exit} | ||
44 | "Child process initialized" | ||
45 | } | ||
46 | sleep 2 | ||
47 | |||
48 | spawn $env(SHELL) | ||
49 | send -- "firemon --seccomp\r" | ||
50 | expect { | ||
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 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
57 | "Seccomp: 2" | ||
58 | } | ||
59 | expect { | ||
60 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
61 | "name=blablabla" | ||
62 | } | ||
63 | after 100 | ||
64 | send -- "firemon --caps\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6\n";exit} | ||
67 | ":firejail evince" | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
71 | "CapBnd:" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
75 | "0000000000000000" | ||
76 | } | ||
77 | expect { | ||
78 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
79 | "name=blablabla" | ||
80 | } | ||
81 | after 100 | ||
82 | |||
83 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail galculator\r" | ||
11 | expect { | ||
12 | timeout {puts "TESTING ERROR 0\n";exit} | ||
13 | "Reading profile /etc/firejail/galculator.profile" | ||
14 | } | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "Child process initialized" | ||
18 | } | ||
19 | sleep 3 | ||
20 | |||
21 | spawn $env(SHELL) | ||
22 | send -- "firejail --list\r" | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 3\n";exit} | ||
25 | ":firejail" | ||
26 | } | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
29 | "galculator" | ||
30 | } | ||
31 | after 100 | ||
32 | |||
33 | # grsecurity exit | ||
34 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
35 | expect { | ||
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 | |||
41 | send -- "firejail --name=blablabla\r" | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 4\n";exit} | ||
44 | "Child process initialized" | ||
45 | } | ||
46 | sleep 2 | ||
47 | |||
48 | spawn $env(SHELL) | ||
49 | send -- "firemon --seccomp\r" | ||
50 | expect { | ||
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 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
57 | "Seccomp: 2" | ||
58 | } | ||
59 | expect { | ||
60 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
61 | "name=blablabla" | ||
62 | } | ||
63 | after 100 | ||
64 | send -- "firemon --caps\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6\n";exit} | ||
67 | ":firejail galculator" | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
71 | "CapBnd:" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
75 | "0000000000000000" | ||
76 | } | ||
77 | expect { | ||
78 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
79 | "name=blablabla" | ||
80 | } | ||
81 | after 100 | ||
82 | |||
83 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail /usr/bin/gedit\r" | ||
11 | expect { | ||
12 | timeout {puts "TESTING ERROR 0\n";exit} | ||
13 | "Reading profile /etc/firejail/gedit.profile" | ||
14 | } | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "Child process initialized" | ||
18 | } | ||
19 | sleep 3 | ||
20 | |||
21 | spawn $env(SHELL) | ||
22 | send -- "firejail --list\r" | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 3\n";exit} | ||
25 | ":firejail" | ||
26 | } | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
29 | "gedit" | ||
30 | } | ||
31 | after 100 | ||
32 | |||
33 | # grsecurity exit | ||
34 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
35 | expect { | ||
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 | |||
41 | send -- "firejail --name=blablabla\r" | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 4\n";exit} | ||
44 | "Child process initialized" | ||
45 | } | ||
46 | sleep 2 | ||
47 | |||
48 | spawn $env(SHELL) | ||
49 | send -- "firemon --seccomp\r" | ||
50 | expect { | ||
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 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
57 | "Seccomp: 2" | ||
58 | } | ||
59 | expect { | ||
60 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
61 | "name=blablabla" | ||
62 | } | ||
63 | after 100 | ||
64 | send -- "firemon --caps\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6\n";exit} | ||
67 | ":firejail /usr/bin/gedit" | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
71 | "CapBnd:" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
75 | "0000000000000000" | ||
76 | } | ||
77 | expect { | ||
78 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
79 | "name=blablabla" | ||
80 | } | ||
81 | after 100 | ||
82 | |||
83 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | # gnome-calculator uses quiet at the top of the profile | ||
11 | # we need to use --ignore | ||
12 | send -- "firejail --ignore=quiet gnome-calculator\r" | ||
13 | expect { | ||
14 | timeout {puts "TESTING ERROR 0\n";exit} | ||
15 | "Reading profile /etc/firejail/gnome-calculator.profile" | ||
16 | } | ||
17 | expect { | ||
18 | timeout {puts "TESTING ERROR 1\n";exit} | ||
19 | "Child process initialized" | ||
20 | } | ||
21 | sleep 3 | ||
22 | |||
23 | spawn $env(SHELL) | ||
24 | send -- "firejail --list\r" | ||
25 | expect { | ||
26 | timeout {puts "TESTING ERROR 3\n";exit} | ||
27 | ":firejail" | ||
28 | } | ||
29 | expect { | ||
30 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
31 | "gnome-calculator" | ||
32 | } | ||
33 | after 100 | ||
34 | |||
35 | # grsecurity exit | ||
36 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
37 | expect { | ||
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 | |||
43 | send -- "firejail --name=blablabla\r" | ||
44 | expect { | ||
45 | timeout {puts "TESTING ERROR 4\n";exit} | ||
46 | "Child process initialized" | ||
47 | } | ||
48 | sleep 2 | ||
49 | |||
50 | spawn $env(SHELL) | ||
51 | send -- "firemon --seccomp\r" | ||
52 | expect { | ||
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 | } | ||
57 | expect { | ||
58 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
59 | "Seccomp: 2" | ||
60 | } | ||
61 | expect { | ||
62 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
63 | "name=blablabla" | ||
64 | } | ||
65 | after 100 | ||
66 | send -- "firemon --caps\r" | ||
67 | expect { | ||
68 | timeout {puts "TESTING ERROR 6\n";exit} | ||
69 | ":firejail --ignore=quiet gnome-calculator" | ||
70 | } | ||
71 | expect { | ||
72 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
73 | "CapBnd:" | ||
74 | } | ||
75 | expect { | ||
76 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
77 | "0000000000000000" | ||
78 | } | ||
79 | expect { | ||
80 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
81 | "name=blablabla" | ||
82 | } | ||
83 | after 100 | ||
84 | |||
85 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail gpicview\r" | ||
11 | expect { | ||
12 | timeout {puts "TESTING ERROR 0\n";exit} | ||
13 | "Reading profile /etc/firejail/gpicview.profile" | ||
14 | } | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "Child process initialized" | ||
18 | } | ||
19 | sleep 3 | ||
20 | |||
21 | spawn $env(SHELL) | ||
22 | send -- "firejail --list\r" | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 3\n";exit} | ||
25 | ":firejail" | ||
26 | } | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
29 | "gpicview" | ||
30 | } | ||
31 | after 100 | ||
32 | |||
33 | # grsecurity exit | ||
34 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
35 | expect { | ||
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 | |||
41 | send -- "firejail --name=blablabla\r" | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 4\n";exit} | ||
44 | "Child process initialized" | ||
45 | } | ||
46 | sleep 2 | ||
47 | |||
48 | spawn $env(SHELL) | ||
49 | send -- "firemon --seccomp\r" | ||
50 | expect { | ||
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 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
57 | "Seccomp: 2" | ||
58 | } | ||
59 | expect { | ||
60 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
61 | "name=blablabla" | ||
62 | } | ||
63 | after 100 | ||
64 | send -- "firemon --caps\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6\n";exit} | ||
67 | ":firejail gpicview" | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
71 | "CapBnd:" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
75 | "0000000000000000" | ||
76 | } | ||
77 | expect { | ||
78 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
79 | "name=blablabla" | ||
80 | } | ||
81 | after 100 | ||
82 | |||
83 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail leafpad\r" | ||
11 | expect { | ||
12 | timeout {puts "TESTING ERROR 0\n";exit} | ||
13 | "Reading profile /etc/firejail/leafpad.profile" | ||
14 | } | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "Child process initialized" | ||
18 | } | ||
19 | sleep 3 | ||
20 | |||
21 | spawn $env(SHELL) | ||
22 | send -- "firejail --list\r" | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 3\n";exit} | ||
25 | ":firejail" | ||
26 | } | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
29 | "leafpad" | ||
30 | } | ||
31 | after 100 | ||
32 | |||
33 | # grsecurity exit | ||
34 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
35 | expect { | ||
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 | |||
41 | send -- "firejail --name=blablabla\r" | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 4\n";exit} | ||
44 | "Child process initialized" | ||
45 | } | ||
46 | sleep 2 | ||
47 | |||
48 | spawn $env(SHELL) | ||
49 | send -- "firemon --seccomp\r" | ||
50 | expect { | ||
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 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
57 | "Seccomp: 2" | ||
58 | } | ||
59 | expect { | ||
60 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
61 | "name=blablabla" | ||
62 | } | ||
63 | after 100 | ||
64 | send -- "firemon --caps\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6\n";exit} | ||
67 | ":firejail leafpad" | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
71 | "CapBnd:" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
75 | "0000000000000000" | ||
76 | } | ||
77 | expect { | ||
78 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
79 | "name=blablabla" | ||
80 | } | ||
81 | after 100 | ||
82 | |||
83 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail mousepad\r" | ||
11 | expect { | ||
12 | timeout {puts "TESTING ERROR 0\n";exit} | ||
13 | "Reading profile /etc/firejail/mousepad.profile" | ||
14 | } | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "Child process initialized" | ||
18 | } | ||
19 | sleep 3 | ||
20 | |||
21 | spawn $env(SHELL) | ||
22 | send -- "firejail --list\r" | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 3\n";exit} | ||
25 | ":firejail" | ||
26 | } | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
29 | "mousepad" | ||
30 | } | ||
31 | after 100 | ||
32 | |||
33 | # grsecurity exit | ||
34 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
35 | expect { | ||
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 | |||
41 | send -- "firejail --name=blablabla\r" | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 4\n";exit} | ||
44 | "Child process initialized" | ||
45 | } | ||
46 | sleep 2 | ||
47 | |||
48 | spawn $env(SHELL) | ||
49 | send -- "firemon --seccomp\r" | ||
50 | expect { | ||
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 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
57 | "Seccomp: 2" | ||
58 | } | ||
59 | expect { | ||
60 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
61 | "name=blablabla" | ||
62 | } | ||
63 | after 100 | ||
64 | send -- "firemon --caps\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6\n";exit} | ||
67 | ":firejail mousepad" | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
71 | "CapBnd:" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
75 | "0000000000000000" | ||
76 | } | ||
77 | expect { | ||
78 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
79 | "name=blablabla" | ||
80 | } | ||
81 | after 100 | ||
82 | |||
83 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail pluma\r" | ||
11 | expect { | ||
12 | timeout {puts "TESTING ERROR 0\n";exit} | ||
13 | "Reading profile /etc/firejail/pluma.profile" | ||
14 | } | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "Child process initialized" | ||
18 | } | ||
19 | sleep 3 | ||
20 | |||
21 | spawn $env(SHELL) | ||
22 | send -- "firejail --list\r" | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 3\n";exit} | ||
25 | ":firejail" | ||
26 | } | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
29 | "pluma" | ||
30 | } | ||
31 | after 100 | ||
32 | |||
33 | # grsecurity exit | ||
34 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
35 | expect { | ||
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 | |||
41 | send -- "firejail --name=blablabla\r" | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 4\n";exit} | ||
44 | "Child process initialized" | ||
45 | } | ||
46 | sleep 2 | ||
47 | |||
48 | spawn $env(SHELL) | ||
49 | send -- "firemon --seccomp\r" | ||
50 | expect { | ||
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 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
57 | "Seccomp: 2" | ||
58 | } | ||
59 | expect { | ||
60 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
61 | "name=blablabla" | ||
62 | } | ||
63 | after 100 | ||
64 | send -- "firemon --caps\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6\n";exit} | ||
67 | ":firejail pluma" | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
71 | "CapBnd:" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
75 | "0000000000000000" | ||
76 | } | ||
77 | expect { | ||
78 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
79 | "name=blablabla" | ||
80 | } | ||
81 | after 100 | ||
82 | |||
83 | puts "\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 | |||
6 | export MALLOC_CHECK_=3 | ||
7 | export MALLOC_PERTURB_=$(($RANDOM % 255 + 1)) | ||
8 | LIST="evince galculator gnome-calculator gedit leafpad mousepad pluma transmission-gtk xcalc atril gpicview eom eog" | ||
9 | |||
10 | |||
11 | for 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 | ||
20 | done | ||
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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail transmission-gtk\r" | ||
11 | expect { | ||
12 | timeout {puts "TESTING ERROR 0\n";exit} | ||
13 | "Reading profile /etc/firejail/transmission-gtk.profile" | ||
14 | } | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "Child process initialized" | ||
18 | } | ||
19 | sleep 3 | ||
20 | |||
21 | spawn $env(SHELL) | ||
22 | send -- "firejail --list\r" | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 3\n";exit} | ||
25 | ":firejail" | ||
26 | } | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
29 | "transmission-gtk" | ||
30 | } | ||
31 | after 100 | ||
32 | |||
33 | # grsecurity exit | ||
34 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
35 | expect { | ||
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 | |||
41 | send -- "firejail --name=blablabla\r" | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 4\n";exit} | ||
44 | "Child process initialized" | ||
45 | } | ||
46 | sleep 2 | ||
47 | |||
48 | spawn $env(SHELL) | ||
49 | send -- "firemon --seccomp\r" | ||
50 | expect { | ||
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 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
57 | "Seccomp: 2" | ||
58 | } | ||
59 | expect { | ||
60 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
61 | "name=blablabla" | ||
62 | } | ||
63 | after 100 | ||
64 | send -- "firemon --caps\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6\n";exit} | ||
67 | ":firejail transmission-gtk" | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
71 | "CapBnd:" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
75 | "0000000000000000" | ||
76 | } | ||
77 | expect { | ||
78 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
79 | "name=blablabla" | ||
80 | } | ||
81 | after 100 | ||
82 | |||
83 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail xcalc\r" | ||
11 | expect { | ||
12 | timeout {puts "TESTING ERROR 0\n";exit} | ||
13 | "Reading profile /etc/firejail/xcalc.profile" | ||
14 | } | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "Child process initialized" | ||
18 | } | ||
19 | sleep 3 | ||
20 | |||
21 | spawn $env(SHELL) | ||
22 | send -- "firejail --list\r" | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 3\n";exit} | ||
25 | ":firejail" | ||
26 | } | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 3.1\n";exit} | ||
29 | "xcalc" | ||
30 | } | ||
31 | after 100 | ||
32 | |||
33 | # grsecurity exit | ||
34 | send -- "file /proc/sys/kernel/grsecurity\r" | ||
35 | expect { | ||
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 | |||
41 | send -- "firejail --name=blablabla\r" | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 4\n";exit} | ||
44 | "Child process initialized" | ||
45 | } | ||
46 | sleep 2 | ||
47 | |||
48 | spawn $env(SHELL) | ||
49 | send -- "firemon --seccomp\r" | ||
50 | expect { | ||
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 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 5.1 (seccomp)\n";exit} | ||
57 | "Seccomp: 2" | ||
58 | } | ||
59 | expect { | ||
60 | timeout {puts "TESTING ERROR 5.1\n";exit} | ||
61 | "name=blablabla" | ||
62 | } | ||
63 | after 100 | ||
64 | send -- "firemon --caps\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 6\n";exit} | ||
67 | ":firejail xcalc" | ||
68 | } | ||
69 | expect { | ||
70 | timeout {puts "TESTING ERROR 6.1\n";exit} | ||
71 | "CapBnd:" | ||
72 | } | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 6.2\n";exit} | ||
75 | "0000000000000000" | ||
76 | } | ||
77 | expect { | ||
78 | timeout {puts "TESTING ERROR 6.3\n";exit} | ||
79 | "name=blablabla" | ||
80 | } | ||
81 | after 100 | ||
82 | |||
83 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail --audit\r" | ||
11 | expect { | ||
12 | timeout {puts "TESTING ERROR 0\n";exit} | ||
13 | "Firejail Audit" | ||
14 | } | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 1\n";exit} | ||
17 | "is running in a PID namespace" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 2\n";exit} | ||
21 | "container/sandbox firejail" | ||
22 | } | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 3\n";exit} | ||
25 | "seccomp BPF enabled" | ||
26 | } | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 4\n";exit} | ||
29 | "all capabilities are disabled" | ||
30 | } | ||
31 | expect { | ||
32 | timeout {puts "TESTING ERROR 5\n";exit} | ||
33 | "dev directory seems to be fully populated" | ||
34 | } | ||
35 | after 100 | ||
36 | |||
37 | |||
38 | send -- "firejail --audit\r" | ||
39 | expect { | ||
40 | timeout {puts "TESTING ERROR 6\n";exit} | ||
41 | "Firejail Audit" | ||
42 | } | ||
43 | expect { | ||
44 | timeout {puts "TESTING ERROR 7\n";exit} | ||
45 | "is running in a PID namespace" | ||
46 | } | ||
47 | expect { | ||
48 | timeout {puts "TESTING ERROR 8\n";exit} | ||
49 | "container/sandbox firejail" | ||
50 | } | ||
51 | expect { | ||
52 | timeout {puts "TESTING ERROR 9\n";exit} | ||
53 | "seccomp BPF enabled" | ||
54 | } | ||
55 | expect { | ||
56 | timeout {puts "TESTING ERROR 10\n";exit} | ||
57 | "all capabilities are disabled" | ||
58 | } | ||
59 | expect { | ||
60 | timeout {puts "TESTING ERROR 11\n";exit} | ||
61 | "dev directory seems to be fully populated" | ||
62 | } | ||
63 | after 100 | ||
64 | |||
65 | send -- "firejail --audit=blablabla\r" | ||
66 | expect { | ||
67 | timeout {puts "TESTING ERROR 12\n";exit} | ||
68 | "cannot find the audit program" | ||
69 | } | ||
70 | after 100 | ||
71 | |||
72 | send -- "firejail --audit=\r" | ||
73 | expect { | ||
74 | timeout {puts "TESTING ERROR 12\n";exit} | ||
75 | "invalid audit program" | ||
76 | } | ||
77 | after 100 | ||
78 | |||
79 | # run audit executable without a sandbox | ||
80 | send -- "faudit\r" | ||
81 | expect { | ||
82 | timeout {puts "TESTING ERROR 13\n";exit} | ||
83 | "is not running in a PID namespace" | ||
84 | } | ||
85 | expect { | ||
86 | timeout {puts "TESTING ERROR 14\n";exit} | ||
87 | "BAD: seccomp disabled" | ||
88 | } | ||
89 | expect { | ||
90 | timeout {puts "TESTING ERROR 15\n";exit} | ||
91 | "BAD: the capability map is" | ||
92 | } | ||
93 | expect { | ||
94 | timeout {puts "TESTING ERROR 16\n";exit} | ||
95 | "MAYBE: /dev directory seems to be fully populated" | ||
96 | } | ||
97 | after 100 | ||
98 | |||
99 | # test seccomp | ||
100 | send -- "firejail --seccomp.drop=mkdir --audit\r" | ||
101 | expect { | ||
102 | timeout {puts "TESTING ERROR 17\n";exit} | ||
103 | "Firejail Audit" | ||
104 | } | ||
105 | expect { | ||
106 | timeout {puts "TESTING ERROR 18\n";exit} | ||
107 | "GOOD: seccomp BPF enabled" | ||
108 | } | ||
109 | expect { | ||
110 | timeout {puts "TESTING ERROR 19\n";exit} | ||
111 | "UGLY: mount syscall permitted" | ||
112 | } | ||
113 | expect { | ||
114 | timeout {puts "TESTING ERROR 20\n";exit} | ||
115 | "UGLY: umount2 syscall permitted" | ||
116 | } | ||
117 | expect { | ||
118 | timeout {puts "TESTING ERROR 21\n";exit} | ||
119 | "UGLY: ptrace syscall permitted" | ||
120 | } | ||
121 | expect { | ||
122 | timeout {puts "TESTING ERROR 22\n";exit} | ||
123 | "UGLY: swapon syscall permitted" | ||
124 | } | ||
125 | expect { | ||
126 | timeout {puts "TESTING ERROR 23\n";exit} | ||
127 | "UGLY: swapoff syscall permitted" | ||
128 | } | ||
129 | expect { | ||
130 | timeout {puts "TESTING ERROR 24\n";exit} | ||
131 | "UGLY: init_module syscall permitted" | ||
132 | } | ||
133 | expect { | ||
134 | timeout {puts "TESTING ERROR 25\n";exit} | ||
135 | "UGLY: delete_module syscall permitted" | ||
136 | } | ||
137 | expect { | ||
138 | timeout {puts "TESTING ERROR 26\n";exit} | ||
139 | "UGLY: chroot syscall permitted" | ||
140 | } | ||
141 | expect { | ||
142 | timeout {puts "TESTING ERROR 27\n";exit} | ||
143 | "UGLY: pivot_root syscall permitted" | ||
144 | } | ||
145 | expect { | ||
146 | timeout {puts "TESTING ERROR 28\n";exit} | ||
147 | "UGLY: iopl syscall permitted" | ||
148 | } | ||
149 | expect { | ||
150 | timeout {puts "TESTING ERROR 29\n";exit} | ||
151 | "UGLY: ioperm syscall permitted" | ||
152 | } | ||
153 | expect { | ||
154 | timeout {puts "TESTING ERROR 30\n";exit} | ||
155 | "GOOD: all capabilities are disabled" | ||
156 | } | ||
157 | after 100 | ||
158 | |||
159 | puts "\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 | |||
6 | set timeout 10 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail --build cat ~/firejail-test-file-7699\r" | ||
11 | expect { | ||
12 | timeout {puts "TESTING ERROR 0\n";exit} | ||
13 | "whitelist ~/firejail-test-file-7699" | ||
14 | } | ||
15 | expect { | ||
16 | timeout {puts "TESTING ERROR 0.1\n";exit} | ||
17 | "include /etc/firejail/whitelist-common.inc" | ||
18 | } | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 1\n";exit} | ||
21 | "private-tmp" | ||
22 | } | ||
23 | expect { | ||
24 | timeout {puts "TESTING ERROR 2\n";exit} | ||
25 | "private-dev" | ||
26 | } | ||
27 | expect { | ||
28 | timeout {puts "TESTING ERROR 3\n";exit} | ||
29 | "blacklist /var" | ||
30 | } | ||
31 | expect { | ||
32 | timeout {puts "TESTING ERROR 4\n";exit} | ||
33 | "private-bin cat," | ||
34 | } | ||
35 | expect { | ||
36 | timeout {puts "TESTING ERROR 5\n";exit} | ||
37 | "caps.drop all" | ||
38 | } | ||
39 | expect { | ||
40 | timeout {puts "TESTING ERROR 6\n";exit} | ||
41 | "nonewprivs" | ||
42 | } | ||
43 | expect { | ||
44 | timeout {puts "TESTING ERROR 7\n";exit} | ||
45 | "seccomp" | ||
46 | } | ||
47 | expect { | ||
48 | timeout {puts "TESTING ERROR 8\n";exit} | ||
49 | "net none" | ||
50 | } | ||
51 | expect { | ||
52 | timeout {puts "TESTING ERROR 9\n";exit} | ||
53 | "shell none" | ||
54 | } | ||
55 | after 100 | ||
56 | |||
57 | send -- "firejail --build cat /etc/passwd\r" | ||
58 | expect { | ||
59 | timeout {puts "TESTING ERROR 10\n";exit} | ||
60 | "private-etc passwd," | ||
61 | } | ||
62 | after 100 | ||
63 | |||
64 | send -- "firejail --build cat /var/tmp/firejail-test-file-7699\r" | ||
65 | expect { | ||
66 | timeout {puts "TESTING ERROR 11\n";exit} | ||
67 | "whitelist /var/tmp/firejail-test-file-7699" | ||
68 | } | ||
69 | after 100 | ||
70 | |||
71 | send -- "firejail --build man firejail\r" | ||
72 | expect { | ||
73 | timeout {puts "TESTING ERROR 12\n";exit} | ||
74 | "whitelist /usr/share/man" | ||
75 | } | ||
76 | after 100 | ||
77 | |||
78 | send -- "firejail --build wget blablabla\r" | ||
79 | expect { | ||
80 | timeout {puts "TESTING ERROR 13\n";exit} | ||
81 | "protocol inet" | ||
82 | } | ||
83 | after 100 | ||
84 | |||
85 | |||
86 | send -- "firejail --build cat /tmp/firejail-test-file-7699\r" | ||
87 | #todo - bug: it comes back with private-tmp | ||
88 | sleep 1 | ||
89 | |||
90 | |||
91 | puts "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 | |||
12 | fi | 12 | fi |
13 | export PATH="$PATH:/usr/lib/firejail:/usr/lib64/firejail" | 13 | export PATH="$PATH:/usr/lib/firejail:/usr/lib64/firejail" |
14 | 14 | ||
15 | echo "testing" > ~/firejail-test-file-7699 | ||
16 | echo "testing" > /tmp/firejail-test-file-7699 | ||
17 | echo "testing" > /var/tmp/firejail-test-file-7699 | ||
18 | echo "TESTING: build (test/utils/build.exp)" | ||
19 | ./build.exp | ||
20 | rm -f ~/firejail-test-file-7699 | ||
21 | rm -f /tmp/firejail-test-file-7699 | ||
22 | rm -f /var/tmp/firejail-test-file-7699 | ||
23 | |||
24 | echo "TESTING: audit (test/utils/audit.exp)" | ||
25 | ./audit.exp | ||
26 | |||
27 | echo "TESTING: name (test/utils/name.exp)" | 15 | echo "TESTING: name (test/utils/name.exp)" |
28 | ./name.exp | 16 | ./name.exp |
29 | 17 | ||