aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/fcopy/main.c27
-rw-r--r--src/firecfg/firecfg.config2
-rw-r--r--src/firejail/fs_lib.c75
-rw-r--r--src/firejail/fs_lib2.c9
-rw-r--r--src/firejail/run_symlink.c47
-rw-r--r--src/man/firejail.txt2
-rw-r--r--src/profstats/main.c24
7 files changed, 116 insertions, 70 deletions
diff --git a/src/fcopy/main.c b/src/fcopy/main.c
index 0a4a61e2a..e65501d6d 100644
--- a/src/fcopy/main.c
+++ b/src/fcopy/main.c
@@ -111,7 +111,7 @@ static void copy_file(const char *srcname, const char *destname, mode_t mode, ui
111 } 111 }
112 112
113 // open destination 113 // open destination
114 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);
115 if (dst < 0) { 115 if (dst < 0) {
116 if (!arg_quiet) 116 if (!arg_quiet)
117 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);
@@ -132,7 +132,8 @@ static void copy_file(const char *srcname, const char *destname, mode_t mode, ui
132 done += rv; 132 done += rv;
133 } 133 }
134 } 134 }
135 fflush(0); 135 if (len < 0)
136 goto errexit;
136 137
137 if (fchown(dst, uid, gid) == -1) 138 if (fchown(dst, uid, gid) == -1)
138 goto errexit; 139 goto errexit;
@@ -179,7 +180,7 @@ void copy_link(const char *target, const char *linkpath, mode_t mode, uid_t uid,
179 180
180 // if the link is already there, don't create it 181 // if the link is already there, don't create it
181 struct stat s; 182 struct stat s;
182 if (stat(linkpath, &s) == 0) 183 if (lstat(linkpath, &s) == 0)
183 return; 184 return;
184 185
185 char *rp = realpath(target, NULL); 186 char *rp = realpath(target, NULL);
@@ -413,25 +414,19 @@ int main(int argc, char **argv) {
413 414
414 warn_dumpable(); 415 warn_dumpable();
415 416
416 // trim trailing chars
417 if (src[strlen(src) - 1] == '/')
418 src[strlen(src) - 1] = '\0';
419 if (dest[strlen(dest) - 1] == '/')
420 dest[strlen(dest) - 1] = '\0';
421
422 // check the two files; remove ending / 417 // check the two files; remove ending /
423 int len = strlen(src); 418 size_t len = strlen(src);
424 if (src[len - 1] == '/') 419 while (len > 1 && src[len - 1] == '/')
425 src[len - 1] = '\0'; 420 src[--len] = '\0';
426 if (strcspn(src, "\\*&!?\"'<>%^(){}[];,") != (size_t)len) { 421 if (strcspn(src, "\\*&!?\"'<>%^(){}[];,") != len) {
427 fprintf(stderr, "Error fcopy: invalid source file name %s\n", src); 422 fprintf(stderr, "Error fcopy: invalid source file name %s\n", src);
428 exit(1); 423 exit(1);
429 } 424 }
430 425
431 len = strlen(dest); 426 len = strlen(dest);
432 if (dest[len - 1] == '/') 427 while (len > 1 && dest[len - 1] == '/')
433 dest[len - 1] = '\0'; 428 dest[--len] = '\0';
434 if (strcspn(dest, "\\*&!?\"'<>%^(){}[];,~") != (size_t)len) { 429 if (strcspn(dest, "\\*&!?\"'<>%^(){}[];,~") != len) {
435 fprintf(stderr, "Error fcopy: invalid dest file name %s\n", dest); 430 fprintf(stderr, "Error fcopy: invalid dest file name %s\n", dest);
436 exit(1); 431 exit(1);
437 } 432 }
diff --git a/src/firecfg/firecfg.config b/src/firecfg/firecfg.config
index 109f89f39..e924ef2ec 100644
--- a/src/firecfg/firecfg.config
+++ b/src/firecfg/firecfg.config
@@ -149,6 +149,7 @@ conkeror
149conky 149conky
150conplay 150conplay
151corebird 151corebird
152coyim
152crawl 153crawl
153crawl-tiles 154crawl-tiles
154crow 155crow
@@ -390,6 +391,7 @@ kazam
390kcalc 391kcalc
391# kdeinit4 392# kdeinit4
392kdenlive 393kdenlive
394kdiff3
393keepass 395keepass
394keepass2 396keepass2
395keepassx 397keepassx
diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c
index a5c005931..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') {
@@ -337,20 +383,39 @@ void fs_private_lib(void) {
337 timetrace_start(); 383 timetrace_start();
338 384
339 // bring in firejail executable libraries in case we are redirected here by a firejail symlink from /usr/local/bin/firejail 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");
340 fslib_install_list(PATH_FIREJAIL); 388 fslib_install_list(PATH_FIREJAIL);
341 389
342 // bring in firejail directory 390 // bring in firejail directory
343 fslib_install_list("firejail"); 391 fslib_install_list(LIBDIR "/firejail");
344 392
345 // for dhclient 393 // bring in dhclient libraries
346 if (any_dhcp()) 394 if (any_dhcp()) {
395 if (arg_debug || arg_debug_private_lib)
396 printf("Installing dhclient libraries\n");
347 fslib_install_list(RUN_MNT_DIR "/dhclient"); 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();
348 402
349 // 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
350 if (cfg.original_program_index > 0) { 404 if (cfg.original_program_index > 0) {
351 if (arg_debug || arg_debug_private_lib) 405 if (arg_debug || arg_debug_private_lib)
352 printf("Installing sandboxed program libraries\n"); 406 printf("Installing sandboxed program libraries\n");
353 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 }
354 } 419 }
355 420
356 // for the shell 421 // for the shell
@@ -379,7 +444,7 @@ void fs_private_lib(void) {
379 } 444 }
380 fmessage("Program libraries installed in %0.2f ms\n", timetrace_end()); 445 fmessage("Program libraries installed in %0.2f ms\n", timetrace_end());
381 446
382 // install the reset of the system libraries 447 // install the rest of the system libraries
383 if (arg_debug || arg_debug_private_lib) 448 if (arg_debug || arg_debug_private_lib)
384 printf("Installing system libraries\n"); 449 printf("Installing system libraries\n");
385 fslib_install_system(); 450 fslib_install_system();
diff --git a/src/firejail/fs_lib2.c b/src/firejail/fs_lib2.c
index 758e079a4..95e10ee05 100644
--- a/src/firejail/fs_lib2.c
+++ b/src/firejail/fs_lib2.c
@@ -108,18 +108,13 @@ void fslib_install_stdc(void) {
108 // install standard C libraries 108 // install standard C libraries
109 timetrace_start(); 109 timetrace_start();
110 struct stat s; 110 struct stat s;
111 char *stdclib = "/lib64"; // CentOS, Fedora, Arch
112
113 if (stat("/lib/x86_64-linux-gnu", &s) == 0) { // Debian & friends 111 if (stat("/lib/x86_64-linux-gnu", &s) == 0) { // Debian & friends
114 // PT_INTERP
115 fslib_duplicate("/lib64/ld-linux-x86-64.so.2");
116
117 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);
118 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");
119 stdclib = "/lib/x86_64-linux-gnu"; 114 stdc("/lib/x86_64-linux-gnu");
120 } 115 }
121 116
122 stdc(stdclib); 117 stdc("/lib64"); // CentOS, Fedora, Arch, ld-linux.so in Debian & friends
123 118
124 // install locale 119 // install locale
125 if (stat("/usr/lib/locale", &s) == 0) 120 if (stat("/usr/lib/locale", &s) == 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/man/firejail.txt b/src/man/firejail.txt
index e72ef48c2..8958dfaee 100644
--- a/src/man/firejail.txt
+++ b/src/man/firejail.txt
@@ -1317,7 +1317,7 @@ $ firejail --netfilter=/etc/firejail/webserver.net --net=eth0 \\
1317.br 1317.br
1318 1318
1319.br 1319.br
1320.B nolocal.net 1320.B nolocal.net/nolocal6.net
1321is a desktop client firewall that disable access to local network. Example: 1321is a desktop client firewall that disable access to local network. Example:
1322.br 1322.br
1323 1323
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}