aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar valoq <valoq@mailbox.org>2016-11-19 22:12:51 +0100
committerLibravatar valoq <valoq@mailbox.org>2016-11-19 22:12:51 +0100
commit530db20edeee191a3b60d56b3b87999a3d10979e (patch)
tree9053d21580917bdf0e6480b2b2875e90b08b1d8c
parentreadme updated (diff)
parentqemu profile (diff)
downloadfirejail-530db20edeee191a3b60d56b3b87999a3d10979e.tar.gz
firejail-530db20edeee191a3b60d56b3b87999a3d10979e.tar.zst
firejail-530db20edeee191a3b60d56b3b87999a3d10979e.zip
fixed readme
-rw-r--r--.gitignore1
-rw-r--r--Makefile.in14
-rw-r--r--README1
-rw-r--r--README.md7
-rw-r--r--RELNOTES5
-rwxr-xr-xconfigure3
-rw-r--r--configure.ac5
-rw-r--r--etc/vivaldi.profile1
-rwxr-xr-xgcov.sh31
-rw-r--r--src/fcopy/Makefile.in45
-rw-r--r--src/fcopy/main.c340
-rw-r--r--src/firejail/appimage.c27
-rw-r--r--src/firejail/firejail.h5
-rw-r--r--src/firejail/fs_bin.c171
-rw-r--r--src/firejail/fs_etc.c146
-rw-r--r--src/firejail/fs_home.c315
-rw-r--r--src/firejail/fs_hostname.c28
-rw-r--r--src/firejail/main.c3
-rw-r--r--src/firejail/profile.c3
-rw-r--r--src/firejail/sandbox.c1
-rw-r--r--src/firejail/util.c10
-rw-r--r--src/firemon/caps.c1
-rw-r--r--src/firemon/netstats.c3
-rw-r--r--src/firemon/procevent.c6
-rw-r--r--src/firemon/seccomp.c4
-rw-r--r--src/firemon/top.c3
-rw-r--r--src/fnet/main.c6
-rw-r--r--src/fseccomp/main.c4
-rw-r--r--src/ftee/main.c32
-rwxr-xr-xtest/appimage/appimage-v1.exp2
-rwxr-xr-xtest/appimage/appimage.sh4
-rwxr-xr-xtest/appimage/filename.exp35
-rwxr-xr-xtest/chroot/chroot-resolvconf.exp (renamed from test/chroot-resolvconf.exp)0
-rwxr-xr-xtest/chroot/fs_chroot.exp (renamed from test/fs_chroot.exp)0
-rwxr-xr-xtest/environment/dns.exp26
-rwxr-xr-xtest/environment/environment.sh26
-rwxr-xr-xtest/environment/ibus.exp28
-rwxr-xr-xtest/environment/rlimit-bad-profile.exp35
-rwxr-xr-xtest/environment/rlimit-bad.exp34
-rw-r--r--test/environment/rlimit-bad1.profile1
-rw-r--r--test/environment/rlimit-bad2.profile1
-rw-r--r--test/environment/rlimit-bad3.profile1
-rw-r--r--test/environment/rlimit-bad4.profile1
-rwxr-xr-xtest/environment/rlimit-profile.exp (renamed from test/rlimit/rlimit-profile.exp)0
-rwxr-xr-xtest/environment/rlimit.exp (renamed from test/rlimit/rlimit.exp)0
-rw-r--r--test/environment/rlimit.profile (renamed from test/rlimit/rlimit.profile)0
-rwxr-xr-xtest/fcopy/cmdline.exp46
-rwxr-xr-xtest/fcopy/dircopy.exp106
-rwxr-xr-xtest/fcopy/fcopy.sh23
-rwxr-xr-xtest/fcopy/filecopy.exp54
-rwxr-xr-xtest/fcopy/linkcopy.exp54
-rw-r--r--test/fcopy/src/a/b/file411
-rw-r--r--test/fcopy/src/a/file30
l---------test/fcopy/src/dircopy.exp1
-rwxr-xr-xtest/fcopy/src/file10
-rw-r--r--test/fcopy/src/file20
-rwxr-xr-xtest/fs/fs.sh13
-rwxr-xr-xtest/fs/fscheck-bindnoroot.exp (renamed from test/fscheck-bindnoroot.exp)5
-rwxr-xr-xtest/fs/fscheck-private.exp50
-rwxr-xr-xtest/fs/fscheck-readonly.exp (renamed from test/fscheck-readonly.exp)3
-rwxr-xr-xtest/fs/fscheck-tmpfs.exp (renamed from test/fscheck-tmpfs.exp)2
-rwxr-xr-xtest/fs/invalid_filename.exp15
-rwxr-xr-xtest/fs/private-bin.exp22
-rwxr-xr-xtest/fs/private-etc.exp34
-rwxr-xr-xtest/fs/private-home.exp62
-rwxr-xr-xtest/fs/read-write.exp28
-rw-r--r--test/fs/testfile10
-rwxr-xr-xtest/fscheck-private.exp70
-rwxr-xr-xtest/rlimit/rlimit.sh14
-rwxr-xr-xtest/utils/firemon-cpu.exp1
-rwxr-xr-xtest/utils/firemon-interface.exp18
-rwxr-xr-xtest/utils/firemon-name.exp28
-rwxr-xr-xtest/utils/firemon-version.exp18
-rwxr-xr-xtest/utils/utils.sh9
74 files changed, 1390 insertions, 712 deletions
diff --git a/.gitignore b/.gitignore
index 459119b14..9b9935b93 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,4 +22,5 @@ src/tags
22src/faudit/faudit 22src/faudit/faudit
23src/fnet/fnet 23src/fnet/fnet
24src/fseccomp/fseccomp 24src/fseccomp/fseccomp
25src/fcopy/fcopy
25uids.h 26uids.h
diff --git a/Makefile.in b/Makefile.in
index 86fd4f4b7..772dc8c06 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,6 +1,6 @@
1all: apps man 1all: apps man
2MYLIBS = src/lib 2MYLIBS = src/lib
3APPS = src/firejail src/firemon src/firecfg src/libtrace src/libtracelog src/ftee src/faudit src/libconnect src/fnet src/fseccomp 3APPS = src/firejail src/firemon src/firecfg src/libtrace src/libtracelog src/ftee src/faudit src/libconnect src/fnet src/fseccomp src/fcopy
4MANPAGES = firejail.1 firemon.1 firecfg.1 firejail-profile.5 firejail-login.5 4MANPAGES = firejail.1 firemon.1 firecfg.1 firejail-profile.5 firejail-login.5
5 5
6prefix=@prefix@ 6prefix=@prefix@
@@ -78,6 +78,7 @@ realinstall:
78 install -c -m 0755 src/faudit/faudit $(DESTDIR)/$(libdir)/firejail/. 78 install -c -m 0755 src/faudit/faudit $(DESTDIR)/$(libdir)/firejail/.
79 install -c -m 0755 src/fnet/fnet $(DESTDIR)/$(libdir)/firejail/. 79 install -c -m 0755 src/fnet/fnet $(DESTDIR)/$(libdir)/firejail/.
80 install -c -m 0755 src/fseccomp/fseccomp $(DESTDIR)/$(libdir)/firejail/. 80 install -c -m 0755 src/fseccomp/fseccomp $(DESTDIR)/$(libdir)/firejail/.
81 install -c -m 0755 src/fcopy/fcopy $(DESTDIR)/$(libdir)/firejail/.
81 # documents 82 # documents
82 install -m 0755 -d $(DESTDIR)/$(DOCDIR) 83 install -m 0755 -d $(DESTDIR)/$(DOCDIR)
83 install -c -m 0644 COPYING $(DESTDIR)/$(DOCDIR)/. 84 install -c -m 0644 COPYING $(DESTDIR)/$(DOCDIR)/.
@@ -128,6 +129,7 @@ install-strip: all
128 strip src/faudit/faudit 129 strip src/faudit/faudit
129 strip src/fnet/fnet 130 strip src/fnet/fnet
130 strip src/fseccomp/fseccomp 131 strip src/fseccomp/fseccomp
132 strip src/fcopy/fcopy
131 $(MAKE) realinstall 133 $(MAKE) realinstall
132 134
133uninstall: 135uninstall:
@@ -145,7 +147,7 @@ uninstall:
145 rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firecfg 147 rm -f $(DESTDIR)/$(datarootdir)/bash-completion/completions/firecfg
146 148
147DISTFILES = "src etc platform configure configure.ac Makefile.in install.sh mkman.sh mketc.sh mkdeb.sh mkuid.sh COPYING README RELNOTES" 149DISTFILES = "src etc platform configure configure.ac Makefile.in install.sh mkman.sh mketc.sh mkdeb.sh mkuid.sh COPYING README RELNOTES"
148DISTFILES_TEST = "test/rlimit test/apps test/apps-x11 test/apps-x11-xorg test/root test/environment test/profiles test/utils test/compile test/filters test/network test/arguments test/fs test/sysutils" 150DISTFILES_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"
149 151
150dist: 152dist:
151 mv config.status config.status.old 153 mv config.status config.status.old
@@ -223,10 +225,10 @@ test-arguments:
223test-fs: 225test-fs:
224 cd test/fs; ./fs.sh | grep TESTING 226 cd test/fs; ./fs.sh | grep TESTING
225 227
226test-rlimit: 228test-fcopy:
227 cd test/rlimit; ./rlimit.sh | grep TESTING 229 cd test/fcopy; ./fcopy.sh | grep TESTING
228 230
229test: test-profiles test-fs test-utils test-environment test-apps test-apps-x11 test-apps-x11-xorg test-filters test-arguments test-rlimit 231test: test-profiles test-fcopy test-fs test-utils test-environment test-apps test-apps-x11 test-apps-x11-xorg test-filters test-arguments
230 echo "TEST COMPLETE" 232 echo "TEST COMPLETE"
231 233
232########################################## 234##########################################
@@ -254,6 +256,6 @@ test-overlay:
254 256
255# For testing hidepid system, the command to set it up is "mount -o remount,rw,hidepid=2 /proc" 257# For testing hidepid system, the command to set it up is "mount -o remount,rw,hidepid=2 /proc"
256 258
257test-all: test-root test-network test-appimage test-overlay test 259test-all: test-root test-network test-appimage test-overlay test-fcopy test
258 echo "TEST COMPLETE" 260 echo "TEST COMPLETE"
259 \ No newline at end of file 261 \ No newline at end of file
diff --git a/README b/README
index e21e96bc7..bd32034a3 100644
--- a/README
+++ b/README
@@ -103,6 +103,7 @@ valoq (https://github.com/valoq)
103 - blacklist suid binaries in disable-common.inc 103 - blacklist suid binaries in disable-common.inc
104 - fix man pages 104 - fix man pages
105 - various profile improvements 105 - various profile improvements
106 - added keypass2, qemu profiles
106Vadim A. Misbakh-Soloviov (https://github.com/msva) 107Vadim A. Misbakh-Soloviov (https://github.com/msva)
107 - profile fixes 108 - profile fixes
108Rafael Cavalcanti (https://github.com/rccavalcanti) 109Rafael Cavalcanti (https://github.com/rccavalcanti)
diff --git a/README.md b/README.md
index af6573600..d653a235c 100644
--- a/README.md
+++ b/README.md
@@ -51,10 +51,15 @@ Use this issue to request new profiles: https://github.com/netblue30/firejail/is
51````` 51`````
52 52
53````` 53`````
54## AppImage type 2 support
55`````
56
57`````
54## New Profiles 58## New Profiles
55xiphos, Tor Browser Bundle, display (imagemagik), Wire, mumble, zoom,Guayadeque 59xiphos, Tor Browser Bundle, display (imagemagik), Wire, mumble, zoom,Guayadeque, qemu, keypass2
56amarok, ark, atool, bleachbit, brasero, dolphin, dragon, elinks, enchant, exiftool, file-roller, gedit 60amarok, ark, atool, bleachbit, brasero, dolphin, dragon, elinks, enchant, exiftool, file-roller, gedit
57gjs, gnome-books, gnome-clocks, gnome-documents, gnome-maps, gnome-music, gnome-photos, gnome-weather 61gjs, gnome-books, gnome-clocks, gnome-documents, gnome-maps, gnome-music, gnome-photos, gnome-weather
58goobox, gpa, gpg, gpg-agent, highlight, img2txt, k3b, kate, lynx, mediainfo, nautilus, odt2txt, pdftotext 62goobox, gpa, gpg, gpg-agent, highlight, img2txt, k3b, kate, lynx, mediainfo, nautilus, odt2txt, pdftotext
59simple-scan, skanlite, ssh-agent, tracker, transmission-cli, transmission-show, w3m, xfburn, xpra 63simple-scan, skanlite, ssh-agent, tracker, transmission-cli, transmission-show, w3m, xfburn, xpra
60 64
65
diff --git a/RELNOTES b/RELNOTES
index e726674ec..3a7c398c2 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -5,9 +5,12 @@ firejail (0.9.45) baseline; urgency=low
5 * security: invalid environment exploit found by Martin Carpenter 5 * security: invalid environment exploit found by Martin Carpenter
6 * security: split most of networking code in a separate executable 6 * security: split most of networking code in a separate executable
7 * security: split seccomp filter code configuration in a separate executable 7 * security: split seccomp filter code configuration in a separate executable
8 * security: split file copying in private option in a separate executable
8 * feature: allow root user access to /dev/shm (--noblacklist=/dev/shm) 9 * feature: allow root user access to /dev/shm (--noblacklist=/dev/shm)
10 * feature: AppImage type 2 support
11 * feature: test coverage (gcov) support
9 * new profiles: xiphos, Tor Browser Bundle, display (imagemagik), Wire, 12 * new profiles: xiphos, Tor Browser Bundle, display (imagemagik), Wire,
10 * new profiles: mumble, zoom, Guayadeque 13 * new profiles: mumble, zoom, Guayadeque, qemu, keypass2
11 * bugfixes 14 * bugfixes
12 -- netblue30 <netblue30@yahoo.com> Sun, 23 Oct 2016 08:00:00 -0500 15 -- netblue30 <netblue30@yahoo.com> Sun, 23 Oct 2016 08:00:00 -0500
13 16
diff --git a/configure b/configure
index 0aefb5c62..9efba1b1d 100755
--- a/configure
+++ b/configure
@@ -3777,7 +3777,7 @@ if test "$prefix" = /usr; then
3777 sysconfdir="/etc" 3777 sysconfdir="/etc"
3778fi 3778fi
3779 3779
3780ac_config_files="$ac_config_files Makefile src/lib/Makefile src/fnet/Makefile src/firejail/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/ftee/Makefile src/faudit/Makefile src/libconnect/Makefile src/fseccomp/Makefile" 3780ac_config_files="$ac_config_files Makefile src/lib/Makefile src/fcopy/Makefile src/fnet/Makefile src/firejail/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile src/ftee/Makefile src/faudit/Makefile src/libconnect/Makefile src/fseccomp/Makefile"
3781 3781
3782cat >confcache <<\_ACEOF 3782cat >confcache <<\_ACEOF
3783# This file is a shell script that caches the results of configure 3783# This file is a shell script that caches the results of configure
@@ -4488,6 +4488,7 @@ do
4488 case $ac_config_target in 4488 case $ac_config_target in
4489 "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; 4489 "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
4490 "src/lib/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib/Makefile" ;; 4490 "src/lib/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib/Makefile" ;;
4491 "src/fcopy/Makefile") CONFIG_FILES="$CONFIG_FILES src/fcopy/Makefile" ;;
4491 "src/fnet/Makefile") CONFIG_FILES="$CONFIG_FILES src/fnet/Makefile" ;; 4492 "src/fnet/Makefile") CONFIG_FILES="$CONFIG_FILES src/fnet/Makefile" ;;
4492 "src/firejail/Makefile") CONFIG_FILES="$CONFIG_FILES src/firejail/Makefile" ;; 4493 "src/firejail/Makefile") CONFIG_FILES="$CONFIG_FILES src/firejail/Makefile" ;;
4493 "src/firemon/Makefile") CONFIG_FILES="$CONFIG_FILES src/firemon/Makefile" ;; 4494 "src/firemon/Makefile") CONFIG_FILES="$CONFIG_FILES src/firemon/Makefile" ;;
diff --git a/configure.ac b/configure.ac
index 74ba09f43..f3076f2f8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -158,8 +158,9 @@ if test "$prefix" = /usr; then
158 sysconfdir="/etc" 158 sysconfdir="/etc"
159fi 159fi
160 160
161AC_OUTPUT(Makefile src/lib/Makefile src/fnet/Makefile src/firejail/Makefile src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile \ 161AC_OUTPUT(Makefile src/lib/Makefile src/fcopy/Makefile src/fnet/Makefile src/firejail/Makefile \
162src/firecfg/Makefile src/ftee/Makefile src/faudit/Makefile src/libconnect/Makefile src/fseccomp/Makefile) 162src/firemon/Makefile src/libtrace/Makefile src/libtracelog/Makefile src/firecfg/Makefile \
163src/ftee/Makefile src/faudit/Makefile src/libconnect/Makefile src/fseccomp/Makefile)
163 164
164echo 165echo
165echo "Configuration options:" 166echo "Configuration options:"
diff --git a/etc/vivaldi.profile b/etc/vivaldi.profile
index 3c608dccb..08b046847 100644
--- a/etc/vivaldi.profile
+++ b/etc/vivaldi.profile
@@ -6,7 +6,6 @@ include /etc/firejail/disable-programs.inc
6include /etc/firejail/disable-devel.inc 6include /etc/firejail/disable-devel.inc
7 7
8netfilter 8netfilter
9nonewprivs
10 9
11whitelist ${DOWNLOADS} 10whitelist ${DOWNLOADS}
12mkdir ~/.config/vivaldi 11mkdir ~/.config/vivaldi
diff --git a/gcov.sh b/gcov.sh
index ffacce6b5..900b7ca41 100755
--- a/gcov.sh
+++ b/gcov.sh
@@ -1,21 +1,28 @@
1#!/bin/bash 1#!/bin/bash
2 2
3gcov_init() {
4 USER=`whoami`
5 firejail --help
6 firemon --help
7 /usr/lib/firejail/fnet --help
8 /usr/lib/firejail/fseccomp --help
9 /usr/lib/firejail/ftee --help
10 /usr/lib/firejail/fcopy --help
11 firecfg --help
12 sudo chown $USER:$USER `find .`
13}
14
3generate() { 15generate() {
4 lcov --capture -d src/firejail -d src/firemon -d src/fseccomp -d src/fnet -d src/ftee -d src/lib -d src/firecfg --output-file gcov-file 16 lcov --capture -d src/firejail -d src/firemon -d src/fcopy -d src/fseccomp -d src/fnet -d src/ftee -d src/lib -d src/firecfg --output-file gcov-file
5 rm -fr gcov-dir 17 rm -fr gcov-dir
6 genhtml gcov-file --output-directory gcov-dir 18 genhtml gcov-file --output-directory gcov-dir
7} 19}
8 20
9# init 21gcov_init
10USER=`whoami`
11firejail --help
12firemon --help
13/usr/lib/firejail/fnet --help
14/usr/lib/firejail/fseccomp --help
15/usr/lib/firejail/ftee --help
16firecfg --help
17sudo chown $USER:$USER `find .`
18generate 22generate
23echo "press any key to continue, or Ctrl-C to exit"
24read text
25
19 26
20# running tests 27# running tests
21make test-root 28make test-root
@@ -34,6 +41,10 @@ make test-overlay
34generate 41generate
35sleep 2 42sleep 2
36 43
44make test-fcopy
45generate
46sleep 2
47
37make test-profiles 48make test-profiles
38generate 49generate
39sleep 2 50sleep 2
diff --git a/src/fcopy/Makefile.in b/src/fcopy/Makefile.in
new file mode 100644
index 000000000..278957a4f
--- /dev/null
+++ b/src/fcopy/Makefile.in
@@ -0,0 +1,45 @@
1all: fcopy
2
3prefix=@prefix@
4exec_prefix=@exec_prefix@
5libdir=@libdir@
6sysconfdir=@sysconfdir@
7
8VERSION=@PACKAGE_VERSION@
9NAME=@PACKAGE_NAME@
10HAVE_SECCOMP_H=@HAVE_SECCOMP_H@
11HAVE_SECCOMP=@HAVE_SECCOMP@
12HAVE_CHROOT=@HAVE_CHROOT@
13HAVE_BIND=@HAVE_BIND@
14HAVE_FATAL_WARNINGS=@HAVE_FATAL_WARNINGS@
15HAVE_NETWORK=@HAVE_NETWORK@
16HAVE_USERNS=@HAVE_USERNS@
17HAVE_X11=@HAVE_X11@
18HAVE_FILE_TRANSFER=@HAVE_FILE_TRANSFER@
19HAVE_WHITELIST=@HAVE_WHITELIST@
20HAVE_GLOBALCFG=@HAVE_GLOBALCFG@
21HAVE_APPARMOR=@HAVE_APPARMOR@
22HAVE_OVERLAYFS=@HAVE_OVERLAYFS@
23HAVE_PRIVATE_HOME=@HAVE_PRIVATE_HOME@
24EXTRA_LDFLAGS +=@EXTRA_LDFLAGS@
25HAVE_GCOV=@HAVE_GCOV@
26EXTRA_LDFLAGS +=@EXTRA_LDFLAGS@
27
28H_FILE_LIST = $(sort $(wildcard *.[h]))
29C_FILE_LIST = $(sort $(wildcard *.c))
30OBJS = $(C_FILE_LIST:.c=.o)
31BINOBJS = $(foreach file, $(OBJS), $file)
32CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' $(HAVE_GCOV) -DPREFIX='"$(prefix)"' -DSYSCONFDIR='"$(sysconfdir)/firejail"' -DLIBDIR='"$(libdir)"' $(HAVE_X11) $(HAVE_PRIVATE_HOME) $(HAVE_APPARMOR) $(HAVE_OVERLAYFS) $(HAVE_SECCOMP) $(HAVE_GLOBALCFG) $(HAVE_SECCOMP_H) $(HAVE_CHROOT) $(HAVE_NETWORK) $(HAVE_USERNS) $(HAVE_BIND) $(HAVE_FILE_TRANSFER) $(HAVE_WHITELIST) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security
33LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread
34
35%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/syscall.h
36 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
37
38fcopy: $(OBJS)
39 $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTRA_LDFLAGS)
40
41clean:; rm -f *.o fcopy *.gcov *.gcda *.gcno
42
43distclean: clean
44 rm -fr Makefile
45
diff --git a/src/fcopy/main.c b/src/fcopy/main.c
new file mode 100644
index 000000000..b1e2813db
--- /dev/null
+++ b/src/fcopy/main.c
@@ -0,0 +1,340 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20
21#include "../include/common.h"
22#include <fcntl.h>
23#include <ftw.h>
24
25
26#define COPY_LIMIT (500 * 1024 *1024)
27static int size_limit_reached = 0;
28static unsigned file_cnt = 0;
29static unsigned size_cnt = 0;
30
31static char *outpath = NULL;
32static char *inpath = NULL;
33
34
35// modified version of the function from util.c
36static void copy_file(const char *srcname, const char *destname, mode_t mode, uid_t uid, gid_t gid) {
37 assert(srcname);
38 assert(destname);
39 mode &= 07777;
40
41 // open source
42 int src = open(srcname, O_RDONLY);
43 if (src < 0) {
44 fprintf(stderr, "Warning: cannot open %s, file not copied\n", srcname);
45 return;
46 }
47
48 // open destination
49 int dst = open(destname, O_CREAT|O_WRONLY|O_TRUNC, 0755);
50 if (dst < 0) {
51 fprintf(stderr, "Warning fcopy: cannot open %s, file not copied\n", destname);
52 close(src);
53 return;
54 }
55
56 // copy
57 ssize_t len;
58 static const int BUFLEN = 1024;
59 unsigned char buf[BUFLEN];
60 while ((len = read(src, buf, BUFLEN)) > 0) {
61 int done = 0;
62 while (done != len) {
63 int rv = write(dst, buf + done, len - done);
64 if (rv == -1)
65 goto errexit;
66 done += rv;
67 }
68 }
69 fflush(0);
70
71 if (fchown(dst, uid, gid) == -1)
72 goto errexit;
73 if (fchmod(dst, mode) == -1)
74 goto errexit;
75
76 close(src);
77 close(dst);
78
79 return;
80
81errexit:
82 close(src);
83 close(dst);
84 unlink(destname);
85 fprintf(stderr, "Warning fcopy: cannot copy %s\n", destname);
86}
87
88
89
90// modified version of the function in firejail/util.c
91static void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid) {
92 assert(fname);
93 mode &= 07777;
94
95 if (mkdir(fname, mode) == -1 ||
96 chmod(fname, mode) == -1) {
97 fprintf(stderr, "Error fcopy: failed to create %s directory\n", fname);
98 errExit("mkdir/chmod");
99 }
100 if (chown(fname, uid, gid))
101 fprintf(stderr, "Warning fcopy: failed to change ownership of %s\n", fname);
102}
103
104void copy_link(const char *target, const char *linkpath, mode_t mode, uid_t uid, gid_t gid) {
105 (void) mode;
106 (void) uid;
107 (void) gid;
108 char *rp = realpath(target, NULL);
109 if (rp) {
110 if (symlink(rp, linkpath) == -1)
111 goto errout;
112 free(rp);
113 }
114 else
115 goto errout;
116
117 return;
118errout:
119 fprintf(stderr, "Warning fcopy: cannot create symbolic link %s\n", target);
120}
121
122static int first = 1;
123static int fs_copydir(const char *infname, const struct stat *st, int ftype, struct FTW *sftw) {
124 (void) st;
125 (void) sftw;
126 assert(infname);
127 assert(*infname != '\0');
128 assert(outpath);
129 assert(*outpath != '\0');
130 assert(inpath);
131
132 // check size limit
133 if (size_limit_reached)
134 return 0;
135
136
137 char *outfname;
138 if (asprintf(&outfname, "%s%s", outpath, infname + strlen(inpath)) == -1)
139 errExit("asprintf");
140
141//printf("outpaht %s\n", outpath);
142//printf("inpath %s\n", inpath);
143//printf("infname %s\n", infname);
144//printf("outfname %s\n\n", outfname);
145
146 // don't copy it if we already have the file
147 struct stat s;
148 if (stat(outfname, &s) == 0) {
149 if (first)
150 first = 0;
151 else
152 fprintf(stderr, "Warning fcopy: skipping %s, file already present\n", infname);
153 free(outfname);
154 return 0;
155 }
156
157 // extract mode and ownership
158 if (stat(infname, &s) != 0) {
159 fprintf(stderr, "Warning fcopy: skipping %s, cannot find inode\n", infname);
160 free(outfname);
161 return 0;
162 }
163 uid_t uid = s.st_uid;
164 gid_t gid = s.st_gid;
165 mode_t mode = s.st_mode;
166
167 // recalculate size
168 if ((s.st_size + size_cnt) > COPY_LIMIT) {
169 fprintf(stderr, "Error fcopy: size limit of %dMB reached\n", (COPY_LIMIT / 1024) / 1024);
170 size_limit_reached = 1;
171 free(outfname);
172 return 0;
173 }
174
175 file_cnt++;
176 size_cnt += s.st_size;
177
178 if(ftype == FTW_F) {
179 copy_file(infname, outfname, mode, uid, gid);
180 }
181 else if (ftype == FTW_D) {
182 mkdir_attr(outfname, mode, uid, gid);
183 }
184 else if (ftype == FTW_SL) {
185 copy_link(infname, outfname, mode, uid, gid);
186 }
187
188 return(0);
189}
190
191static char *check(const char *src) {
192 struct stat s;
193 char *rsrc = realpath(src, NULL);
194 if (!rsrc || stat(rsrc, &s) == -1)
195 goto errexit;
196
197 // check uid
198 if (s.st_uid != getuid() || s.st_gid != getgid())
199 goto errexit;
200
201 // dir, link, regular file
202 if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode) || S_ISLNK(s.st_mode))
203 return rsrc; // normal exit from the function
204
205errexit:
206 fprintf(stderr, "Error fcopy: invalid file %s\n", src);
207 exit(1);
208}
209
210static void duplicate_dir(const char *src, const char *dest, struct stat *s) {
211 (void) s;
212 char *rsrc = check(src);
213 char *rdest = check(dest);
214 inpath = rsrc;
215 outpath = rdest;
216
217 // walk
218 if(nftw(rsrc, fs_copydir, 1, FTW_PHYS) != 0) {
219 fprintf(stderr, "Error: unable to copy file\n");
220 exit(1);
221 }
222
223 free(rsrc);
224 free(rdest);
225}
226
227static void duplicate_file(const char *src, const char *dest, struct stat *s) {
228 char *rsrc = check(src);
229 char *rdest = check(dest);
230 uid_t uid = s->st_uid;
231 gid_t gid = s->st_gid;
232 mode_t mode = s->st_mode;
233
234 // build destination file name
235 char *name;
236 char *ptr = strrchr(rsrc, '/');
237 ptr++;
238 if (asprintf(&name, "%s/%s", rdest, ptr) == -1)
239 errExit("asprintf");
240
241 // copy
242 copy_file(rsrc, name, mode, uid, gid);
243
244 free(name);
245 free(rsrc);
246 free(rdest);
247}
248
249static void duplicate_link(const char *src, const char *dest, struct stat *s) {
250 char *rsrc = check(src); // we drop the result and use the original name
251 char *rdest = check(dest);
252 uid_t uid = s->st_uid;
253 gid_t gid = s->st_gid;
254 mode_t mode = s->st_mode;
255
256 // build destination file name
257 char *name;
258// char *ptr = strrchr(rsrc, '/');
259 char *ptr = strrchr(src, '/');
260 ptr++;
261 if (asprintf(&name, "%s/%s", rdest, ptr) == -1)
262 errExit("asprintf");
263
264 // copy
265 copy_link(rsrc, name, mode, uid, gid);
266
267 free(name);
268 free(rsrc);
269 free(rdest);
270}
271
272static void usage(void) {
273 printf("Usage: fcopy src dest\n");
274 printf("Copy src file in dest directory. If src is a directory, copy all the files in\n");
275 printf("src recoursively. If the destination directory does not exist, it will be created.\n");
276}
277
278int main(int argc, char **argv) {
279#if 0
280{
281//system("cat /proc/self/status");
282int i;
283for (i = 0; i < argc; i++)
284 printf("*%s* ", argv[i]);
285printf("\n");
286}
287#endif
288 if (argc != 3) {
289 fprintf(stderr, "Error fcopy: files missing\n");
290 usage();
291 exit(1);
292 }
293
294 // check the two files; remove ending /
295 char *src = argv[1];
296 int len = strlen(src);
297 if (src[len - 1] == '/')
298 src[len - 1] = '\0';
299 if (strcspn(src, "\\*&!?\"'<>%^(){}[];,") != (size_t)len) {
300 fprintf(stderr, "Error fcopy: invalid file name %s\n", src);
301 exit(1);
302 }
303
304 char *dest = argv[2];
305 len = strlen(dest);
306 if (dest[len - 1] == '/')
307 dest[len - 1] = '\0';
308 if (strcspn(dest, "\\*&!?\"'<>%^(){}[];,~") != (size_t)len) {
309 fprintf(stderr, "Error fcopy: invalid file name %s\n", dest);
310 exit(1);
311 }
312
313
314 // the destination should be a directory;
315 struct stat s;
316 if (stat(dest, &s) == -1 ||
317 !S_ISDIR(s.st_mode)) {
318 fprintf(stderr, "Error fcopy: invalid destination directory\n");
319 exit(1);
320 }
321
322 // copy files
323 if (lstat(src, &s) == -1) {
324 fprintf(stderr, "Error fcopy: cannot find source file\n");
325 exit(1);
326 }
327
328 if (S_ISDIR(s.st_mode))
329 duplicate_dir(src, dest, &s);
330 else if (S_ISREG(s.st_mode))
331 duplicate_file(src, dest, &s);
332 else if (S_ISLNK(s.st_mode))
333 duplicate_link(src, dest, &s);
334 else {
335 fprintf(stderr, "Error fcopy: source file unsupported\n");
336 exit(1);
337 }
338
339 return 0;
340}
diff --git a/src/firejail/appimage.c b/src/firejail/appimage.c
index a658173eb..6a9ca1679 100644
--- a/src/firejail/appimage.c
+++ b/src/firejail/appimage.c
@@ -31,38 +31,39 @@
31static char *devloop = NULL; // device file 31static char *devloop = NULL; // device file
32static char *mntdir = NULL; // mount point in /tmp directory 32static char *mntdir = NULL; // mount point in /tmp directory
33 33
34const char *appimage_getdir(void) { 34void appimage_set(const char *appimage) {
35 return mntdir; 35 assert(appimage);
36}
37
38void appimage_set(const char *appimage_path) {
39 assert(appimage_path);
40 assert(devloop == NULL); // don't call this twice! 36 assert(devloop == NULL); // don't call this twice!
41 EUID_ASSERT(); 37 EUID_ASSERT();
42 38
43#ifdef LOOP_CTL_GET_FREE // test for older kernels; this definition is found in /usr/include/linux/loop.h 39#ifdef LOOP_CTL_GET_FREE // test for older kernels; this definition is found in /usr/include/linux/loop.h
44 // check appimage_path 40 // check appimage file
45 if (access(appimage_path, R_OK) == -1) { 41 invalid_filename(appimage);
42 if (access(appimage, R_OK) == -1) {
46 fprintf(stderr, "Error: cannot access AppImage file\n"); 43 fprintf(stderr, "Error: cannot access AppImage file\n");
47 exit(1); 44 exit(1);
48 } 45 }
49 46
50 // get appimage type and ELF size 47 // get appimage type and ELF size
51 // a value of 0 means we are dealing with a type1 appimage 48 // a value of 0 means we are dealing with a type1 appimage
52 long unsigned int size = appimage2_size(appimage_path); 49 long unsigned int size = appimage2_size(appimage);
53 if (arg_debug) 50 if (arg_debug)
54 printf("AppImage ELF size %lu\n", size); 51 printf("AppImage ELF size %lu\n", size);
55 52
56 // open as user to prevent race condition 53 // open appimage file
57 int ffd = open(appimage_path, O_RDONLY|O_CLOEXEC); 54 int ffd = open(appimage, O_RDONLY|O_CLOEXEC);
58 if (ffd == -1) { 55 if (ffd == -1) {
59 fprintf(stderr, "Error: /dev/loop-control interface is not supported by your kernel\n"); 56 fprintf(stderr, "Error: cannot open AppImage file\n");
60 exit(1); 57 exit(1);
61 } 58 }
62 59
63 // find or allocate a free loop device to use 60 // find or allocate a free loop device to use
64 EUID_ROOT(); 61 EUID_ROOT();
65 int cfd = open("/dev/loop-control", O_RDWR); 62 int cfd = open("/dev/loop-control", O_RDWR);
63 if (cfd == -1) {
64 fprintf(stderr, "Error: /dev/loop-control interface is not supported by your kernel\n");
65 exit(1);
66 }
66 int devnr = ioctl(cfd, LOOP_CTL_GET_FREE); 67 int devnr = ioctl(cfd, LOOP_CTL_GET_FREE);
67 if (devnr == -1) { 68 if (devnr == -1) {
68 fprintf(stderr, "Error: cannot allocate a new loopback device\n"); 69 fprintf(stderr, "Error: cannot allocate a new loopback device\n");
@@ -117,7 +118,7 @@ void appimage_set(const char *appimage_path) {
117 EUID_USER(); 118 EUID_USER();
118 119
119 // set environment 120 // set environment
120 if (appimage_path && setenv("APPIMAGE", appimage_path, 1) < 0) 121 if (appimage && setenv("APPIMAGE", appimage, 1) < 0)
121 errExit("setenv"); 122 errExit("setenv");
122 if (mntdir && setenv("APPDIR", mntdir, 1) < 0) 123 if (mntdir && setenv("APPDIR", mntdir, 1) < 0)
123 errExit("setenv"); 124 errExit("setenv");
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index d7ba539e6..2562094d3 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -490,8 +490,6 @@ void fs_private_template(void);
490void fs_check_private_dir(void); 490void fs_check_private_dir(void);
491// check new private template home directory (--private-template= option) exit if it fails 491// check new private template home directory (--private-template= option) exit if it fails
492void fs_check_private_template(void); 492void fs_check_private_template(void);
493// check directory list specified by user (--private-home option) - exit if it fails
494void fs_check_home_list(void);
495void fs_private_home_list(void); 493void fs_private_home_list(void);
496 494
497 495
@@ -557,7 +555,6 @@ void network_del_run_file(pid_t pid);
557void network_set_run_file(pid_t pid); 555void network_set_run_file(pid_t pid);
558 556
559// fs_etc.c 557// fs_etc.c
560void fs_check_etc_list(void);
561void fs_private_etc_list(void); 558void fs_private_etc_list(void);
562 559
563// no_sandbox.c 560// no_sandbox.c
@@ -590,7 +587,6 @@ void pulseaudio_init(void);
590void pulseaudio_disable(void); 587void pulseaudio_disable(void);
591 588
592// fs_bin.c 589// fs_bin.c
593void fs_check_bin_list(void);
594void fs_private_bin_list(void); 590void fs_private_bin_list(void);
595 591
596// protocol.c 592// protocol.c
@@ -681,6 +677,7 @@ void build_cmdline(char **command_line, char **window_title, int argc, char **ar
681#define PATH_FNET (LIBDIR "/firejail/fnet") 677#define PATH_FNET (LIBDIR "/firejail/fnet")
682#define PATH_FIREMON (PREFIX "/bin/firemon") 678#define PATH_FIREMON (PREFIX "/bin/firemon")
683#define PATH_FSECCOMP (LIBDIR "/firejail/fseccomp") 679#define PATH_FSECCOMP (LIBDIR "/firejail/fseccomp")
680#define PATH_FCOPY (LIBDIR "/firejail/fcopy")
684// bitmapped filters for sbox_run 681// bitmapped filters for sbox_run
685#define SBOX_ROOT (1 << 0) // run the sandbox as root 682#define SBOX_ROOT (1 << 0) // run the sandbox as root
686#define SBOX_USER (1 << 1) // run the sandbox as a regular user 683#define SBOX_USER (1 << 1) // run the sandbox as a regular user
diff --git a/src/firejail/fs_bin.c b/src/firejail/fs_bin.c
index 6cc1bf3ab..421df717d 100644
--- a/src/firejail/fs_bin.c
+++ b/src/firejail/fs_bin.c
@@ -39,7 +39,6 @@ static char *paths[] = {
39// return 1 if found, 0 if not found 39// return 1 if found, 0 if not found
40static char *check_dir_or_file(const char *name) { 40static char *check_dir_or_file(const char *name) {
41 assert(name); 41 assert(name);
42 invalid_filename(name);
43 42
44 struct stat s; 43 struct stat s;
45 char *fname = NULL; 44 char *fname = NULL;
@@ -94,68 +93,13 @@ static char *check_dir_or_file(const char *name) {
94 return paths[i]; 93 return paths[i];
95} 94}
96 95
97void fs_check_bin_list(void) { 96static void duplicate(char *fname) {
98 EUID_ASSERT(); 97 if (*fname == '~' || *fname == '/' || strstr(fname, "..")) {
99 if (strstr(cfg.bin_private_keep, "..")) { 98 fprintf(stderr, "Error: \"%s\" is an invalid filename\n", fname);
100 fprintf(stderr, "Error: invalid private bin list\n");
101 exit(1); 99 exit(1);
102 } 100 }
103 101 invalid_filename(fname);
104 char *dlist = strdup(cfg.bin_private_keep);
105 if (!dlist)
106 errExit("strdup");
107
108 // create a new list removing files not found
109 char *newlist = malloc(strlen(dlist) + 1 + 1); // +',' + '\0'
110 if (!newlist)
111 errExit("malloc");
112 *newlist = '\0';
113 char *newlistptr = newlist;
114
115 // check the first file
116 char *ptr = strtok(dlist, ",");
117 int notfound = 0;
118 if (check_dir_or_file(ptr)) {
119 // file found, copy the name in the new list
120 strcpy(newlistptr, ptr);
121 strcat(newlistptr, ",");
122 newlistptr += strlen(newlistptr);
123 }
124 else
125 notfound = 1;
126
127 // check the rest of the list
128 while ((ptr = strtok(NULL, ",")) != NULL) {
129 if (check_dir_or_file(ptr)) {
130 // file found, copy the name in the new list
131 strcpy(newlistptr, ptr);
132 strcat(newlistptr, ",");
133 newlistptr += strlen(newlistptr);
134 }
135 else
136 notfound = 1;
137 }
138
139 if (*newlist == '\0') {
140// fprintf(stderr, "Warning: no --private-bin list executable found, option disabled\n");
141// cfg.bin_private_keep = NULL;
142// arg_private_bin = 0;
143 free(newlist);
144 }
145 else {
146 ptr = strrchr(newlist, ',');
147 assert(ptr);
148 *ptr = '\0';
149 if (notfound && !arg_quiet)
150 fprintf(stderr, "Warning: not all executables from --private-bin list were found. The current list is %s\n", newlist);
151
152 cfg.bin_private_keep = newlist;
153 }
154
155 free(dlist);
156}
157 102
158static void duplicate(char *fname) {
159 char *path = check_dir_or_file(fname); 103 char *path = check_dir_or_file(fname);
160 if (!path) 104 if (!path)
161 return; 105 return;
@@ -165,44 +109,9 @@ static void duplicate(char *fname) {
165 if (asprintf(&full_path, "%s/%s", path, fname) == -1) 109 if (asprintf(&full_path, "%s/%s", path, fname) == -1)
166 errExit("asprintf"); 110 errExit("asprintf");
167 111
168 char *actual_path = realpath(full_path, NULL); 112 // copy the file
169 if (actual_path) { 113 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, full_path, RUN_BIN_DIR);
170 // if the file is a symbolic link not under path, make a symbolic link 114 fs_logger2("clone", fname);
171 if (is_link(full_path) && strncmp(actual_path, path, strlen(path))) {
172 char *lnkname;
173 if (asprintf(&lnkname, "%s/%s", RUN_BIN_DIR, fname) == -1)
174 errExit("asprintf");
175 int rv = symlink(actual_path, lnkname);
176 if (rv)
177 fprintf(stderr, "Warning cannot create symbolic link %s\n", lnkname);
178 else if (arg_debug)
179 printf("Created symbolic link %s -> %s\n", lnkname, actual_path);
180 free(lnkname);
181 }
182 else {
183 // copy the file
184 if (arg_debug)
185 printf("running: %s -a %s %s/%s", RUN_CP_COMMAND, actual_path, RUN_BIN_DIR, fname);
186
187 pid_t child = fork();
188 if (child < 0)
189 errExit("fork");
190 if (child == 0) {
191 char *f;
192 if (asprintf(&f, "%s/%s", RUN_BIN_DIR, fname) == -1)
193 errExit("asprintf");
194 clearenv();
195 execlp(RUN_CP_COMMAND, RUN_CP_COMMAND, "-a", actual_path, f, NULL);
196 perror("execlp");
197 _exit(1);
198 }
199 // wait for the child to finish
200 waitpid(child, NULL, 0);
201
202 }
203 free(actual_path);
204 }
205
206 free(full_path); 115 free(full_path);
207} 116}
208 117
@@ -214,42 +123,20 @@ void fs_private_bin_list(void) {
214 // create /run/firejail/mnt/bin directory 123 // create /run/firejail/mnt/bin directory
215 mkdir_attr(RUN_BIN_DIR, 0755, 0, 0); 124 mkdir_attr(RUN_BIN_DIR, 0755, 0, 0);
216 125
217 // copy the list of files in the new etc directory 126 if (arg_debug)
218 // using a new child process without root privileges 127 printf("Copying files in the new bin directory\n");
219 fs_logger_print(); // save the current log
220 pid_t child = fork();
221 if (child < 0)
222 errExit("fork");
223 if (child == 0) {
224 if (arg_debug)
225 printf("Copying files in the new home:\n");
226 128
227 // elevate privileges - files in the new /bin directory belong to root 129 // copy the list of files in the new home directory
228 if (setreuid(0, 0) < 0) 130 char *dlist = strdup(private_list);
229 errExit("setreuid"); 131 if (!dlist)
230 if (setregid(0, 0) < 0) 132 errExit("strdup");
231 errExit("setregid");
232
233 // copy the list of files in the new home directory
234 char *dlist = strdup(private_list);
235 if (!dlist)
236 errExit("strdup");
237
238 133
239 char *ptr = strtok(dlist, ","); 134 char *ptr = strtok(dlist, ",");
135 duplicate(ptr);
136 while ((ptr = strtok(NULL, ",")) != NULL)
240 duplicate(ptr); 137 duplicate(ptr);
241 138 free(dlist);
242 while ((ptr = strtok(NULL, ",")) != NULL)
243 duplicate(ptr);
244 free(dlist);
245 fs_logger_print(); 139 fs_logger_print();
246#ifdef HAVE_GCOV
247 __gcov_flush();
248#endif
249 _exit(0);
250 }
251 // wait for the child to finish
252 waitpid(child, NULL, 0);
253 140
254 // mount-bind 141 // mount-bind
255 int i = 0; 142 int i = 0;
@@ -265,29 +152,5 @@ void fs_private_bin_list(void) {
265 } 152 }
266 i++; 153 i++;
267 } 154 }
268
269 // log cloned files
270 char *dlist = strdup(private_list);
271 if (!dlist)
272 errExit("strdup");
273
274
275 char *ptr = strtok(dlist, ",");
276 while (ptr) {
277 i = 0;
278 while (paths[i]) {
279 struct stat s;
280 if (stat(paths[i], &s) == 0) {
281 char *fname;
282 if (asprintf(&fname, "%s/%s", paths[i], ptr) == -1)
283 errExit("asprintf");
284 fs_logger2("clone", fname);
285 free(fname);
286 }
287 i++;
288 }
289 ptr = strtok(NULL, ",");
290 }
291 free(dlist);
292} 155}
293 156
diff --git a/src/firejail/fs_etc.c b/src/firejail/fs_etc.c
index 7e18840fd..80329d5ba 100644
--- a/src/firejail/fs_etc.c
+++ b/src/firejail/fs_etc.c
@@ -21,20 +21,13 @@
21#include <sys/mount.h> 21#include <sys/mount.h>
22#include <sys/stat.h> 22#include <sys/stat.h>
23#include <sys/types.h> 23#include <sys/types.h>
24#include <sys/wait.h>
25#include <unistd.h> 24#include <unistd.h>
26 25
27// return 0 if file not found, 1 if found 26// return 0 if file not found, 1 if found
28static int check_dir_or_file(const char *name) { 27static int check_dir_or_file(const char *fname) {
29 assert(name); 28 assert(fname);
30 invalid_filename(name);
31 29
32 struct stat s; 30 struct stat s;
33 char *fname;
34 if (asprintf(&fname, "/etc/%s", name) == -1)
35 errExit("asprintf");
36 if (arg_debug)
37 printf("Checking %s\n", fname);
38 if (stat(fname, &s) == -1) { 31 if (stat(fname, &s) == -1) {
39 if (arg_debug) 32 if (arg_debug)
40 printf("Warning: file %s not found.\n", fname); 33 printf("Warning: file %s not found.\n", fname);
@@ -46,78 +39,46 @@ static int check_dir_or_file(const char *name) {
46 goto errexit; 39 goto errexit;
47 40
48 // dir or regular file 41 // dir or regular file
49 if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode)) { 42 if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode) || !is_link(fname))
50 free(fname); 43 return 1; // normal exit
51 return 1;
52 }
53
54 if (!is_link(fname)) {
55 free(fname);
56 return 1;
57 }
58
59 44
60errexit: 45errexit:
61 fprintf(stderr, "Error: invalid file type, %s.\n", fname); 46 fprintf(stderr, "Error: invalid file type, %s.\n", fname);
62 exit(1); 47 exit(1);
63} 48}
64 49
65void fs_check_etc_list(void) { 50static void duplicate(char *fname) {
66 EUID_ASSERT(); 51 if (*fname == '~' || *fname == '/' || strstr(fname, "..")) {
67 if (strstr(cfg.etc_private_keep, "..")) { 52 fprintf(stderr, "Error: \"%s\" is an invalid filename\n", fname);
68 fprintf(stderr, "Error: invalid private etc list\n");
69 exit(1); 53 exit(1);
70 } 54 }
71 55 invalid_filename(fname);
72 char *dlist = strdup(cfg.etc_private_keep); 56
73 if (!dlist) 57 char *src;
74 errExit("strdup"); 58 if (asprintf(&src, "/etc/%s", fname) == -1)
75 59 errExit("asprintf");
76 // build a new list only with the files found 60 if (check_dir_or_file(src) == 0) {
77 char *newlist = malloc(strlen(cfg.etc_private_keep) + 1); 61 if (!arg_quiet)
78 if (!newlist) 62 fprintf(stderr, "Warning: skipping %s for private bin\n", fname);
79 errExit("malloc"); 63 free(src);
80 *newlist = '\0'; 64 return;
81
82 char *ptr = strtok(dlist, ",");
83 if (check_dir_or_file(ptr))
84 strcat(newlist, ptr);
85 while ((ptr = strtok(NULL, ",")) != NULL) {
86 if (check_dir_or_file(ptr)) {
87 strcat(newlist, ",");
88 strcat(newlist, ptr);
89 }
90 } 65 }
91 cfg.etc_private_keep = newlist;
92
93 free(dlist);
94}
95 66
96static void duplicate(char *fname) { 67 struct stat s;
97 // copy the file 68 if (stat(src, &s) == 0 && S_ISDIR(s.st_mode)) {
98 if (arg_debug) 69 // create the directory in RUN_ETC_DIR
99 printf("running: %s -a --parents /etc/%s %s\n", RUN_CP_COMMAND, fname, RUN_MNT_DIR); 70 char *dirname;
100 71 if (asprintf(&dirname, "%s/%s", RUN_ETC_DIR, fname) == -1)
101 pid_t child = fork();
102 if (child < 0)
103 errExit("fork");
104 if (child == 0) {
105 char *f;
106 if (asprintf(&f, "/etc/%s", fname) == -1)
107 errExit("asprintf"); 72 errExit("asprintf");
108 clearenv(); 73 create_empty_dir_as_root(dirname, s.st_mode);
109 execlp(RUN_CP_COMMAND, RUN_CP_COMMAND, "-a", "--parents", f, RUN_MNT_DIR, NULL); 74 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, src, dirname);
110 perror("execlp"); 75 free(dirname);
111 _exit(1);
112 } 76 }
113 // wait for the child to finish 77 else
114 waitpid(child, NULL, 0); 78 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, src, RUN_ETC_DIR);
115 79
116 char *name; 80 fs_logger2("clone", src);
117 if (asprintf(&name, "/etc/%s", fname) == -1) 81 free(src);
118 errExit("asprintf");
119 fs_logger2("clone", name);
120 free(name);
121} 82}
122 83
123 84
@@ -125,12 +86,6 @@ void fs_private_etc_list(void) {
125 char *private_list = cfg.etc_private_keep; 86 char *private_list = cfg.etc_private_keep;
126 assert(private_list); 87 assert(private_list);
127 88
128 struct stat s;
129 if (stat("/etc", &s) == -1) {
130 fprintf(stderr, "Error: cannot find user /etc directory\n");
131 exit(1);
132 }
133
134 // create /run/firejail/mnt/etc directory 89 // create /run/firejail/mnt/etc directory
135 mkdir_attr(RUN_ETC_DIR, 0755, 0, 0); 90 mkdir_attr(RUN_ETC_DIR, 0755, 0, 0);
136 fs_logger("tmpfs /etc"); 91 fs_logger("tmpfs /etc");
@@ -141,39 +96,22 @@ void fs_private_etc_list(void) {
141 // copy the list of files in the new etc directory 96 // copy the list of files in the new etc directory
142 // using a new child process with root privileges 97 // using a new child process with root privileges
143 if (*private_list != '\0') { 98 if (*private_list != '\0') {
144 pid_t child = fork(); 99 if (arg_debug)
145 if (child < 0) 100 printf("Copying files in the new etc directory:\n");
146 errExit("fork"); 101
147 if (child == 0) { 102 // copy the list of files in the new home directory
148 if (arg_debug) 103 char *dlist = strdup(private_list);
149 printf("Copying files in the new etc directory:\n"); 104 if (!dlist)
105 errExit("strdup");
150 106
151 // elevate privileges - files in the new /etc directory belong to root 107
152 if (setreuid(0, 0) < 0) 108 char *ptr = strtok(dlist, ",");
153 errExit("setreuid"); 109 duplicate(ptr);
154 if (setregid(0, 0) < 0)
155 errExit("setregid");
156
157 // copy the list of files in the new home directory
158 char *dlist = strdup(private_list);
159 if (!dlist)
160 errExit("strdup");
161
162 110
163 char *ptr = strtok(dlist, ","); 111 while ((ptr = strtok(NULL, ",")) != NULL)
164 duplicate(ptr); 112 duplicate(ptr);
165 113 free(dlist);
166 while ((ptr = strtok(NULL, ",")) != NULL) 114 fs_logger_print();
167 duplicate(ptr);
168 free(dlist);
169 fs_logger_print();
170#ifdef HAVE_GCOV
171 __gcov_flush();
172#endif
173 _exit(0);
174 }
175 // wait for the child to finish
176 waitpid(child, NULL, 0);
177 } 115 }
178 116
179 if (arg_debug) 117 if (arg_debug)
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c
index 242482d26..1f8da398e 100644
--- a/src/firejail/fs_home.c
+++ b/src/firejail/fs_home.c
@@ -28,7 +28,7 @@
28#include <sys/wait.h> 28#include <sys/wait.h>
29#include <unistd.h> 29#include <unistd.h>
30#include <grp.h> 30#include <grp.h>
31#include <ftw.h> 31//#include <ftw.h>
32 32
33static void skel(const char *homedir, uid_t u, gid_t g) { 33static void skel(const char *homedir, uid_t u, gid_t g) {
34 char *fname; 34 char *fname;
@@ -212,12 +212,6 @@ void fs_private_homedir(void) {
212 212
213 uid_t u = getuid(); 213 uid_t u = getuid();
214 gid_t g = getgid(); 214 gid_t g = getgid();
215 struct stat s;
216 if (stat(homedir, &s) == -1) {
217 fprintf(stderr, "Error: cannot find user home directory\n");
218 exit(1);
219 }
220
221 215
222 // mount bind private_homedir on top of homedir 216 // mount bind private_homedir on top of homedir
223 if (arg_debug) 217 if (arg_debug)
@@ -349,122 +343,17 @@ void fs_check_private_dir(void) {
349//*********************************************************************************** 343//***********************************************************************************
350// --private-home 344// --private-home
351//*********************************************************************************** 345//***********************************************************************************
352#define PRIVATE_COPY_LIMIT (500 * 1024 *1024)
353static int size_limit_reached = 0;
354static unsigned file_cnt = 0;
355static unsigned size_cnt = 0;
356static char *check_dir_or_file(const char *name);
357
358int fs_copydir(const char *path, const struct stat *st, int ftype, struct FTW *sftw) {
359 (void) st;
360 (void) sftw;
361 if (size_limit_reached)
362 return 0;
363
364 struct stat s;
365 char *dest;
366 if (asprintf(&dest, "%s%s", RUN_HOME_DIR, path + strlen(cfg.homedir)) == -1)
367 errExit("asprintf");
368
369 // don't copy it if we already have the file
370 if (stat(dest, &s) == 0) {
371 free(dest);
372 return 0;
373 }
374
375 // extract mode and ownership
376 if (stat(path, &s) != 0) {
377 free(dest);
378 return 0;
379 }
380
381 // check uid
382 if (s.st_uid != firejail_uid || s.st_gid != firejail_gid) {
383 free(dest);
384 return 0;
385 }
386
387 if ((s.st_size + size_cnt) > PRIVATE_COPY_LIMIT) {
388 size_limit_reached = 1;
389 free(dest);
390 return 0;
391 }
392
393 file_cnt++;
394 size_cnt += s.st_size;
395
396 if(ftype == FTW_F)
397 copy_file(path, dest, firejail_uid, firejail_gid, s.st_mode);
398 else if (ftype == FTW_D) {
399 if (mkdir(dest, s.st_mode) == -1)
400 errExit("mkdir");
401 if (set_perms(dest, firejail_uid, firejail_gid, s.st_mode))
402 errExit("set_perms");
403#if 0
404struct stat s2;
405if (stat(dest, &s2) == 0) {
406 printf("%s\t", dest);
407 printf((S_ISDIR(s.st_mode)) ? "d" : "-");
408 printf((s.st_mode & S_IRUSR) ? "r" : "-");
409 printf((s.st_mode & S_IWUSR) ? "w" : "-");
410 printf((s.st_mode & S_IXUSR) ? "x" : "-");
411 printf((s.st_mode & S_IRGRP) ? "r" : "-");
412 printf((s.st_mode & S_IWGRP) ? "w" : "-");
413 printf((s.st_mode & S_IXGRP) ? "x" : "-");
414 printf((s.st_mode & S_IROTH) ? "r" : "-");
415 printf((s.st_mode & S_IWOTH) ? "w" : "-");
416 printf((s.st_mode & S_IXOTH) ? "x" : "-");
417 printf("\n");
418}
419#endif
420
421 fs_logger2("clone", path);
422 }
423
424 free(dest);
425 return(0);
426}
427
428static void duplicate(char *name) {
429 char *fname = check_dir_or_file(name);
430
431 if (arg_debug)
432 printf("Private home: duplicating %s\n", fname);
433 assert(strncmp(fname, cfg.homedir, strlen(cfg.homedir)) == 0);
434
435 struct stat s;
436 if (stat(fname, &s) == -1) {
437 free(fname);
438 return;
439 }
440
441 if(nftw(fname, fs_copydir, 1, FTW_PHYS) != 0) {
442 fprintf(stderr, "Error: unable to copy template dir\n");
443 exit(1);
444 }
445 fs_logger_print(); // save the current log
446
447 free(fname);
448}
449
450
451
452static char *check_dir_or_file(const char *name) { 346static char *check_dir_or_file(const char *name) {
453 assert(name); 347 assert(name);
454 struct stat s;
455 348
456 // basic checks 349 // basic checks
457 invalid_filename(name); 350 invalid_filename(name);
458
459 if (arg_debug) 351 if (arg_debug)
460 printf("Private home: checking %s\n", name); 352 printf("Private home: checking %s\n", name);
461 353
462 // expand home directory 354 // expand home directory
463 char *fname = expand_home(name, cfg.homedir); 355 char *fname = expand_home(name, cfg.homedir);
464 if (!fname) { 356 assert(fname);
465 fprintf(stderr, "Error: file %s not found.\n", name);
466 exit(1);
467 }
468 357
469 // If it doesn't start with '/', it must be relative to homedir 358 // If it doesn't start with '/', it must be relative to homedir
470 if (fname[0] != '/') { 359 if (fname[0] != '/') {
@@ -475,87 +364,77 @@ static char *check_dir_or_file(const char *name) {
475 fname = tmp; 364 fname = tmp;
476 } 365 }
477 366
478 // check the file is in user home directory 367 // we allow only files in user home directory or symbolic links to files or directories owned by the user
479 char *rname = realpath(fname, NULL); 368 struct stat s;
480 if (!rname) { 369 if (lstat(fname, &s) == 0 && S_ISLNK(s.st_mode)) {
481 fprintf(stderr, "Error: invalid file %s\n", name); 370 if (stat(fname, &s) == 0) {
482 exit(1); 371 if (s.st_uid != getuid()) {
483 } 372 fprintf(stderr, "Error: symbolic link %s to file or directory not owned by the user\n", fname);
484 if (strncmp(rname, cfg.homedir, strlen(cfg.homedir)) != 0) { 373 exit(1);
485 fprintf(stderr, "Error: file %s is not in user home directory\n", name); 374 }
486 exit(1); 375 return fname;
487 } 376 }
488 377 else {
489 // a full home directory is not allowed 378 fprintf(stderr, "Error: invalid file %s\n", name);
490 if (strcmp(rname, cfg.homedir) == 0) {
491 fprintf(stderr, "Error: invalid directory %s\n", rname);
492 exit(1);
493 }
494
495 // only top files and directories in user home are allowed
496 char *ptr = rname + strlen(cfg.homedir);
497 if (*ptr == '\0') {
498 fprintf(stderr, "Error: invalid file %s\n", name);
499 exit(1);
500 }
501 ptr++;
502 ptr = strchr(ptr, '/');
503 if (ptr) {
504 if (*ptr != '\0') {
505 fprintf(stderr, "Error: only top files and directories in user home are allowed\n");
506 exit(1); 379 exit(1);
507 } 380 }
508 } 381 }
509 382 else {
510 if (stat(fname, &s) == -1) { 383 // check the file is in user home directory, a full home directory is not allowed
511 fprintf(stderr, "Error: file %s not found.\n", fname); 384 char *rname = realpath(fname, NULL);
512 exit(1); 385 if (!rname ||
513 } 386 strncmp(rname, cfg.homedir, strlen(cfg.homedir)) != 0 ||
514 387 strcmp(rname, cfg.homedir) == 0) {
515 // check uid 388 fprintf(stderr, "Error: invalid file %s\n", name);
516 uid_t uid = getuid(); 389 exit(1);
517 gid_t gid = getgid(); 390 }
518 if (s.st_uid != uid || s.st_gid != gid) { 391
519 fprintf(stderr, "Error: only files or directories created by the current user are allowed.\n"); 392 // only top files and directories in user home are allowed
520 exit(1); 393 char *ptr = rname + strlen(cfg.homedir);
521 } 394 assert(*ptr != '\0');
522 395 ptr = strchr(++ptr, '/');
523 // dir or regular file 396 if (ptr) {
524 if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode)) { 397 if (*ptr != '\0') {
398 fprintf(stderr, "Error: only top files and directories in user home are allowed\n");
399 exit(1);
400 }
401 }
525 free(fname); 402 free(fname);
526 return rname; // regular exit from the function 403 return rname;
527 } 404 }
528
529 fprintf(stderr, "Error: invalid file type, %s.\n", fname);
530 exit(1);
531} 405}
532 406
407static void duplicate(char *name) {
408 char *fname = check_dir_or_file(name);
533 409
534// check directory list specified by user (--private-home option) - exit if it fails 410 if (arg_debug)
535void fs_check_home_list(void) { 411 printf("Private home: duplicating %s\n", fname);
536 if (strstr(cfg.home_private_keep, "..")) { 412 assert(strncmp(fname, cfg.homedir, strlen(cfg.homedir)) == 0);
537 fprintf(stderr, "Error: invalid private-home list\n");
538 exit(1);
539 }
540
541 char *dlist = strdup(cfg.home_private_keep);
542 if (!dlist)
543 errExit("strdup");
544
545 char *ptr = strtok(dlist, ",");
546 char *tmp = check_dir_or_file(ptr);
547 free(tmp);
548 413
549 while ((ptr = strtok(NULL, ",")) != NULL) { 414 struct stat s;
550 tmp = check_dir_or_file(ptr); 415 if (lstat(fname, &s) == -1) {
551 free(tmp); 416 free(fname);
417 return;
418 }
419 else if (S_ISDIR(s.st_mode)) {
420 // create the directory in RUN_HOME_DIR
421 char *name;
422 char *ptr = strrchr(fname, '/');
423 ptr++;
424 if (asprintf(&name, "%s/%s", RUN_HOME_DIR, ptr) == -1)
425 errExit("asprintf");
426 mkdir_attr(name, 0755, getuid(), getgid());
427 sbox_run(SBOX_USER| SBOX_CAPS_NONE | SBOX_SECCOMP, 3, PATH_FCOPY, fname, name);
428 free(name);
552 } 429 }
430 else
431 sbox_run(SBOX_USER| SBOX_CAPS_NONE | SBOX_SECCOMP, 3, PATH_FCOPY, fname, RUN_HOME_DIR);
432 fs_logger2("clone", fname);
433 fs_logger_print(); // save the current log
553 434
554 free(dlist); 435 free(fname);
555} 436}
556 437
557
558
559// private mode (--private-home=list): 438// private mode (--private-home=list):
560// mount homedir on top of /home/user, 439// mount homedir on top of /home/user,
561// tmpfs on top of /root in nonroot mode, 440// tmpfs on top of /root in nonroot mode,
@@ -571,68 +450,28 @@ void fs_private_home_list(void) {
571 int xflag = store_xauthority(); 450 int xflag = store_xauthority();
572 int aflag = store_asoundrc(); 451 int aflag = store_asoundrc();
573 452
574 uid_t u = firejail_uid; 453 uid_t uid = getuid();
575 gid_t g = firejail_gid; 454 gid_t gid = getgid();
576 struct stat s;
577 if (stat(homedir, &s) == -1) {
578 fprintf(stderr, "Error: cannot find user home directory\n");
579 exit(1);
580 }
581 455
582 // create /run/firejail/mnt/home directory 456 // create /run/firejail/mnt/home directory
583 int rv = mkdir(RUN_HOME_DIR, 0755); 457 mkdir_attr(RUN_HOME_DIR, 0755, uid, gid);
584 if (rv == -1)
585 errExit("mkdir");
586 if (set_perms(RUN_HOME_DIR, u, g, 0755))
587 errExit("set_perms");
588 ASSERT_PERMS(RUN_HOME_DIR, u, g, 0755);
589
590 fs_logger_print(); // save the current log 458 fs_logger_print(); // save the current log
591 459
460 if (arg_debug)
461 printf("Copying files in the new home:\n");
462
592 // copy the list of files in the new home directory 463 // copy the list of files in the new home directory
593 // using a new child process without root privileges 464 char *dlist = strdup(cfg.home_private_keep);
594 pid_t child = fork(); 465 if (!dlist)
595 if (child < 0) 466 errExit("strdup");
596 errExit("fork"); 467
597 if (child == 0) { 468 char *ptr = strtok(dlist, ",");
598 if (arg_debug) 469 duplicate(ptr);
599 printf("Copying files in the new home:\n"); 470 while ((ptr = strtok(NULL, ",")) != NULL)
600
601 // drop privileges
602 if (setgroups(0, NULL) < 0)
603 errExit("setgroups");
604 if (setgid(getgid()) < 0)
605 errExit("setgid/getgid");
606 if (setuid(getuid()) < 0)
607 errExit("setuid/getuid");
608
609 // copy the list of files in the new home directory
610 char *dlist = strdup(cfg.home_private_keep);
611 if (!dlist)
612 errExit("strdup");
613
614 char *ptr = strtok(dlist, ",");
615 duplicate(ptr); 471 duplicate(ptr);
616 while ((ptr = strtok(NULL, ",")) != NULL)
617 duplicate(ptr);
618
619 if (!arg_quiet) {
620 if (size_limit_reached)
621 fprintf(stderr, "Warning: private-home copy limit of %u MB reached, not all the files were copied\n",
622 PRIVATE_COPY_LIMIT / (1024 *1024));
623 else
624 printf("Private home: %u files, total size %u bytes\n", file_cnt, size_cnt);
625 }
626 472
627 fs_logger_print(); // save the current log 473 fs_logger_print(); // save the current log
628 free(dlist); 474 free(dlist);
629#ifdef HAVE_GCOV
630 __gcov_flush();
631#endif
632 _exit(0);
633 }
634 // wait for the child to finish
635 waitpid(child, NULL, 0);
636 475
637 if (arg_debug) 476 if (arg_debug)
638 printf("Mount-bind %s on top of %s\n", RUN_HOME_DIR, homedir); 477 printf("Mount-bind %s on top of %s\n", RUN_HOME_DIR, homedir);
@@ -640,7 +479,7 @@ void fs_private_home_list(void) {
640 if (mount(RUN_HOME_DIR, homedir, NULL, MS_BIND|MS_REC, NULL) < 0) 479 if (mount(RUN_HOME_DIR, homedir, NULL, MS_BIND|MS_REC, NULL) < 0)
641 errExit("mount bind"); 480 errExit("mount bind");
642 481
643 if (u != 0) { 482 if (uid != 0) {
644 // mask /root 483 // mask /root
645 if (arg_debug) 484 if (arg_debug)
646 printf("Mounting a new /root directory\n"); 485 printf("Mounting a new /root directory\n");
@@ -655,7 +494,7 @@ void fs_private_home_list(void) {
655 errExit("mounting home directory"); 494 errExit("mounting home directory");
656 } 495 }
657 496
658 skel(homedir, u, g); 497 skel(homedir, uid, gid);
659 if (xflag) 498 if (xflag)
660 copy_xauthority(); 499 copy_xauthority();
661 if (aflag) 500 if (aflag)
diff --git a/src/firejail/fs_hostname.c b/src/firejail/fs_hostname.c
index 04197eb8f..dcf06fc6f 100644
--- a/src/firejail/fs_hostname.c
+++ b/src/firejail/fs_hostname.c
@@ -33,15 +33,7 @@ void fs_hostname(const char *hostname) {
33 if (arg_debug) 33 if (arg_debug)
34 printf("Creating a new /etc/hostname file\n"); 34 printf("Creating a new /etc/hostname file\n");
35 35
36 FILE *fp = fopen(RUN_HOSTNAME_FILE, "w"); 36 create_empty_file_as_root(RUN_HOSTNAME_FILE, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH);
37 if (!fp) {
38 fprintf(stderr, "Error: cannot create %s\n", RUN_HOSTNAME_FILE);
39 exit(1);
40 }
41 fprintf(fp, "%s\n", hostname);
42 // mode and owner
43 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH);
44 fclose(fp);
45 37
46 // bind-mount the file on top of /etc/hostname 38 // bind-mount the file on top of /etc/hostname
47 if (mount(RUN_HOSTNAME_FILE, "/etc/hostname", NULL, MS_BIND|MS_REC, NULL) < 0) 39 if (mount(RUN_HOSTNAME_FILE, "/etc/hostname", NULL, MS_BIND|MS_REC, NULL) < 0)
@@ -56,15 +48,12 @@ void fs_hostname(const char *hostname) {
56 // copy /etc/host into our new file, and modify it on the fly 48 // copy /etc/host into our new file, and modify it on the fly
57 /* coverity[toctou] */ 49 /* coverity[toctou] */
58 FILE *fp1 = fopen("/etc/hosts", "r"); 50 FILE *fp1 = fopen("/etc/hosts", "r");
59 if (!fp1) { 51 if (!fp1)
60 fprintf(stderr, "Error: cannot open /etc/hosts\n"); 52 goto errexit;
61 exit(1); 53
62 }
63 FILE *fp2 = fopen(RUN_HOSTS_FILE, "w"); 54 FILE *fp2 = fopen(RUN_HOSTS_FILE, "w");
64 if (!fp2) { 55 if (!fp2)
65 fprintf(stderr, "Error: cannot create %s\n", RUN_HOSTS_FILE); 56 goto errexit;
66 exit(1);
67 }
68 57
69 char buf[4096]; 58 char buf[4096];
70 int done = 0; 59 int done = 0;
@@ -92,6 +81,11 @@ void fs_hostname(const char *hostname) {
92 errExit("mount bind /etc/hosts"); 81 errExit("mount bind /etc/hosts");
93 fs_logger("create /etc/hosts"); 82 fs_logger("create /etc/hosts");
94 } 83 }
84 return;
85
86errexit:
87 fprintf(stderr, "Error: cannot create hostname file\n");
88 exit(1);
95} 89}
96 90
97void fs_resolvconf(void) { 91void fs_resolvconf(void) {
diff --git a/src/firejail/main.c b/src/firejail/main.c
index ec0c31285..ff7b762cd 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -1601,7 +1601,6 @@ int main(int argc, char **argv) {
1601 1601
1602 // extract private home dirname 1602 // extract private home dirname
1603 cfg.home_private_keep = argv[i] + 15; 1603 cfg.home_private_keep = argv[i] + 15;
1604 fs_check_home_list();
1605 arg_private = 1; 1604 arg_private = 1;
1606 } 1605 }
1607 else { 1606 else {
@@ -1625,7 +1624,6 @@ int main(int argc, char **argv) {
1625 fprintf(stderr, "Error: invalid private-etc option\n"); 1624 fprintf(stderr, "Error: invalid private-etc option\n");
1626 exit(1); 1625 exit(1);
1627 } 1626 }
1628 fs_check_etc_list();
1629 arg_private_etc = 1; 1627 arg_private_etc = 1;
1630 } 1628 }
1631 else if (strncmp(argv[i], "--private-bin=", 14) == 0) { 1629 else if (strncmp(argv[i], "--private-bin=", 14) == 0) {
@@ -1636,7 +1634,6 @@ int main(int argc, char **argv) {
1636 exit(1); 1634 exit(1);
1637 } 1635 }
1638 arg_private_bin = 1; 1636 arg_private_bin = 1;
1639 fs_check_bin_list();
1640 } 1637 }
1641 else if (strcmp(argv[i], "--private-tmp") == 0) { 1638 else if (strcmp(argv[i], "--private-tmp") == 0) {
1642 arg_private_tmp = 1; 1639 arg_private_tmp = 1;
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 0fd45d1ef..688fa9609 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -173,7 +173,6 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
173#ifdef HAVE_PRIVATE_HOME 173#ifdef HAVE_PRIVATE_HOME
174 if (checkcfg(CFG_PRIVATE_HOME)) { 174 if (checkcfg(CFG_PRIVATE_HOME)) {
175 cfg.home_private_keep = ptr + 13; 175 cfg.home_private_keep = ptr + 13;
176 fs_check_home_list();
177 arg_private = 1; 176 arg_private = 1;
178 } 177 }
179 else 178 else
@@ -737,7 +736,6 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
737 exit(1); 736 exit(1);
738 } 737 }
739 cfg.etc_private_keep = ptr + 12; 738 cfg.etc_private_keep = ptr + 12;
740 fs_check_etc_list();
741 arg_private_etc = 1; 739 arg_private_etc = 1;
742 740
743 return 0; 741 return 0;
@@ -747,7 +745,6 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
747 if (strncmp(ptr, "private-bin ", 12) == 0) { 745 if (strncmp(ptr, "private-bin ", 12) == 0) {
748 cfg.bin_private_keep = ptr + 12; 746 cfg.bin_private_keep = ptr + 12;
749 arg_private_bin = 1; 747 arg_private_bin = 1;
750 fs_check_bin_list();
751 return 0; 748 return 0;
752 } 749 }
753 750
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 109daf552..c2e053b0c 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -696,7 +696,6 @@ int sandbox(void* sandbox_arg) {
696 if (asprintf(&tmp, "%s,xauth", cfg.bin_private_keep) == -1) 696 if (asprintf(&tmp, "%s,xauth", cfg.bin_private_keep) == -1)
697 errExit("asprintf"); 697 errExit("asprintf");
698 cfg.bin_private_keep = tmp; 698 cfg.bin_private_keep = tmp;
699 fs_check_bin_list();
700 EUID_ROOT(); 699 EUID_ROOT();
701 } 700 }
702 fs_private_bin_list(); 701 fs_private_bin_list();
diff --git a/src/firejail/util.c b/src/firejail/util.c
index d928c6b42..03f52fabb 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -206,6 +206,7 @@ int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, m
206 done += rv; 206 done += rv;
207 } 207 }
208 } 208 }
209 fflush(0);
209 210
210 if (fchown(dst, uid, gid) == -1) 211 if (fchown(dst, uid, gid) == -1)
211 errExit("fchown"); 212 errExit("fchown");
@@ -561,7 +562,10 @@ char *expand_home(const char *path, const char* homedir) {
561 return new_name; 562 return new_name;
562 } 563 }
563 564
564 return strdup(path); 565 char *rv = strdup(path);
566 if (!rv)
567 errExit("strdup");
568 return rv;
565} 569}
566 570
567 571
@@ -624,7 +628,7 @@ uid_t pid_get_uid(pid_t pid) {
624 628
625 629
626void invalid_filename(const char *fname) { 630void invalid_filename(const char *fname) {
627 EUID_ASSERT(); 631// EUID_ASSERT();
628 assert(fname); 632 assert(fname);
629 const char *ptr = fname; 633 const char *ptr = fname;
630 634
@@ -690,6 +694,7 @@ void flush_stdin(void) {
690 694
691void create_empty_dir_as_root(const char *dir, mode_t mode) { 695void create_empty_dir_as_root(const char *dir, mode_t mode) {
692 assert(dir); 696 assert(dir);
697 mode &= 07777;
693 struct stat s; 698 struct stat s;
694 699
695 if (stat(dir, &s)) { 700 if (stat(dir, &s)) {
@@ -705,6 +710,7 @@ void create_empty_dir_as_root(const char *dir, mode_t mode) {
705 710
706void create_empty_file_as_root(const char *fname, mode_t mode) { 711void create_empty_file_as_root(const char *fname, mode_t mode) {
707 assert(fname); 712 assert(fname);
713 mode &= 07777;
708 struct stat s; 714 struct stat s;
709 715
710 if (stat(fname, &s)) { 716 if (stat(fname, &s)) {
diff --git a/src/firemon/caps.c b/src/firemon/caps.c
index 81877ab87..3f8a139ae 100644
--- a/src/firemon/caps.c
+++ b/src/firemon/caps.c
@@ -24,7 +24,6 @@ static void print_caps(int pid) {
24 char *file; 24 char *file;
25 if (asprintf(&file, "/proc/%d/status", pid) == -1) { 25 if (asprintf(&file, "/proc/%d/status", pid) == -1) {
26 errExit("asprintf"); 26 errExit("asprintf");
27 exit(1);
28 } 27 }
29 28
30 FILE *fp = fopen(file, "r"); 29 FILE *fp = fopen(file, "r");
diff --git a/src/firemon/netstats.c b/src/firemon/netstats.c
index 3c020d630..534d783cb 100644
--- a/src/firemon/netstats.c
+++ b/src/firemon/netstats.c
@@ -216,6 +216,9 @@ void netstats(void) {
216 print_proc(i, itv, col); 216 print_proc(i, itv, col);
217 } 217 }
218 } 218 }
219#ifdef HAVE_GCOV
220 __gcov_flush();
221#endif
219 } 222 }
220} 223}
221 224
diff --git a/src/firemon/procevent.c b/src/firemon/procevent.c
index 1940f4a34..edae21951 100644
--- a/src/firemon/procevent.c
+++ b/src/firemon/procevent.c
@@ -43,10 +43,8 @@ static int pid_is_firejail(pid_t pid) {
43 43
44 // open /proc/self/comm 44 // open /proc/self/comm
45 char *file; 45 char *file;
46 if (asprintf(&file, "/proc/%u/comm", pid) == -1) { 46 if (asprintf(&file, "/proc/%u/comm", pid) == -1)
47 perror("asprintf"); 47 errExit("asprintf");
48 exit(1);
49 }
50 48
51 FILE *fp = fopen(file, "r"); 49 FILE *fp = fopen(file, "r");
52 if (!fp) { 50 if (!fp) {
diff --git a/src/firemon/seccomp.c b/src/firemon/seccomp.c
index abc698bb8..f11c624ea 100644
--- a/src/firemon/seccomp.c
+++ b/src/firemon/seccomp.c
@@ -22,10 +22,8 @@
22#define MAXBUF 4098 22#define MAXBUF 4098
23static void print_seccomp(int pid) { 23static void print_seccomp(int pid) {
24 char *file; 24 char *file;
25 if (asprintf(&file, "/proc/%d/status", pid) == -1) { 25 if (asprintf(&file, "/proc/%d/status", pid) == -1)
26 errExit("asprintf"); 26 errExit("asprintf");
27 exit(1);
28 }
29 27
30 FILE *fp = fopen(file, "r"); 28 FILE *fp = fopen(file, "r");
31 if (!fp) { 29 if (!fp) {
diff --git a/src/firemon/top.c b/src/firemon/top.c
index b804761dd..94271523c 100644
--- a/src/firemon/top.c
+++ b/src/firemon/top.c
@@ -292,6 +292,9 @@ void top(void) {
292 } 292 }
293 } 293 }
294 head_print(col, row); 294 head_print(col, row);
295#ifdef HAVE_GCOV
296 __gcov_flush();
297#endif
295 } 298 }
296} 299}
297 300
diff --git a/src/fnet/main.c b/src/fnet/main.c
index 4ae9eb6e3..4e7807d07 100644
--- a/src/fnet/main.c
+++ b/src/fnet/main.c
@@ -42,10 +42,10 @@ for (i = 0; i < argc; i++)
42printf("\n"); 42printf("\n");
43} 43}
44#endif 44#endif
45 if (argc < 2) 45 if (argc < 2) {
46 usage();
46 return 1; 47 return 1;
47 48 }
48
49 49
50 if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") ==0) { 50 if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") ==0) {
51 usage(); 51 usage();
diff --git a/src/fseccomp/main.c b/src/fseccomp/main.c
index 39e72fdf9..2f85a786b 100644
--- a/src/fseccomp/main.c
+++ b/src/fseccomp/main.c
@@ -47,8 +47,10 @@ for (i = 0; i < argc; i++)
47printf("\n"); 47printf("\n");
48} 48}
49#endif 49#endif
50 if (argc < 2) 50 if (argc < 2) {
51 usage();
51 return 1; 52 return 1;
53 }
52 54
53 if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") ==0) { 55 if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") ==0) {
54 usage(); 56 usage();
diff --git a/src/ftee/main.c b/src/ftee/main.c
index e6aa5f567..2b27baa5a 100644
--- a/src/ftee/main.c
+++ b/src/ftee/main.c
@@ -179,10 +179,6 @@ static int is_link(const char *fname) {
179 return 0; 179 return 0;
180} 180}
181 181
182
183
184
185
186static void usage(void) { 182static void usage(void) {
187 printf("Usage: ftee filename\n"); 183 printf("Usage: ftee filename\n");
188} 184}
@@ -201,33 +197,25 @@ int main(int argc, char **argv) {
201 197
202 198
203 // do not accept directories, links, and files with ".." 199 // do not accept directories, links, and files with ".."
204 if (strstr(fname, "..") || is_link(fname) || is_dir(fname)) { 200 if (strstr(fname, "..") || is_link(fname) || is_dir(fname))
205 fprintf(stderr, "Error: invalid output file. Links, directories and files with \"..\" are not allowed.\n"); 201 goto errexit;
206 exit(1);
207 }
208 202
209 struct stat s; 203 struct stat s;
210 if (stat(fname, &s) == 0) { 204 if (stat(fname, &s) == 0) {
211 // check permissions 205 // check permissions
212 if (s.st_uid != getuid() || s.st_gid != getgid()) { 206 if (s.st_uid != getuid() || s.st_gid != getgid())
213 fprintf(stderr, "Error: the output file needs to be owned by the current user.\n"); 207 goto errexit;
214 exit(1);
215 }
216 208
217 // check hard links 209 // check hard links
218 if (s.st_nlink != 1) { 210 if (s.st_nlink != 1)
219 fprintf(stderr, "Error: no hard links allowed.\n"); 211 goto errexit;
220 exit(1);
221 }
222 } 212 }
223 213
224 // check if we can append to this file 214 // check if we can append to this file
225 /* coverity[toctou] */ 215 /* coverity[toctou] */
226 FILE *fp = fopen(fname, "a"); 216 FILE *fp = fopen(fname, "a");
227 if (!fp) { 217 if (!fp)
228 fprintf(stderr, "Error: cannot open output file %s\n", fname); 218 goto errexit;
229 exit(1);
230 }
231 fclose(fp); 219 fclose(fp);
232 220
233 221
@@ -248,4 +236,8 @@ int main(int argc, char **argv) {
248 236
249 log_close(); 237 log_close();
250 return 0; 238 return 0;
239
240errexit:
241 fprintf(stderr, "Error ftee: invalid output file.\n");
242 return 1;
251} 243}
diff --git a/test/appimage/appimage-v1.exp b/test/appimage/appimage-v1.exp
index 503da2b9b..f1c1c10f5 100755
--- a/test/appimage/appimage-v1.exp
+++ b/test/appimage/appimage-v1.exp
@@ -7,7 +7,7 @@ set timeout 10
7spawn $env(SHELL) 7spawn $env(SHELL)
8match_max 100000 8match_max 100000
9 9
10send -- "firejail --name=appimage-test --appimage Leafpad-0.8.17-x86_64.AppImage\r" 10send -- "firejail --name=appimage-test --debug --appimage Leafpad-0.8.17-x86_64.AppImage\r"
11expect { 11expect {
12 timeout {puts "TESTING ERROR 1\n";exit} 12 timeout {puts "TESTING ERROR 1\n";exit}
13 "Child process initialized" 13 "Child process initialized"
diff --git a/test/appimage/appimage.sh b/test/appimage/appimage.sh
index 6a73d0a7e..db221ec8a 100755
--- a/test/appimage/appimage.sh
+++ b/test/appimage/appimage.sh
@@ -10,5 +10,7 @@ echo "TESTING: AppImage v1 (test/appimage/appimage-v1.exp)"
10./appimage-v1.exp 10./appimage-v1.exp
11 11
12echo "TESTING: AppImage v2 (test/appimage/appimage-v2.exp)" 12echo "TESTING: AppImage v2 (test/appimage/appimage-v2.exp)"
13./appimage-v1.exp 13./appimage-v2.exp
14 14
15echo "TESTING: AppImage file name (test/appimage/filename.exp)";
16./filename.exp \ No newline at end of file
diff --git a/test/appimage/filename.exp b/test/appimage/filename.exp
new file mode 100755
index 000000000..ce8d70464
--- /dev/null
+++ b/test/appimage/filename.exp
@@ -0,0 +1,35 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --appimage \"bla;bla\"\r"
11expect {
12 timeout {puts "TESTING ERROR 1\n";exit}
13 "is an invalid filename"
14}
15after 100
16
17send -- "firejail --appimage /etc/shadow\r"
18expect {
19 timeout {puts "TESTING ERROR 2\n";exit}
20 "cannot access"
21}
22after 100
23
24send -- "firejail --appimage appimage.sh\r"
25expect {
26 timeout {puts "TESTING ERROR 2\n";exit}
27 "Error mounting appimage"
28}
29after 100
30
31
32
33
34puts "\nall done\n"
35
diff --git a/test/chroot-resolvconf.exp b/test/chroot/chroot-resolvconf.exp
index 2d0da2fb0..2d0da2fb0 100755
--- a/test/chroot-resolvconf.exp
+++ b/test/chroot/chroot-resolvconf.exp
diff --git a/test/fs_chroot.exp b/test/chroot/fs_chroot.exp
index aeb5669e1..aeb5669e1 100755
--- a/test/fs_chroot.exp
+++ b/test/chroot/fs_chroot.exp
diff --git a/test/environment/dns.exp b/test/environment/dns.exp
index 6ffb124cf..a6a7171eb 100755
--- a/test/environment/dns.exp
+++ b/test/environment/dns.exp
@@ -22,9 +22,33 @@ expect {
22 timeout {puts "TESTING ERROR 1.2\n";exit} 22 timeout {puts "TESTING ERROR 1.2\n";exit}
23 "53" 23 "53"
24} 24}
25
26after 100 25after 100
27 26
28send -- "rm index.html\r" 27send -- "rm index.html\r"
29after 100 28after 100
29send -- "exit\r"
30sleep 1
31
32send -- "firejail --dns=8.8.4.4 --dns=8.8.8.8 --dns=4.2.2.1\r"
33expect {
34 timeout {puts "TESTING ERROR 2.1\n";exit}
35 "Child process initialized"
36}
37sleep 1
38
39send -- "cat /etc/resolv.conf\r"
40expect {
41 timeout {puts "TESTING ERROR 2.2\n";exit}
42 "nameserver 8.8.4.4"
43}
44expect {
45 timeout {puts "TESTING ERROR 2.3\n";exit}
46 "nameserver 8.8.8.8"
47}
48expect {
49 timeout {puts "TESTING ERROR 2.4\n";exit}
50 "nameserver 4.2.2.1"
51}
52after 100
53
30puts "\nall done\n" 54puts "\nall done\n"
diff --git a/test/environment/environment.sh b/test/environment/environment.sh
index 5c4d49331..2bb5a249e 100755
--- a/test/environment/environment.sh
+++ b/test/environment/environment.sh
@@ -6,6 +6,7 @@
6export MALLOC_CHECK_=3 6export MALLOC_CHECK_=3
7export MALLOC_PERTURB_=$(($RANDOM % 255 + 1)) 7export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
8 8
9
9echo "TESTING: DNS (test/environment/dns.exp)" 10echo "TESTING: DNS (test/environment/dns.exp)"
10./dns.exp 11./dns.exp
11 12
@@ -85,3 +86,28 @@ else
85 echo "TESTING SKIP: strace not found" 86 echo "TESTING SKIP: strace not found"
86fi 87fi
87 88
89# to install ibus:
90# $ sudo apt-get install ibus-table-array30
91# $ ibus-setup
92
93find ~/.config/ibus/bus | grep unix-0
94if [ "$?" -eq 0 ];
95then
96 echo "TESTING: ibus (test/environment/ibus.exp)"
97 ./ibus.exp
98else
99 echo "TESTING SKIP: ibus not configured"
100fi
101
102echo "TESTING: rlimit (test/rlimit/rlimit.exp)"
103./rlimit.exp
104
105echo "TESTING: rlimit profile (test/rlimit/rlimit-profile.exp)"
106./rlimit-profile.exp
107
108echo "TESTING: rlimit errors (test/rlimit/rlimit-bad.exp)"
109./rlimit-bad.exp
110
111echo "TESTING: rlimit errors profile (test/rlimit/rlimit-bad-profile.exp)"
112./rlimit-bad-profile.exp
113
diff --git a/test/environment/ibus.exp b/test/environment/ibus.exp
new file mode 100755
index 000000000..4344011a6
--- /dev/null
+++ b/test/environment/ibus.exp
@@ -0,0 +1,28 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4cd /home
5spawn $env(SHELL)
6match_max 100000
7
8send -- "firejail\r"
9expect {
10 timeout {puts "TESTING ERROR 0\n";exit}
11 "Child process initialized"
12}
13after 100
14
15send -- "env | grep IBUS\r"
16expect {
17 timeout {puts "TESTING ERROR 1\n";exit}
18 "IBUS_ADDRESS"
19}
20expect {
21 timeout {puts "TESTING ERROR 2\n";exit}
22 "IBUS_DAEMON_PID"
23}
24after 100
25
26
27puts "\nall done\n"
28
diff --git a/test/environment/rlimit-bad-profile.exp b/test/environment/rlimit-bad-profile.exp
new file mode 100755
index 000000000..80693a4a0
--- /dev/null
+++ b/test/environment/rlimit-bad-profile.exp
@@ -0,0 +1,35 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7
8send -- "firejail --profile=rlimit-bad1.profile\r"
9expect {
10 timeout {puts "TESTING ERROR 4\n";exit}
11 "Invalid rlimit option"
12}
13after 100
14
15send -- "firejail --profile=rlimit-bad2.profile\r"
16expect {
17 timeout {puts "TESTING ERROR 5\n";exit}
18 "Invalid rlimit option"
19}
20after 100
21
22send -- "firejail --profile=rlimit-bad3.profile\r"
23expect {
24 timeout {puts "TESTING ERROR 6\n";exit}
25 "Invalid rlimit option"
26}
27after 100
28send -- "firejail --profile=rlimit-bad4.profile\r"
29expect {
30 timeout {puts "TESTING ERROR 7\n";exit}
31 "Invalid rlimit option"
32}
33after 100
34
35puts "\nall done\n"
diff --git a/test/environment/rlimit-bad.exp b/test/environment/rlimit-bad.exp
new file mode 100755
index 000000000..574e7e174
--- /dev/null
+++ b/test/environment/rlimit-bad.exp
@@ -0,0 +1,34 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "firejail --rlimit-fsize=-1024\r"
8expect {
9 timeout {puts "TESTING ERROR 0\n";exit}
10 "invalid rlimt fsize"
11}
12after 100
13
14send -- "firejail --rlimit-nofile=asdf\r"
15expect {
16 timeout {puts "TESTING ERROR 1\n";exit}
17 "invalid rlimt nofile"
18}
19after 100
20
21send -- "firejail --rlimit-nproc=100.23\r"
22expect {
23 timeout {puts "TESTING ERROR 2\n";exit}
24 "invalid rlimt nproc"
25}
26after 100
27send -- "firejail --rlimit-sigpending=2345-78\r"
28expect {
29 timeout {puts "TESTING ERROR 3\n";exit}
30 "invalid rlimt sigpending"
31}
32after 100
33
34puts "\nall done\n"
diff --git a/test/environment/rlimit-bad1.profile b/test/environment/rlimit-bad1.profile
new file mode 100644
index 000000000..b6d3340d8
--- /dev/null
+++ b/test/environment/rlimit-bad1.profile
@@ -0,0 +1 @@
rlimit-fsize -1024
diff --git a/test/environment/rlimit-bad2.profile b/test/environment/rlimit-bad2.profile
new file mode 100644
index 000000000..ef3f243c6
--- /dev/null
+++ b/test/environment/rlimit-bad2.profile
@@ -0,0 +1 @@
rlimit-nofile asdf
diff --git a/test/environment/rlimit-bad3.profile b/test/environment/rlimit-bad3.profile
new file mode 100644
index 000000000..af016a29f
--- /dev/null
+++ b/test/environment/rlimit-bad3.profile
@@ -0,0 +1 @@
rlimit-nproc 100.23
diff --git a/test/environment/rlimit-bad4.profile b/test/environment/rlimit-bad4.profile
new file mode 100644
index 000000000..aabe3d008
--- /dev/null
+++ b/test/environment/rlimit-bad4.profile
@@ -0,0 +1 @@
rlimit-sigpending 67asd56 \ No newline at end of file
diff --git a/test/rlimit/rlimit-profile.exp b/test/environment/rlimit-profile.exp
index a9e54a405..a9e54a405 100755
--- a/test/rlimit/rlimit-profile.exp
+++ b/test/environment/rlimit-profile.exp
diff --git a/test/rlimit/rlimit.exp b/test/environment/rlimit.exp
index 611f69821..611f69821 100755
--- a/test/rlimit/rlimit.exp
+++ b/test/environment/rlimit.exp
diff --git a/test/rlimit/rlimit.profile b/test/environment/rlimit.profile
index 271891c03..271891c03 100644
--- a/test/rlimit/rlimit.profile
+++ b/test/environment/rlimit.profile
diff --git a/test/fcopy/cmdline.exp b/test/fcopy/cmdline.exp
new file mode 100755
index 000000000..24bb19351
--- /dev/null
+++ b/test/fcopy/cmdline.exp
@@ -0,0 +1,46 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "/usr/lib/firejail/fcopy\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "files missing"
14}
15expect {
16 timeout {puts "TESTING ERROR 1\n";exit}
17 "Usage:"
18}
19after 100
20
21send -- "/usr/lib/firejail/fcopy foo\r"
22expect {
23 timeout {puts "TESTING ERROR 2\n";exit}
24 "files missing"
25}
26expect {
27 timeout {puts "TESTING ERROR 3\n";exit}
28 "Usage:"
29}
30after 100
31
32send -- "/usr/lib/firejail/fcopy f%oo1 foo2\r"
33expect {
34 timeout {puts "TESTING ERROR 4\n";exit}
35 "invalid file name"
36}
37after 100
38
39send -- "/usr/lib/firejail/fcopy foo1 f,oo2\r"
40expect {
41 timeout {puts "TESTING ERROR 5\n";exit}
42 "invalid file name"
43}
44after 100
45
46puts "\nall done\n"
diff --git a/test/fcopy/dircopy.exp b/test/fcopy/dircopy.exp
new file mode 100755
index 000000000..00b0204ae
--- /dev/null
+++ b/test/fcopy/dircopy.exp
@@ -0,0 +1,106 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6#
7# copy directory src to dest
8#
9set timeout 10
10spawn $env(SHELL)
11match_max 100000
12
13send -- "rm -fr dest/*\r"
14after 100
15
16send -- "/usr/lib/firejail/fcopy src dest\r"
17after 100
18
19send -- "find dest\r"
20expect {
21 timeout {puts "TESTING ERROR 0\n";exit}
22 "dest/"
23}
24expect {
25 timeout {puts "TESTING ERROR 1\n";exit}
26 "dest/a"
27}
28expect {
29 timeout {puts "TESTING ERROR 2\n";exit}
30 "dest/a/b"
31}
32expect {
33 timeout {puts "TESTING ERROR 3\n";exit}
34 "dest/a/b/file4"
35}
36expect {
37 timeout {puts "TESTING ERROR 4\n";exit}
38 "dest/a/file3"
39}
40expect {
41 timeout {puts "TESTING ERROR 5\n";exit}
42 "dest/dircopy.exp"
43}
44expect {
45 timeout {puts "TESTING ERROR 6\n";exit}
46 "dest/file2"
47}
48expect {
49 timeout {puts "TESTING ERROR 7\n";exit}
50 "dest/file1"
51}
52after 100
53
54
55send -- "ls -al dest\r"
56expect {
57 timeout {puts "TESTING ERROR 8\n";exit}
58 "drwxr-xr-x"
59}
60expect {
61 timeout {puts "TESTING ERROR 9\n";exit}
62 "a"
63}
64expect {
65 timeout {puts "TESTING ERROR 10\n";exit}
66 "lrwxrwxrwx"
67}
68expect {
69 timeout {puts "TESTING ERROR 11\n";exit}
70 "dircopy.exp"
71}
72expect {
73 timeout {puts "TESTING ERROR 12\n";exit}
74 "rwxr-xr-x"
75}
76expect {
77 timeout {puts "TESTING ERROR 13\n";exit}
78 "file1"
79}
80expect {
81 timeout {puts "TESTING ERROR 14\n";exit}
82 "rw-r--r--"
83}
84expect {
85 timeout {puts "TESTING ERROR 15\n";exit}
86 "file2"
87}
88after 100
89
90send -- "diff -q src/a/b/file4 dest/a/b/file4; echo done\r"
91expect {
92 timeout {puts "TESTING ERROR 16\n";exit}
93 "differ" {puts "TESTING ERROR 17\n";exit}
94 "done"
95}
96
97send -- "file dest/dircopy.exp\r"
98expect {
99 timeout {puts "TESTING ERROR 18\n";exit}
100 "symbolic link"
101}
102
103send -- "rm -fr dest/*\r"
104after 100
105
106puts "\nall done\n"
diff --git a/test/fcopy/fcopy.sh b/test/fcopy/fcopy.sh
new file mode 100755
index 000000000..dcda5ca31
--- /dev/null
+++ b/test/fcopy/fcopy.sh
@@ -0,0 +1,23 @@
1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6export MALLOC_CHECK_=3
7export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
8
9mkdir dest
10
11echo "TESTING: fcopy cmdline (test/fcopy/cmdline.exp)"
12./cmdline.exp
13
14echo "TESTING: fcopy directory (test/fcopy/dircopy.exp)"
15./dircopy.exp
16
17echo "TESTING: fcopy file (test/fcopy/filecopy.exp)"
18./filecopy.exp
19
20echo "TESTING: fcopy link (test/fcopy/linkcopy.exp)"
21./linkcopy.exp
22
23rm -fr dest/*
diff --git a/test/fcopy/filecopy.exp b/test/fcopy/filecopy.exp
new file mode 100755
index 000000000..d1f0a4424
--- /dev/null
+++ b/test/fcopy/filecopy.exp
@@ -0,0 +1,54 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6#
7# copy directory src to dest
8#
9set timeout 10
10spawn $env(SHELL)
11match_max 100000
12
13send -- "rm -fr dest/*\r"
14after 100
15
16send -- "/usr/lib/firejail/fcopy dircopy.exp dest\r"
17after 100
18
19send -- "find dest\r"
20expect {
21 timeout {puts "TESTING ERROR 0\n";exit}
22 "dest/"
23}
24expect {
25 timeout {puts "TESTING ERROR 1\n";exit}
26 "dest/dircopy.exp"
27}
28after 100
29
30
31send -- "ls -al dest\r"
32expect {
33 timeout {puts "TESTING ERROR 2\n";exit}
34 "rwxr-xr-x"
35}
36after 100
37
38send -- "diff -q dircopy.exp dest/dircopy.exp; echo done\r"
39expect {
40 timeout {puts "TESTING ERROR 3\n";exit}
41 "differ" {puts "TESTING ERROR 4\n";exit}
42 "done"
43}
44
45send -- "file dest/dircopy.exp\r"
46expect {
47 timeout {puts "TESTING ERROR 5\n";exit}
48 "ASCII text"
49}
50
51send -- "rm -fr dest/*\r"
52after 100
53
54puts "\nall done\n"
diff --git a/test/fcopy/linkcopy.exp b/test/fcopy/linkcopy.exp
new file mode 100755
index 000000000..9927e18fe
--- /dev/null
+++ b/test/fcopy/linkcopy.exp
@@ -0,0 +1,54 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6#
7# copy directory src to dest
8#
9set timeout 10
10spawn $env(SHELL)
11match_max 100000
12
13send -- "rm -fr dest/*\r"
14after 100
15
16send -- "/usr/lib/firejail/fcopy src/dircopy.exp dest\r"
17after 100
18
19send -- "find dest\r"
20expect {
21 timeout {puts "TESTING ERROR 0\n";exit}
22 "dest/"
23}
24expect {
25 timeout {puts "TESTING ERROR 1\n";exit}
26 "dest/dircopy.exp"
27}
28after 100
29
30
31send -- "ls -al dest\r"
32expect {
33 timeout {puts "TESTING ERROR 2\n";exit}
34 "lrwxrwxrwx"
35}
36after 100
37
38send -- "diff -q dircopy.exp dest/dircopy.exp; echo done\r"
39expect {
40 timeout {puts "TESTING ERROR 3\n";exit}
41 "differ" {puts "TESTING ERROR 4\n";exit}
42 "done"
43}
44
45send -- "file dest/dircopy.exp\r"
46expect {
47 timeout {puts "TESTING ERROR 5\n";exit}
48 "symbolic link"
49}
50
51send -- "rm -fr dest/*\r"
52after 100
53
54puts "\nall done\n"
diff --git a/test/fcopy/src/a/b/file4 b/test/fcopy/src/a/b/file4
new file mode 100644
index 000000000..ac318d7ab
--- /dev/null
+++ b/test/fcopy/src/a/b/file4
@@ -0,0 +1,11 @@
1
2
3Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam interdum at massa non aliquam. Maecenas molestie id orci volutpat porta. Praesent aliquam nunc quis mi tristique, ac feugiat enim rutrum. Nulla vitae metus sodales, pellentesque risus sit amet, volutpat nisl. Curabitur accumsan arcu congue lacus porta laoreet. Nulla facilisi. Integer nec augue id magna gravida tincidunt id vitae lorem. Curabitur facilisis, tellus vel pellentesque pretium, odio dolor efficitur lorem, et tincidunt dui enim cursus lacus. Cras a orci ac magna semper dapibus nec et velit. Nullam aliquam sollicitudin auctor.
4
5Mauris ac quam vel purus volutpat semper eget a ante. Curabitur arcu nisl, dapibus ac lectus ac, porttitor fermentum metus. Aliquam et sem aliquam magna interdum ultricies at eu orci. Aenean tortor augue, volutpat nec magna nec, rutrum bibendum justo. Vivamus ex quam, auctor ut pellentesque mattis, aliquet a eros. Etiam ac lacus ac ante ullamcorper sollicitudin a quis orci. Suspendisse quis justo ac mauris cursus finibus quis at elit. Vestibulum elementum finibus diam, eget convallis purus aliquet et. Fusce fermentum ornare urna, non ornare nisl tincidunt consectetur. Donec et lacus vitae ex eleifend porttitor id ut odio. Quisque luctus eget lorem et sollicitudin.
6
7Aliquam libero elit, finibus a nisl a, commodo viverra turpis. Nam pulvinar in est sit amet fermentum. Praesent scelerisque tempus lectus, ac porta elit sodales rutrum. Duis faucibus faucibus urna eget accumsan. Vivamus in turpis ut massa rhoncus pretium nec et lorem. Aenean at tellus eget metus porta ornare. Aliquam erat volutpat. Donec hendrerit a massa vel malesuada. Integer varius sapien et orci viverra pretium. In at velit aliquet, vulputate nisi lobortis, aliquam augue.
8
9Ut aliquam turpis ut lorem aliquam, in faucibus elit pulvinar. Vivamus viverra tortor ornare, lacinia leo sit amet, auctor arcu. Sed erat leo, pellentesque vel nibh a, malesuada vehicula purus. Vivamus est dolor, aliquet quis facilisis fermentum, varius in dolor. Nunc quis libero feugiat, imperdiet est vitae, mollis risus. Vestibulum elementum mattis lorem vitae gravida. Nullam id tellus interdum, aliquam erat eu, laoreet nunc. Aliquam ut felis vel mauris maximus pellentesque.
10
11Vestibulum tempus mauris eget ex interdum, vitae vehicula tortor sollicitudin. Pellentesque et dolor cursus dui vulputate laoreet. Morbi eu bibendum quam, at ultrices elit. Vestibulum dictum enim sit amet ultricies imperdiet. Praesent congue magna ac mauris mattis, a iaculis ante aliquet. Vivamus at egestas ex. Suspendisse orci dolor, pharetra at aliquam a, faucibus facilisis leo. Quisque semper lorem eget elit commodo pretium. Aenean posuere augue quis arcu finibus, sit amet fringilla risus congue. Pellentesque rutrum nunc leo, aliquam lobortis lacus molestie nec. Donec convallis congue diam, ullamcorper vestibulum dui varius nec. Praesent pellentesque nisi risus. In aliquam molestie malesuada. Nulla facilisis a risus eu tristique. Morbi molestie et arcu quis efficitur. Curabitur cursus vestibulum luctus.
diff --git a/test/fcopy/src/a/file3 b/test/fcopy/src/a/file3
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/test/fcopy/src/a/file3
diff --git a/test/fcopy/src/dircopy.exp b/test/fcopy/src/dircopy.exp
new file mode 120000
index 000000000..2acf88f7b
--- /dev/null
+++ b/test/fcopy/src/dircopy.exp
@@ -0,0 +1 @@
../dircopy.exp \ No newline at end of file
diff --git a/test/fcopy/src/file1 b/test/fcopy/src/file1
new file mode 100755
index 000000000..e69de29bb
--- /dev/null
+++ b/test/fcopy/src/file1
diff --git a/test/fcopy/src/file2 b/test/fcopy/src/file2
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/test/fcopy/src/file2
diff --git a/test/fs/fs.sh b/test/fs/fs.sh
index efbf505ee..1c5473f79 100755
--- a/test/fs/fs.sh
+++ b/test/fs/fs.sh
@@ -82,10 +82,21 @@ echo "TESTING: recursive mkdir (test/fs/mkdir.exp)"
82echo "TESTING: double whitelist (test/fs/whitelist-double.exp)" 82echo "TESTING: double whitelist (test/fs/whitelist-double.exp)"
83./whitelist-double.exp 83./whitelist-double.exp
84 84
85
86echo "TESTING: whitelist (test/fs/whitelist.exp)" 85echo "TESTING: whitelist (test/fs/whitelist.exp)"
87./whitelist.exp 86./whitelist.exp
88 87
88echo "TESTING: fscheck --bind non root (test/fs/fscheck-bindnoroot.exp)"
89./fscheck-bindnoroot.exp
90
91echo "TESTING: fscheck --tmpfs non root (test/fs/fscheck-tmpfs.exp)"
92./fscheck-tmpfs.exp
93
94echo "TESTING: fscheck --private= (test/fs/fscheck-private.exp)"
95./fscheck-private.exp
96
97echo "TESTING: fscheck --read-only= (test/fs/fscheck-readonly.exp)"
98./fscheck-readonly.exp
99
89#cleanup 100#cleanup
90rm -fr ~/fjtest-dir 101rm -fr ~/fjtest-dir
91rm -fr ~/fjtest-dir-lnk 102rm -fr ~/fjtest-dir-lnk
diff --git a/test/fscheck-bindnoroot.exp b/test/fs/fscheck-bindnoroot.exp
index 796a7d975..8cbe2b8af 100755
--- a/test/fscheck-bindnoroot.exp
+++ b/test/fs/fscheck-bindnoroot.exp
@@ -5,10 +5,13 @@ spawn $env(SHELL)
5match_max 100000 5match_max 100000
6 6
7# dir 7# dir
8send -- "firejail --net=br0 --bind=fscheck-dir,/etc\r" 8send -- "firejail --net=br0 --bind=testdir1,/etc\r"
9expect { 9expect {
10 timeout {puts "TESTING ERROR 0\n";exit} 10 timeout {puts "TESTING ERROR 0\n";exit}
11 "Error" 11 "Error"
12} 12}
13after 100 13after 100
14 14
15puts "\nall done\n"
16
17
diff --git a/test/fs/fscheck-private.exp b/test/fs/fscheck-private.exp
new file mode 100755
index 000000000..28c921538
--- /dev/null
+++ b/test/fs/fscheck-private.exp
@@ -0,0 +1,50 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7
8
9# file link
10#send -- "firejail --private=fscheck-file-link\r"
11#expect {
12# timeout {puts "TESTING ERROR 2\n";exit}
13# "Error"
14#}
15#after 100
16
17# file
18send -- "firejail --private=testfile1\r"
19expect {
20 timeout {puts "TESTING ERROR 2.1\n";exit}
21 "Error"
22}
23after 100
24
25# ..
26send -- "firejail --private=../fs/testfile1\r"
27expect {
28 timeout {puts "TESTING ERROR 2.2\n";exit}
29 "Error"
30}
31after 100
32
33# no file
34send -- "firejail --private=../test/nodir\r"
35expect {
36 timeout {puts "TESTING ERROR 3\n";exit}
37 "Error"
38}
39after 100
40
41# same owner
42send -- "firejail --private=/etc\r"
43expect {
44 timeout {puts "TESTING ERROR 4\n";exit}
45 "Error"
46}
47after 100
48
49puts "\nall done\n"
50
diff --git a/test/fscheck-readonly.exp b/test/fs/fscheck-readonly.exp
index e0f0a8a1d..4d7528e50 100755
--- a/test/fscheck-readonly.exp
+++ b/test/fs/fscheck-readonly.exp
@@ -5,10 +5,11 @@ spawn $env(SHELL)
5match_max 100000 5match_max 100000
6 6
7# dir 7# dir
8send -- "firejail --net=br0 --read-only=../test/fscheck-dir\r" 8send -- "firejail --read-only=../test/testdir1\r"
9expect { 9expect {
10 timeout {puts "TESTING ERROR 0\n";exit} 10 timeout {puts "TESTING ERROR 0\n";exit}
11 "Error" 11 "Error"
12} 12}
13after 100 13after 100
14 14
15puts "\nall done\n"
diff --git a/test/fscheck-tmpfs.exp b/test/fs/fscheck-tmpfs.exp
index d5bbccd96..deac5a631 100755
--- a/test/fscheck-tmpfs.exp
+++ b/test/fs/fscheck-tmpfs.exp
@@ -5,7 +5,7 @@ spawn $env(SHELL)
5match_max 100000 5match_max 100000
6 6
7# .. 7# ..
8send -- "firejail --net=br0 --tmpfs=../test/fscheck-dir\r" 8send -- "firejail --tmpfs=fscheck-dir\r"
9expect { 9expect {
10 timeout {puts "TESTING ERROR 0.1\n";exit} 10 timeout {puts "TESTING ERROR 0.1\n";exit}
11 "Error" 11 "Error"
diff --git a/test/fs/invalid_filename.exp b/test/fs/invalid_filename.exp
index 1acc85491..a6efc24b6 100755
--- a/test/fs/invalid_filename.exp
+++ b/test/fs/invalid_filename.exp
@@ -109,6 +109,21 @@ expect {
109} 109}
110after 100 110after 100
111 111
112send -- "firejail --debug-check-filename --noprofile --private-home=\"bla&&bla\"\r"
113expect {
114 timeout {puts "TESTING ERROR 8.1\n";exit}
115 "Checking filename bla&&bla"
116}
117expect {
118 timeout {puts "TESTING ERROR 8.2\n";exit}
119 "Error:"
120}
121expect {
122 timeout {puts "TESTING ERROR 8.3\n";exit}
123 "is an invalid filename"
124}
125after 100
126
112send -- "firejail --debug-check-filename --noprofile --private-etc=\"bla&&bla\"\r" 127send -- "firejail --debug-check-filename --noprofile --private-etc=\"bla&&bla\"\r"
113expect { 128expect {
114 timeout {puts "TESTING ERROR 9.1\n";exit} 129 timeout {puts "TESTING ERROR 9.1\n";exit}
diff --git a/test/fs/private-bin.exp b/test/fs/private-bin.exp
index fe9468be9..f7181d218 100755
--- a/test/fs/private-bin.exp
+++ b/test/fs/private-bin.exp
@@ -65,6 +65,28 @@ expect {
65 "sh" 65 "sh"
66} 66}
67send -- "exit\r" 67send -- "exit\r"
68after 100
69
70
71send -- "firejail --private-bin=/etc/shadow\r"
72expect {
73 timeout {puts "TESTING ERROR 8\n";exit}
74 "invalid filename"
75}
76after 100
77
78send -- "firejail --private-bin=\"bla;bla\"\r"
79expect {
80 timeout {puts "TESTING ERROR 9\n";exit}
81 "is an invalid filename"
82}
83after 100
84
85send -- "firejail --private-etc=../bin/ls\r"
86expect {
87 timeout {puts "TESTING ERROR 10\n";exit}
88 "is an invalid filename"
89}
68 90
69after 100 91after 100
70puts "\nall done\n" 92puts "\nall done\n"
diff --git a/test/fs/private-etc.exp b/test/fs/private-etc.exp
index e692f7382..36b5d247c 100755
--- a/test/fs/private-etc.exp
+++ b/test/fs/private-etc.exp
@@ -33,12 +33,40 @@ expect {
33 "resolv.conf" 33 "resolv.conf"
34} 34}
35 35
36send -- "ls -al /etc; echo done\r" 36
37send -- "file /etc/shadow\r"
37expect { 38expect {
38 timeout {puts "TESTING ERROR 7\n";exit} 39 timeout {puts "TESTING ERROR 7\n";exit}
39 "shadow" {puts "TESTING ERROR 8\n";exit} 40 "No such file or directory"
40 "done" 41}
42after 100
43send -- "exit\r"
44sleep 1
45
46send -- "firejail --private-etc=shadow\r"
47expect {
48 timeout {puts "TESTING ERROR 8\n";exit}
49 "invalid file type"
50}
51after 100
52
53send -- "firejail --private-etc=\"bla;bla\"\r"
54expect {
55 timeout {puts "TESTING ERROR 9\n";exit}
56 "is an invalid filename"
41} 57}
58after 100
59
60send -- "firejail --private-etc=../bin/ls\r"
61expect {
62 timeout {puts "TESTING ERROR 10\n";exit}
63 "is an invalid filename"
64}
65after 100
66
67
68
69
42 70
43after 100 71after 100
44puts "\nall done\n" 72puts "\nall done\n"
diff --git a/test/fs/private-home.exp b/test/fs/private-home.exp
index de5a88dea..3840d1cb8 100755
--- a/test/fs/private-home.exp
+++ b/test/fs/private-home.exp
@@ -9,11 +9,19 @@ match_max 100000
9 9
10# create some test files in user home directory 10# create some test files in user home directory
11send -- "touch ~/_firejail_test_file1\r" 11send -- "touch ~/_firejail_test_file1\r"
12after 100
12send -- "touch ~/_firejail_test_file2\r" 13send -- "touch ~/_firejail_test_file2\r"
14after 100
13send -- "mkdir ~/_firejail_test_dir1\r" 15send -- "mkdir ~/_firejail_test_dir1\r"
16after 100
14send -- "mkdir ~/_firejail_test_dir1/_firejail_test_dir2\r" 17send -- "mkdir ~/_firejail_test_dir1/_firejail_test_dir2\r"
18after 100
15send -- "touch ~/_firejail_test_dir1/_firejail_test_dir2/_firejail_test_file3\r" 19send -- "touch ~/_firejail_test_dir1/_firejail_test_dir2/_firejail_test_file3\r"
16after 100 20after 100
21send -- "ln -s /etc ~/_firejail_test_link1\r"
22after 100
23send -- "ln -s ~/_firejail_test_dir1 ~/_firejail_test_link2\r"
24after 100
17 25
18send -- "firejail --private-home=_firejail_test_file1,_firejail_test_file2,_firejail_test_dir1\r" 26send -- "firejail --private-home=_firejail_test_file1,_firejail_test_file2,_firejail_test_dir1\r"
19expect { 27expect {
@@ -37,8 +45,58 @@ expect {
37} 45}
38after 100 46after 100
39 47
40send -- "rm -f ~/_firejail_test_file*\r" 48send -- "exit\r"
41send -- "rm -fr ~/_firejail_test_dir*\r" 49sleep 1
50
51send -- "firejail --private-home=\"bla;bla\"\r"
52expect {
53 timeout {puts "TESTING ERROR 5\n";exit}
54 "is an invalid filename"
55}
56after 100
57
58send -- "firejail --private-home=/etc/shadow\r"
59expect {
60 timeout {puts "TESTING ERROR 6\n";exit}
61 "invalid file"
62}
63after 100
64
65send -- "firejail --private-home=/etc/passwd\r"
66expect {
67 timeout {puts "TESTING ERROR 7\n";exit}
68 "invalid file"
69}
70after 100
71
72send -- "firejail --private-home=../../etc/passwd\r"
73expect {
74 timeout {puts "TESTING ERROR 8\n";exit}
75 "invalid file"
76}
77after 100
78
79send -- "firejail --private-home=_firejail_test_link1\r"
80expect {
81 timeout {puts "TESTING ERROR 9\n";exit}
82 "to file or directory not owned by the user"
83}
84after 100
85
86send -- "firejail --private-home=_firejail_test_link2\r"
87expect {
88 timeout {puts "TESTING ERROR 10\n";exit}
89 "Child process initialized"
90}
91after 100
92send -- "file file ~/_firejail_test_link2\r"
93expect {
94 timeout {puts "TESTING ERROR 11\n";exit}
95 "broken symbolic link"
96}
97send -- "exit\r"
98
99send -- "rm -f ~/_firejail_test*\r"
42after 100 100after 100
43 101
44puts "\nall done\n" 102puts "\nall done\n"
diff --git a/test/fs/read-write.exp b/test/fs/read-write.exp
index 57986488e..19a915f66 100755
--- a/test/fs/read-write.exp
+++ b/test/fs/read-write.exp
@@ -15,37 +15,21 @@ expect {
15} 15}
16sleep 1 16sleep 1
17 17
18send -- "echo mytest >~/_firejail_test_dir/a;echo done\r" 18send -- "echo mytest > ~/_firejail_test_dir/a\r"
19expect { 19expect {
20 timeout {puts "TESTING ERROR 1\n";exit} 20 timeout {puts "TESTING ERROR 5\n";exit}
21 "done" 21 "Read-only file system"
22}
23after 100
24
25send -- "echo mytest >~/_firejail_test_dir/test1/b;echo done\r"
26expect {
27 timeout {puts "TESTING ERROR 2\n";exit}
28 "done"
29} 22}
30after 100 23after 100
31 24
32send -- "cat ~/_firejail_test_dir/a;echo done\r" 25send -- "echo mytest > ~/_firejail_test_dir/test1/b\r"
33expect { 26sleep 1
34 timeout {puts "TESTING ERROR 3\n";exit}
35 "mytest" {puts "TESTING ERROR 4\n";exit}
36 "done"
37}
38after 100
39 27
40send -- "cat ~/_firejail_test_dir/test1/b;echo done\r" 28send -- "cat ~/_firejail_test_dir/test1/b\r"
41expect { 29expect {
42 timeout {puts "TESTING ERROR 5\n";exit} 30 timeout {puts "TESTING ERROR 5\n";exit}
43 "mytest" 31 "mytest"
44} 32}
45expect {
46 timeout {puts "TESTING ERROR 6\n";exit}
47 "done"
48}
49 33
50after 100 34after 100
51puts "\nall done\n" 35puts "\nall done\n"
diff --git a/test/fs/testfile1 b/test/fs/testfile1
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/test/fs/testfile1
diff --git a/test/fscheck-private.exp b/test/fscheck-private.exp
deleted file mode 100755
index 8e485cc03..000000000
--- a/test/fscheck-private.exp
+++ /dev/null
@@ -1,70 +0,0 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7
8# ..
9#send -- "firejail --net=br0 --private=../test/fscheck-dir\r"
10#expect {
11# timeout {puts "TESTING ERROR 0.1\n";exit}
12# "Error"
13#}
14#after 100
15
16# dir link
17#send -- "firejail --net=br0 --private=fscheck-dir-link\r"
18#expect {
19# timeout {puts "TESTING ERROR 1\n";exit}
20# "Error"
21#}
22#after 100
23
24# ..
25#send -- "firejail --net=br0 --private=../test/fscheck-dir-link\r"
26#expect {
27# timeout {puts "TESTING ERROR 1.1\n";exit}
28# "Error"
29#}
30#after 100
31
32# file link
33send -- "firejail --net=br0 --private=fscheck-file-link\r"
34expect {
35 timeout {puts "TESTING ERROR 2\n";exit}
36 "Error"
37}
38after 100
39
40# file
41send -- "firejail --net=br0 --private=fscheck-file\r"
42expect {
43 timeout {puts "TESTING ERROR 2.1\n";exit}
44 "Error"
45}
46after 100
47
48# ..
49send -- "firejail --net=br0 --private=../test/fscheck-file\r"
50expect {
51 timeout {puts "TESTING ERROR 2.2\n";exit}
52 "Error"
53}
54after 100
55
56# no file
57send -- "firejail --net=br0 --private=../test/nodir\r"
58expect {
59 timeout {puts "TESTING ERROR 3\n";exit}
60 "Error"
61}
62after 100
63
64# same owner
65send -- "firejail --net=br0 --private=/etc\r"
66expect {
67 timeout {puts "TESTING ERROR 4\n";exit}
68 "Error"
69}
70after 100
diff --git a/test/rlimit/rlimit.sh b/test/rlimit/rlimit.sh
deleted file mode 100755
index d85497176..000000000
--- a/test/rlimit/rlimit.sh
+++ /dev/null
@@ -1,14 +0,0 @@
1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6export MALLOC_CHECK_=3
7export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
8
9echo "TESTING: rlimit (test/rlimit/rlimit.exp)"
10./rlimit.exp
11
12echo "TESTING: rlimit profile (test/rlimit/rlimit-profile.exp)"
13./rlimit-profile.exp
14
diff --git a/test/utils/firemon-cpu.exp b/test/utils/firemon-cpu.exp
index f2ecd4a5c..00156c909 100755
--- a/test/utils/firemon-cpu.exp
+++ b/test/utils/firemon-cpu.exp
@@ -24,7 +24,6 @@ sleep 1
24 24
25spawn $env(SHELL) 25spawn $env(SHELL)
26send -- "firemon --cpu\r" 26send -- "firemon --cpu\r"
27sleep 4
28expect { 27expect {
29 timeout {puts "TESTING ERROR 2\n";exit} 28 timeout {puts "TESTING ERROR 2\n";exit}
30 "need to be root" {puts "TESTING SKIP: /proc mounted as hidepid\n"; exit} 29 "need to be root" {puts "TESTING SKIP: /proc mounted as hidepid\n"; exit}
diff --git a/test/utils/firemon-interface.exp b/test/utils/firemon-interface.exp
new file mode 100755
index 000000000..edafd1639
--- /dev/null
+++ b/test/utils/firemon-interface.exp
@@ -0,0 +1,18 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firemon --interface\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "you need to be root"
14}
15after 100
16
17puts "\nall done\n"
18
diff --git a/test/utils/firemon-name.exp b/test/utils/firemon-name.exp
new file mode 100755
index 000000000..c5dbfabab
--- /dev/null
+++ b/test/utils/firemon-name.exp
@@ -0,0 +1,28 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --name=test\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Child process initialized"
14}
15sleep 1
16
17spawn $env(SHELL)
18send -- "firemon --cpu --name=test\r"
19expect {
20 timeout {puts "TESTING ERROR 2\n";exit}
21 "need to be root" {puts "TESTING SKIP: /proc mounted as hidepid\n"; exit}
22 "Cpus_allowed_list"
23}
24
25after 100
26
27puts "\nall done\n"
28
diff --git a/test/utils/firemon-version.exp b/test/utils/firemon-version.exp
new file mode 100755
index 000000000..639c15c29
--- /dev/null
+++ b/test/utils/firemon-version.exp
@@ -0,0 +1,18 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firemon --version\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "firemon version"
14}
15after 100
16
17puts "\nall done\n"
18
diff --git a/test/utils/utils.sh b/test/utils/utils.sh
index bd91110f7..804e5ae0f 100755
--- a/test/utils/utils.sh
+++ b/test/utils/utils.sh
@@ -100,3 +100,12 @@ echo "TESTING: firemon cpu (test/utils/firemon-cpu.exp)"
100echo "TESTING: firemon cgroup (test/utils/firemon-cgroup.exp)" 100echo "TESTING: firemon cgroup (test/utils/firemon-cgroup.exp)"
101./firemon-cgroup.exp 101./firemon-cgroup.exp
102 102
103echo "TESTING: firemon version (test/utils/firemon-version.exp)"
104./firemon-version.exp
105
106echo "TESTING: firemon interface (test/utils/firemon-interface.exp)"
107./firemon-interface.exp
108
109echo "TESTING: firemon name (test/utils/firemon-name.exp)"
110./firemon-name.exp
111