From 33e2ed2d854373567f0eb49d017e511376100a0b Mon Sep 17 00:00:00 2001 From: netblue30 Date: Sun, 13 Mar 2016 10:49:44 -0400 Subject: cfg chroot, seccomp --- src/firejail/checkcfg.c | 20 +++- src/firejail/firejail.h | 4 +- src/firejail/main.c | 236 +++++++++++++++++++++++++++++++----------------- src/firejail/profile.c | 57 ++++++++---- 4 files changed, 213 insertions(+), 104 deletions(-) (limited to 'src') diff --git a/src/firejail/checkcfg.c b/src/firejail/checkcfg.c index 670fdc502..8376cd9af 100644 --- a/src/firejail/checkcfg.c +++ b/src/firejail/checkcfg.c @@ -86,7 +86,7 @@ int checkcfg(int val) { else goto errout; } - // bind + // user namespace else if (strncmp(ptr, "userns ", 7) == 0) { if (strcmp(ptr + 7, "yes") == 0) cfg_val[CFG_USERNS] = 1; @@ -95,6 +95,24 @@ int checkcfg(int val) { else goto errout; } + // chroot + else if (strncmp(ptr, "chroot ", 7) == 0) { + if (strcmp(ptr + 7, "yes") == 0) + cfg_val[CFG_CHROOT] = 1; + else if (strcmp(ptr + 7, "no") == 0) + cfg_val[CFG_CHROOT] = 0; + else + goto errout; + } + // seccomp + else if (strncmp(ptr, "seccomp ", 8) == 0) { + if (strcmp(ptr + 8, "yes") == 0) + cfg_val[CFG_SECCOMP] = 1; + else if (strcmp(ptr + 8, "no") == 0) + cfg_val[CFG_SECCOMP] = 0; + else + goto errout; + } else goto errout; free(ptr); diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index ed9343345..2b2912b3e 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -542,7 +542,9 @@ void sandboxfs(int op, pid_t pid, const char *patqh); #define CFG_X11 1 #define CFG_BIND 2 #define CFG_USERNS 3 -#define CFG_MAX 4 // this should always be the last entry +#define CFG_CHROOT 4 +#define CFG_SECCOMP 5 +#define CFG_MAX 6 // this should always be the last entry int checkcfg(int val); #endif diff --git a/src/firejail/main.c b/src/firejail/main.c index df625a7ba..8f89a804f 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -356,20 +356,38 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { //************************************* #ifdef HAVE_SECCOMP else if (strcmp(argv[i], "--debug-syscalls") == 0) { - syscall_print(); - exit(0); + if (checkcfg(CFG_SECCOMP)) { + syscall_print(); + exit(0); + } + else { + fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); + exit(1); + } } else if (strcmp(argv[i], "--debug-errnos") == 0) { - errno_print(); + if (checkcfg(CFG_SECCOMP)) { + errno_print(); + } + else { + fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); + exit(1); + } exit(0); } else if (strncmp(argv[i], "--seccomp.print=", 16) == 0) { - // print seccomp filter for a sandbox specified by pid or by name - pid_t pid; - if (read_pid(argv[i] + 16, &pid) == 0) - seccomp_print_filter(pid); - else - seccomp_print_filter_name(argv[i] + 16); + if (checkcfg(CFG_SECCOMP)) { + // print seccomp filter for a sandbox specified by pid or by name + pid_t pid; + if (read_pid(argv[i] + 16, &pid) == 0) + seccomp_print_filter(pid); + else + seccomp_print_filter_name(argv[i] + 16); + } + else { + fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); + exit(1); + } exit(0); } else if (strcmp(argv[i], "--debug-protocols") == 0) { @@ -377,12 +395,18 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { exit(0); } else if (strncmp(argv[i], "--protocol.print=", 17) == 0) { - // print seccomp filter for a sandbox specified by pid or by name - pid_t pid; - if (read_pid(argv[i] + 17, &pid) == 0) - protocol_print_filter(pid); - else - protocol_print_filter_name(argv[i] + 17); + if (checkcfg(CFG_SECCOMP)) { + // print seccomp filter for a sandbox specified by pid or by name + pid_t pid; + if (read_pid(argv[i] + 17, &pid) == 0) + protocol_print_filter(pid); + else + protocol_print_filter_name(argv[i] + 17); + } + else { + fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); + exit(1); + } exit(0); } #endif @@ -733,72 +757,109 @@ int main(int argc, char **argv) { // filtering //************************************* #ifdef HAVE_SECCOMP - else if (strncmp(argv[i], "--protocol=", 11) == 0) - protocol_store(argv[i] + 11); + else if (strncmp(argv[i], "--protocol=", 11) == 0) { + if (checkcfg(CFG_SECCOMP)) { + protocol_store(argv[i] + 11); + } + else { + fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); + exit(1); + } + } else if (strcmp(argv[i], "--seccomp") == 0) { - if (arg_seccomp) { - fprintf(stderr, "Error: seccomp already enabled\n"); + if (checkcfg(CFG_SECCOMP)) { + if (arg_seccomp) { + fprintf(stderr, "Error: seccomp already enabled\n"); + exit(1); + } + arg_seccomp = 1; + } + else { + fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); exit(1); } - arg_seccomp = 1; } else if (strncmp(argv[i], "--seccomp=", 10) == 0) { - if (arg_seccomp) { - fprintf(stderr, "Error: seccomp already enabled\n"); + if (checkcfg(CFG_SECCOMP)) { + if (arg_seccomp) { + fprintf(stderr, "Error: seccomp already enabled\n"); + exit(1); + } + arg_seccomp = 1; + cfg.seccomp_list = strdup(argv[i] + 10); + if (!cfg.seccomp_list) + errExit("strdup"); + } + else { + fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); exit(1); } - arg_seccomp = 1; - cfg.seccomp_list = strdup(argv[i] + 10); - if (!cfg.seccomp_list) - errExit("strdup"); } else if (strncmp(argv[i], "--seccomp.drop=", 15) == 0) { - if (arg_seccomp) { - fprintf(stderr, "Error: seccomp already enabled\n"); + if (checkcfg(CFG_SECCOMP)) { + if (arg_seccomp) { + fprintf(stderr, "Error: seccomp already enabled\n"); + exit(1); + } + arg_seccomp = 1; + cfg.seccomp_list_drop = strdup(argv[i] + 15); + if (!cfg.seccomp_list_drop) + errExit("strdup"); + } + else { + fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); exit(1); } - arg_seccomp = 1; - cfg.seccomp_list_drop = strdup(argv[i] + 15); - if (!cfg.seccomp_list_drop) - errExit("strdup"); } else if (strncmp(argv[i], "--seccomp.keep=", 15) == 0) { - if (arg_seccomp) { - fprintf(stderr, "Error: seccomp already enabled\n"); + if (checkcfg(CFG_SECCOMP)) { + if (arg_seccomp) { + fprintf(stderr, "Error: seccomp already enabled\n"); + exit(1); + } + arg_seccomp = 1; + cfg.seccomp_list_keep = strdup(argv[i] + 15); + if (!cfg.seccomp_list_keep) + errExit("strdup"); + } + else { + fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); exit(1); } - arg_seccomp = 1; - cfg.seccomp_list_keep = strdup(argv[i] + 15); - if (!cfg.seccomp_list_keep) - errExit("strdup"); } else if (strncmp(argv[i], "--seccomp.e", 11) == 0 && strchr(argv[i], '=')) { - if (arg_seccomp && !cfg.seccomp_list_errno) { - fprintf(stderr, "Error: seccomp already enabled\n"); - exit(1); - } - char *eq = strchr(argv[i], '='); - char *errnoname = strndup(argv[i] + 10, eq - (argv[i] + 10)); - int nr = errno_find_name(errnoname); - if (nr == -1) { - fprintf(stderr, "Error: unknown errno %s\n", errnoname); + if (checkcfg(CFG_SECCOMP)) { + if (arg_seccomp && !cfg.seccomp_list_errno) { + fprintf(stderr, "Error: seccomp already enabled\n"); + exit(1); + } + char *eq = strchr(argv[i], '='); + char *errnoname = strndup(argv[i] + 10, eq - (argv[i] + 10)); + int nr = errno_find_name(errnoname); + if (nr == -1) { + fprintf(stderr, "Error: unknown errno %s\n", errnoname); + free(errnoname); + exit(1); + } + + if (!cfg.seccomp_list_errno) + cfg.seccomp_list_errno = calloc(highest_errno+1, sizeof(cfg.seccomp_list_errno[0])); + + if (cfg.seccomp_list_errno[nr]) { + fprintf(stderr, "Error: errno %s already configured\n", errnoname); + free(errnoname); + exit(1); + } + arg_seccomp = 1; + cfg.seccomp_list_errno[nr] = strdup(eq+1); + if (!cfg.seccomp_list_errno[nr]) + errExit("strdup"); free(errnoname); - exit(1); } - - if (!cfg.seccomp_list_errno) - cfg.seccomp_list_errno = calloc(highest_errno+1, sizeof(cfg.seccomp_list_errno[0])); - - if (cfg.seccomp_list_errno[nr]) { - fprintf(stderr, "Error: errno %s already configured\n", errnoname); - free(errnoname); + else { + fprintf(stderr, "Error: seccomp feature is disabled in Firejail configuration file\n"); exit(1); } - arg_seccomp = 1; - cfg.seccomp_list_errno[nr] = strdup(eq+1); - if (!cfg.seccomp_list_errno[nr]) - errExit("strdup"); - free(errnoname); } #endif else if (strcmp(argv[i], "--caps") == 0) @@ -1061,33 +1122,40 @@ int main(int argc, char **argv) { } #ifdef HAVE_CHROOT else if (strncmp(argv[i], "--chroot=", 9) == 0) { - if (arg_overlay) { - fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); - exit(1); - } - invalid_filename(argv[i] + 9); - - // extract chroot dirname - cfg.chrootdir = argv[i] + 9; - // if the directory starts with ~, expand the home directory - if (*cfg.chrootdir == '~') { - char *tmp; - if (asprintf(&tmp, "%s%s", cfg.homedir, cfg.chrootdir + 1) == -1) - errExit("asprintf"); - cfg.chrootdir = tmp; - } - - // check chroot dirname exists - if (strstr(cfg.chrootdir, "..") || !is_dir(cfg.chrootdir) || is_link(cfg.chrootdir)) { - fprintf(stderr, "Error: invalid directory %s\n", cfg.chrootdir); - return 1; + if (checkcfg(CFG_CHROOT)) { + if (arg_overlay) { + fprintf(stderr, "Error: --overlay and --chroot options are mutually exclusive\n"); + exit(1); + } + invalid_filename(argv[i] + 9); + + // extract chroot dirname + cfg.chrootdir = argv[i] + 9; + // if the directory starts with ~, expand the home directory + if (*cfg.chrootdir == '~') { + char *tmp; + if (asprintf(&tmp, "%s%s", cfg.homedir, cfg.chrootdir + 1) == -1) + errExit("asprintf"); + cfg.chrootdir = tmp; + } + + // check chroot dirname exists + if (strstr(cfg.chrootdir, "..") || !is_dir(cfg.chrootdir) || is_link(cfg.chrootdir)) { + fprintf(stderr, "Error: invalid directory %s\n", cfg.chrootdir); + return 1; + } + + // check chroot directory structure + if (fs_check_chroot_dir(cfg.chrootdir)) { + fprintf(stderr, "Error: invalid chroot\n"); + exit(1); + } } - - // check chroot directory structure - if (fs_check_chroot_dir(cfg.chrootdir)) { - fprintf(stderr, "Error: invalid chroot\n"); + else { + fprintf(stderr, "Error: --chroot feature is disabled in Firejail configuration file\n"); exit(1); } + } #endif else if (strcmp(argv[i], "--private") == 0) diff --git a/src/firejail/profile.c b/src/firejail/profile.c index 1c843a460..723889dd2 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c @@ -132,7 +132,12 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { return 0; } else if (strcmp(ptr, "seccomp") == 0) { - arg_seccomp = 1; +#ifdef HAVE_SECCOMP + if (checkcfg(CFG_SECCOMP)) + arg_seccomp = 1; + else + fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); +#endif return 0; } else if (strcmp(ptr, "caps") == 0) { @@ -209,12 +214,15 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { return 0; } -#ifdef HAVE_SECCOMP if (strncmp(ptr, "protocol ", 9) == 0) { - protocol_store(ptr + 9); +#ifdef HAVE_SECCOMP + if (checkcfg(CFG_SECCOMP)) + protocol_store(ptr + 9); + else + fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); +#endif return 0; } -#endif if (strncmp(ptr, "env ", 4) == 0) { env_store(ptr + 4); @@ -223,34 +231,47 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { // seccomp drop list on top of default list if (strncmp(ptr, "seccomp ", 8) == 0) { - arg_seccomp = 1; #ifdef HAVE_SECCOMP - cfg.seccomp_list = strdup(ptr + 8); - if (!cfg.seccomp_list) - errExit("strdup"); + if (checkcfg(CFG_SECCOMP)) { + arg_seccomp = 1; + cfg.seccomp_list = strdup(ptr + 8); + if (!cfg.seccomp_list) + errExit("strdup"); + } + else + fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); #endif + return 0; } // seccomp drop list without default list if (strncmp(ptr, "seccomp.drop ", 13) == 0) { - arg_seccomp = 1; #ifdef HAVE_SECCOMP - cfg.seccomp_list_drop = strdup(ptr + 13); - if (!cfg.seccomp_list_drop) - errExit("strdup"); -#endif + if (checkcfg(CFG_SECCOMP)) { + arg_seccomp = 1; + cfg.seccomp_list_drop = strdup(ptr + 13); + if (!cfg.seccomp_list_drop) + errExit("strdup"); + } + else + fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); +#endif return 0; } // seccomp keep list if (strncmp(ptr, "seccomp.keep ", 13) == 0) { - arg_seccomp = 1; #ifdef HAVE_SECCOMP - cfg.seccomp_list_keep= strdup(ptr + 13); - if (!cfg.seccomp_list_keep) - errExit("strdup"); -#endif + if (checkcfg(CFG_SECCOMP)) { + arg_seccomp = 1; + cfg.seccomp_list_keep= strdup(ptr + 13); + if (!cfg.seccomp_list_keep) + errExit("strdup"); + } + else + fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); +#endif return 0; } -- cgit v1.2.3-54-g00ecf