From 73c5236e195332ef0b8792712d4ff5c24399c19c Mon Sep 17 00:00:00 2001 From: netblue30 Date: Sun, 23 Aug 2015 07:17:30 -0400 Subject: if a sandbox is already running, the program is started directly --- src/firejail/firejail.h | 4 ++ src/firejail/main.c | 10 +++- src/firejail/no_sandbox.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 src/firejail/no_sandbox.c (limited to 'src') diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 3acaeb6fb..321f0e830 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -358,5 +358,9 @@ void network_shm_set_file(pid_t pid); void fs_check_etc_list(void); void fs_private_etc_list(void); +// no_sandbox.c +int check_kernel_procs(void); +void run_no_sandbox(int argc, char **argv); + #endif diff --git a/src/firejail/main.c b/src/firejail/main.c index 14a5d9d47..9acfb254f 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -242,12 +242,18 @@ int main(int argc, char **argv) { int arg_ipc = 0; int arg_cgroup = 0; int custom_profile = 0; // custom profile loaded + + // if a sandbox is already running, start the program directly without sandboxing + if (check_kernel_procs() == 0) { + run_no_sandbox(argc, argv); + // it will never get here! + assert(0); + } // initialize globals init_cfg(); cfg.original_argv = argv; cfg.original_argc = argc; - // initialize random number generator sandbox_pid = getpid(); @@ -276,7 +282,7 @@ int main(int argc, char **argv) { // check --output option and execute it; check_output(argc, argv); // the function will not return if --output option was found } - + // parse arguments for (i = 1; i < argc; i++) { //************************************* diff --git a/src/firejail/no_sandbox.c b/src/firejail/no_sandbox.c new file mode 100644 index 000000000..9dc01435f --- /dev/null +++ b/src/firejail/no_sandbox.c @@ -0,0 +1,119 @@ +#include "firejail.h" +#include +#include +#include + +// check process space for kernel processes +// return 1 if found, 0 if not found +int check_kernel_procs(void) { + char *kern_proc[] = { + "kthreadd", + "ksoftirqd", + "kworker", + "rcu_sched", + "rcu_bh", + NULL // NULL terminated list + }; + int i; + + // look at the first 10 processes + // if a kernel process is found, return 1 + for (i = 1; i <= 10; i++) { + struct stat s; + char *fname; + if (asprintf(&fname, "/proc/%d/comm", i) == -1) + errExit("asprintf"); + if (stat(fname, &s) == -1) { + free(fname); + continue; + } + + // open file + FILE *fp = fopen(fname, "r"); + if (!fp) { + fprintf(stderr, "Warning: cannot open %s\n", fname); + free(fname); + continue; + } + + // read file + char buf[100]; + if (fgets(buf, 10, fp) == NULL) { + fprintf(stderr, "Warning: cannot read %s\n", fname); + fclose(fp); + free(fname); + continue; + } + // clean /n + char *ptr; + if ((ptr = strchr(buf, '\n')) != NULL) + *ptr = '\0'; + + // check process name against the kernel list + int j = 0; + while (kern_proc[j] != NULL) { + if (strncmp(buf, kern_proc[j], strlen(kern_proc[j])) == 0) { + fclose(fp); + free(fname); + return 1; + } + j++; + } + + fclose(fp); + free(fname); + } + + return 0; +} + +void run_no_sandbox(int argc, char **argv) { + // drop privileges + int rv = setgroups(0, NULL); // this could fail + (void) rv; + if (setgid(getgid()) < 0) + errExit("setgid/getgid"); + if (setuid(getuid()) < 0) + errExit("setuid/getuid"); + + + // build command + char *command = NULL; + int allocated = 0; + if (argc == 1) + command = "/bin/bash"; + else { + // calculate length + int len = 0; + int i; + for (i = 1; i < argc; i++) { + if (*argv[i] == '-') + continue; + break; + } + int start_index = i; + for (i = start_index; i < argc; i++) + len += strlen(argv[i]) + 1; + + // allocate + command = malloc(len + 1); + if (!command) + errExit("malloc"); + memset(command, 0, len + 1); + allocated = 1; + + // copy + for (i = start_index; i < argc; i++) { + strcat(command, argv[i]); + strcat(command, " "); + } + } + + // start the program in /bin/sh + fprintf(stderr, "Warning: an existing sandbox was detected. " + "%s will run without any additional sandboxing features in a /bin/sh shell\n", command); + system(command); + if (allocated) + free(command); + exit(1); +} -- cgit v1.2.3-54-g00ecf