diff options
-rw-r--r-- | src/firejail/checkcfg.c | 48 | ||||
-rw-r--r-- | src/firejail/firejail.h | 7 | ||||
-rw-r--r-- | src/firejail/fs.c | 4 | ||||
-rw-r--r-- | src/firejail/main.c | 275 | ||||
-rw-r--r-- | src/firejail/profile.c | 125 |
5 files changed, 315 insertions, 144 deletions
diff --git a/src/firejail/checkcfg.c b/src/firejail/checkcfg.c index 9ac08b1a6..8376cd9af 100644 --- a/src/firejail/checkcfg.c +++ b/src/firejail/checkcfg.c | |||
@@ -58,7 +58,8 @@ int checkcfg(int val) { | |||
58 | char *ptr = line_remove_spaces(buf); | 58 | char *ptr = line_remove_spaces(buf); |
59 | if (!ptr) | 59 | if (!ptr) |
60 | continue; | 60 | continue; |
61 | 61 | ||
62 | // file transfer | ||
62 | if (strncmp(ptr, "file-transfer ", 14) == 0) { | 63 | if (strncmp(ptr, "file-transfer ", 14) == 0) { |
63 | if (strcmp(ptr + 14, "yes") == 0) | 64 | if (strcmp(ptr + 14, "yes") == 0) |
64 | cfg_val[CFG_FILE_TRANSFER] = 1; | 65 | cfg_val[CFG_FILE_TRANSFER] = 1; |
@@ -67,6 +68,51 @@ int checkcfg(int val) { | |||
67 | else | 68 | else |
68 | goto errout; | 69 | goto errout; |
69 | } | 70 | } |
71 | // x11 | ||
72 | else if (strncmp(ptr, "x11 ", 4) == 0) { | ||
73 | if (strcmp(ptr + 4, "yes") == 0) | ||
74 | cfg_val[CFG_X11] = 1; | ||
75 | else if (strcmp(ptr + 4, "no") == 0) | ||
76 | cfg_val[CFG_X11] = 0; | ||
77 | else | ||
78 | goto errout; | ||
79 | } | ||
80 | // bind | ||
81 | else if (strncmp(ptr, "bind ", 5) == 0) { | ||
82 | if (strcmp(ptr + 5, "yes") == 0) | ||
83 | cfg_val[CFG_BIND] = 1; | ||
84 | else if (strcmp(ptr + 5, "no") == 0) | ||
85 | cfg_val[CFG_BIND] = 0; | ||
86 | else | ||
87 | goto errout; | ||
88 | } | ||
89 | // user namespace | ||
90 | else if (strncmp(ptr, "userns ", 7) == 0) { | ||
91 | if (strcmp(ptr + 7, "yes") == 0) | ||
92 | cfg_val[CFG_USERNS] = 1; | ||
93 | else if (strcmp(ptr + 7, "no") == 0) | ||
94 | cfg_val[CFG_USERNS] = 0; | ||
95 | else | ||
96 | goto errout; | ||
97 | } | ||
98 | // chroot | ||
99 | else if (strncmp(ptr, "chroot ", 7) == 0) { | ||
100 | if (strcmp(ptr + 7, "yes") == 0) | ||
101 | cfg_val[CFG_CHROOT] = 1; | ||
102 | else if (strcmp(ptr + 7, "no") == 0) | ||
103 | cfg_val[CFG_CHROOT] = 0; | ||
104 | else | ||
105 | goto errout; | ||
106 | } | ||
107 | // seccomp | ||
108 | else if (strncmp(ptr, "seccomp ", 8) == 0) { | ||
109 | if (strcmp(ptr + 8, "yes") == 0) | ||
110 | cfg_val[CFG_SECCOMP] = 1; | ||
111 | else if (strcmp(ptr + 8, "no") == 0) | ||
112 | cfg_val[CFG_SECCOMP] = 0; | ||
113 | else | ||
114 | goto errout; | ||
115 | } | ||
70 | else | 116 | else |
71 | goto errout; | 117 | goto errout; |
72 | free(ptr); | 118 | free(ptr); |
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index bf0937f35..2b2912b3e 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -539,7 +539,12 @@ void sandboxfs(int op, pid_t pid, const char *patqh); | |||
539 | 539 | ||
540 | // checkcfg.c | 540 | // checkcfg.c |
541 | #define CFG_FILE_TRANSFER 0 | 541 | #define CFG_FILE_TRANSFER 0 |
542 | #define CFG_MAX 1 // this should always be the last entry | 542 | #define CFG_X11 1 |
543 | #define CFG_BIND 2 | ||
544 | #define CFG_USERNS 3 | ||
545 | #define CFG_CHROOT 4 | ||
546 | #define CFG_SECCOMP 5 | ||
547 | #define CFG_MAX 6 // this should always be the last entry | ||
543 | int checkcfg(int val); | 548 | int checkcfg(int val); |
544 | 549 | ||
545 | #endif | 550 | #endif |
diff --git a/src/firejail/fs.c b/src/firejail/fs.c index acee0ba1d..f63e8b5eb 100644 --- a/src/firejail/fs.c +++ b/src/firejail/fs.c | |||
@@ -435,12 +435,12 @@ void fs_blacklist(void) { | |||
435 | } | 435 | } |
436 | struct stat s; | 436 | struct stat s; |
437 | if (stat(dname1, &s) == -1) { | 437 | if (stat(dname1, &s) == -1) { |
438 | fprintf(stderr, "Error: cannot find directories for bind command\n"); | 438 | fprintf(stderr, "Error: cannot find %s for bind command\n", dname1); |
439 | entry = entry->next; | 439 | entry = entry->next; |
440 | continue; | 440 | continue; |
441 | } | 441 | } |
442 | if (stat(dname2, &s) == -1) { | 442 | if (stat(dname2, &s) == -1) { |
443 | fprintf(stderr, "Error: cannot find directories for bind command\n"); | 443 | fprintf(stderr, "Error: cannot find %s for bind command\n", dname2); |
444 | entry = entry->next; | 444 | entry = entry->next; |
445 | continue; | 445 | continue; |
446 | } | 446 | } |
diff --git a/src/firejail/main.c b/src/firejail/main.c index 0a02d0918..8f89a804f 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -278,8 +278,14 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { | |||
278 | } | 278 | } |
279 | #ifdef HAVE_X11 | 279 | #ifdef HAVE_X11 |
280 | else if (strcmp(argv[i], "--x11") == 0) { | 280 | else if (strcmp(argv[i], "--x11") == 0) { |
281 | x11_start(argc, argv); | 281 | if (checkcfg(CFG_X11)) { |
282 | exit(0); | 282 | x11_start(argc, argv); |
283 | exit(0); | ||
284 | } | ||
285 | else { | ||
286 | fprintf(stderr, "Error: --x11 feature is disabled in Firejail configuration file\n"); | ||
287 | exit(1); | ||
288 | } | ||
283 | } | 289 | } |
284 | #endif | 290 | #endif |
285 | #ifdef HAVE_NETWORK | 291 | #ifdef HAVE_NETWORK |
@@ -350,20 +356,38 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { | |||
350 | //************************************* | 356 | //************************************* |
351 | #ifdef HAVE_SECCOMP | 357 | #ifdef HAVE_SECCOMP |
352 | else if (strcmp(argv[i], "--debug-syscalls") == 0) { | 358 | else if (strcmp(argv[i], "--debug-syscalls") == 0) { |
353 | syscall_print(); | 359 | if (checkcfg(CFG_SECCOMP)) { |
354 | exit(0); | 360 | syscall_print(); |
361 | exit(0); | ||
362 | } | ||
363 | else { | ||
364 | fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); | ||
365 | exit(1); | ||
366 | } | ||
355 | } | 367 | } |
356 | else if (strcmp(argv[i], "--debug-errnos") == 0) { | 368 | else if (strcmp(argv[i], "--debug-errnos") == 0) { |
357 | errno_print(); | 369 | if (checkcfg(CFG_SECCOMP)) { |
370 | errno_print(); | ||
371 | } | ||
372 | else { | ||
373 | fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); | ||
374 | exit(1); | ||
375 | } | ||
358 | exit(0); | 376 | exit(0); |
359 | } | 377 | } |
360 | else if (strncmp(argv[i], "--seccomp.print=", 16) == 0) { | 378 | else if (strncmp(argv[i], "--seccomp.print=", 16) == 0) { |
361 | // print seccomp filter for a sandbox specified by pid or by name | 379 | if (checkcfg(CFG_SECCOMP)) { |
362 | pid_t pid; | 380 | // print seccomp filter for a sandbox specified by pid or by name |
363 | if (read_pid(argv[i] + 16, &pid) == 0) | 381 | pid_t pid; |
364 | seccomp_print_filter(pid); | 382 | if (read_pid(argv[i] + 16, &pid) == 0) |
365 | else | 383 | seccomp_print_filter(pid); |
366 | seccomp_print_filter_name(argv[i] + 16); | 384 | else |
385 | seccomp_print_filter_name(argv[i] + 16); | ||
386 | } | ||
387 | else { | ||
388 | fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); | ||
389 | exit(1); | ||
390 | } | ||
367 | exit(0); | 391 | exit(0); |
368 | } | 392 | } |
369 | else if (strcmp(argv[i], "--debug-protocols") == 0) { | 393 | else if (strcmp(argv[i], "--debug-protocols") == 0) { |
@@ -371,12 +395,18 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { | |||
371 | exit(0); | 395 | exit(0); |
372 | } | 396 | } |
373 | else if (strncmp(argv[i], "--protocol.print=", 17) == 0) { | 397 | else if (strncmp(argv[i], "--protocol.print=", 17) == 0) { |
374 | // print seccomp filter for a sandbox specified by pid or by name | 398 | if (checkcfg(CFG_SECCOMP)) { |
375 | pid_t pid; | 399 | // print seccomp filter for a sandbox specified by pid or by name |
376 | if (read_pid(argv[i] + 17, &pid) == 0) | 400 | pid_t pid; |
377 | protocol_print_filter(pid); | 401 | if (read_pid(argv[i] + 17, &pid) == 0) |
378 | else | 402 | protocol_print_filter(pid); |
379 | protocol_print_filter_name(argv[i] + 17); | 403 | else |
404 | protocol_print_filter_name(argv[i] + 17); | ||
405 | } | ||
406 | else { | ||
407 | fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); | ||
408 | exit(1); | ||
409 | } | ||
380 | exit(0); | 410 | exit(0); |
381 | } | 411 | } |
382 | #endif | 412 | #endif |
@@ -455,7 +485,7 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { | |||
455 | exit(0); | 485 | exit(0); |
456 | } | 486 | } |
457 | else { | 487 | else { |
458 | fprintf(stderr, "Error: this feature is disabled in Firejail configuration file\n"); | 488 | fprintf(stderr, "Error: --get feature is disabled in Firejail configuration file\n"); |
459 | exit(1); | 489 | exit(1); |
460 | } | 490 | } |
461 | } | 491 | } |
@@ -484,7 +514,7 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { | |||
484 | exit(0); | 514 | exit(0); |
485 | } | 515 | } |
486 | else { | 516 | else { |
487 | fprintf(stderr, "Error: this feature is disabled in Firejail configuration file\n"); | 517 | fprintf(stderr, "Error: --ls feature is disabled in Firejail configuration file\n"); |
488 | exit(1); | 518 | exit(1); |
489 | } | 519 | } |
490 | } | 520 | } |
@@ -727,72 +757,109 @@ int main(int argc, char **argv) { | |||
727 | // filtering | 757 | // filtering |
728 | //************************************* | 758 | //************************************* |
729 | #ifdef HAVE_SECCOMP | 759 | #ifdef HAVE_SECCOMP |
730 | else if (strncmp(argv[i], "--protocol=", 11) == 0) | 760 | else if (strncmp(argv[i], "--protocol=", 11) == 0) { |
731 | protocol_store(argv[i] + 11); | 761 | if (checkcfg(CFG_SECCOMP)) { |
762 | protocol_store(argv[i] + 11); | ||
763 | } | ||
764 | else { | ||
765 | fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); | ||
766 | exit(1); | ||
767 | } | ||
768 | } | ||
732 | else if (strcmp(argv[i], "--seccomp") == 0) { | 769 | else if (strcmp(argv[i], "--seccomp") == 0) { |
733 | if (arg_seccomp) { | 770 | if (checkcfg(CFG_SECCOMP)) { |
734 | fprintf(stderr, "Error: seccomp already enabled\n"); | 771 | if (arg_seccomp) { |
772 | fprintf(stderr, "Error: seccomp already enabled\n"); | ||
773 | exit(1); | ||
774 | } | ||
775 | arg_seccomp = 1; | ||
776 | } | ||
777 | else { | ||
778 | fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); | ||
735 | exit(1); | 779 | exit(1); |
736 | } | 780 | } |
737 | arg_seccomp = 1; | ||
738 | } | 781 | } |
739 | else if (strncmp(argv[i], "--seccomp=", 10) == 0) { | 782 | else if (strncmp(argv[i], "--seccomp=", 10) == 0) { |
740 | if (arg_seccomp) { | 783 | if (checkcfg(CFG_SECCOMP)) { |
741 | fprintf(stderr, "Error: seccomp already enabled\n"); | 784 | if (arg_seccomp) { |
785 | fprintf(stderr, "Error: seccomp already enabled\n"); | ||
786 | exit(1); | ||
787 | } | ||
788 | arg_seccomp = 1; | ||
789 | cfg.seccomp_list = strdup(argv[i] + 10); | ||
790 | if (!cfg.seccomp_list) | ||
791 | errExit("strdup"); | ||
792 | } | ||
793 | else { | ||
794 | fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); | ||
742 | exit(1); | 795 | exit(1); |
743 | } | 796 | } |
744 | arg_seccomp = 1; | ||
745 | cfg.seccomp_list = strdup(argv[i] + 10); | ||
746 | if (!cfg.seccomp_list) | ||
747 | errExit("strdup"); | ||
748 | } | 797 | } |
749 | else if (strncmp(argv[i], "--seccomp.drop=", 15) == 0) { | 798 | else if (strncmp(argv[i], "--seccomp.drop=", 15) == 0) { |
750 | if (arg_seccomp) { | 799 | if (checkcfg(CFG_SECCOMP)) { |
751 | fprintf(stderr, "Error: seccomp already enabled\n"); | 800 | if (arg_seccomp) { |
801 | fprintf(stderr, "Error: seccomp already enabled\n"); | ||
802 | exit(1); | ||
803 | } | ||
804 | arg_seccomp = 1; | ||
805 | cfg.seccomp_list_drop = strdup(argv[i] + 15); | ||
806 | if (!cfg.seccomp_list_drop) | ||
807 | errExit("strdup"); | ||
808 | } | ||
809 | else { | ||
810 | fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); | ||
752 | exit(1); | 811 | exit(1); |
753 | } | 812 | } |
754 | arg_seccomp = 1; | ||
755 | cfg.seccomp_list_drop = strdup(argv[i] + 15); | ||
756 | if (!cfg.seccomp_list_drop) | ||
757 | errExit("strdup"); | ||
758 | } | 813 | } |
759 | else if (strncmp(argv[i], "--seccomp.keep=", 15) == 0) { | 814 | else if (strncmp(argv[i], "--seccomp.keep=", 15) == 0) { |
760 | if (arg_seccomp) { | 815 | if (checkcfg(CFG_SECCOMP)) { |
761 | fprintf(stderr, "Error: seccomp already enabled\n"); | 816 | if (arg_seccomp) { |
817 | fprintf(stderr, "Error: seccomp already enabled\n"); | ||
818 | exit(1); | ||
819 | } | ||
820 | arg_seccomp = 1; | ||
821 | cfg.seccomp_list_keep = strdup(argv[i] + 15); | ||
822 | if (!cfg.seccomp_list_keep) | ||
823 | errExit("strdup"); | ||
824 | } | ||
825 | else { | ||
826 | fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); | ||
762 | exit(1); | 827 | exit(1); |
763 | } | 828 | } |
764 | arg_seccomp = 1; | ||
765 | cfg.seccomp_list_keep = strdup(argv[i] + 15); | ||
766 | if (!cfg.seccomp_list_keep) | ||
767 | errExit("strdup"); | ||
768 | } | 829 | } |
769 | else if (strncmp(argv[i], "--seccomp.e", 11) == 0 && strchr(argv[i], '=')) { | 830 | else if (strncmp(argv[i], "--seccomp.e", 11) == 0 && strchr(argv[i], '=')) { |
770 | if (arg_seccomp && !cfg.seccomp_list_errno) { | 831 | if (checkcfg(CFG_SECCOMP)) { |
771 | fprintf(stderr, "Error: seccomp already enabled\n"); | 832 | if (arg_seccomp && !cfg.seccomp_list_errno) { |
772 | exit(1); | 833 | fprintf(stderr, "Error: seccomp already enabled\n"); |
773 | } | 834 | exit(1); |
774 | char *eq = strchr(argv[i], '='); | 835 | } |
775 | char *errnoname = strndup(argv[i] + 10, eq - (argv[i] + 10)); | 836 | char *eq = strchr(argv[i], '='); |
776 | int nr = errno_find_name(errnoname); | 837 | char *errnoname = strndup(argv[i] + 10, eq - (argv[i] + 10)); |
777 | if (nr == -1) { | 838 | int nr = errno_find_name(errnoname); |
778 | fprintf(stderr, "Error: unknown errno %s\n", errnoname); | 839 | if (nr == -1) { |
840 | fprintf(stderr, "Error: unknown errno %s\n", errnoname); | ||
841 | free(errnoname); | ||
842 | exit(1); | ||
843 | } | ||
844 | |||
845 | if (!cfg.seccomp_list_errno) | ||
846 | cfg.seccomp_list_errno = calloc(highest_errno+1, sizeof(cfg.seccomp_list_errno[0])); | ||
847 | |||
848 | if (cfg.seccomp_list_errno[nr]) { | ||
849 | fprintf(stderr, "Error: errno %s already configured\n", errnoname); | ||
850 | free(errnoname); | ||
851 | exit(1); | ||
852 | } | ||
853 | arg_seccomp = 1; | ||
854 | cfg.seccomp_list_errno[nr] = strdup(eq+1); | ||
855 | if (!cfg.seccomp_list_errno[nr]) | ||
856 | errExit("strdup"); | ||
779 | free(errnoname); | 857 | free(errnoname); |
780 | exit(1); | ||
781 | } | 858 | } |
782 | 859 | else { | |
783 | if (!cfg.seccomp_list_errno) | 860 | fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); |
784 | cfg.seccomp_list_errno = calloc(highest_errno+1, sizeof(cfg.seccomp_list_errno[0])); | ||
785 | |||
786 | if (cfg.seccomp_list_errno[nr]) { | ||
787 | fprintf(stderr, "Error: errno %s already configured\n", errnoname); | ||
788 | free(errnoname); | ||
789 | exit(1); | 861 | exit(1); |
790 | } | 862 | } |
791 | arg_seccomp = 1; | ||
792 | cfg.seccomp_list_errno[nr] = strdup(eq+1); | ||
793 | if (!cfg.seccomp_list_errno[nr]) | ||
794 | errExit("strdup"); | ||
795 | free(errnoname); | ||
796 | } | 863 | } |
797 | #endif | 864 | #endif |
798 | else if (strcmp(argv[i], "--caps") == 0) | 865 | else if (strcmp(argv[i], "--caps") == 0) |
@@ -881,12 +948,18 @@ int main(int argc, char **argv) { | |||
881 | //************************************* | 948 | //************************************* |
882 | #ifdef HAVE_BIND | 949 | #ifdef HAVE_BIND |
883 | else if (strncmp(argv[i], "--bind=", 7) == 0) { | 950 | else if (strncmp(argv[i], "--bind=", 7) == 0) { |
884 | char *line; | 951 | if (checkcfg(CFG_BIND)) { |
885 | if (asprintf(&line, "bind %s", argv[i] + 7) == -1) | 952 | char *line; |
886 | errExit("asprintf"); | 953 | if (asprintf(&line, "bind %s", argv[i] + 7) == -1) |
887 | 954 | errExit("asprintf"); | |
888 | profile_check_line(line, 0, NULL); // will exit if something wrong | 955 | |
889 | profile_add(line); | 956 | profile_check_line(line, 0, NULL); // will exit if something wrong |
957 | profile_add(line); | ||
958 | } | ||
959 | else { | ||
960 | fprintf(stderr, "Error: --bind feature is disabled in Firejail configuration file\n"); | ||
961 | exit(1); | ||
962 | } | ||
890 | } | 963 | } |
891 | #endif | 964 | #endif |
892 | else if (strncmp(argv[i], "--tmpfs=", 8) == 0) { | 965 | else if (strncmp(argv[i], "--tmpfs=", 8) == 0) { |
@@ -1049,33 +1122,40 @@ int main(int argc, char **argv) { | |||
1049 | } | 1122 | } |
1050 | #ifdef HAVE_CHROOT | 1123 | #ifdef HAVE_CHROOT |
1051 | else if (strncmp(argv[i], "--chroot=", 9) == 0) { | 1124 | else if (strncmp(argv[i], "--chroot=", 9) == 0) { |
1052 | if (arg_overlay) { | 1125 | if (checkcfg(CFG_CHROOT)) { |
1053 | fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); | 1126 | if (arg_overlay) { |
1054 | exit(1); | 1127 | fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); |
1055 | } | 1128 | exit(1); |
1056 | invalid_filename(argv[i] + 9); | 1129 | } |
1057 | 1130 | invalid_filename(argv[i] + 9); | |
1058 | // extract chroot dirname | 1131 | |
1059 | cfg.chrootdir = argv[i] + 9; | 1132 | // extract chroot dirname |
1060 | // if the directory starts with ~, expand the home directory | 1133 | cfg.chrootdir = argv[i] + 9; |
1061 | if (*cfg.chrootdir == '~') { | 1134 | // if the directory starts with ~, expand the home directory |
1062 | char *tmp; | 1135 | if (*cfg.chrootdir == '~') { |
1063 | if (asprintf(&tmp, "%s%s", cfg.homedir, cfg.chrootdir + 1) == -1) | 1136 | char *tmp; |
1064 | errExit("asprintf"); | 1137 | if (asprintf(&tmp, "%s%s", cfg.homedir, cfg.chrootdir + 1) == -1) |
1065 | cfg.chrootdir = tmp; | 1138 | errExit("asprintf"); |
1066 | } | 1139 | cfg.chrootdir = tmp; |
1067 | 1140 | } | |
1068 | // check chroot dirname exists | 1141 | |
1069 | if (strstr(cfg.chrootdir, "..") || !is_dir(cfg.chrootdir) || is_link(cfg.chrootdir)) { | 1142 | // check chroot dirname exists |
1070 | fprintf(stderr, "Error: invalid directory %s\n", cfg.chrootdir); | 1143 | if (strstr(cfg.chrootdir, "..") || !is_dir(cfg.chrootdir) || is_link(cfg.chrootdir)) { |
1071 | return 1; | 1144 | fprintf(stderr, "Error: invalid directory %s\n", cfg.chrootdir); |
1145 | return 1; | ||
1146 | } | ||
1147 | |||
1148 | // check chroot directory structure | ||
1149 | if (fs_check_chroot_dir(cfg.chrootdir)) { | ||
1150 | fprintf(stderr, "Error: invalid chroot\n"); | ||
1151 | exit(1); | ||
1152 | } | ||
1072 | } | 1153 | } |
1073 | 1154 | else { | |
1074 | // check chroot directory structure | 1155 | fprintf(stderr, "Error: --chroot feature is disabled in Firejail configuration file\n"); |
1075 | if (fs_check_chroot_dir(cfg.chrootdir)) { | ||
1076 | fprintf(stderr, "Error: invalid chroot\n"); | ||
1077 | exit(1); | 1156 | exit(1); |
1078 | } | 1157 | } |
1158 | |||
1079 | } | 1159 | } |
1080 | #endif | 1160 | #endif |
1081 | else if (strcmp(argv[i], "--private") == 0) | 1161 | else if (strcmp(argv[i], "--private") == 0) |
@@ -1143,7 +1223,12 @@ int main(int argc, char **argv) { | |||
1143 | arg_nogroups = 1; | 1223 | arg_nogroups = 1; |
1144 | #ifdef HAVE_USERNS | 1224 | #ifdef HAVE_USERNS |
1145 | else if (strcmp(argv[i], "--noroot") == 0) { | 1225 | else if (strcmp(argv[i], "--noroot") == 0) { |
1146 | check_user_namespace(); | 1226 | if (checkcfg(CFG_USERNS)) |
1227 | check_user_namespace(); | ||
1228 | else { | ||
1229 | fprintf(stderr, "Error: --noroot feature is disabled in Firejail configuration file\n"); | ||
1230 | exit(1); | ||
1231 | } | ||
1147 | } | 1232 | } |
1148 | #endif | 1233 | #endif |
1149 | else if (strncmp(argv[i], "--env=", 6) == 0) | 1234 | else if (strncmp(argv[i], "--env=", 6) == 0) |
diff --git a/src/firejail/profile.c b/src/firejail/profile.c index 461bcb941..723889dd2 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c | |||
@@ -123,12 +123,21 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
123 | // seccomp, caps, private, user namespace | 123 | // seccomp, caps, private, user namespace |
124 | else if (strcmp(ptr, "noroot") == 0) { | 124 | else if (strcmp(ptr, "noroot") == 0) { |
125 | #if HAVE_USERNS | 125 | #if HAVE_USERNS |
126 | check_user_namespace(); | 126 | if (checkcfg(CFG_USERNS)) |
127 | check_user_namespace(); | ||
128 | else | ||
129 | fprintf(stderr, "Warning: user namespace feature is disabled in Firejail configuration file\n"); | ||
127 | #endif | 130 | #endif |
131 | |||
128 | return 0; | 132 | return 0; |
129 | } | 133 | } |
130 | else if (strcmp(ptr, "seccomp") == 0) { | 134 | else if (strcmp(ptr, "seccomp") == 0) { |
131 | arg_seccomp = 1; | 135 | #ifdef HAVE_SECCOMP |
136 | if (checkcfg(CFG_SECCOMP)) | ||
137 | arg_seccomp = 1; | ||
138 | else | ||
139 | fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); | ||
140 | #endif | ||
132 | return 0; | 141 | return 0; |
133 | } | 142 | } |
134 | else if (strcmp(ptr, "caps") == 0) { | 143 | else if (strcmp(ptr, "caps") == 0) { |
@@ -205,12 +214,15 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
205 | return 0; | 214 | return 0; |
206 | } | 215 | } |
207 | 216 | ||
208 | #ifdef HAVE_SECCOMP | ||
209 | if (strncmp(ptr, "protocol ", 9) == 0) { | 217 | if (strncmp(ptr, "protocol ", 9) == 0) { |
210 | protocol_store(ptr + 9); | 218 | #ifdef HAVE_SECCOMP |
219 | if (checkcfg(CFG_SECCOMP)) | ||
220 | protocol_store(ptr + 9); | ||
221 | else | ||
222 | fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); | ||
223 | #endif | ||
211 | return 0; | 224 | return 0; |
212 | } | 225 | } |
213 | #endif | ||
214 | 226 | ||
215 | if (strncmp(ptr, "env ", 4) == 0) { | 227 | if (strncmp(ptr, "env ", 4) == 0) { |
216 | env_store(ptr + 4); | 228 | env_store(ptr + 4); |
@@ -219,34 +231,47 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
219 | 231 | ||
220 | // seccomp drop list on top of default list | 232 | // seccomp drop list on top of default list |
221 | if (strncmp(ptr, "seccomp ", 8) == 0) { | 233 | if (strncmp(ptr, "seccomp ", 8) == 0) { |
222 | arg_seccomp = 1; | ||
223 | #ifdef HAVE_SECCOMP | 234 | #ifdef HAVE_SECCOMP |
224 | cfg.seccomp_list = strdup(ptr + 8); | 235 | if (checkcfg(CFG_SECCOMP)) { |
225 | if (!cfg.seccomp_list) | 236 | arg_seccomp = 1; |
226 | errExit("strdup"); | 237 | cfg.seccomp_list = strdup(ptr + 8); |
238 | if (!cfg.seccomp_list) | ||
239 | errExit("strdup"); | ||
240 | } | ||
241 | else | ||
242 | fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); | ||
227 | #endif | 243 | #endif |
244 | |||
228 | return 0; | 245 | return 0; |
229 | } | 246 | } |
230 | 247 | ||
231 | // seccomp drop list without default list | 248 | // seccomp drop list without default list |
232 | if (strncmp(ptr, "seccomp.drop ", 13) == 0) { | 249 | if (strncmp(ptr, "seccomp.drop ", 13) == 0) { |
233 | arg_seccomp = 1; | ||
234 | #ifdef HAVE_SECCOMP | 250 | #ifdef HAVE_SECCOMP |
235 | cfg.seccomp_list_drop = strdup(ptr + 13); | 251 | if (checkcfg(CFG_SECCOMP)) { |
236 | if (!cfg.seccomp_list_drop) | 252 | arg_seccomp = 1; |
237 | errExit("strdup"); | 253 | cfg.seccomp_list_drop = strdup(ptr + 13); |
238 | #endif | 254 | if (!cfg.seccomp_list_drop) |
255 | errExit("strdup"); | ||
256 | } | ||
257 | else | ||
258 | fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); | ||
259 | #endif | ||
239 | return 0; | 260 | return 0; |
240 | } | 261 | } |
241 | 262 | ||
242 | // seccomp keep list | 263 | // seccomp keep list |
243 | if (strncmp(ptr, "seccomp.keep ", 13) == 0) { | 264 | if (strncmp(ptr, "seccomp.keep ", 13) == 0) { |
244 | arg_seccomp = 1; | ||
245 | #ifdef HAVE_SECCOMP | 265 | #ifdef HAVE_SECCOMP |
246 | cfg.seccomp_list_keep= strdup(ptr + 13); | 266 | if (checkcfg(CFG_SECCOMP)) { |
247 | if (!cfg.seccomp_list_keep) | 267 | arg_seccomp = 1; |
248 | errExit("strdup"); | 268 | cfg.seccomp_list_keep= strdup(ptr + 13); |
249 | #endif | 269 | if (!cfg.seccomp_list_keep) |
270 | errExit("strdup"); | ||
271 | } | ||
272 | else | ||
273 | fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); | ||
274 | #endif | ||
250 | return 0; | 275 | return 0; |
251 | } | 276 | } |
252 | 277 | ||
@@ -352,34 +377,44 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
352 | 377 | ||
353 | // filesystem bind | 378 | // filesystem bind |
354 | if (strncmp(ptr, "bind ", 5) == 0) { | 379 | if (strncmp(ptr, "bind ", 5) == 0) { |
355 | if (getuid() != 0) { | 380 | #ifdef HAVE_BIND |
356 | fprintf(stderr, "Error: --bind option is available only if running as root\n"); | 381 | if (checkcfg(CFG_BIND)) { |
357 | exit(1); | 382 | if (getuid() != 0) { |
358 | } | 383 | fprintf(stderr, "Error: --bind option is available only if running as root\n"); |
359 | 384 | exit(1); | |
360 | // extract two directories | 385 | } |
361 | char *dname1 = ptr + 5; | 386 | |
362 | char *dname2 = split_comma(dname1); // this inserts a '0 to separate the two dierctories | 387 | // extract two directories |
363 | if (dname2 == NULL) { | 388 | char *dname1 = ptr + 5; |
364 | fprintf(stderr, "Error: missing second directory for bind\n"); | 389 | char *dname2 = split_comma(dname1); // this inserts a '0 to separate the two dierctories |
365 | exit(1); | 390 | if (dname2 == NULL) { |
366 | } | 391 | fprintf(stderr, "Error: missing second directory for bind\n"); |
367 | 392 | exit(1); | |
368 | // check directories | 393 | } |
369 | invalid_filename(dname1); | 394 | |
370 | invalid_filename(dname2); | 395 | // check directories |
371 | if (strstr(dname1, "..") || strstr(dname2, "..")) { | 396 | invalid_filename(dname1); |
372 | fprintf(stderr, "Error: invalid file name.\n"); | 397 | invalid_filename(dname2); |
373 | exit(1); | 398 | if (strstr(dname1, "..") || strstr(dname2, "..")) { |
399 | fprintf(stderr, "Error: invalid file name.\n"); | ||
400 | exit(1); | ||
401 | } | ||
402 | if (is_link(dname1) || is_link(dname2)) { | ||
403 | fprintf(stderr, "Symbolic links are not allowed for bind command\n"); | ||
404 | exit(1); | ||
405 | } | ||
406 | |||
407 | // insert comma back | ||
408 | *(dname2 - 1) = ','; | ||
409 | return 1; | ||
374 | } | 410 | } |
375 | if (is_link(dname1) || is_link(dname2)) { | 411 | else { |
376 | fprintf(stderr, "Symbolic links are not allowed for bind command\n"); | 412 | fprintf(stderr, "Warning: bind feature is disabled in Firejail configuration file\n"); |
377 | exit(1); | 413 | return 0; |
378 | } | 414 | } |
379 | 415 | #else | |
380 | // insert comma back | 416 | return 0; |
381 | *(dname2 - 1) = ','; | 417 | #endif |
382 | return 1; | ||
383 | } | 418 | } |
384 | 419 | ||
385 | // rlimit | 420 | // rlimit |