diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/firecfg/firecfg.config | 8 | ||||
-rw-r--r-- | src/firecfg/util.c | 12 | ||||
-rw-r--r-- | src/firejail/firejail.h | 10 | ||||
-rw-r--r-- | src/firejail/fs_bin.c | 8 | ||||
-rw-r--r-- | src/firejail/fs_lib.c | 18 | ||||
-rw-r--r-- | src/firejail/fs_whitelist.c | 19 | ||||
-rw-r--r-- | src/firejail/util.c | 36 | ||||
-rw-r--r-- | src/fldd/main.c | 6 | ||||
-rw-r--r-- | src/lib/firejail_user.c | 3 |
9 files changed, 97 insertions, 23 deletions
diff --git a/src/firecfg/firecfg.config b/src/firecfg/firecfg.config index 1835502a4..da8937717 100644 --- a/src/firecfg/firecfg.config +++ b/src/firecfg/firecfg.config | |||
@@ -15,12 +15,14 @@ Viber | |||
15 | VirtualBox | 15 | VirtualBox |
16 | Wire | 16 | Wire |
17 | Xephyr | 17 | Xephyr |
18 | XMind | ||
18 | abrowser | 19 | abrowser |
19 | akonadi_control | 20 | akonadi_control |
20 | akregator | 21 | akregator |
21 | amarok | 22 | amarok |
22 | amule | 23 | amule |
23 | android-studio | 24 | android-studio |
25 | anydesk | ||
24 | apktool | 26 | apktool |
25 | arch-audit | 27 | arch-audit |
26 | archaudit-report | 28 | archaudit-report |
@@ -273,7 +275,7 @@ musescore | |||
273 | musixmatch | 275 | musixmatch |
274 | mutt | 276 | mutt |
275 | natron | 277 | natron |
276 | nautilus | 278 | #nautilus - removed in order to let the application start in a new sandbox when clicking on icons in the file manager |
277 | ncdu | 279 | ncdu |
278 | netsurf | 280 | netsurf |
279 | neverball | 281 | neverball |
@@ -298,7 +300,7 @@ pdftotext | |||
298 | peek | 300 | peek |
299 | picard | 301 | picard |
300 | pidgin | 302 | pidgin |
301 | ping | 303 | #ping - disabled until we fix #1912 |
302 | pingus | 304 | pingus |
303 | pinta | 305 | pinta |
304 | pithos | 306 | pithos |
@@ -331,6 +333,7 @@ ristretto | |||
331 | rocketchat | 333 | rocketchat |
332 | rtorrent | 334 | rtorrent |
333 | runenpass.sh | 335 | runenpass.sh |
336 | scallion | ||
334 | scribus | 337 | scribus |
335 | sdat2img | 338 | sdat2img |
336 | seamonkey | 339 | seamonkey |
@@ -410,6 +413,7 @@ vym | |||
410 | w3m | 413 | w3m |
411 | warzone2100 | 414 | warzone2100 |
412 | waterfox | 415 | waterfox |
416 | webstorm | ||
413 | weechat | 417 | weechat |
414 | weechat-curses | 418 | weechat-curses |
415 | wesnoth | 419 | wesnoth |
diff --git a/src/firecfg/util.c b/src/firecfg/util.c index f0446ca8d..7ed86c36e 100644 --- a/src/firecfg/util.c +++ b/src/firecfg/util.c | |||
@@ -58,9 +58,15 @@ int which(const char *program) { | |||
58 | // use path2 to count the entries | 58 | // use path2 to count the entries |
59 | char *ptr = strtok(path2, ":"); | 59 | char *ptr = strtok(path2, ":"); |
60 | while (ptr) { | 60 | while (ptr) { |
61 | if (find(program, ptr)) { | 61 | // Ubuntu 18.04 is adding /snap/bin to PATH; |
62 | free(path2); | 62 | // they populate /snap/bin with simbolic links to /usr/bin/ programs; |
63 | return 1; | 63 | // most simlinked programs are not installed by default. |
64 | // Removing /snap/bin from our search | ||
65 | if (strcmp(ptr, "/snap/bin") != 0) { | ||
66 | if (find(program, ptr)) { | ||
67 | free(path2); | ||
68 | return 1; | ||
69 | } | ||
64 | } | 70 | } |
65 | ptr = strtok(NULL, ":"); | 71 | ptr = strtok(NULL, ":"); |
66 | } | 72 | } |
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 0df832c09..14f87c36c 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -524,6 +524,16 @@ unsigned extract_timeout(const char *str); | |||
524 | void disable_file_or_dir(const char *fname); | 524 | void disable_file_or_dir(const char *fname); |
525 | void disable_file_path(const char *path, const char *file); | 525 | void disable_file_path(const char *path, const char *file); |
526 | 526 | ||
527 | // Get info regarding the last kernel mount operation. | ||
528 | // The return value points to a static area, and will be overwritten by subsequent calls. | ||
529 | // The function does an exit(1) if anything goes wrong. | ||
530 | typedef struct { | ||
531 | char *fsname; | ||
532 | char *dir; | ||
533 | } MountData; | ||
534 | MountData *get_last_mount(void); | ||
535 | |||
536 | |||
527 | // fs_var.c | 537 | // fs_var.c |
528 | void fs_var_log(void); // mounting /var/log | 538 | void fs_var_log(void); // mounting /var/log |
529 | void fs_var_lib(void); // various other fixes for software in /var directory | 539 | void fs_var_lib(void); // various other fixes for software in /var directory |
diff --git a/src/firejail/fs_bin.c b/src/firejail/fs_bin.c index d4cdbbe0a..b0ad35299 100644 --- a/src/firejail/fs_bin.c +++ b/src/firejail/fs_bin.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <unistd.h> | 25 | #include <unistd.h> |
26 | #include <glob.h> | 26 | #include <glob.h> |
27 | 27 | ||
28 | static int prog_cnt = 0; | ||
29 | |||
28 | static char *paths[] = { | 30 | static char *paths[] = { |
29 | "/usr/local/bin", | 31 | "/usr/local/bin", |
30 | "/usr/bin", | 32 | "/usr/bin", |
@@ -191,6 +193,7 @@ static void duplicate(char *fname, FILE *fplist) { | |||
191 | // solving problems such as /bin/sh -> /bin/dash | 193 | // solving problems such as /bin/sh -> /bin/dash |
192 | // copy the real file pointed by symlink | 194 | // copy the real file pointed by symlink |
193 | sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, actual_path, RUN_BIN_DIR); | 195 | sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, actual_path, RUN_BIN_DIR); |
196 | prog_cnt++; | ||
194 | char *f = strrchr(actual_path, '/'); | 197 | char *f = strrchr(actual_path, '/'); |
195 | if (f && *(++f) !='\0') | 198 | if (f && *(++f) !='\0') |
196 | report_duplication(f); | 199 | report_duplication(f); |
@@ -201,6 +204,7 @@ static void duplicate(char *fname, FILE *fplist) { | |||
201 | 204 | ||
202 | // copy a file or a symlink | 205 | // copy a file or a symlink |
203 | sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, full_path, RUN_BIN_DIR); | 206 | sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, full_path, RUN_BIN_DIR); |
207 | prog_cnt++; | ||
204 | free(full_path); | 208 | free(full_path); |
205 | report_duplication(fname); | 209 | report_duplication(fname); |
206 | } | 210 | } |
@@ -256,6 +260,9 @@ void fs_private_bin_list(void) { | |||
256 | char *private_list = cfg.bin_private_keep; | 260 | char *private_list = cfg.bin_private_keep; |
257 | assert(private_list); | 261 | assert(private_list); |
258 | 262 | ||
263 | // start timetrace | ||
264 | timetrace_start(); | ||
265 | |||
259 | // create /run/firejail/mnt/bin directory | 266 | // create /run/firejail/mnt/bin directory |
260 | mkdir_attr(RUN_BIN_DIR, 0755, 0, 0); | 267 | mkdir_attr(RUN_BIN_DIR, 0755, 0, 0); |
261 | 268 | ||
@@ -298,4 +305,5 @@ void fs_private_bin_list(void) { | |||
298 | } | 305 | } |
299 | i++; | 306 | i++; |
300 | } | 307 | } |
308 | fmessage("%d %s installed in %0.2f ms\n", prog_cnt, (prog_cnt == 1)? "program": "programs", timetrace_end()); | ||
301 | } | 309 | } |
diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c index 8a105be97..363b48d1d 100644 --- a/src/firejail/fs_lib.c +++ b/src/firejail/fs_lib.c | |||
@@ -201,7 +201,7 @@ static char *valid_file(const char *lib) { | |||
201 | } | 201 | } |
202 | free(fname); | 202 | free(fname); |
203 | } | 203 | } |
204 | printf("not found %s\n", lib); | 204 | |
205 | fwarning("%s library not found, skipping...\n", lib); | 205 | fwarning("%s library not found, skipping...\n", lib); |
206 | return NULL; | 206 | return NULL; |
207 | } | 207 | } |
@@ -352,7 +352,7 @@ void fs_private_lib(void) { | |||
352 | fslib_copy_dir(name); | 352 | fslib_copy_dir(name); |
353 | free(name); | 353 | free(name); |
354 | 354 | ||
355 | // /usr/lib/x86_linux-gnu - debian & frriends | 355 | // /usr/lib/x86_linux-gnu - debian & friends |
356 | if (asprintf(&name, "/usr/lib/x86_64-linux-gnu/%s", ptr) == -1) | 356 | if (asprintf(&name, "/usr/lib/x86_64-linux-gnu/%s", ptr) == -1) |
357 | errExit("asprintf"); | 357 | errExit("asprintf"); |
358 | if (is_dir(name)) | 358 | if (is_dir(name)) |
@@ -377,20 +377,12 @@ void fs_private_lib(void) { | |||
377 | printf("*** Installing system libraries\n"); | 377 | printf("*** Installing system libraries\n"); |
378 | fslib_install_system(); | 378 | fslib_install_system(); |
379 | 379 | ||
380 | fmessage("Installed %d libraries and %d directories\n", lib_cnt, dir_cnt); | 380 | fmessage("Installed %d %s and %d %s\n", lib_cnt, (lib_cnt == 1)? "library": "libraries", |
381 | dir_cnt, (dir_cnt == 1)? "directory": "directories"); | ||
381 | 382 | ||
382 | // bring in firejail directory for --trace options | 383 | // bring in firejail directory for --trace and seccomp post exec |
383 | fslib_copy_dir(LIBDIR "/firejail"); | 384 | fslib_copy_dir(LIBDIR "/firejail"); |
384 | 385 | ||
385 | // ... and for sandbox in sandbox functionality | ||
386 | fslib_copy_libs(LIBDIR "/firejail/faudit"); | ||
387 | fslib_copy_libs(LIBDIR "/firejail/fbuilder"); | ||
388 | fslib_copy_libs(LIBDIR "/firejail/fcopy"); | ||
389 | fslib_copy_libs(LIBDIR "/firejail/fldd"); | ||
390 | fslib_copy_libs(LIBDIR "/firejail/fnet"); | ||
391 | fslib_copy_libs(LIBDIR "/firejail/fnetfilter"); | ||
392 | fslib_copy_libs(LIBDIR "/firejail/fseccomp"); | ||
393 | fslib_copy_libs(LIBDIR "/firejail/ftee"); | ||
394 | // mount lib filesystem | 386 | // mount lib filesystem |
395 | mount_directories(); | 387 | mount_directories(); |
396 | } | 388 | } |
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c index d4c7de342..60bb0f6ed 100644 --- a/src/firejail/fs_whitelist.c +++ b/src/firejail/fs_whitelist.c | |||
@@ -317,6 +317,16 @@ static void whitelist_path(ProfileEntry *entry) { | |||
317 | if (mount(wfile, path, NULL, MS_BIND|MS_REC, NULL) < 0) | 317 | if (mount(wfile, path, NULL, MS_BIND|MS_REC, NULL) < 0) |
318 | errExit("mount bind"); | 318 | errExit("mount bind"); |
319 | 319 | ||
320 | // check the last mount operation | ||
321 | MountData *mptr = get_last_mount(); // will do exit(1) if the mount cannot be found | ||
322 | |||
323 | // No mounts are allowed on top level directories. A destination such as "/etc" is very bad! | ||
324 | // - there should be more than one '/' char in dest string | ||
325 | if (mptr->dir == strrchr(mptr->dir, '/')) { | ||
326 | fprintf(stderr, "Error: invalid mount on top of %s\n", mptr->dir); | ||
327 | exit(1); | ||
328 | } | ||
329 | |||
320 | free(wfile); | 330 | free(wfile); |
321 | return; | 331 | return; |
322 | 332 | ||
@@ -859,6 +869,15 @@ void fs_whitelist(void) { | |||
859 | fprintf(stderr, "Warning cannot create symbolic link %s\n", entry->link); | 869 | fprintf(stderr, "Warning cannot create symbolic link %s\n", entry->link); |
860 | else if (arg_debug || arg_debug_whitelists) | 870 | else if (arg_debug || arg_debug_whitelists) |
861 | printf("Created symbolic link %s -> %s\n", entry->link, entry->data + 10); | 871 | printf("Created symbolic link %s -> %s\n", entry->link, entry->data + 10); |
872 | |||
873 | // check again for files in /tmp directory | ||
874 | if (strncmp(entry->link, "/tmp/", 5) == 0) { | ||
875 | char *path = realpath(entry->link, NULL); | ||
876 | if (path == NULL || strncmp(path, "/tmp/", 5) != 0) { | ||
877 | fprintf(stderr, "Error: invalid symbolic link %s\n", entry->link); | ||
878 | exit(1); | ||
879 | } | ||
880 | } | ||
862 | } | 881 | } |
863 | } | 882 | } |
864 | } | 883 | } |
diff --git a/src/firejail/util.c b/src/firejail/util.c index a44e52e98..f441f283f 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c | |||
@@ -1029,3 +1029,39 @@ void disable_file_path(const char *path, const char *file) { | |||
1029 | free(fname); | 1029 | free(fname); |
1030 | } | 1030 | } |
1031 | 1031 | ||
1032 | #define MAX_BUF 4096 | ||
1033 | static char mbuf[MAX_BUF]; | ||
1034 | static MountData mdata; | ||
1035 | |||
1036 | // Get info regarding the last kernel mount operation. | ||
1037 | // The return value points to a static area, and will be overwritten by subsequent calls. | ||
1038 | // The function does an exit(1) if anything goes wrong. | ||
1039 | MountData *get_last_mount(void) { | ||
1040 | // open /proc/self/mounts | ||
1041 | FILE *fp = fopen("/proc/self/mounts", "r"); | ||
1042 | if (!fp) | ||
1043 | goto errexit; | ||
1044 | |||
1045 | mbuf[0] = '\0'; | ||
1046 | while (fgets(mbuf, MAX_BUF, fp)); | ||
1047 | fclose(fp); | ||
1048 | if (arg_debug || arg_debug_whitelists) | ||
1049 | printf("%s", mbuf); | ||
1050 | |||
1051 | // there should be no reason to have a new mount on top of a top level directory | ||
1052 | mdata.fsname = mbuf; | ||
1053 | mdata.dir = strstr(mbuf, " "); | ||
1054 | if (!mdata.dir) | ||
1055 | goto errexit; | ||
1056 | mdata.dir++; | ||
1057 | char *end = strstr(mdata.dir, " "); | ||
1058 | if (!end) | ||
1059 | goto errexit; | ||
1060 | *end = '\0'; | ||
1061 | |||
1062 | return &mdata; | ||
1063 | |||
1064 | errexit: | ||
1065 | fprintf(stderr, "Error: cannot read /proc/self/mounts"); | ||
1066 | exit(1); | ||
1067 | } | ||
diff --git a/src/fldd/main.c b/src/fldd/main.c index be4500d2a..4658e82fb 100644 --- a/src/fldd/main.c +++ b/src/fldd/main.c | |||
@@ -340,10 +340,8 @@ printf("\n"); | |||
340 | else { | 340 | else { |
341 | if (is_lib_64(argv[1])) | 341 | if (is_lib_64(argv[1])) |
342 | parse_elf(argv[1]); | 342 | parse_elf(argv[1]); |
343 | else { | 343 | else |
344 | fprintf(stderr, "Error fldd: %s is not a 64bit program/library\n", argv[1]); | 344 | fprintf(stderr, "Warning fldd: %s is not a 64bit program/library\n", argv[1]); |
345 | exit(1); | ||
346 | } | ||
347 | } | 345 | } |
348 | 346 | ||
349 | 347 | ||
diff --git a/src/lib/firejail_user.c b/src/lib/firejail_user.c index 09a4da0e7..0cc0ac6c1 100644 --- a/src/lib/firejail_user.c +++ b/src/lib/firejail_user.c | |||
@@ -47,7 +47,8 @@ int firejail_user_check(const char *name) { | |||
47 | return 1; | 47 | return 1; |
48 | 48 | ||
49 | // other system users will run the program as is | 49 | // other system users will run the program as is |
50 | if (getuid() < UID_MIN || strcmp(name, "nobody") == 0) | 50 | uid_t uid = getuid(); |
51 | if ((uid < UID_MIN && uid != 0) || strcmp(name, "nobody") == 0) | ||
51 | return 0; | 52 | return 0; |
52 | 53 | ||
53 | // check file existence | 54 | // check file existence |