aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/fbuilder/build_fs.c4
-rw-r--r--src/fbuilder/build_home.c2
-rw-r--r--src/fbuilder/build_profile.c26
-rw-r--r--src/fcopy/Makefile.in4
-rw-r--r--src/fcopy/main.c33
-rw-r--r--src/firecfg/firecfg.config9
-rw-r--r--src/firejail/firejail.h3
-rw-r--r--src/firejail/fs.c2
-rw-r--r--src/firejail/fs_lib.c88
-rw-r--r--src/firejail/fs_lib2.c10
-rw-r--r--src/firejail/join.c40
-rw-r--r--src/firejail/main.c7
-rw-r--r--src/firejail/no_sandbox.c15
-rw-r--r--src/firejail/profile.c11
-rw-r--r--src/firejail/run_symlink.c47
-rw-r--r--src/firejail/sandbox.c41
-rw-r--r--src/firejail/util.c45
-rw-r--r--src/fldd/Makefile.in4
-rw-r--r--src/fldd/main.c6
-rw-r--r--src/fnet/Makefile.in4
-rw-r--r--src/fnet/main.c8
-rw-r--r--src/fnetfilter/Makefile.in4
-rw-r--r--src/fnetfilter/main.c8
-rw-r--r--src/fsec-optimize/Makefile.in4
-rw-r--r--src/fsec-optimize/fsec_optimize.h1
-rw-r--r--src/fsec-optimize/main.c6
-rw-r--r--src/fsec-print/Makefile.in4
-rw-r--r--src/fsec-print/fsec_print.h1
-rw-r--r--src/fsec-print/main.c5
-rw-r--r--src/fseccomp/Makefile.in4
-rw-r--r--src/fseccomp/fseccomp.h1
-rw-r--r--src/fseccomp/main.c6
-rw-r--r--src/include/common.h7
-rw-r--r--src/lib/common.c34
-rw-r--r--src/lib/syscall.c1
-rw-r--r--src/man/firejail-profile.txt5
-rw-r--r--src/man/firejail.txt12
-rw-r--r--src/profstats/main.c24
38 files changed, 316 insertions, 220 deletions
diff --git a/src/fbuilder/build_fs.c b/src/fbuilder/build_fs.c
index 1b8231033..0bc4a0ee2 100644
--- a/src/fbuilder/build_fs.c
+++ b/src/fbuilder/build_fs.c
@@ -217,6 +217,10 @@ void build_share(const char *fname, FILE *fp) {
217//******************************************* 217//*******************************************
218static FileDB *tmp_out = NULL; 218static FileDB *tmp_out = NULL;
219static void tmp_callback(char *ptr) { 219static void tmp_callback(char *ptr) {
220 // skip strace file
221 if (strncmp(ptr, "/tmp/firejail-strace", 20) == 0)
222 return;
223
220 tmp_out = filedb_add(tmp_out, ptr); 224 tmp_out = filedb_add(tmp_out, ptr);
221} 225}
222 226
diff --git a/src/fbuilder/build_home.c b/src/fbuilder/build_home.c
index fca3396c4..c0f4a3407 100644
--- a/src/fbuilder/build_home.c
+++ b/src/fbuilder/build_home.c
@@ -24,7 +24,7 @@ static FileDB *db_skip = NULL;
24static FileDB *db_out = NULL; 24static FileDB *db_out = NULL;
25 25
26static void load_whitelist_common(void) { 26static void load_whitelist_common(void) {
27 FILE *fp = fopen("/etc/firejail/whitelist-common.inc", "r"); 27 FILE *fp = fopen(SYSCONFDIR "/whitelist-common.inc", "r");
28 if (!fp) { 28 if (!fp) {
29 fprintf(stderr, "Error: cannot open whitelist-common.inc\n"); 29 fprintf(stderr, "Error: cannot open whitelist-common.inc\n");
30 exit(1); 30 exit(1);
diff --git a/src/fbuilder/build_profile.c b/src/fbuilder/build_profile.c
index adc00e67b..09f41a838 100644
--- a/src/fbuilder/build_profile.c
+++ b/src/fbuilder/build_profile.c
@@ -80,10 +80,19 @@ void build_profile(int argc, char **argv, int index, FILE *fp) {
80 stroutput, 80 stroutput,
81 }; 81 };
82 82
83 // detect strace 83 // detect strace and check if Yama LSM allows us to use it
84 int have_strace = 0; 84 int have_strace = 0;
85 if (access("/usr/bin/strace", X_OK) == 0) 85 int have_yama_permission = 1;
86 if (access("/usr/bin/strace", X_OK) == 0) {
86 have_strace = 1; 87 have_strace = 1;
88 FILE *ps = fopen("/proc/sys/kernel/yama/ptrace_scope", "r");
89 if (ps) {
90 unsigned val;
91 if (fscanf(ps, "%u", &val) == 1)
92 have_yama_permission = (val < 2);
93 fclose(ps);
94 }
95 }
87 96
88 // calculate command length 97 // calculate command length
89 unsigned len = (int) sizeof(cmdlist) / sizeof(char*) + argc - index + 1; 98 unsigned len = (int) sizeof(cmdlist) / sizeof(char*) + argc - index + 1;
@@ -93,10 +102,11 @@ void build_profile(int argc, char **argv, int index, FILE *fp) {
93 cmd[0] = cmdlist[0]; // explicit assignment to clean scan-build error 102 cmd[0] = cmdlist[0]; // explicit assignment to clean scan-build error
94 103
95 // build command 104 // build command
105 // skip strace if not installed, or no permission to use it
106 int skip_strace = !(have_strace && have_yama_permission);
96 unsigned i = 0; 107 unsigned i = 0;
97 for (i = 0; i < (int) sizeof(cmdlist) / sizeof(char*); i++) { 108 for (i = 0; i < (int) sizeof(cmdlist) / sizeof(char*); i++) {
98 // skip strace if not installed 109 if (skip_strace && strcmp(cmdlist[i], "/usr/bin/strace") == 0)
99 if (have_strace == 0 && strcmp(cmdlist[i], "/usr/bin/strace") == 0)
100 break; 110 break;
101 cmd[i] = cmdlist[i]; 111 cmd[i] = cmdlist[i];
102 } 112 }
@@ -172,12 +182,14 @@ void build_profile(int argc, char **argv, int index, FILE *fp) {
172 fprintf(fp, "caps.drop all\n"); 182 fprintf(fp, "caps.drop all\n");
173 fprintf(fp, "nonewprivs\n"); 183 fprintf(fp, "nonewprivs\n");
174 fprintf(fp, "seccomp\n"); 184 fprintf(fp, "seccomp\n");
175 if (have_strace) 185 if (!have_strace) {
176 build_seccomp(strace_output, fp);
177 else {
178 fprintf(fp, "# If you install strace on your system, Firejail will also create a\n"); 186 fprintf(fp, "# If you install strace on your system, Firejail will also create a\n");
179 fprintf(fp, "# whitelisted seccomp filter.\n"); 187 fprintf(fp, "# whitelisted seccomp filter.\n");
180 } 188 }
189 else if (!have_yama_permission)
190 fprintf(fp, "# Yama security module prevents creation of a whitelisted seccomp filter\n");
191 else
192 build_seccomp(strace_output, fp);
181 fprintf(fp, "\n"); 193 fprintf(fp, "\n");
182 194
183 fprintf(fp, "### network\n"); 195 fprintf(fp, "### network\n");
diff --git a/src/fcopy/Makefile.in b/src/fcopy/Makefile.in
index 64e277e2d..85f84aa32 100644
--- a/src/fcopy/Makefile.in
+++ b/src/fcopy/Makefile.in
@@ -5,8 +5,8 @@ include ../common.mk
5%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/syscall.h 5%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/syscall.h
6 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@ 6 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@
7 7
8fcopy: $(OBJS) 8fcopy: $(OBJS) ../lib/common.o
9 $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTRA_LDFLAGS) 9 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o $(LIBS) $(EXTRA_LDFLAGS)
10 10
11clean:; rm -fr *.o fcopy *.gcov *.gcda *.gcno *.plist 11clean:; rm -fr *.o fcopy *.gcov *.gcda *.gcno *.plist
12 12
diff --git a/src/fcopy/main.c b/src/fcopy/main.c
index 67237b4ea..e65501d6d 100644
--- a/src/fcopy/main.c
+++ b/src/fcopy/main.c
@@ -23,7 +23,6 @@
23#include <ftw.h> 23#include <ftw.h>
24#include <errno.h> 24#include <errno.h>
25#include <pwd.h> 25#include <pwd.h>
26#include <sys/prctl.h>
27 26
28#if HAVE_SELINUX 27#if HAVE_SELINUX
29#include <sys/stat.h> 28#include <sys/stat.h>
@@ -112,7 +111,7 @@ static void copy_file(const char *srcname, const char *destname, mode_t mode, ui
112 } 111 }
113 112
114 // open destination 113 // open destination
115 int dst = open(destname, O_CREAT|O_WRONLY|O_TRUNC, 0755); 114 int dst = open(destname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR);
116 if (dst < 0) { 115 if (dst < 0) {
117 if (!arg_quiet) 116 if (!arg_quiet)
118 fprintf(stderr, "Warning fcopy: cannot open %s, file not copied\n", destname); 117 fprintf(stderr, "Warning fcopy: cannot open %s, file not copied\n", destname);
@@ -133,7 +132,8 @@ static void copy_file(const char *srcname, const char *destname, mode_t mode, ui
133 done += rv; 132 done += rv;
134 } 133 }
135 } 134 }
136 fflush(0); 135 if (len < 0)
136 goto errexit;
137 137
138 if (fchown(dst, uid, gid) == -1) 138 if (fchown(dst, uid, gid) == -1)
139 goto errexit; 139 goto errexit;
@@ -180,7 +180,7 @@ void copy_link(const char *target, const char *linkpath, mode_t mode, uid_t uid,
180 180
181 // if the link is already there, don't create it 181 // if the link is already there, don't create it
182 struct stat s; 182 struct stat s;
183 if (stat(linkpath, &s) == 0) 183 if (lstat(linkpath, &s) == 0)
184 return; 184 return;
185 185
186 char *rp = realpath(target, NULL); 186 char *rp = realpath(target, NULL);
@@ -412,30 +412,21 @@ int main(int argc, char **argv) {
412 exit(1); 412 exit(1);
413 } 413 }
414 414
415#ifdef WARN_DUMPABLE 415 warn_dumpable();
416 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 1 && getuid())
417 fprintf(stderr, "Error fcopy: I am dumpable\n");
418#endif
419
420 // trim trailing chars
421 if (src[strlen(src) - 1] == '/')
422 src[strlen(src) - 1] = '\0';
423 if (dest[strlen(dest) - 1] == '/')
424 dest[strlen(dest) - 1] = '\0';
425 416
426 // check the two files; remove ending / 417 // check the two files; remove ending /
427 int len = strlen(src); 418 size_t len = strlen(src);
428 if (src[len - 1] == '/') 419 while (len > 1 && src[len - 1] == '/')
429 src[len - 1] = '\0'; 420 src[--len] = '\0';
430 if (strcspn(src, "\\*&!?\"'<>%^(){}[];,") != (size_t)len) { 421 if (strcspn(src, "\\*&!?\"'<>%^(){}[];,") != len) {
431 fprintf(stderr, "Error fcopy: invalid source file name %s\n", src); 422 fprintf(stderr, "Error fcopy: invalid source file name %s\n", src);
432 exit(1); 423 exit(1);
433 } 424 }
434 425
435 len = strlen(dest); 426 len = strlen(dest);
436 if (dest[len - 1] == '/') 427 while (len > 1 && dest[len - 1] == '/')
437 dest[len - 1] = '\0'; 428 dest[--len] = '\0';
438 if (strcspn(dest, "\\*&!?\"'<>%^(){}[];,~") != (size_t)len) { 429 if (strcspn(dest, "\\*&!?\"'<>%^(){}[];,~") != len) {
439 fprintf(stderr, "Error fcopy: invalid dest file name %s\n", dest); 430 fprintf(stderr, "Error fcopy: invalid dest file name %s\n", dest);
440 exit(1); 431 exit(1);
441 } 432 }
diff --git a/src/firecfg/firecfg.config b/src/firecfg/firecfg.config
index 4853e099b..e924ef2ec 100644
--- a/src/firecfg/firecfg.config
+++ b/src/firecfg/firecfg.config
@@ -391,6 +391,7 @@ kazam
391kcalc 391kcalc
392# kdeinit4 392# kdeinit4
393kdenlive 393kdenlive
394kdiff3
394keepass 395keepass
395keepass2 396keepass2
396keepassx 397keepassx
@@ -424,6 +425,7 @@ kwrite
424leafpad 425leafpad
425# less - breaks man 426# less - breaks man
426libreoffice 427libreoffice
428librewolf
427liferea 429liferea
428lightsoff 430lightsoff
429lincity-ng 431lincity-ng
@@ -455,6 +457,7 @@ macrofusion
455magicor 457magicor
456# man 458# man
457manaplus 459manaplus
460marker
458masterpdfeditor 461masterpdfeditor
459masterpdfeditor4 462masterpdfeditor4
460masterpdfeditor5 463masterpdfeditor5
@@ -463,6 +466,7 @@ mate-calculator
463mate-color-select 466mate-color-select
464mate-dictionary 467mate-dictionary
465mathematica 468mathematica
469matrix-mirage
466mattermost-desktop 470mattermost-desktop
467mcabber 471mcabber
468mediainfo 472mediainfo
@@ -474,6 +478,8 @@ mencoder
474mendeleydesktop 478mendeleydesktop
475menulibre 479menulibre
476meteo-qt 480meteo-qt
481microsoft-edge
482microsoft-edge-dev
477midori 483midori
478min 484min
479mindless 485mindless
@@ -618,6 +624,7 @@ qemu-launcher
618qgis 624qgis
619qlipper 625qlipper
620qmmp 626qmmp
627qnapi
621qpdfview 628qpdfview
622qt-faststart 629qt-faststart
623qtox 630qtox
@@ -659,6 +666,7 @@ secret-tool
659shellcheck 666shellcheck
660shortwave 667shortwave
661shotcut 668shotcut
669shotwell
662signal-cli 670signal-cli
663signal-desktop 671signal-desktop
664silentarmy 672silentarmy
@@ -768,6 +776,7 @@ tremulous
768trojita 776trojita
769truecraft 777truecraft
770tshark 778tshark
779tutanota-desktop
771tuxguitar 780tuxguitar
772tvbrowser 781tvbrowser
773twitch 782twitch
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 6c0ebcd43..9ea3edcd0 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -372,7 +372,7 @@ char *guess_shell(void);
372// sandbox.c 372// sandbox.c
373#define SANDBOX_DONE '1' 373#define SANDBOX_DONE '1'
374int sandbox(void* sandbox_arg); 374int sandbox(void* sandbox_arg);
375void start_application(int no_sandbox, char *set_sandbox_status) __attribute__((noreturn)); 375void start_application(int no_sandbox, int fd, char *set_sandbox_status) __attribute__((noreturn));
376void set_apparmor(void); 376void set_apparmor(void);
377 377
378// network_main.c 378// network_main.c
@@ -513,7 +513,6 @@ void check_private_dir(void);
513void update_map(char *mapping, char *map_file); 513void update_map(char *mapping, char *map_file);
514void wait_for_other(int fd); 514void wait_for_other(int fd);
515void notify_other(int fd); 515void notify_other(int fd);
516const char *gnu_basename(const char *path);
517uid_t pid_get_uid(pid_t pid); 516uid_t pid_get_uid(pid_t pid);
518uid_t get_group_id(const char *group); 517uid_t get_group_id(const char *group);
519int remove_overlay_directory(void); 518int remove_overlay_directory(void);
diff --git a/src/firejail/fs.c b/src/firejail/fs.c
index 0d4e496e8..4e6c1adc3 100644
--- a/src/firejail/fs.c
+++ b/src/firejail/fs.c
@@ -795,6 +795,8 @@ void disable_config(void) {
795 disable_file(BLACKLIST_FILE, RUN_FIREJAIL_PROFILE_DIR); 795 disable_file(BLACKLIST_FILE, RUN_FIREJAIL_PROFILE_DIR);
796 if (stat(RUN_FIREJAIL_X11_DIR, &s) == 0) 796 if (stat(RUN_FIREJAIL_X11_DIR, &s) == 0)
797 disable_file(BLACKLIST_FILE, RUN_FIREJAIL_X11_DIR); 797 disable_file(BLACKLIST_FILE, RUN_FIREJAIL_X11_DIR);
798 if (!arg_appimage && stat(RUN_FIREJAIL_APPIMAGE_DIR, &s) == 0)
799 disable_file(BLACKLIST_FILE, RUN_FIREJAIL_APPIMAGE_DIR);
798} 800}
799 801
800 802
diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c
index 5cfd33b42..b8c1b21b1 100644
--- a/src/firejail/fs_lib.c
+++ b/src/firejail/fs_lib.c
@@ -33,6 +33,52 @@ extern void fslib_install_system(void);
33static int lib_cnt = 0; 33static int lib_cnt = 0;
34static int dir_cnt = 0; 34static int dir_cnt = 0;
35 35
36char *find_in_path(const char *program) {
37 EUID_ASSERT();
38 if (arg_debug)
39 printf("Searching $PATH for %s\n", program);
40
41 char self[MAXBUF];
42 ssize_t len = readlink("/proc/self/exe", self, MAXBUF - 1);
43 if (len < 0)
44 errExit("readlink");
45 self[len] = '\0';
46
47 char *path = getenv("PATH");
48 if (!path)
49 return NULL;
50 char *dup = strdup(path);
51 if (!dup)
52 errExit("strdup");
53 char *tok = strtok(dup, ":");
54 while (tok) {
55 char *fname;
56 if (asprintf(&fname, "%s/%s", tok, program) == -1)
57 errExit("asprintf");
58
59 if (arg_debug)
60 printf("trying #%s#\n", fname);
61 struct stat s;
62 if (stat(fname, &s) == 0) {
63 // but skip links created by firecfg
64 char *rp = realpath(fname, NULL);
65 if (!rp)
66 errExit("realpath");
67 if (strcmp(self, rp) != 0) {
68 free(rp);
69 free(dup);
70 return fname;
71 }
72 free(rp);
73 }
74 free(fname);
75 tok = strtok(NULL, ":");
76 }
77
78 free(dup);
79 return NULL;
80}
81
36static void report_duplication(const char *full_path) { 82static void report_duplication(const char *full_path) {
37 char *fname = strrchr(full_path, '/'); 83 char *fname = strrchr(full_path, '/');
38 if (fname && *(++fname) != '\0') { 84 if (fname && *(++fname) != '\0') {
@@ -165,7 +211,7 @@ void fslib_copy_dir(const char *full_path) {
165 mkdir_attr(dest, 0755, 0, 0); 211 mkdir_attr(dest, 0755, 0, 0);
166 212
167 if (mount(full_path, dest, NULL, MS_BIND|MS_REC, NULL) < 0 || 213 if (mount(full_path, dest, NULL, MS_BIND|MS_REC, NULL) < 0 ||
168 mount(NULL, dest, NULL, MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0) 214 mount(NULL, dest, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0)
169 errExit("mount bind"); 215 errExit("mount bind");
170 fs_logger2("clone", full_path); 216 fs_logger2("clone", full_path);
171 fs_logger2("mount", full_path); 217 fs_logger2("mount", full_path);
@@ -336,11 +382,40 @@ void fs_private_lib(void) {
336 // start timetrace 382 // start timetrace
337 timetrace_start(); 383 timetrace_start();
338 384
385 // bring in firejail executable libraries in case we are redirected here by a firejail symlink from /usr/local/bin/firejail
386 if (arg_debug || arg_debug_private_lib)
387 printf("Installing Firejail libraries\n");
388 fslib_install_list(PATH_FIREJAIL);
389
390 // bring in firejail directory
391 fslib_install_list(LIBDIR "/firejail");
392
393 // bring in dhclient libraries
394 if (any_dhcp()) {
395 if (arg_debug || arg_debug_private_lib)
396 printf("Installing dhclient libraries\n");
397 fslib_install_list(RUN_MNT_DIR "/dhclient");
398 }
399 fmessage("Firejail libraries installed in %0.2f ms\n", timetrace_end());
400
401 timetrace_start();
402
339 // copy the libs in the new lib directory for the main exe 403 // copy the libs in the new lib directory for the main exe
340 if (cfg.original_program_index > 0) { 404 if (cfg.original_program_index > 0) {
341 if (arg_debug || arg_debug_private_lib) 405 if (arg_debug || arg_debug_private_lib)
342 printf("Installing sandboxed program libraries\n"); 406 printf("Installing sandboxed program libraries\n");
343 fslib_install_list(cfg.original_argv[cfg.original_program_index]); 407
408 if (strchr(cfg.original_argv[cfg.original_program_index], '/'))
409 fslib_install_list(cfg.original_argv[cfg.original_program_index]);
410 else { // search executable in $PATH
411 EUID_USER();
412 char *fname = find_in_path(cfg.original_argv[cfg.original_program_index]);
413 EUID_ROOT();
414 if (fname) {
415 fslib_install_list(fname);
416 free(fname);
417 }
418 }
344 } 419 }
345 420
346 // for the shell 421 // for the shell
@@ -369,18 +444,11 @@ void fs_private_lib(void) {
369 } 444 }
370 fmessage("Program libraries installed in %0.2f ms\n", timetrace_end()); 445 fmessage("Program libraries installed in %0.2f ms\n", timetrace_end());
371 446
372 // install the reset of the system libraries 447 // install the rest of the system libraries
373 if (arg_debug || arg_debug_private_lib) 448 if (arg_debug || arg_debug_private_lib)
374 printf("Installing system libraries\n"); 449 printf("Installing system libraries\n");
375 fslib_install_system(); 450 fslib_install_system();
376 451
377 // bring in firejail directory for --trace and seccomp post exec
378 // bring in firejail executable libraries in case we are redirected here by a firejail symlink from /usr/local/bin/firejail
379 fslib_install_list("/usr/bin/firejail,firejail"); // todo: use the installed path for the executable
380
381 // install libraries needed by fcopy
382 fslib_install_list(PATH_FCOPY);
383
384 fmessage("Installed %d %s and %d %s\n", lib_cnt, (lib_cnt == 1)? "library": "libraries", 452 fmessage("Installed %d %s and %d %s\n", lib_cnt, (lib_cnt == 1)? "library": "libraries",
385 dir_cnt, (dir_cnt == 1)? "directory": "directories"); 453 dir_cnt, (dir_cnt == 1)? "directory": "directories");
386 454
diff --git a/src/firejail/fs_lib2.c b/src/firejail/fs_lib2.c
index b2ae07f3e..95e10ee05 100644
--- a/src/firejail/fs_lib2.c
+++ b/src/firejail/fs_lib2.c
@@ -30,6 +30,7 @@ extern void fslib_copy_dir(const char *full_path);
30//*************************************************************** 30//***************************************************************
31// standard libc libraries based on Debian's libc6 package 31// standard libc libraries based on Debian's libc6 package
32// selinux seems to be linked in most command line utilities 32// selinux seems to be linked in most command line utilities
33// libpcre2 is a dependency of selinux
33// locale (/usr/lib/locale) - without it, the program will default to "C" locale 34// locale (/usr/lib/locale) - without it, the program will default to "C" locale
34typedef struct liblist_t { 35typedef struct liblist_t {
35 const char *name; 36 const char *name;
@@ -38,6 +39,7 @@ typedef struct liblist_t {
38 39
39static LibList libc_list[] = { 40static LibList libc_list[] = {
40 { "libselinux.so.", 0 }, 41 { "libselinux.so.", 0 },
42 { "libpcre2-8.so.", 0 },
41 { "libapparmor.so.", 0}, 43 { "libapparmor.so.", 0},
42 { "ld-linux-x86-64.so.", 0 }, 44 { "ld-linux-x86-64.so.", 0 },
43 { "libanl.so.", 0 }, 45 { "libanl.so.", 0 },
@@ -104,17 +106,15 @@ static void stdc(const char *dirname) {
104 106
105void fslib_install_stdc(void) { 107void fslib_install_stdc(void) {
106 // install standard C libraries 108 // install standard C libraries
109 timetrace_start();
107 struct stat s; 110 struct stat s;
108 char *stdclib = "/lib64"; // CentOS, Fedora, Arch
109
110 if (stat("/lib/x86_64-linux-gnu", &s) == 0) { // Debian & friends 111 if (stat("/lib/x86_64-linux-gnu", &s) == 0) { // Debian & friends
111 mkdir_attr(RUN_LIB_DIR "/x86_64-linux-gnu", 0755, 0, 0); 112 mkdir_attr(RUN_LIB_DIR "/x86_64-linux-gnu", 0755, 0, 0);
112 selinux_relabel_path(RUN_LIB_DIR "/x86_64-linux-gnu", "/lib/x86_64-linux-gnu"); 113 selinux_relabel_path(RUN_LIB_DIR "/x86_64-linux-gnu", "/lib/x86_64-linux-gnu");
113 stdclib = "/lib/x86_64-linux-gnu"; 114 stdc("/lib/x86_64-linux-gnu");
114 } 115 }
115 116
116 timetrace_start(); 117 stdc("/lib64"); // CentOS, Fedora, Arch, ld-linux.so in Debian & friends
117 stdc(stdclib);
118 118
119 // install locale 119 // install locale
120 if (stat("/usr/lib/locale", &s) == 0) 120 if (stat("/usr/lib/locale", &s) == 0)
diff --git a/src/firejail/join.c b/src/firejail/join.c
index ca8b8c4bf..4f0210f95 100644
--- a/src/firejail/join.c
+++ b/src/firejail/join.c
@@ -20,10 +20,14 @@
20#include "firejail.h" 20#include "firejail.h"
21#include <sys/stat.h> 21#include <sys/stat.h>
22#include <sys/wait.h> 22#include <sys/wait.h>
23#include <fcntl.h>
24#include <unistd.h> 23#include <unistd.h>
25#include <errno.h> 24#include <errno.h>
26 25
26#include <fcntl.h>
27#ifndef O_PATH
28#define O_PATH 010000000
29#endif
30
27#include <sys/prctl.h> 31#include <sys/prctl.h>
28#ifndef PR_SET_NO_NEW_PRIVS 32#ifndef PR_SET_NO_NEW_PRIVS
29#define PR_SET_NO_NEW_PRIVS 38 33#define PR_SET_NO_NEW_PRIVS 38
@@ -292,13 +296,28 @@ static void extract_umask(pid_t pid) {
292 fprintf(stderr, "Error: cannot open umask file\n"); 296 fprintf(stderr, "Error: cannot open umask file\n");
293 exit(1); 297 exit(1);
294 } 298 }
295 if (fscanf(fp, "%o", &orig_umask) != 1) { 299 if (fscanf(fp, "%3o", &orig_umask) != 1) {
296 fprintf(stderr, "Error: cannot read umask\n"); 300 fprintf(stderr, "Error: cannot read umask\n");
297 exit(1); 301 exit(1);
298 } 302 }
299 fclose(fp); 303 fclose(fp);
300} 304}
301 305
306static int open_shell(void) {
307 EUID_ASSERT();
308 assert(cfg.shell);
309
310 if (arg_debug)
311 printf("Opening shell %s\n", cfg.shell);
312 // file descriptor will leak if not opened with O_CLOEXEC !!
313 int fd = open(cfg.shell, O_PATH|O_CLOEXEC);
314 if (fd == -1) {
315 fprintf(stderr, "Error: cannot open shell %s\n", cfg.shell);
316 exit(1);
317 }
318 return fd;
319}
320
302// return false if the sandbox identified by pid is not fully set up yet or if 321// return false if the sandbox identified by pid is not fully set up yet or if
303// it is no firejail sandbox at all, return true if the sandbox is complete 322// it is no firejail sandbox at all, return true if the sandbox is complete
304bool is_ready_for_join(const pid_t pid) { 323bool is_ready_for_join(const pid_t pid) {
@@ -316,7 +335,7 @@ bool is_ready_for_join(const pid_t pid) {
316 struct stat s; 335 struct stat s;
317 if (fstat(fd, &s) == -1) 336 if (fstat(fd, &s) == -1)
318 errExit("fstat"); 337 errExit("fstat");
319 if (!S_ISREG(s.st_mode) || s.st_uid != 0) { 338 if (!S_ISREG(s.st_mode) || s.st_uid != 0 || s.st_size != 1) {
320 close(fd); 339 close(fd);
321 return false; 340 return false;
322 } 341 }
@@ -391,6 +410,10 @@ void join(pid_t pid, int argc, char **argv, int index) {
391 410
392 extract_x11_display(parent); 411 extract_x11_display(parent);
393 412
413 int shfd = -1;
414 if (!arg_shell_none && !arg_audit)
415 shfd = open_shell();
416
394 EUID_ROOT(); 417 EUID_ROOT();
395 // in user mode set caps seccomp, cpu, cgroup, etc 418 // in user mode set caps seccomp, cpu, cgroup, etc
396 if (getuid() != 0) { 419 if (getuid() != 0) {
@@ -400,6 +423,7 @@ void join(pid_t pid, int argc, char **argv, int index) {
400 extract_cgroup(pid); 423 extract_cgroup(pid);
401 extract_nogroups(pid); 424 extract_nogroups(pid);
402 extract_user_namespace(pid); 425 extract_user_namespace(pid);
426 extract_umask(pid);
403#ifdef HAVE_APPARMOR 427#ifdef HAVE_APPARMOR
404 extract_apparmor(pid); 428 extract_apparmor(pid);
405#endif 429#endif
@@ -409,9 +433,6 @@ void join(pid_t pid, int argc, char **argv, int index) {
409 if (cfg.cgroup) // not available for uid 0 433 if (cfg.cgroup) // not available for uid 0
410 set_cgroup(cfg.cgroup); 434 set_cgroup(cfg.cgroup);
411 435
412 // set umask, also uid 0
413 extract_umask(pid);
414
415 // join namespaces 436 // join namespaces
416 if (arg_join_network) { 437 if (arg_join_network) {
417 if (join_namespace(pid, "net")) 438 if (join_namespace(pid, "net"))
@@ -522,10 +543,9 @@ void join(pid_t pid, int argc, char **argv, int index) {
522 extract_command(argc, argv, index); 543 extract_command(argc, argv, index);
523 if (cfg.command_line == NULL) { 544 if (cfg.command_line == NULL) {
524 assert(cfg.shell); 545 assert(cfg.shell);
525 cfg.command_line = cfg.shell;
526 cfg.window_title = cfg.shell; 546 cfg.window_title = cfg.shell;
527 } 547 }
528 if (arg_debug) 548 else if (arg_debug)
529 printf("Extracted command #%s#\n", cfg.command_line); 549 printf("Extracted command #%s#\n", cfg.command_line);
530 550
531 // set cpu affinity 551 // set cpu affinity
@@ -554,11 +574,13 @@ void join(pid_t pid, int argc, char **argv, int index) {
554 dbus_set_system_bus_env(); 574 dbus_set_system_bus_env();
555#endif 575#endif
556 576
557 start_application(0, NULL); 577 start_application(0, shfd, NULL);
558 578
559 __builtin_unreachable(); 579 __builtin_unreachable();
560 } 580 }
561 EUID_USER(); 581 EUID_USER();
582 if (shfd != -1)
583 close(shfd);
562 584
563 int status = 0; 585 int status = 0;
564 //***************************** 586 //*****************************
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 544bfe83a..0f0086a6e 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -1231,11 +1231,6 @@ int main(int argc, char **argv, char **envp) {
1231 } 1231 }
1232 EUID_ASSERT(); 1232 EUID_ASSERT();
1233 1233
1234#ifdef WARN_DUMPABLE
1235 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 1 && getuid())
1236 fprintf(stderr, "Error: Firejail is dumpable\n");
1237#endif
1238
1239 // check for force-nonewprivs in /etc/firejail/firejail.config file 1234 // check for force-nonewprivs in /etc/firejail/firejail.config file
1240 if (checkcfg(CFG_FORCE_NONEWPRIVS)) 1235 if (checkcfg(CFG_FORCE_NONEWPRIVS))
1241 arg_nonewprivs = 1; 1236 arg_nonewprivs = 1;
@@ -2787,7 +2782,7 @@ int main(int argc, char **argv, char **envp) {
2787 2782
2788 // build the sandbox command 2783 // build the sandbox command
2789 if (prog_index == -1 && cfg.shell) { 2784 if (prog_index == -1 && cfg.shell) {
2790 cfg.command_line = cfg.shell; 2785 assert(cfg.command_line == NULL); // runs cfg.shell
2791 cfg.window_title = cfg.shell; 2786 cfg.window_title = cfg.shell;
2792 cfg.command_name = cfg.shell; 2787 cfg.command_name = cfg.shell;
2793 } 2788 }
diff --git a/src/firejail/no_sandbox.c b/src/firejail/no_sandbox.c
index 01df77ee6..6c7803602 100644
--- a/src/firejail/no_sandbox.c
+++ b/src/firejail/no_sandbox.c
@@ -204,14 +204,15 @@ void run_no_sandbox(int argc, char **argv) {
204 break; 204 break;
205 } 205 }
206 } 206 }
207 // if shell is /usr/bin/firejail, replace it with /bin/bash 207
208 if (strcmp(cfg.shell, PATH_FIREJAIL) == 0) { 208// if shell is /usr/bin/firejail, replace it with /bin/bash
209 cfg.shell = "/bin/bash"; 209// if (strcmp(cfg.shell, PATH_FIREJAIL) == 0) {
210 prog_index = 0; 210// cfg.shell = "/bin/bash";
211 } 211// prog_index = 0;
212// }
212 213
213 if (prog_index == 0) { 214 if (prog_index == 0) {
214 cfg.command_line = cfg.shell; 215 assert(cfg.command_line == NULL); // runs cfg.shell
215 cfg.window_title = cfg.shell; 216 cfg.window_title = cfg.shell;
216 } else { 217 } else {
217 build_cmdline(&cfg.command_line, &cfg.window_title, argc, argv, prog_index); 218 build_cmdline(&cfg.command_line, &cfg.window_title, argc, argv, prog_index);
@@ -230,5 +231,5 @@ void run_no_sandbox(int argc, char **argv) {
230 231
231 arg_quiet = 1; 232 arg_quiet = 1;
232 233
233 start_application(1, NULL); 234 start_application(1, -1, NULL);
234} 235}
diff --git a/src/firejail/profile.c b/src/firejail/profile.c
index 4172c96f7..1ee8cdfcb 100644
--- a/src/firejail/profile.c
+++ b/src/firejail/profile.c
@@ -619,6 +619,17 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
619#endif 619#endif
620 return 0; 620 return 0;
621 } 621 }
622 else if (strncmp(ptr, "netns ", 6) == 0) {
623#ifdef HAVE_NETWORK
624 if (checkcfg(CFG_NETWORK)) {
625 arg_netns = ptr + 6;
626 check_netns(arg_netns);
627 }
628 else
629 warning_feature_disabled("networking");
630#endif
631 return 0;
632 }
622 else if (strcmp(ptr, "net none") == 0) { 633 else if (strcmp(ptr, "net none") == 0) {
623 arg_nonetwork = 1; 634 arg_nonetwork = 1;
624 cfg.bridge0.configured = 0; 635 cfg.bridge0.configured = 0;
diff --git a/src/firejail/run_symlink.c b/src/firejail/run_symlink.c
index ea3889024..b38cc0ca6 100644
--- a/src/firejail/run_symlink.c
+++ b/src/firejail/run_symlink.c
@@ -22,6 +22,8 @@
22#include <sys/stat.h> 22#include <sys/stat.h>
23#include <unistd.h> 23#include <unistd.h>
24 24
25extern char *find_in_path(const char *program);
26
25void run_symlink(int argc, char **argv, int run_as_is) { 27void run_symlink(int argc, char **argv, int run_as_is) {
26 EUID_ASSERT(); 28 EUID_ASSERT();
27 29
@@ -40,54 +42,17 @@ void run_symlink(int argc, char **argv, int run_as_is) {
40 errExit("setresuid"); 42 errExit("setresuid");
41 43
42 // find the real program by looking in PATH 44 // find the real program by looking in PATH
43 char *p = getenv("PATH"); 45 if (!getenv("PATH")) {
44 if (!p) {
45 fprintf(stderr, "Error: PATH environment variable not set\n"); 46 fprintf(stderr, "Error: PATH environment variable not set\n");
46 exit(1); 47 exit(1);
47 } 48 }
48 49
49 char *path = strdup(p); 50 char *p = find_in_path(program);
50 if (!path) 51 if (!p) {
51 errExit("strdup");
52
53 char *selfpath = realpath("/proc/self/exe", NULL);
54 if (!selfpath)
55 errExit("realpath");
56
57 // look in path for our program
58 char *tok = strtok(path, ":");
59 int found = 0;
60 while (tok) {
61 char *name;
62 if (asprintf(&name, "%s/%s", tok, program) == -1)
63 errExit("asprintf");
64
65 struct stat s;
66 if (stat(name, &s) == 0) {
67 /* coverity[toctou] */
68 char* rp = realpath(name, NULL);
69 if (!rp)
70 errExit("realpath");
71
72 if (strcmp(selfpath, rp) != 0) {
73 program = strdup(name);
74 found = 1;
75 free(rp);
76 break;
77 }
78
79 free(rp);
80 }
81
82 free(name);
83 tok = strtok(NULL, ":");
84 }
85 if (!found) {
86 fprintf(stderr, "Error: cannot find the program in the path\n"); 52 fprintf(stderr, "Error: cannot find the program in the path\n");
87 exit(1); 53 exit(1);
88 } 54 }
89 55 program = p;
90 free(selfpath);
91 56
92 // restore original umask 57 // restore original umask
93 umask(orig_umask); 58 umask(orig_umask);
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 5115191ea..d811fe45a 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -461,7 +461,7 @@ static int ok_to_run(const char *program) {
461 return 0; 461 return 0;
462} 462}
463 463
464void start_application(int no_sandbox, char *set_sandbox_status) { 464void start_application(int no_sandbox, int fd, char *set_sandbox_status) {
465 // set environment 465 // set environment
466 if (no_sandbox == 0) { 466 if (no_sandbox == 0) {
467 env_defaults(); 467 env_defaults();
@@ -471,7 +471,7 @@ void start_application(int no_sandbox, char *set_sandbox_status) {
471 umask(orig_umask); 471 umask(orig_umask);
472 472
473 if (arg_debug) { 473 if (arg_debug) {
474 printf("starting application\n"); 474 printf("Starting application\n");
475 printf("LD_PRELOAD=%s\n", getenv("LD_PRELOAD")); 475 printf("LD_PRELOAD=%s\n", getenv("LD_PRELOAD"));
476 } 476 }
477 477
@@ -488,9 +488,6 @@ void start_application(int no_sandbox, char *set_sandbox_status) {
488 if (set_sandbox_status) 488 if (set_sandbox_status)
489 *set_sandbox_status = SANDBOX_DONE; 489 *set_sandbox_status = SANDBOX_DONE;
490 execl(arg_audit_prog, arg_audit_prog, NULL); 490 execl(arg_audit_prog, arg_audit_prog, NULL);
491
492 perror("execl");
493 exit(1);
494 } 491 }
495 //**************************************** 492 //****************************************
496 // start the program without using a shell 493 // start the program without using a shell
@@ -532,35 +529,37 @@ void start_application(int no_sandbox, char *set_sandbox_status) {
532 //**************************************** 529 //****************************************
533 else { 530 else {
534 assert(cfg.shell); 531 assert(cfg.shell);
535 assert(cfg.command_line);
536 532
537 char *arg[5]; 533 char *arg[5];
538 int index = 0; 534 int index = 0;
539 arg[index++] = cfg.shell; 535 arg[index++] = cfg.shell;
540 if (login_shell) { 536 if (cfg.command_line) {
541 arg[index++] = "-l";
542 if (arg_debug)
543 printf("Starting %s login shell\n", cfg.shell);
544 } else {
545 arg[index++] = "-c";
546 if (arg_debug) 537 if (arg_debug)
547 printf("Running %s command through %s\n", cfg.command_line, cfg.shell); 538 printf("Running %s command through %s\n", cfg.command_line, cfg.shell);
539 arg[index++] = "-c";
548 if (arg_doubledash) 540 if (arg_doubledash)
549 arg[index++] = "--"; 541 arg[index++] = "--";
550 arg[index++] = cfg.command_line; 542 arg[index++] = cfg.command_line;
551 } 543 }
552 arg[index] = NULL; 544 else if (login_shell) {
545 if (arg_debug)
546 printf("Starting %s login shell\n", cfg.shell);
547 arg[index++] = "-l";
548 }
549 else if (arg_debug)
550 printf("Starting %s shell\n", cfg.shell);
551
553 assert(index < 5); 552 assert(index < 5);
553 arg[index] = NULL;
554 554
555 if (arg_debug) { 555 if (arg_debug) {
556 char *msg; 556 char *msg;
557 if (asprintf(&msg, "sandbox %d, execvp into %s", sandbox_pid, cfg.command_line) == -1) 557 if (asprintf(&msg, "sandbox %d, execvp into %s",
558 sandbox_pid, cfg.command_line ? cfg.command_line : cfg.shell) == -1)
558 errExit("asprintf"); 559 errExit("asprintf");
559 logmsg(msg); 560 logmsg(msg);
560 free(msg); 561 free(msg);
561 }
562 562
563 if (arg_debug) {
564 int i; 563 int i;
565 for (i = 0; i < 5; i++) { 564 for (i = 0; i < 5; i++) {
566 if (arg[i] == NULL) 565 if (arg[i] == NULL)
@@ -580,10 +579,14 @@ void start_application(int no_sandbox, char *set_sandbox_status) {
580 if (set_sandbox_status) 579 if (set_sandbox_status)
581 *set_sandbox_status = SANDBOX_DONE; 580 *set_sandbox_status = SANDBOX_DONE;
582 execvp(arg[0], arg); 581 execvp(arg[0], arg);
582
583 // join sandbox without shell in the mount namespace
584 if (fd > -1)
585 fexecve(fd, arg, environ);
583 } 586 }
584 587
585 perror("execvp"); 588 perror("Cannot start application");
586 exit(1); // it should never get here!!! 589 exit(1);
587} 590}
588 591
589static void enforce_filters(void) { 592static void enforce_filters(void) {
@@ -1223,7 +1226,7 @@ int sandbox(void* sandbox_arg) {
1223 set_nice(cfg.nice); 1226 set_nice(cfg.nice);
1224 set_rlimits(); 1227 set_rlimits();
1225 1228
1226 start_application(0, set_sandbox_status); 1229 start_application(0, -1, set_sandbox_status);
1227 } 1230 }
1228 1231
1229 munmap(set_sandbox_status, 1); 1232 munmap(set_sandbox_status, 1);
diff --git a/src/firejail/util.c b/src/firejail/util.c
index a3927cc88..911c8bd94 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -565,27 +565,18 @@ char *clean_pathname(const char *path) {
565 if (!rv) 565 if (!rv)
566 errExit("malloc"); 566 errExit("malloc");
567 567
568 if (len > 0) { 568 size_t i = 0;
569 size_t i = 0, j = 0, cnt = 0; 569 size_t j = 0;
570 for (; i < len; i++) { 570 while (path[i]) {
571 if (path[i] == '/') 571 while (path[i] == '/' && path[i+1] == '/')
572 cnt++; 572 i++;
573 else 573 rv[j++] = path[i++];
574 cnt = 0;
575
576 if (cnt < 2) {
577 rv[j] = path[i];
578 j++;
579 }
580 }
581 rv[j] = '\0';
582
583 // remove a trailing slash
584 if (j > 1 && rv[j - 1] == '/')
585 rv[j - 1] = '\0';
586 } 574 }
587 else 575 rv[j] = '\0';
588 *rv = '\0'; 576
577 // remove a trailing slash
578 if (j > 1 && rv[j - 1] == '/')
579 rv[j - 1] = '\0';
589 580
590 return rv; 581 return rv;
591} 582}
@@ -820,20 +811,6 @@ void notify_other(int fd) {
820 fclose(stream); 811 fclose(stream);
821} 812}
822 813
823
824
825
826// Equivalent to the GNU version of basename, which is incompatible with
827// the POSIX basename. A few lines of code saves any portability pain.
828// https://www.gnu.org/software/libc/manual/html_node/Finding-Tokens-in-a-String.html#index-basename
829const char *gnu_basename(const char *path) {
830 const char *last_slash = strrchr(path, '/');
831 if (!last_slash)
832 return path;
833 return last_slash+1;
834}
835
836
837uid_t pid_get_uid(pid_t pid) { 814uid_t pid_get_uid(pid_t pid) {
838 EUID_ASSERT(); 815 EUID_ASSERT();
839 uid_t rv = 0; 816 uid_t rv = 0;
diff --git a/src/fldd/Makefile.in b/src/fldd/Makefile.in
index 53382c2df..37b139d38 100644
--- a/src/fldd/Makefile.in
+++ b/src/fldd/Makefile.in
@@ -5,8 +5,8 @@ include ../common.mk
5%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/syscall.h ../include/ldd_utils.h 5%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/syscall.h ../include/ldd_utils.h
6 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@ 6 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@
7 7
8fldd: $(OBJS) ../lib/ldd_utils.o 8fldd: $(OBJS) ../lib/common.o ../lib/ldd_utils.o
9 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/ldd_utils.o $(LIBS) $(EXTRA_LDFLAGS) 9 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o ../lib/ldd_utils.o $(LIBS) $(EXTRA_LDFLAGS)
10 10
11clean:; rm -fr *.o fldd *.gcov *.gcda *.gcno *.plist 11clean:; rm -fr *.o fldd *.gcov *.gcda *.gcno *.plist
12 12
diff --git a/src/fldd/main.c b/src/fldd/main.c
index d68504f6b..55a0dfcce 100644
--- a/src/fldd/main.c
+++ b/src/fldd/main.c
@@ -24,7 +24,6 @@
24#include <fcntl.h> 24#include <fcntl.h>
25#include <sys/mman.h> 25#include <sys/mman.h>
26#include <sys/mount.h> 26#include <sys/mount.h>
27#include <sys/prctl.h>
28#include <sys/stat.h> 27#include <sys/stat.h>
29#include <sys/types.h> 28#include <sys/types.h>
30#include <unistd.h> 29#include <unistd.h>
@@ -303,10 +302,7 @@ printf("\n");
303 return 0; 302 return 0;
304 } 303 }
305 304
306#ifdef WARN_DUMPABLE 305 warn_dumpable();
307 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 1 && getuid())
308 fprintf(stderr, "Error fldd: I am dumpable\n");
309#endif
310 306
311 // check program access 307 // check program access
312 if (access(argv[1], R_OK)) { 308 if (access(argv[1], R_OK)) {
diff --git a/src/fnet/Makefile.in b/src/fnet/Makefile.in
index 37566db72..bd5fe9e7a 100644
--- a/src/fnet/Makefile.in
+++ b/src/fnet/Makefile.in
@@ -5,8 +5,8 @@ include ../common.mk
5%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/libnetlink.h 5%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/libnetlink.h
6 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@ 6 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@
7 7
8fnet: $(OBJS) ../lib/libnetlink.o 8fnet: $(OBJS) ../lib/common.o ../lib/libnetlink.o
9 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/libnetlink.o $(LIBS) $(EXTRA_LDFLAGS) 9 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o ../lib/libnetlink.o $(LIBS) $(EXTRA_LDFLAGS)
10 10
11clean:; rm -fr *.o fnet *.gcov *.gcda *.gcno *.plist 11clean:; rm -fr *.o fnet *.gcov *.gcda *.gcno *.plist
12 12
diff --git a/src/fnet/main.c b/src/fnet/main.c
index f6316a7fe..db090fb95 100644
--- a/src/fnet/main.c
+++ b/src/fnet/main.c
@@ -21,7 +21,6 @@
21#include <sys/types.h> 21#include <sys/types.h>
22#include <sys/stat.h> 22#include <sys/stat.h>
23#include <sys/utsname.h> 23#include <sys/utsname.h>
24#include <sys/prctl.h>
25 24
26int arg_quiet = 0; 25int arg_quiet = 0;
27 26
@@ -69,10 +68,9 @@ printf("\n");
69 usage(); 68 usage();
70 return 0; 69 return 0;
71 } 70 }
72#ifdef WARN_DUMPABLE 71
73 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 1 && getuid()) 72 warn_dumpable();
74 fprintf(stderr, "Error fnet: I am dumpable\n"); 73
75#endif
76 char *quiet = getenv("FIREJAIL_QUIET"); 74 char *quiet = getenv("FIREJAIL_QUIET");
77 if (quiet && strcmp(quiet, "yes") == 0) 75 if (quiet && strcmp(quiet, "yes") == 0)
78 arg_quiet = 1; 76 arg_quiet = 1;
diff --git a/src/fnetfilter/Makefile.in b/src/fnetfilter/Makefile.in
index 055167192..6fe650a17 100644
--- a/src/fnetfilter/Makefile.in
+++ b/src/fnetfilter/Makefile.in
@@ -5,8 +5,8 @@ include ../common.mk
5%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/syscall.h 5%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/syscall.h
6 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@ 6 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@
7 7
8fnetfilter: $(OBJS) 8fnetfilter: $(OBJS) ../lib/common.o
9 $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTRA_LDFLAGS) 9 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o $(LIBS) $(EXTRA_LDFLAGS)
10 10
11clean:; rm -fr *.o fnetfilter *.gcov *.gcda *.gcno *.plist 11clean:; rm -fr *.o fnetfilter *.gcov *.gcda *.gcno *.plist
12 12
diff --git a/src/fnetfilter/main.c b/src/fnetfilter/main.c
index 1ca35ab56..381d0d36e 100644
--- a/src/fnetfilter/main.c
+++ b/src/fnetfilter/main.c
@@ -18,7 +18,6 @@
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/ 19*/
20#include "../include/common.h" 20#include "../include/common.h"
21#include <sys/prctl.h>
22 21
23#define MAXBUF 4098 22#define MAXBUF 4098
24#define MAXARGS 16 23#define MAXARGS 16
@@ -181,10 +180,9 @@ printf("\n");
181 usage(); 180 usage();
182 return 1; 181 return 1;
183 } 182 }
184#ifdef WARN_DUMPABLE 183
185 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 1 && getuid()) 184 warn_dumpable();
186 fprintf(stderr, "Error fnetfilter: I am dumpable\n"); 185
187#endif
188 char *destfile = (argc == 3)? argv[2]: argv[1]; 186 char *destfile = (argc == 3)? argv[2]: argv[1];
189 char *command = (argc == 3)? argv[1]: NULL; 187 char *command = (argc == 3)? argv[1]: NULL;
190//printf("command %s\n", command); 188//printf("command %s\n", command);
diff --git a/src/fsec-optimize/Makefile.in b/src/fsec-optimize/Makefile.in
index 0387f7ec7..b6a28fdd8 100644
--- a/src/fsec-optimize/Makefile.in
+++ b/src/fsec-optimize/Makefile.in
@@ -5,8 +5,8 @@ include ../common.mk
5%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/seccomp.h ../include/syscall.h 5%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/seccomp.h ../include/syscall.h
6 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@ 6 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@
7 7
8fsec-optimize: $(OBJS) ../lib/libnetlink.o 8fsec-optimize: $(OBJS) ../lib/common.o ../lib/libnetlink.o
9 $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(EXTRA_LDFLAGS) 9 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o $(LIBS) $(EXTRA_LDFLAGS)
10 10
11clean:; rm -fr *.o fsec-optimize *.gcov *.gcda *.gcno *.plist 11clean:; rm -fr *.o fsec-optimize *.gcov *.gcda *.gcno *.plist
12 12
diff --git a/src/fsec-optimize/fsec_optimize.h b/src/fsec-optimize/fsec_optimize.h
index 034fde2ac..211111641 100644
--- a/src/fsec-optimize/fsec_optimize.h
+++ b/src/fsec-optimize/fsec_optimize.h
@@ -22,7 +22,6 @@
22#include "../include/common.h" 22#include "../include/common.h"
23#include "../include/seccomp.h" 23#include "../include/seccomp.h"
24#include <sys/mman.h> 24#include <sys/mman.h>
25#include <sys/prctl.h>
26 25
27// optimize.c 26// optimize.c
28struct sock_filter *duplicate(struct sock_filter *filter, int entries); 27struct sock_filter *duplicate(struct sock_filter *filter, int entries);
diff --git a/src/fsec-optimize/main.c b/src/fsec-optimize/main.c
index fb13eeca8..74aebc9e0 100644
--- a/src/fsec-optimize/main.c
+++ b/src/fsec-optimize/main.c
@@ -44,11 +44,7 @@ printf("\n");
44 return 0; 44 return 0;
45 } 45 }
46 46
47#ifdef WARN_DUMPABLE 47 warn_dumpable();
48 // check FIREJAIL_PLUGIN in order to not print a warning during make
49 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 1 && getuid() && getenv("FIREJAIL_PLUGIN"))
50 fprintf(stderr, "Error fsec-optimize: I am dumpable\n");
51#endif
52 48
53 char *fname = argv[1]; 49 char *fname = argv[1];
54 50
diff --git a/src/fsec-print/Makefile.in b/src/fsec-print/Makefile.in
index a30ff4ba3..bf39a8c77 100644
--- a/src/fsec-print/Makefile.in
+++ b/src/fsec-print/Makefile.in
@@ -5,8 +5,8 @@ include ../common.mk
5%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/seccomp.h ../include/syscall.h 5%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/seccomp.h ../include/syscall.h
6 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@ 6 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@
7 7
8fsec-print: $(OBJS) ../lib/libnetlink.o ../lib/errno.o ../lib/syscall.o 8fsec-print: $(OBJS) ../lib/common.o ../lib/libnetlink.o ../lib/errno.o ../lib/syscall.o
9 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/errno.o ../lib/syscall.o $(LIBS) $(EXTRA_LDFLAGS) 9 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o ../lib/errno.o ../lib/syscall.o $(LIBS) $(EXTRA_LDFLAGS)
10 10
11clean:; rm -fr *.o fsec-print *.gcov *.gcda *.gcno *.plist 11clean:; rm -fr *.o fsec-print *.gcov *.gcda *.gcno *.plist
12 12
diff --git a/src/fsec-print/fsec_print.h b/src/fsec-print/fsec_print.h
index 9d17e3f18..337199288 100644
--- a/src/fsec-print/fsec_print.h
+++ b/src/fsec-print/fsec_print.h
@@ -23,7 +23,6 @@
23#include "../include/seccomp.h" 23#include "../include/seccomp.h"
24#include "../include/syscall.h" 24#include "../include/syscall.h"
25#include <sys/mman.h> 25#include <sys/mman.h>
26#include <sys/prctl.h>
27 26
28// print.c 27// print.c
29void print(struct sock_filter *filter, int entries); 28void print(struct sock_filter *filter, int entries);
diff --git a/src/fsec-print/main.c b/src/fsec-print/main.c
index d1f056e47..ed030db21 100644
--- a/src/fsec-print/main.c
+++ b/src/fsec-print/main.c
@@ -61,10 +61,7 @@ printf("\n");
61 return 0; 61 return 0;
62 } 62 }
63 63
64#ifdef WARN_DUMPABLE 64 warn_dumpable();
65 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 1 && getuid())
66 fprintf(stderr, "Error fsec-print: I am dumpable\n");
67#endif
68 65
69 char *fname = argv[1]; 66 char *fname = argv[1];
70 67
diff --git a/src/fseccomp/Makefile.in b/src/fseccomp/Makefile.in
index 8623db6f8..b776a73ce 100644
--- a/src/fseccomp/Makefile.in
+++ b/src/fseccomp/Makefile.in
@@ -5,8 +5,8 @@ include ../common.mk
5%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/syscall.h 5%.o : %.c $(H_FILE_LIST) ../include/common.h ../include/syscall.h
6 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@ 6 $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@
7 7
8fseccomp: $(OBJS) ../lib/errno.o ../lib/syscall.o 8fseccomp: $(OBJS) ../lib/common.o ../lib/errno.o ../lib/syscall.o
9 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/errno.o ../lib/syscall.o $(LIBS) $(EXTRA_LDFLAGS) 9 $(CC) $(LDFLAGS) -o $@ $(OBJS) ../lib/common.o ../lib/errno.o ../lib/syscall.o $(LIBS) $(EXTRA_LDFLAGS)
10 10
11clean:; rm -fr *.o fseccomp *.gcov *.gcda *.gcno *.plist 11clean:; rm -fr *.o fseccomp *.gcov *.gcda *.gcno *.plist
12 12
diff --git a/src/fseccomp/fseccomp.h b/src/fseccomp/fseccomp.h
index e40999938..e8dd083b6 100644
--- a/src/fseccomp/fseccomp.h
+++ b/src/fseccomp/fseccomp.h
@@ -23,7 +23,6 @@
23#include <stdlib.h> 23#include <stdlib.h>
24#include <string.h> 24#include <string.h>
25#include <assert.h> 25#include <assert.h>
26#include <sys/prctl.h>
27#include "../include/common.h" 26#include "../include/common.h"
28#include "../include/syscall.h" 27#include "../include/syscall.h"
29 28
diff --git a/src/fseccomp/main.c b/src/fseccomp/main.c
index f505ca0f3..c8259b079 100644
--- a/src/fseccomp/main.c
+++ b/src/fseccomp/main.c
@@ -69,11 +69,7 @@ printf("\n");
69 return 0; 69 return 0;
70 } 70 }
71 71
72#ifdef WARN_DUMPABLE 72 warn_dumpable();
73 // check FIREJAIL_PLUGIN in order to not print a warning during make
74 if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 1 && getuid() && getenv("FIREJAIL_PLUGIN"))
75 fprintf(stderr, "Error fseccomp: I am dumpable\n");
76#endif
77 73
78 char *quiet = getenv("FIREJAIL_QUIET"); 74 char *quiet = getenv("FIREJAIL_QUIET");
79 if (quiet && strcmp(quiet, "yes") == 0) 75 if (quiet && strcmp(quiet, "yes") == 0)
diff --git a/src/include/common.h b/src/include/common.h
index 5df51c5a9..5497929c7 100644
--- a/src/include/common.h
+++ b/src/include/common.h
@@ -38,11 +38,6 @@
38 38
39#define errExit(msg) do { char msgout[500]; snprintf(msgout, 500, "Error %s: %s:%d %s", msg, __FILE__, __LINE__, __FUNCTION__); perror(msgout); exit(1);} while (0) 39#define errExit(msg) do { char msgout[500]; snprintf(msgout, 500, "Error %s: %s:%d %s", msg, __FILE__, __LINE__, __FUNCTION__); perror(msgout); exit(1);} while (0)
40 40
41// check if processes run with dumpable flag set
42// currently we get "Error fseccomp: I am dumpable" every time we run a firejail build on Debian 8,
43// regardless what Debian version we run the build on
44//#define WARN_DUMPABLE
45
46// macro to print ip addresses in a printf statement 41// macro to print ip addresses in a printf statement
47#define PRINT_IP(A) \ 42#define PRINT_IP(A) \
48((int) (((A) >> 24) & 0xFF)), ((int) (((A) >> 16) & 0xFF)), ((int) (((A) >> 8) & 0xFF)), ((int) ( (A) & 0xFF)) 43((int) (((A) >> 24) & 0xFF)), ((int) (((A) >> 16) & 0xFF)), ((int) (((A) >> 8) & 0xFF)), ((int) ( (A) & 0xFF))
@@ -126,4 +121,6 @@ char *pid_proc_comm(const pid_t pid);
126char *pid_proc_cmdline(const pid_t pid); 121char *pid_proc_cmdline(const pid_t pid);
127int pid_proc_cmdline_x11_xpra_xephyr(const pid_t pid); 122int pid_proc_cmdline_x11_xpra_xephyr(const pid_t pid);
128int pid_hidepid(void); 123int pid_hidepid(void);
124void warn_dumpable(void);
125const char *gnu_basename(const char *path);
129#endif 126#endif
diff --git a/src/lib/common.c b/src/lib/common.c
index 823442835..ace5cb87e 100644
--- a/src/lib/common.c
+++ b/src/lib/common.c
@@ -267,7 +267,6 @@ int pid_proc_cmdline_x11_xpra_xephyr(const pid_t pid) {
267} 267}
268 268
269// return 1 if /proc is mounted hidepid, or if /proc/mouns access is denied 269// return 1 if /proc is mounted hidepid, or if /proc/mouns access is denied
270#define BUFLEN 4096
271int pid_hidepid(void) { 270int pid_hidepid(void) {
272 FILE *fp = fopen("/proc/mounts", "r"); 271 FILE *fp = fopen("/proc/mounts", "r");
273 if (!fp) 272 if (!fp)
@@ -288,6 +287,39 @@ int pid_hidepid(void) {
288 return 0; 287 return 0;
289} 288}
290 289
290// print error if unprivileged users can trace the process
291void warn_dumpable(void) {
292 if (getuid() != 0 && prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 1 && getenv("FIREJAIL_PLUGIN")) {
293 fprintf(stderr, "Error: dumpable process\n");
294
295 // best effort to provide detailed debug information
296 // cannot use process name, it is just a file descriptor number
297 char path[BUFLEN];
298 ssize_t len = readlink("/proc/self/exe", path, BUFLEN - 1);
299 if (len < 0)
300 return;
301 path[len] = '\0';
302 // path can refer to a sandbox mount namespace, use basename only
303 const char *base = gnu_basename(path);
304
305 struct stat s;
306 if (stat("/proc/self/exe", &s) == 0 && s.st_uid != 0)
307 fprintf(stderr, "Change owner of %s executable to root\n", base);
308 else if (access("/proc/self/exe", R_OK) == 0)
309 fprintf(stderr, "Remove read permission on %s executable\n", base);
310 }
311}
312
313// Equivalent to the GNU version of basename, which is incompatible with
314// the POSIX basename. A few lines of code saves any portability pain.
315// https://www.gnu.org/software/libc/manual/html_node/Finding-Tokens-in-a-String.html#index-basename
316const char *gnu_basename(const char *path) {
317 const char *last_slash = strrchr(path, '/');
318 if (!last_slash)
319 return path;
320 return last_slash+1;
321}
322
291//************************** 323//**************************
292// time trace based on getticks function 324// time trace based on getticks function
293//************************** 325//**************************
diff --git a/src/lib/syscall.c b/src/lib/syscall.c
index 4903971ad..6823d0ae6 100644
--- a/src/lib/syscall.c
+++ b/src/lib/syscall.c
@@ -336,6 +336,7 @@ static const SyscallGroupList sysgroups[] = {
336#endif 336#endif
337 }, 337 },
338 { .name = "@default-keep", .list = 338 { .name = "@default-keep", .list =
339 "execveat," // commonly used by fexecve
339 "execve," 340 "execve,"
340 "prctl" 341 "prctl"
341 }, 342 },
diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt
index 9524254c1..030a3c95c 100644
--- a/src/man/firejail-profile.txt
+++ b/src/man/firejail-profile.txt
@@ -862,6 +862,11 @@ the parent interface specified by --net is not configured. An IP address and
862a default gateway address also have to be added. 862a default gateway address also have to be added.
863 863
864.TP 864.TP
865\fBnetns namespace
866Run the program in a named, persistent network namespace. These can
867be created and configured using "ip netns".
868
869.TP
865\fBveth-name name 870\fBveth-name name
866Use this name for the interface connected to the bridge for --net=bridge_interface commands, 871Use this name for the interface connected to the bridge for --net=bridge_interface commands,
867instead of the default one. 872instead of the default one.
diff --git a/src/man/firejail.txt b/src/man/firejail.txt
index 562b3eda3..e72ef48c2 100644
--- a/src/man/firejail.txt
+++ b/src/man/firejail.txt
@@ -76,10 +76,10 @@ If an appropriate profile is not found, Firejail will use a default profile.
76The default profile is quite restrictive. In case the application doesn't work, use --noprofile option 76The default profile is quite restrictive. In case the application doesn't work, use --noprofile option
77to disable it. For more information, please see \fBSECURITY PROFILES\fR section below. 77to disable it. For more information, please see \fBSECURITY PROFILES\fR section below.
78.PP 78.PP
79If a program argument is not specified, Firejail starts /bin/bash shell. 79If a program argument is not specified, Firejail starts the user's preferred shell.
80Examples: 80Examples:
81.PP 81.PP
82$ firejail [OPTIONS] # starting a /bin/bash shell 82$ firejail [OPTIONS] # starting the program specified in $SHELL, usually /bin/bash
83.PP 83.PP
84$ firejail [OPTIONS] firefox # starting Mozilla Firefox 84$ firejail [OPTIONS] firefox # starting Mozilla Firefox
85.PP 85.PP
@@ -2273,7 +2273,7 @@ rm: cannot remove `testfile': Operation not permitted
2273.TP 2273.TP
2274\fB\-\-seccomp.keep=syscall,@group,!syscall2 2274\fB\-\-seccomp.keep=syscall,@group,!syscall2
2275Enable seccomp filter, blacklist all syscall not listed and "syscall2". 2275Enable seccomp filter, blacklist all syscall not listed and "syscall2".
2276The system calls needed by Firejail (group @default-keep: prctl, execve) 2276The system calls needed by Firejail (group @default-keep: prctl, execve, execveat)
2277are handled with the preload library. On a 64 bit architecture, an 2277are handled with the preload library. On a 64 bit architecture, an
2278additional filter for 32 bit system calls can be installed with 2278additional filter for 32 bit system calls can be installed with
2279\-\-seccomp.32.keep. 2279\-\-seccomp.32.keep.
@@ -2476,7 +2476,7 @@ $ firejail \-\-shell=none script.sh
2476\fB\-\-shell=program 2476\fB\-\-shell=program
2477Set default user shell. Use this shell to run the application using \-c shell option. 2477Set default user shell. Use this shell to run the application using \-c shell option.
2478For example "firejail \-\-shell=/bin/dash firefox" will start Mozilla Firefox as "/bin/dash \-c firefox". 2478For example "firejail \-\-shell=/bin/dash firefox" will start Mozilla Firefox as "/bin/dash \-c firefox".
2479By default Bash shell (/bin/bash) is used. 2479By default the user's preferred shell is used.
2480.br 2480.br
2481 2481
2482.br 2482.br
@@ -3023,7 +3023,7 @@ We provide a tool that automates all this integration, please see \&\flfirecfg\f
3023.SH EXAMPLES 3023.SH EXAMPLES
3024.TP 3024.TP
3025\f\firejail 3025\f\firejail
3026Sandbox a regular /bin/bash session. 3026Sandbox a regular shell session.
3027.TP 3027.TP
3028\f\firejail firefox 3028\f\firejail firefox
3029Start Mozilla Firefox. 3029Start Mozilla Firefox.
@@ -3043,7 +3043,7 @@ Start Firefox in a new network namespace. An IP address is
3043assigned automatically. 3043assigned automatically.
3044.TP 3044.TP
3045\f\firejail \-\-net=br0 \-\-ip=10.10.20.5 \-\-net=br1 \-\-net=br2 3045\f\firejail \-\-net=br0 \-\-ip=10.10.20.5 \-\-net=br1 \-\-net=br2
3046Start a /bin/bash session in a new network namespace and connect it 3046Start a shell session in a new network namespace and connect it
3047to br0, br1, and br2 host bridge devices. IP addresses are assigned 3047to br0, br1, and br2 host bridge devices. IP addresses are assigned
3048automatically for the interfaces connected to br1 and b2 3048automatically for the interfaces connected to br1 and b2
3049#endif 3049#endif
diff --git a/src/profstats/main.c b/src/profstats/main.c
index 4c1221464..68f62831b 100644
--- a/src/profstats/main.c
+++ b/src/profstats/main.c
@@ -30,6 +30,8 @@ static int cnt_seccomp = 0;
30static int cnt_caps = 0; 30static int cnt_caps = 0;
31static int cnt_dbus_system_none = 0; 31static int cnt_dbus_system_none = 0;
32static int cnt_dbus_user_none = 0; 32static int cnt_dbus_user_none = 0;
33static int cnt_dbus_system_filter = 0;
34static int cnt_dbus_user_filter = 0;
33static int cnt_dotlocal = 0; 35static int cnt_dotlocal = 0;
34static int cnt_globalsdotlocal = 0; 36static int cnt_globalsdotlocal = 0;
35static int cnt_netnone = 0; 37static int cnt_netnone = 0;
@@ -107,6 +109,7 @@ void process_file(const char *fname) {
107 return; 109 return;
108 } 110 }
109 111
112 int have_include_local = 0;
110 char buf[MAXBUF]; 113 char buf[MAXBUF];
111 while (fgets(buf, MAXBUF, fp)) { 114 while (fgets(buf, MAXBUF, fp)) {
112 char *ptr = strchr(buf, '\n'); 115 char *ptr = strchr(buf, '\n');
@@ -152,11 +155,16 @@ void process_file(const char *fname) {
152 cnt_privateetc++; 155 cnt_privateetc++;
153 else if (strncmp(ptr, "dbus-system none", 16) == 0) 156 else if (strncmp(ptr, "dbus-system none", 16) == 0)
154 cnt_dbus_system_none++; 157 cnt_dbus_system_none++;
158 else if (strncmp(ptr, "dbus-system", 11) == 0)
159 cnt_dbus_system_filter++;
155 else if (strncmp(ptr, "dbus-user none", 14) == 0) 160 else if (strncmp(ptr, "dbus-user none", 14) == 0)
156 cnt_dbus_user_none++; 161 cnt_dbus_user_none++;
162 else if (strncmp(ptr, "dbus-user", 9) == 0)
163 cnt_dbus_user_filter++;
157 else if (strncmp(ptr, "include ", 8) == 0) { 164 else if (strncmp(ptr, "include ", 8) == 0) {
158 // not processing .local files 165 // not processing .local files
159 if (strstr(ptr, ".local")) { 166 if (strstr(ptr, ".local")) {
167 have_include_local = 1;
160//printf("dotlocal %d, level %d - #%s#, redirect #%s#\n", cnt_dotlocal, level, fname, buf + 8); 168//printf("dotlocal %d, level %d - #%s#, redirect #%s#\n", cnt_dotlocal, level, fname, buf + 8);
161 if (strstr(ptr, "globals.local")) 169 if (strstr(ptr, "globals.local"))
162 cnt_globalsdotlocal++; 170 cnt_globalsdotlocal++;
@@ -174,6 +182,8 @@ void process_file(const char *fname) {
174 } 182 }
175 183
176 fclose(fp); 184 fclose(fp);
185 if (!have_include_local)
186 printf("No include .local found in %s\n", fname);
177 level--; 187 level--;
178} 188}
179 189
@@ -257,7 +267,9 @@ int main(int argc, char **argv) {
257 int whitelistrunuser = cnt_whitelistrunuser; 267 int whitelistrunuser = cnt_whitelistrunuser;
258 int whitelistusrshare = cnt_whitelistusrshare; 268 int whitelistusrshare = cnt_whitelistusrshare;
259 int dbussystemnone = cnt_dbus_system_none; 269 int dbussystemnone = cnt_dbus_system_none;
270 int dbussystemfilter = cnt_dbus_system_filter;
260 int dbususernone = cnt_dbus_user_none; 271 int dbususernone = cnt_dbus_user_none;
272 int dbususerfilter = cnt_dbus_user_filter;
261 int ssh = cnt_ssh; 273 int ssh = cnt_ssh;
262 int mdwx = cnt_mdwx; 274 int mdwx = cnt_mdwx;
263 275
@@ -278,6 +290,16 @@ int main(int argc, char **argv) {
278 cnt_globalsdotlocal = globalsdotlocal + 1; 290 cnt_globalsdotlocal = globalsdotlocal + 1;
279 if (cnt_whitelistrunuser > (whitelistrunuser + 1)) 291 if (cnt_whitelistrunuser > (whitelistrunuser + 1))
280 cnt_whitelistrunuser = whitelistrunuser + 1; 292 cnt_whitelistrunuser = whitelistrunuser + 1;
293 if (cnt_seccomp > (seccomp + 1))
294 cnt_seccomp = seccomp + 1;
295 if (cnt_dbus_user_none > (dbususernone + 1))
296 cnt_dbus_user_none = dbususernone + 1;
297 if (cnt_dbus_user_filter > (dbususerfilter + 1))
298 cnt_dbus_user_filter = dbususerfilter + 1;
299 if (cnt_dbus_system_none > (dbussystemnone + 1))
300 cnt_dbus_system_none = dbussystemnone + 1;
301 if (cnt_dbus_system_filter > (dbussystemfilter + 1))
302 cnt_dbus_system_filter = dbussystemfilter + 1;
281 303
282 if (arg_dbus_system_none && dbussystemnone == cnt_dbus_system_none) 304 if (arg_dbus_system_none && dbussystemnone == cnt_dbus_system_none)
283 printf("No dbus-system none found in %s\n", argv[i]); 305 printf("No dbus-system none found in %s\n", argv[i]);
@@ -337,7 +359,9 @@ int main(int argc, char **argv) {
337 printf(" whitelist usr/share\t\t%d (include whitelist-usr-share-common.inc\n", cnt_whitelistusrshare); 359 printf(" whitelist usr/share\t\t%d (include whitelist-usr-share-common.inc\n", cnt_whitelistusrshare);
338 printf(" net none\t\t\t%d\n", cnt_netnone); 360 printf(" net none\t\t\t%d\n", cnt_netnone);
339 printf(" dbus-user none \t\t%d\n", cnt_dbus_user_none); 361 printf(" dbus-user none \t\t%d\n", cnt_dbus_user_none);
362 printf(" dbus-user filter \t\t%d\n", cnt_dbus_user_filter);
340 printf(" dbus-system none \t\t%d\n", cnt_dbus_system_none); 363 printf(" dbus-system none \t\t%d\n", cnt_dbus_system_none);
364 printf(" dbus-system filter \t\t%d\n", cnt_dbus_system_filter);
341 printf("\n"); 365 printf("\n");
342 return 0; 366 return 0;
343} 367}