summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README6
-rw-r--r--README.md7
-rw-r--r--RELNOTES1
-rw-r--r--etc/disable-common.inc3
-rw-r--r--etc/qutebrowser.profile2
-rwxr-xr-xgcov.sh21
-rw-r--r--src/firejail/firejail.h2
-rw-r--r--src/firejail/fs.c5
-rw-r--r--src/firejail/fs_etc.c51
-rw-r--r--src/firejail/main.c139
-rw-r--r--src/firejail/no_sandbox.c97
-rw-r--r--src/firejail/profile.c7
-rw-r--r--src/firejail/rlimit.c12
-rw-r--r--src/firejail/sandbox.c9
-rw-r--r--src/firejail/usage.c3
-rw-r--r--src/man/firejail-profile.txt4
-rw-r--r--src/man/firejail.txt10
-rwxr-xr-xtest/environment/firejail-in-firejail.exp27
-rwxr-xr-xtest/environment/firejail-in-firejail2.exp29
-rwxr-xr-xtest/network/dns-print.exp31
-rwxr-xr-xtest/network/net_macvlan2.exp43
-rwxr-xr-xtest/network/network.sh9
-rwxr-xr-xtest/stress/net_macvlan.exp (renamed from test/network/net_macvlan.exp)2
-rwxr-xr-xtest/stress/stress.sh11
-rw-r--r--todo2
25 files changed, 344 insertions, 189 deletions
diff --git a/README b/README
index 8df3e8ad3..7570cc3f6 100644
--- a/README
+++ b/README
@@ -80,8 +80,8 @@ Fred-Barclay (https://github.com/Fred-Barclay)
80 - evince profile enhancement 80 - evince profile enhancement
81 - tightened Spotify profile 81 - tightened Spotify profile
82 - added xiphos and Tor Browser Bundle profiles 82 - added xiphos and Tor Browser Bundle profiles
83 - added xed and pluma profiles 83 - added xed and pluma profiles
84 - added Cryptocat profile 84 - added Cryptocat profile
85valoq (https://github.com/valoq) 85valoq (https://github.com/valoq)
86 - lots of profile fixes 86 - lots of profile fixes
87 - added support for /srv in --whitelist feature 87 - added support for /srv in --whitelist feature
@@ -95,6 +95,8 @@ valoq (https://github.com/valoq)
95 - added img2txt, k3b, kate, lynx, mediainfo, nautilus, odt2txt, pdftotext, simple-scan profiles 95 - added img2txt, k3b, kate, lynx, mediainfo, nautilus, odt2txt, pdftotext, simple-scan profiles
96 - added skanlite, ssh-agent, transmission-cli, tracker, transmission-show, w3m, xfburn, xpra profiles 96 - added skanlite, ssh-agent, transmission-cli, tracker, transmission-show, w3m, xfburn, xpra profiles
97 - added wget profile 97 - added wget profile
98Lari Rauno (https://github.com/tuutti)
99 - qutebrowser profile fixes
98SpotComms (https://github.com/SpotComms) 100SpotComms (https://github.com/SpotComms)
99 - added Bless, Gnome 2048, Gnome Calculator, Gnome Contacts, JD-GUI, Lollypop, MultiMC5 profiles 101 - added Bless, Gnome 2048, Gnome Calculator, Gnome Contacts, JD-GUI, Lollypop, MultiMC5 profiles
100 - added PDFSam, Pithos, and Xonotic profiles 102 - added PDFSam, Pithos, and Xonotic profiles
diff --git a/README.md b/README.md
index bafcf6120..16f84493b 100644
--- a/README.md
+++ b/README.md
@@ -74,6 +74,13 @@ Use this issue to request new profiles: https://github.com/netblue30/firejail/is
74 74
75 Example: 75 Example:
76 # firejail --private-srv=www /etc/init.d/apache2 start 76 # firejail --private-srv=www /etc/init.d/apache2 start
77
78 --machine-id
79 Preserve id number in /etc/machine-id file. By default a new
80 random id is generated inside the sandbox.
81
82 Example:
83 $ firejail --machine-id
77````` 84`````
78## New Profiles 85## New Profiles
79xiphos, Tor Browser Bundle, display (imagemagik), Wire, mumble, zoom, Guayadeque, qemu, keypass2, 86xiphos, Tor Browser Bundle, display (imagemagik), Wire, mumble, zoom, Guayadeque, qemu, keypass2,
diff --git a/RELNOTES b/RELNOTES
index 3ccd51ce7..c3a077c5e 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -11,6 +11,7 @@ firejail (0.9.45) baseline; urgency=low
11 * feature: test coverage (gcov) support 11 * feature: test coverage (gcov) support
12 * feature: private /opt directory (--private-opt, profile support) 12 * feature: private /opt directory (--private-opt, profile support)
13 * feature: private /srv directory (--private-srv, profile support) 13 * feature: private /srv directory (--private-srv, profile support)
14 * feature: spoof machine-id
14 * new profiles: xiphos, Tor Browser Bundle, display (imagemagik), Wire, 15 * new profiles: xiphos, Tor Browser Bundle, display (imagemagik), Wire,
15 * new profiles: mumble, zoom, Guayadeque, qemu, keypass2, xed, pluma, 16 * new profiles: mumble, zoom, Guayadeque, qemu, keypass2, xed, pluma,
16 * new profiles: Cryptocat, Bless, Gnome 2048, Gnome Calculator, 17 * new profiles: Cryptocat, Bless, Gnome 2048, Gnome Calculator,
diff --git a/etc/disable-common.inc b/etc/disable-common.inc
index 95af0aa34..b86c6f998 100644
--- a/etc/disable-common.inc
+++ b/etc/disable-common.inc
@@ -209,7 +209,8 @@ blacklist ${PATH}/roxterm-config
209blacklist ${PATH}/terminix 209blacklist ${PATH}/terminix
210blacklist ${PATH}/urxvtc 210blacklist ${PATH}/urxvtc
211blacklist ${PATH}/urxvtcd 211blacklist ${PATH}/urxvtcd
212blacklist ${PATH}/konsole 212#konsole doesn't seem to have this problem - last tested on Ubuntu 16.04
213#blacklist ${PATH}/konsole
213 214
214# kernel files 215# kernel files
215blacklist /vmlinuz* 216blacklist /vmlinuz*
diff --git a/etc/qutebrowser.profile b/etc/qutebrowser.profile
index eabbe0f3e..dcacd4f29 100644
--- a/etc/qutebrowser.profile
+++ b/etc/qutebrowser.profile
@@ -18,4 +18,6 @@ mkdir ~/.config/qutebrowser
18whitelist ~/.config/qutebrowser 18whitelist ~/.config/qutebrowser
19mkdir ~/.cache/qutebrowser 19mkdir ~/.cache/qutebrowser
20whitelist ~/.cache/qutebrowser 20whitelist ~/.cache/qutebrowser
21mkdir ~/.local/share/qutebrowser
22whitelist ~/.local/share/qutebrowser
21include /etc/firejail/whitelist-common.inc 23include /etc/firejail/whitelist-common.inc
diff --git a/gcov.sh b/gcov.sh
index a3cd8c5ee..57190cad2 100755
--- a/gcov.sh
+++ b/gcov.sh
@@ -2,13 +2,13 @@
2 2
3gcov_init() { 3gcov_init() {
4 USER=`whoami` 4 USER=`whoami`
5 firejail --help 5 firejail --help > /dev/null
6 firemon --help 6 firemon --help > /dev/null
7 /usr/lib/firejail/fnet --help 7 /usr/lib/firejail/fnet --help > /dev/null
8 /usr/lib/firejail/fseccomp --help 8 /usr/lib/firejail/fseccomp --help > /dev/null
9 /usr/lib/firejail/ftee --help 9 /usr/lib/firejail/ftee --help > /dev/null
10 /usr/lib/firejail/fcopy --help 10 /usr/lib/firejail/fcopy --help > /dev/null
11 firecfg --help 11 firecfg --help > /dev/null
12 sudo chown $USER:$USER `find .` 12 sudo chown $USER:$USER `find .`
13} 13}
14 14
@@ -24,6 +24,13 @@ generate() {
24 24
25 25
26gcov_init 26gcov_init
27lcov -q --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-old
28
29#make test-environment
30#generate
31#sleep 2
32#exit
33
27 34
28# running tests 35# running tests
29make test-root 36make test-root
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index d172efce1..368e0d88d 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -78,6 +78,7 @@
78#define RUN_HOSTNAME_FILE "/run/firejail/mnt/hostname" 78#define RUN_HOSTNAME_FILE "/run/firejail/mnt/hostname"
79#define RUN_HOSTS_FILE "/run/firejail/mnt/hosts" 79#define RUN_HOSTS_FILE "/run/firejail/mnt/hosts"
80#define RUN_RESOLVCONF_FILE "/run/firejail/mnt/resolv.conf" 80#define RUN_RESOLVCONF_FILE "/run/firejail/mnt/resolv.conf"
81#define RUN_MACHINEID "/run/firejail/mnt/machine-id"
81#define RUN_LDPRELOAD_FILE "/run/firejail/mnt/ld.so.preload" 82#define RUN_LDPRELOAD_FILE "/run/firejail/mnt/ld.so.preload"
82#define RUN_UTMP_FILE "/run/firejail/mnt/utmp" 83#define RUN_UTMP_FILE "/run/firejail/mnt/utmp"
83#define RUN_PASSWD_FILE "/run/firejail/mnt/passwd" 84#define RUN_PASSWD_FILE "/run/firejail/mnt/passwd"
@@ -342,6 +343,7 @@ extern int arg_allow_debuggers; // allow debuggers
342extern int arg_x11_block; // block X11 343extern int arg_x11_block; // block X11
343extern int arg_x11_xorg; // use X11 security extention 344extern int arg_x11_xorg; // use X11 security extention
344extern int arg_allusers; // all user home directories visible 345extern int arg_allusers; // all user home directories visible
346extern int arg_machineid; // preserve /etc/machine-id
345 347
346extern int login_shell; 348extern int login_shell;
347extern int parent_to_child_fds[2]; 349extern int parent_to_child_fds[2];
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index ffad961c3..905d2903d 100644
--- a/src/firejail/fs.c
+++ b/src/firejail/fs.c
@@ -662,7 +662,8 @@ void fs_basic_fs(void) {
662 fs_var_lib(); 662 fs_var_lib();
663 fs_var_cache(); 663 fs_var_cache();
664 fs_var_utmp(); 664 fs_var_utmp();
665 665 fs_machineid();
666
666 // don't leak user information 667 // don't leak user information
667 restrict_users(); 668 restrict_users();
668 669
@@ -945,6 +946,7 @@ void fs_overlayfs(void) {
945 fs_var_lib(); 946 fs_var_lib();
946 fs_var_cache(); 947 fs_var_cache();
947 fs_var_utmp(); 948 fs_var_utmp();
949 fs_machineid();
948 950
949 // don't leak user information 951 // don't leak user information
950 restrict_users(); 952 restrict_users();
@@ -1126,6 +1128,7 @@ void fs_chroot(const char *rootdir) {
1126 fs_var_lib(); 1128 fs_var_lib();
1127 fs_var_cache(); 1129 fs_var_cache();
1128 fs_var_utmp(); 1130 fs_var_utmp();
1131 fs_machineid();
1129 1132
1130 // don't leak user information 1133 // don't leak user information
1131 restrict_users(); 1134 restrict_users();
diff --git a/src/firejail/fs_etc.c b/src/firejail/fs_etc.c
index 9a28ac601..a04bf6725 100644
--- a/src/firejail/fs_etc.c
+++ b/src/firejail/fs_etc.c
@@ -23,6 +23,57 @@
23#include <sys/types.h> 23#include <sys/types.h>
24#include <unistd.h> 24#include <unistd.h>
25 25
26// spoof /etc/machine_id
27void fs_machineid(void) {
28 union machineid_t {
29 uint8_t u8[16];
30 uint32_t u32[4];
31 } mid;
32
33 // if --machine-id flag is active, do nothing
34 if (arg_machineid)
35 return;
36
37 // init random number generator
38 srand(time(NULL));
39
40 // generate random id
41 mid.u32[0] = rand();
42 mid.u32[1] = rand();
43 mid.u32[2] = rand();
44 mid.u32[3] = rand();
45
46 // UUID version 4 and DCE variant
47 mid.u8[6] = (mid.u8[6] & 0x0F) | 0x40;
48 mid.u8[8] = (mid.u8[8] & 0x3F) | 0x80;
49
50 // write it in a file
51 FILE *fp = fopen(RUN_MACHINEID, "w");
52 if (!fp)
53 errExit("fopen");
54 fprintf(fp, "%08x%08x%08x%08x\n", mid.u32[0], mid.u32[1], mid.u32[2], mid.u32[3]);
55 fclose(fp);
56 if (set_perms(RUN_MACHINEID, 0, 0, 0444))
57 errExit("set_perms");
58
59
60 struct stat s;
61 // mount-bind
62 if (stat("/etc/machine-id", &s) == 0) {
63 if (arg_debug)
64 printf("installing a new /etc/machine-id\n");
65
66 if (mount(RUN_MACHINEID, "/etc/machine-id", "none", MS_BIND, "mode=444,gid=0"))
67 errExit("mount");
68 }
69//#if 0 // todo: investigate
70 if (stat("/var/lib/dbus/machine-id", &s) == 0) {
71 if (mount(RUN_MACHINEID, "/etc/machine-id", "none", MS_BIND, "mode=444,gid=0"))
72 errExit("mount");
73 }
74//#endif
75}
76
26// return 0 if file not found, 1 if found 77// return 0 if file not found, 1 if found
27static int check_dir_or_file(const char *fname) { 78static int check_dir_or_file(const char *fname) {
28 assert(fname); 79 assert(fname);
diff --git a/src/firejail/main.c b/src/firejail/main.c
index aa855b7eb..b25bad9f2 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -111,6 +111,7 @@ int arg_allow_debuggers = 0; // allow debuggers
111int arg_x11_block = 0; // block X11 111int arg_x11_block = 0; // block X11
112int arg_x11_xorg = 0; // use X11 security extention 112int arg_x11_xorg = 0; // use X11 security extention
113int arg_allusers = 0; // all user home directories visible 113int arg_allusers = 0; // all user home directories visible
114int arg_machineid = 0; // preserve /etc/machine-id
114 115
115int login_shell = 0; 116int login_shell = 0;
116 117
@@ -750,42 +751,6 @@ static void delete_x11_file(pid_t pid) {
750 free(fname); 751 free(fname);
751} 752}
752 753
753static void detect_quiet(int argc, char **argv) {
754 int i;
755
756 // detect --quiet
757 for (i = 1; i < argc; i++) {
758 if (strcmp(argv[i], "--quiet") == 0) {
759 arg_quiet = 1;
760 break;
761 }
762
763 // detect end of firejail params
764 if (strcmp(argv[i], "--") == 0)
765 break;
766 if (strncmp(argv[i], "--", 2) != 0)
767 break;
768 }
769}
770
771static void detect_allow_debuggers(int argc, char **argv) {
772 int i;
773
774 // detect --allow-debuggers
775 for (i = 1; i < argc; i++) {
776 if (strcmp(argv[i], "--allow-debuggers") == 0) {
777 arg_allow_debuggers = 1;
778 break;
779 }
780
781 // detect end of firejail params
782 if (strcmp(argv[i], "--") == 0)
783 break;
784 if (strncmp(argv[i], "--", 2) != 0)
785 break;
786 }
787}
788
789char *guess_shell(void) { 754char *guess_shell(void) {
790 char *shell = NULL; 755 char *shell = NULL;
791 // shells in order of preference 756 // shells in order of preference
@@ -805,6 +770,25 @@ char *guess_shell(void) {
805 return shell; 770 return shell;
806} 771}
807 772
773static int check_arg(int argc, char **argv, const char *argument) {
774 int i;
775 int found = 0;
776 for (i = 1; i < argc; i++) {
777 if (strcmp(argv[i], argument) == 0) {
778 found = 1;
779 break;
780 }
781
782 // detect end of firejail params
783 if (strcmp(argv[i], "--") == 0)
784 break;
785 if (strncmp(argv[i], "--", 2) != 0)
786 break;
787 }
788
789 return found;
790}
791
808//******************************************* 792//*******************************************
809// Main program 793// Main program
810//******************************************* 794//*******************************************
@@ -821,8 +805,10 @@ int main(int argc, char **argv) {
821 // build /run/firejail directory structure 805 // build /run/firejail directory structure
822 preproc_build_firejail_dir(); 806 preproc_build_firejail_dir();
823 807
824 detect_quiet(argc, argv); 808 if (check_arg(argc, argv, "--quiet"))
825 detect_allow_debuggers(argc, argv); 809 arg_quiet = 1;
810 if (check_arg(argc, argv, "--allow-debuggers"))
811 arg_allow_debuggers = 1;
826 812
827 // drop permissions by default and rise them when required 813 // drop permissions by default and rise them when required
828 EUID_INIT(); 814 EUID_INIT();
@@ -844,78 +830,32 @@ int main(int argc, char **argv) {
844 EUID_USER(); 830 EUID_USER();
845 if (rv == 0) { 831 if (rv == 0) {
846 // if --force option is passed to the program, disregard the existing sandbox 832 // if --force option is passed to the program, disregard the existing sandbox
847 int found = 0; 833 if (check_arg(argc, argv, "--force"))
848 for (i = 1; i < argc; i++) { 834 option_force = 1;
849 if (strcmp(argv[i], "--force") == 0 || 835 else {
850 strcmp(argv[i], "--list") == 0 || 836 if (check_arg(argc, argv, "--version")) {
851 strcmp(argv[i], "--netstats") == 0 || 837 printf("firejail version %s\n", VERSION);
852 strcmp(argv[i], "--tree") == 0 || 838 exit(0);
853 strcmp(argv[i], "--top") == 0 ||
854 strncmp(argv[i], "--ls=", 5) == 0 ||
855 strncmp(argv[i], "--get=", 6) == 0 ||
856 strcmp(argv[i], "--debug-caps") == 0 ||
857 strcmp(argv[i], "--debug-errnos") == 0 ||
858 strcmp(argv[i], "--debug-syscalls") == 0 ||
859 strcmp(argv[i], "--debug-protocols") == 0 ||
860 strcmp(argv[i], "--help") == 0 ||
861 strcmp(argv[i], "--version") == 0 ||
862 strcmp(argv[i], "--overlay-clean") == 0 ||
863 strncmp(argv[i], "--dns.print=", 12) == 0 ||
864 strncmp(argv[i], "--bandwidth=", 12) == 0 ||
865 strncmp(argv[i], "--caps.print=", 13) == 0 ||
866 strncmp(argv[i], "--cpu.print=", 12) == 0 ||
867 //********************************************************************************
868 // todo: fix the following problems
869 strncmp(argv[i], "--join=", 7) == 0 ||
870 //[netblue@debian Downloads]$ firejail --join=896
871 //Switching to pid 897, the first child process inside the sandbox
872 //Error: seccomp file not found
873 //********************************************************************************
874
875 strncmp(argv[i], "--join-filesystem=", 18) == 0 ||
876 strncmp(argv[i], "--join-network=", 15) == 0 ||
877 strncmp(argv[i], "--fs.print=", 11) == 0 ||
878 strncmp(argv[i], "--protocol.print=", 17) == 0 ||
879 strncmp(argv[i], "--seccomp.print", 15) == 0 ||
880 strncmp(argv[i], "--shutdown=", 11) == 0) {
881 found = 1;
882 break;
883 } 839 }
884 840
885 // detect end of firejail params
886 if (strcmp(argv[i], "--") == 0)
887 break;
888 if (strncmp(argv[i], "--", 2) != 0)
889 break;
890 }
891
892 if (found == 0) {
893 // start the program directly without sandboxing 841 // start the program directly without sandboxing
894 run_no_sandbox(argc, argv); 842 run_no_sandbox(argc, argv);
895 // it will never get here! 843 // it will never get here!
896 assert(0); 844 assert(0);
897 } 845 }
898 else
899 option_force = 1;
900 } 846 }
901 } 847 }
902 848
903 // check root/suid 849 // check root/suid
904 EUID_ROOT(); 850 EUID_ROOT();
905 if (geteuid()) { 851 if (geteuid()) {
906 // detect --version 852 // only --version is supported without SUID support
907 for (i = 1; i < argc; i++) { 853 if (check_arg(argc, argv, "--version")) {
908 if (strcmp(argv[i], "--version") == 0) { 854 printf("firejail version %s\n", VERSION);
909 printf("firejail version %s\n", VERSION); 855 exit(0);
910 exit(0);
911 }
912
913 // detect end of firejail params
914 if (strcmp(argv[i], "--") == 0)
915 break;
916 if (strncmp(argv[i], "--", 2) != 0)
917 break;
918 } 856 }
857
858 fprintf(stderr, "Error: cannot rise privileges\n");
919 exit(1); 859 exit(1);
920 } 860 }
921 EUID_USER(); 861 EUID_USER();
@@ -1520,6 +1460,9 @@ int main(int argc, char **argv) {
1520 else if (strcmp(argv[i], "--writable-var") == 0) { 1460 else if (strcmp(argv[i], "--writable-var") == 0) {
1521 arg_writable_var = 1; 1461 arg_writable_var = 1;
1522 } 1462 }
1463 else if (strcmp(argv[i], "--machine-id") == 0) {
1464 arg_machineid = 1;
1465 }
1523 else if (strcmp(argv[i], "--private") == 0) { 1466 else if (strcmp(argv[i], "--private") == 0) {
1524 arg_private = 1; 1467 arg_private = 1;
1525 } 1468 }
diff --git a/src/firejail/no_sandbox.c b/src/firejail/no_sandbox.c
index 8af555ea2..c56d90994 100644
--- a/src/firejail/no_sandbox.c
+++ b/src/firejail/no_sandbox.c
@@ -165,84 +165,28 @@ void run_no_sandbox(int argc, char **argv) {
165 // process limited subset of options 165 // process limited subset of options
166 int i; 166 int i;
167 for (i = 0; i < argc; i++) { 167 for (i = 0; i < argc; i++) {
168 if (strcmp(argv[i], "--csh") == 0) { 168 if (strcmp(argv[i], "--debug") == 0)
169 if (arg_shell_none) { 169 arg_debug = 1;
170 fprintf(stderr, "Error: --shell=none was already specified.\n"); 170 else if (strcmp(argv[i], "--csh") == 0 ||
171 exit(1); 171 strcmp(argv[i], "--zsh") == 0 ||
172 } 172 strcmp(argv[i], "--shell=none") == 0 ||
173 if (cfg.shell) { 173 strncmp(argv[i], "--shell=", 8) == 0)
174 fprintf(stderr, "Error: only one default user shell can be specified\n"); 174 fprintf(stderr, "Warning: shell-related command line options are disregarded - using SHELL environment variable");
175 exit(1);
176 }
177 cfg.shell = "/bin/csh";
178 }
179 else if (strcmp(argv[i], "--zsh") == 0) {
180 if (arg_shell_none) {
181 fprintf(stderr, "Error: --shell=none was already specified.\n");
182 exit(1);
183 }
184 if (cfg.shell) {
185 fprintf(stderr, "Error: only one default user shell can be specified\n");
186 exit(1);
187 }
188 cfg.shell = "/bin/zsh";
189 }
190 else if (strcmp(argv[i], "--shell=none") == 0) {
191 arg_shell_none = 1;
192 if (cfg.shell) {
193 fprintf(stderr, "Error: a shell was already specified\n");
194 exit(1);
195 }
196 }
197 else if (strncmp(argv[i], "--shell=", 8) == 0) {
198 if (arg_shell_none) {
199 fprintf(stderr, "Error: --shell=none was already specified.\n");
200 exit(1);
201 }
202 invalid_filename(argv[i] + 8);
203
204 if (cfg.shell) {
205 fprintf(stderr, "Error: only one user shell can be specified\n");
206 exit(1);
207 }
208 cfg.shell = argv[i] + 8;
209
210 if (is_dir(cfg.shell) || strstr(cfg.shell, "..")) {
211 fprintf(stderr, "Error: invalid shell\n");
212 exit(1);
213 }
214
215 // access call checks as real UID/GID, not as effective UID/GID
216 if(cfg.chrootdir) {
217 char *shellpath;
218 if (asprintf(&shellpath, "%s%s", cfg.chrootdir, cfg.shell) == -1)
219 errExit("asprintf");
220 if (access(shellpath, R_OK)) {
221 fprintf(stderr, "Error: cannot access shell file in chroot\n");
222 exit(1);
223 }
224 free(shellpath);
225 } else if (access(cfg.shell, R_OK)) {
226 fprintf(stderr, "Error: cannot access shell file\n");
227 exit(1);
228 }
229 }
230 } 175 }
231 176
232 // use $SHELL to get shell used in sandbox 177 // use $SHELL to get shell used in sandbox
233 if (!arg_shell_none && !cfg.shell) { 178 char *shell = getenv("SHELL");
234 char *shell = getenv("SHELL"); 179 if (shell && access(shell, R_OK) == 0)
235 if (shell && access(shell, R_OK) == 0) 180 cfg.shell = shell;
236 cfg.shell = shell; 181
237 }
238 // guess shell otherwise 182 // guess shell otherwise
239 if (!arg_shell_none && !cfg.shell) { 183 if (!cfg.shell) {
240 cfg.shell = guess_shell(); 184 cfg.shell = guess_shell();
241 if (arg_debug) 185 if (arg_debug)
242 printf("Autoselecting %s as shell\n", cfg.shell); 186 printf("Autoselecting %s as shell\n", cfg.shell);
243 } 187 }
244 if (!arg_shell_none && !cfg.shell) { 188 if (!cfg.shell) {
245 fprintf(stderr, "Error: unable to guess your shell, please set explicitly by using --shell option.\n"); 189 fprintf(stderr, "Error: unable to guess your shell, please set SHELL environment variable\n");
246 exit(1); 190 exit(1);
247 } 191 }
248 192
@@ -266,13 +210,11 @@ void run_no_sandbox(int argc, char **argv) {
266 } 210 }
267 } 211 }
268 212
269 if (!arg_shell_none) { 213 if (prog_index == 0) {
270 if (prog_index == 0) { 214 cfg.command_line = cfg.shell;
271 cfg.command_line = cfg.shell; 215 cfg.window_title = cfg.shell;
272 cfg.window_title = cfg.shell; 216 } else {
273 } else { 217 build_cmdline(&cfg.command_line, &cfg.window_title, argc, argv, prog_index);
274 build_cmdline(&cfg.command_line, &cfg.window_title, argc, argv, prog_index);
275 }
276 } 218 }
277 219
278 cfg.original_argv = argv; 220 cfg.original_argv = argv;
@@ -287,5 +229,6 @@ void run_no_sandbox(int argc, char **argv) {
287 fprintf(stderr, "Warning: an existing sandbox was detected. " 229 fprintf(stderr, "Warning: an existing sandbox was detected. "
288 "%s will run without any additional sandboxing features\n", command); 230 "%s will run without any additional sandboxing features\n", command);
289 231
232 arg_quiet = 1;
290 start_application(); 233 start_application();
291} 234}
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 3697b54b9..da3daf95a 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -650,6 +650,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
650 return 0; 650 return 0;
651 } 651 }
652 652
653 if (strcmp(ptr, "machine-id") == 0) {
654 arg_machineid = 1;
655 return 0;
656 }
653 // writable-var 657 // writable-var
654 if (strcmp(ptr, "writable-var") == 0) { 658 if (strcmp(ptr, "writable-var") == 0) {
655 arg_writable_var = 1; 659 arg_writable_var = 1;
@@ -1049,6 +1053,9 @@ void profile_read(const char *fname) {
1049// else { 1053// else {
1050// free(ptr); 1054// free(ptr);
1051// } 1055// }
1056#ifdef HAVE_GCOV
1057 __gcov_flush();
1058#endif
1052 } 1059 }
1053 fclose(fp); 1060 fclose(fp);
1054} 1061}
diff --git a/src/firejail/rlimit.c b/src/firejail/rlimit.c
index a774fd6f5..47dd846d2 100644
--- a/src/firejail/rlimit.c
+++ b/src/firejail/rlimit.c
@@ -27,6 +27,9 @@ void set_rlimits(void) {
27 if (arg_rlimit_nofile) { 27 if (arg_rlimit_nofile) {
28 rl.rlim_cur = (rlim_t) cfg.rlimit_nofile; 28 rl.rlim_cur = (rlim_t) cfg.rlimit_nofile;
29 rl.rlim_max = (rlim_t) cfg.rlimit_nofile; 29 rl.rlim_max = (rlim_t) cfg.rlimit_nofile;
30#ifdef HAVE_GCOV // gcov-instrumented programs might crash at this point
31 __gcov_dump();
32#endif
30 if (setrlimit(RLIMIT_NOFILE, &rl) == -1) 33 if (setrlimit(RLIMIT_NOFILE, &rl) == -1)
31 errExit("setrlimit"); 34 errExit("setrlimit");
32 if (arg_debug) 35 if (arg_debug)
@@ -36,6 +39,9 @@ void set_rlimits(void) {
36 if (arg_rlimit_nproc) { 39 if (arg_rlimit_nproc) {
37 rl.rlim_cur = (rlim_t) cfg.rlimit_nproc; 40 rl.rlim_cur = (rlim_t) cfg.rlimit_nproc;
38 rl.rlim_max = (rlim_t) cfg.rlimit_nproc; 41 rl.rlim_max = (rlim_t) cfg.rlimit_nproc;
42#ifdef HAVE_GCOV
43 __gcov_dump();
44#endif
39 if (setrlimit(RLIMIT_NPROC, &rl) == -1) 45 if (setrlimit(RLIMIT_NPROC, &rl) == -1)
40 errExit("setrlimit"); 46 errExit("setrlimit");
41 if (arg_debug) 47 if (arg_debug)
@@ -45,6 +51,9 @@ void set_rlimits(void) {
45 if (arg_rlimit_fsize) { 51 if (arg_rlimit_fsize) {
46 rl.rlim_cur = (rlim_t) cfg.rlimit_fsize; 52 rl.rlim_cur = (rlim_t) cfg.rlimit_fsize;
47 rl.rlim_max = (rlim_t) cfg.rlimit_fsize; 53 rl.rlim_max = (rlim_t) cfg.rlimit_fsize;
54#ifdef HAVE_GCOV
55 __gcov_dump();
56#endif
48 if (setrlimit(RLIMIT_FSIZE, &rl) == -1) 57 if (setrlimit(RLIMIT_FSIZE, &rl) == -1)
49 errExit("setrlimit"); 58 errExit("setrlimit");
50 if (arg_debug) 59 if (arg_debug)
@@ -54,6 +63,9 @@ void set_rlimits(void) {
54 if (arg_rlimit_sigpending) { 63 if (arg_rlimit_sigpending) {
55 rl.rlim_cur = (rlim_t) cfg.rlimit_sigpending; 64 rl.rlim_cur = (rlim_t) cfg.rlimit_sigpending;
56 rl.rlim_max = (rlim_t) cfg.rlimit_sigpending; 65 rl.rlim_max = (rlim_t) cfg.rlimit_sigpending;
66#ifdef HAVE_GCOV
67 __gcov_dump();
68#endif
57 if (setrlimit(RLIMIT_SIGPENDING, &rl) == -1) 69 if (setrlimit(RLIMIT_SIGPENDING, &rl) == -1)
58 errExit("setrlimit"); 70 errExit("setrlimit");
59 if (arg_debug) 71 if (arg_debug)
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 68b8f554d..50fcd6ed0 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -286,6 +286,9 @@ void start_application(void) {
286 //**************************************** 286 //****************************************
287 if (arg_audit) { 287 if (arg_audit) {
288 assert(arg_audit_prog); 288 assert(arg_audit_prog);
289#ifdef HAVE_GCOV
290 __gcov_dump();
291#endif
289 execl(arg_audit_prog, arg_audit_prog, NULL); 292 execl(arg_audit_prog, arg_audit_prog, NULL);
290 } 293 }
291 //**************************************** 294 //****************************************
@@ -309,6 +312,9 @@ void start_application(void) {
309 if (!arg_command && !arg_quiet) 312 if (!arg_command && !arg_quiet)
310 printf("Child process initialized\n"); 313 printf("Child process initialized\n");
311 314
315#ifdef HAVE_GCOV
316 __gcov_dump();
317#endif
312 execvp(cfg.original_argv[cfg.original_program_index], &cfg.original_argv[cfg.original_program_index]); 318 execvp(cfg.original_argv[cfg.original_program_index], &cfg.original_argv[cfg.original_program_index]);
313 exit(1); 319 exit(1);
314 } 320 }
@@ -356,6 +362,9 @@ void start_application(void) {
356 362
357 if (!arg_command && !arg_quiet) 363 if (!arg_command && !arg_quiet)
358 printf("Child process initialized\n"); 364 printf("Child process initialized\n");
365#ifdef HAVE_GCOV
366 __gcov_dump();
367#endif
359 execvp(arg[0], arg); 368 execvp(arg[0], arg);
360 } 369 }
361 370
diff --git a/src/firejail/usage.c b/src/firejail/usage.c
index c8bed06e3..db3c25a5a 100644
--- a/src/firejail/usage.c
+++ b/src/firejail/usage.c
@@ -94,6 +94,9 @@ void usage(void) {
94 printf(" --ls=name|pid dir_or_filename - list files in sandbox container.\n"); 94 printf(" --ls=name|pid dir_or_filename - list files in sandbox container.\n");
95#ifdef HAVE_NETWORK 95#ifdef HAVE_NETWORK
96 printf(" --mac=xx:xx:xx:xx:xx:xx - set interface MAC address.\n"); 96 printf(" --mac=xx:xx:xx:xx:xx:xx - set interface MAC address.\n");
97#endif
98 printf(" --machine-id - preserve /etc/machine-id\n");
99#ifdef HAVE_NETWORK
97 printf(" --mtu=number - set interface MTU.\n"); 100 printf(" --mtu=number - set interface MTU.\n");
98#endif 101#endif
99 printf(" --name=name - set sandbox name.\n"); 102 printf(" --name=name - set sandbox name.\n");
diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt
index 007374c75..fa522c154 100644
--- a/src/man/firejail-profile.txt
+++ b/src/man/firejail-profile.txt
@@ -447,6 +447,10 @@ iprange 192.168.1.150,192.168.1.160
447Assign MAC addresses to the last network interface defined by a net command. 447Assign MAC addresses to the last network interface defined by a net command.
448 448
449.TP 449.TP
450\fBmachine-id
451Preserve id number in /etc/machine-id file. By default a new random id is generated inside the sandbox.
452
453.TP
450\fBmtu number 454\fBmtu number
451Assign a MTU value to the last network interface defined by a net command. 455Assign a MTU value to the last network interface defined by a net command.
452 456
diff --git a/src/man/firejail.txt b/src/man/firejail.txt
index 450f30c68..fdeb9ea3f 100644
--- a/src/man/firejail.txt
+++ b/src/man/firejail.txt
@@ -666,6 +666,16 @@ Example:
666$ firejail \-\-net=eth0 \-\-mac=00:11:22:33:44:55 firefox 666$ firejail \-\-net=eth0 \-\-mac=00:11:22:33:44:55 firefox
667 667
668.TP 668.TP
669\fB\-\-machine-id
670Preserve id number in /etc/machine-id file. By default a new random id is generated inside the sandbox.
671.br
672
673.br
674Example:
675.br
676$ firejail \-\-machine-id
677
678.TP
669\fB\-\-mtu=number 679\fB\-\-mtu=number
670Assign a MTU value to the last network interface defined by a \-\-net option. 680Assign a MTU value to the last network interface defined by a \-\-net option.
671.br 681.br
diff --git a/test/environment/firejail-in-firejail.exp b/test/environment/firejail-in-firejail.exp
index 1122b712f..2b851ee72 100755
--- a/test/environment/firejail-in-firejail.exp
+++ b/test/environment/firejail-in-firejail.exp
@@ -16,9 +16,34 @@ sleep 1
16 16
17send -- "firejail\r" 17send -- "firejail\r"
18expect { 18expect {
19 timeout {puts "TESTING ERROR 1\n";exit} 19 timeout {puts "TESTING ERROR 2\n";exit}
20 "Warning: an existing sandbox was detected" 20 "Warning: an existing sandbox was detected"
21} 21}
22after 100 22after 100
23 23
24send -- "exit\r"
25after 100
26
27send -- "firejail --force\r"
28expect {
29 timeout {puts "TESTING ERROR 3\n";exit}
30 "cannot rise privileges"
31}
32after 100
33
34send -- "firejail --version\r"
35expect {
36 timeout {puts "TESTING ERROR 4\n";exit}
37 "firejail version"
38}
39after 100
40
41send -- "firejail --version --force\r"
42expect {
43 timeout {puts "TESTING ERROR 5\n";exit}
44 "firejail version"
45}
46after 100
47
48
24puts "\nall done\n" 49puts "\nall done\n"
diff --git a/test/environment/firejail-in-firejail2.exp b/test/environment/firejail-in-firejail2.exp
index 37d1c2870..330e5e372 100755
--- a/test/environment/firejail-in-firejail2.exp
+++ b/test/environment/firejail-in-firejail2.exp
@@ -14,11 +14,38 @@ expect {
14} 14}
15sleep 1 15sleep 1
16 16
17send -- "firejail\r"
18expect {
19 timeout {puts "TESTING ERROR 2\n";exit}
20 "Warning: an existing sandbox was detected"
21}
22after 100
23
24send -- "exit\r"
25after 100
26
17send -- "firejail --force\r" 27send -- "firejail --force\r"
18expect { 28expect {
19 timeout {puts "TESTING ERROR 1\n";exit} 29 timeout {puts "TESTING ERROR 3\n";exit}
20 "Child process initialized" 30 "Child process initialized"
21} 31}
22after 100 32after 100
23 33
34send -- "exit\r"
35after 100
36
37send -- "firejail --version\r"
38expect {
39 timeout {puts "TESTING ERROR 4\n";exit}
40 "firejail version"
41}
42after 100
43
44send -- "firejail --version --force\r"
45expect {
46 timeout {puts "TESTING ERROR 5\n";exit}
47 "firejail version"
48}
49after 100
50
24puts "\nall done\n" 51puts "\nall done\n"
diff --git a/test/network/dns-print.exp b/test/network/dns-print.exp
new file mode 100755
index 000000000..9cdc14a6d
--- /dev/null
+++ b/test/network/dns-print.exp
@@ -0,0 +1,31 @@
1#!/usr/bin/expect -f
2
3set timeout 10
4spawn $env(SHELL)
5match_max 100000
6
7send -- "firejail --name=test-dns --net=eth0 --dns=1.2.3.4 --dns=2.3.4.5 --dns=3.4.5.6\r"
8expect {
9 timeout {puts "TESTING ERROR 1\n";exit}
10 "Child process initialized"
11}
12sleep 1
13
14spawn $env(SHELL)
15send -- "firejail --dns.print=test-dns\r"
16expect {
17 timeout {puts "TESTING ERROR 2\n";exit}
18 "nameserver 1.2.3.4"
19}
20expect {
21 timeout {puts "TESTING ERROR 2\n";exit}
22 "nameserver 2.3.4.5"
23}
24expect {
25 timeout {puts "TESTING ERROR 2\n";exit}
26 "nameserver 3.4.5.6"
27}
28
29after 100
30
31puts "\nall done\n"
diff --git a/test/network/net_macvlan2.exp b/test/network/net_macvlan2.exp
new file mode 100755
index 000000000..7f21fc083
--- /dev/null
+++ b/test/network/net_macvlan2.exp
@@ -0,0 +1,43 @@
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 --net=eth0 --net=eth0 --net=eth0 --net=eth0\r"
11expect {
12 timeout {puts "TESTING ERROR 0.1\n";exit}
13 "eth0-"
14}
15expect {
16 timeout {puts "TESTING ERROR 0.2\n";exit}
17 "eth1-"
18}
19expect {
20 timeout {puts "TESTING ERROR 0.3\n";exit}
21 "eth2-"
22}
23expect {
24 timeout {puts "TESTING ERROR 0.4\n";exit}
25 "eth3-"
26}
27expect {
28 timeout {puts "TESTING ERROR 0.5\n";exit}
29 "Default gateway 192.168.1.1"
30}
31expect {
32 timeout {puts "TESTING ERROR 0.6\n";exit}
33 "Child process initialized"
34}
35after 100
36send -- "exit\r"
37sleep 1
38
39
40after 100
41
42puts "\nall done\n"
43
diff --git a/test/network/network.sh b/test/network/network.sh
index bea5dfb26..94df9935e 100755
--- a/test/network/network.sh
+++ b/test/network/network.sh
@@ -11,6 +11,9 @@ sudo ./configure
11echo "TESTING: firemon interface (firemon-interfaces.exp)" 11echo "TESTING: firemon interface (firemon-interfaces.exp)"
12sudo ./firemon-interfaces.exp 12sudo ./firemon-interfaces.exp
13 13
14echo "TESTING: print dns (dns-print.exp)"
15./dns-print.exp
16
14echo "TESTING: firemon arp (firemon-arp.exp)" 17echo "TESTING: firemon arp (firemon-arp.exp)"
15./firemon-arp.exp 18./firemon-arp.exp
16 19
@@ -69,6 +72,9 @@ echo "TESTING: network default gateway test 3 (net_defaultgw3.exp)"
69echo "TESTING: scan (net_scan.exp)" 72echo "TESTING: scan (net_scan.exp)"
70./net_scan.exp 73./net_scan.exp
71 74
75echo "TESTING: mtu (mtu.exp)"
76./mtu.exp
77
72echo "TESTING: interface (interface.exp)" 78echo "TESTING: interface (interface.exp)"
73./interface.exp 79./interface.exp
74 80
@@ -84,6 +90,9 @@ echo "TESTING: iprange (iprange.exp)"
84echo "TESTING: veth-name (veth-name.exp)" 90echo "TESTING: veth-name (veth-name.exp)"
85./veth-name.exp 91./veth-name.exp
86 92
93echo "TESTING: macvlan2 (net_macvlan2.exp)"
94./net_macvlan2.exp
95
87echo "TESTING: 4 bridges ARP (4bridges_arp.exp)" 96echo "TESTING: 4 bridges ARP (4bridges_arp.exp)"
88./4bridges_arp.exp 97./4bridges_arp.exp
89 98
diff --git a/test/network/net_macvlan.exp b/test/stress/net_macvlan.exp
index f457ea98f..6ea4a6adf 100755
--- a/test/network/net_macvlan.exp
+++ b/test/stress/net_macvlan.exp
@@ -12,7 +12,7 @@ spawn $env(SHELL)
12send -- "firejail --net=eth0 --ip=192.168.1.60\r" 12send -- "firejail --net=eth0 --ip=192.168.1.60\r"
13expect { 13expect {
14 timeout {puts "TESTING ERROR 1.1\n";puts "Please open a sandbox on 192.168.1.60\n";exit} 14 timeout {puts "TESTING ERROR 1.1\n";puts "Please open a sandbox on 192.168.1.60\n";exit}
15 "the address 192.168.1.60 is already in use" 15 "192.168.1.60 is interface eth0 address"
16} 16}
17 17
18 18
diff --git a/test/stress/stress.sh b/test/stress/stress.sh
new file mode 100755
index 000000000..35c846071
--- /dev/null
+++ b/test/stress/stress.sh
@@ -0,0 +1,11 @@
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: macvlan (net_macvlan.exp)"
10./net_macvlan.exp
11
diff --git a/todo b/todo
index 954fd786a..86917e6cd 100644
--- a/todo
+++ b/todo
@@ -299,3 +299,5 @@ read-only /var
299read-only /bin 299read-only /bin
300 300
30131. --private and --allusers are coliding 30131. --private and --allusers are coliding
302
30332. machine-id defined in rfc4122