diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/fcopy/main.c | 27 | ||||
-rw-r--r-- | src/firecfg/firecfg.config | 2 | ||||
-rw-r--r-- | src/firejail/fs_lib.c | 75 | ||||
-rw-r--r-- | src/firejail/fs_lib2.c | 9 | ||||
-rw-r--r-- | src/firejail/run_symlink.c | 47 | ||||
-rw-r--r-- | src/man/firejail.txt | 2 | ||||
-rw-r--r-- | src/profstats/main.c | 24 |
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 | |||
149 | conky | 149 | conky |
150 | conplay | 150 | conplay |
151 | corebird | 151 | corebird |
152 | coyim | ||
152 | crawl | 153 | crawl |
153 | crawl-tiles | 154 | crawl-tiles |
154 | crow | 155 | crow |
@@ -390,6 +391,7 @@ kazam | |||
390 | kcalc | 391 | kcalc |
391 | # kdeinit4 | 392 | # kdeinit4 |
392 | kdenlive | 393 | kdenlive |
394 | kdiff3 | ||
393 | keepass | 395 | keepass |
394 | keepass2 | 396 | keepass2 |
395 | keepassx | 397 | keepassx |
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); | |||
33 | static int lib_cnt = 0; | 33 | static int lib_cnt = 0; |
34 | static int dir_cnt = 0; | 34 | static int dir_cnt = 0; |
35 | 35 | ||
36 | char *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 | |||
36 | static void report_duplication(const char *full_path) { | 82 | static 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 | ||
25 | extern char *find_in_path(const char *program); | ||
26 | |||
25 | void run_symlink(int argc, char **argv, int run_as_is) { | 27 | void 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 |
1321 | is a desktop client firewall that disable access to local network. Example: | 1321 | is 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; | |||
30 | static int cnt_caps = 0; | 30 | static int cnt_caps = 0; |
31 | static int cnt_dbus_system_none = 0; | 31 | static int cnt_dbus_system_none = 0; |
32 | static int cnt_dbus_user_none = 0; | 32 | static int cnt_dbus_user_none = 0; |
33 | static int cnt_dbus_system_filter = 0; | ||
34 | static int cnt_dbus_user_filter = 0; | ||
33 | static int cnt_dotlocal = 0; | 35 | static int cnt_dotlocal = 0; |
34 | static int cnt_globalsdotlocal = 0; | 36 | static int cnt_globalsdotlocal = 0; |
35 | static int cnt_netnone = 0; | 37 | static 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 | } |