From dbb15d0067f1fce7478ff4059a5e1d78dec37804 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Tue, 3 Nov 2015 08:55:40 -0500 Subject: --private.print option --- src/firejail/cpu.c | 4 +- src/firejail/firejail.h | 3 + src/firejail/join.c | 9 ++- src/firejail/protocol.c | 145 ++++++++++++++++++++++++++++++++++++++++-------- src/firejail/sandbox.c | 3 +- src/firejail/seccomp.c | 5 +- 6 files changed, 138 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/firejail/cpu.c b/src/firejail/cpu.c index 6dcbbd07b..807dc55a4 100644 --- a/src/firejail/cpu.c +++ b/src/firejail/cpu.c @@ -75,6 +75,8 @@ void save_cpu(void) { if (fp) { fprintf(fp, "%x\n", cfg.cpus); fclose(fp); + if (chmod(CPU_CFG, 0600) < 0) + errExit("chmod"); if (chown(CPU_CFG, 0, 0) < 0) errExit("chown"); } @@ -126,7 +128,7 @@ void set_cpu_affinity(void) { fprintf(stderr, " "); perror("sched_getaffinity"); } - else { + else if (arg_debug) { if (CPU_EQUAL(&mask, &mask2)) printf("CPU affinity set\n"); else diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 1068485ff..29ce77ca4 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -31,6 +31,7 @@ #define CGROUP_CFG "/tmp/firejail/mnt/cgroup" #define CPU_CFG "/tmp/firejail/mnt/cpu" #define GROUPS_CFG "/tmp/firejail/mnt/groups" +#define PROTOCOL_CFG "/tmp/firejail/mnt/protocol" #define CP_COMMAND "/tmp/firejail/mnt/cp" #define HOME_DIR "/tmp/firejail/mnt/home" #define ETC_DIR "/tmp/firejail/mnt/etc" @@ -447,5 +448,7 @@ void protocol_print_filter_name(const char *name); void protocol_print_filter(pid_t pid); void protocol_store(const char *prlist); void protocol_filter(void); +void protocol_filter_save(void); +void protocol_filter_load(const char *fname); #endif diff --git a/src/firejail/join.c b/src/firejail/join.c index 91dad420a..64e092197 100644 --- a/src/firejail/join.c +++ b/src/firejail/join.c @@ -144,7 +144,7 @@ static void extract_caps_seccomp(pid_t pid) { free(file); } -void extract_user_namespace(pid_t pid) { +static void extract_user_namespace(pid_t pid) { // test user namespaces available in the kernel struct stat s1; struct stat s2; @@ -280,9 +280,16 @@ void join(pid_t pid, const char *homedir, int argc, char **argv, int index) { if (apply_caps == 1) caps_set(caps); #ifdef HAVE_SECCOMP + // set protocol filter + protocol_filter_load(PROTOCOL_CFG); + if (cfg.protocol) { + protocol_filter(); + } + // set seccomp filter if (apply_seccomp == 1) seccomp_set(); + #endif // fix qt 4.8 diff --git a/src/firejail/protocol.c b/src/firejail/protocol.c index e71daaad8..8ee5fd3b8 100644 --- a/src/firejail/protocol.c +++ b/src/firejail/protocol.c @@ -114,27 +114,6 @@ void protocol_list(void) { printf("\n"); } -// --protocol.print -void protocol_print_filter_name(const char *name) { - (void) name; -#ifdef SYS_socket -//todo -#else - fprintf(stderr, "Warning: --protocol not supported on this platform\n"); - return; -#endif -} - -// --protocol.print -void protocol_print_filter(pid_t pid) { - (void) pid; -#ifdef SYS_socket -//todo -#else - fprintf(stderr, "Warning: --protocol not supported on this platform\n"); - return; -#endif -} // check protocol list and store it in cfg structure void protocol_store(const char *prlist) { @@ -171,6 +150,8 @@ errout: // install protocol filter void protocol_filter(void) { assert(cfg.protocol); + if (arg_debug) + printf("Set protocol filter: %s\n", cfg.protocol); #ifndef SYS_socket (void) find_protocol_domain; @@ -273,10 +254,126 @@ printf("entries %u\n", (unsigned) ((uint64_t) ptr - (uint64_t) (filter)) / (uns fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); return; } - else if (arg_debug) { - printf("seccomp protocol filter enabled\n"); - } #endif // SYS_socket } +void protocol_filter_save(void) { + // save protocol filter configuration in PROTOCOL_CFG + fs_build_mnt_dir(); + + FILE *fp = fopen(PROTOCOL_CFG, "w"); + if (!fp) + errExit("fopen"); + fprintf(fp, "%s\n", cfg.protocol); + fclose(fp); + + if (chmod(PROTOCOL_CFG, 0600) < 0) + errExit("chmod"); + + if (chown(PROTOCOL_CFG, 0, 0) < 0) + errExit("chown"); + +} + +void protocol_filter_load(const char *fname) { + assert(fname); + + // read protocol filter configuration from PROTOCOL_CFG + FILE *fp = fopen(fname, "r"); + if (!fp) + return; + + const int MAXBUF = 4098; + char buf[MAXBUF]; + if (fgets(buf, MAXBUF, fp) == NULL) { + // empty file + fclose(fp); + return; + } + fclose(fp); + + char *ptr = strchr(buf, '\n'); + if (ptr) + *ptr = '\0'; + cfg.protocol = strdup(buf); + if (!cfg.protocol) + errExit("strdup"); +} + + +// --protocol.print +void protocol_print_filter_name(const char *name) { + (void) name; +#ifdef SYS_socket + if (!name || strlen(name) == 0) { + fprintf(stderr, "Error: invalid sandbox name\n"); + exit(1); + } + pid_t pid; + if (name2pid(name, &pid)) { + fprintf(stderr, "Error: cannot find sandbox %s\n", name); + exit(1); + } + + protocol_print_filter(pid); +#else + fprintf(stderr, "Warning: --protocol not supported on this platform\n"); + return; +#endif +} + +// --protocol.print +void protocol_print_filter(pid_t pid) { + (void) pid; +#ifdef SYS_socket + // if the pid is that of a firejail process, use the pid of the first child process + char *comm = pid_proc_comm(pid); + if (comm) { + // remove \n + char *ptr = strchr(comm, '\n'); + if (ptr) + *ptr = '\0'; + if (strcmp(comm, "firejail") == 0) { + pid_t child; + if (find_child(pid, &child) == 0) { + pid = child; + } + } + free(comm); + } + + // check privileges for non-root users + uid_t uid = getuid(); + if (uid != 0) { + uid_t sandbox_uid = pid_get_uid(pid); + if (uid != sandbox_uid) { + fprintf(stderr, "Error: permission denied.\n"); + exit(1); + } + } + + // find the seccomp filter + char *fname; + if (asprintf(&fname, "/proc/%d/root%s", pid, PROTOCOL_CFG) == -1) + errExit("asprintf"); + + struct stat s; + if (stat(fname, &s) == -1) { + printf("Cannot access seccomp filter.\n"); + exit(1); + } + + // read and print the filter + protocol_filter_load(fname); + free(fname); + if (cfg.protocol) + printf("%s\n", cfg.protocol); + exit(0); +#else + fprintf(stderr, "Warning: --protocol not supported on this platform\n"); + return; +#endif +} + + #endif // HAVE_SECCOMP diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index d9ce717e0..79ed473c0 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c @@ -425,7 +425,8 @@ int sandbox(void* sandbox_arg) { #ifdef HAVE_SECCOMP // install protocol filter if (cfg.protocol) { - protocol_filter(); + protocol_filter(); // install filter + protocol_filter_save(); // save filter in PROTOCOL_CFG } // if a keep list is available, disregard the drop list diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c index f8053d698..a3efa54df 100644 --- a/src/firejail/seccomp.c +++ b/src/firejail/seccomp.c @@ -385,7 +385,7 @@ void seccomp_filter_32(void) { ; } else if (arg_debug) { - printf("dual i386/amd64 seccomp filter\n"); + printf("Dual i386/amd64 seccomp filter configured\n"); } } @@ -598,9 +598,6 @@ int seccomp_filter_drop(void) { fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); return 1; } - else if (arg_debug) { - printf("seccomp enabled\n"); - } return 0; } -- cgit v1.2.3-70-g09d2