From c9c18b4cd34bff4df679bb9706fe98f1a8843f26 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Sat, 9 Apr 2016 09:38:59 -0400 Subject: networking fixes --- src/firejail/bandwidth.c | 97 +++++++++++++++++++----------------------------- src/firejail/firejail.h | 9 ++--- src/firejail/main.c | 45 +++++++++++++--------- src/firejail/shutdown.c | 2 + src/firemon/netstats.c | 10 ++++- 5 files changed, 79 insertions(+), 84 deletions(-) diff --git a/src/firejail/bandwidth.c b/src/firejail/bandwidth.c index b7bfb43e6..34c5ca509 100644 --- a/src/firejail/bandwidth.c +++ b/src/firejail/bandwidth.c @@ -112,28 +112,11 @@ int fibw_count(void) { //*********************************** -// shm file handling +// run file handling //*********************************** -void shm_create_firejail_dir(void) { - struct stat s; - if (stat("/dev/shm/firejail", &s) == -1) { - /* coverity[toctou] */ - if (mkdir("/dev/shm/firejail", 0644) == -1) - errExit("mkdir"); - if (chown("/dev/shm/firejail", 0, 0) == -1) - errExit("chown"); - } - else { // check /dev/shm/firejail directory belongs to root end exit if doesn't! - if (s.st_uid != 0 || s.st_gid != 0) { - fprintf(stderr, "Error: non-root %s directory, exiting...\n", "/dev/shm/firejail"); - exit(1); - } - } -} - -static void shm_create_bandwidth_file(pid_t pid) { +static void bandwidth_create_run_file(pid_t pid) { char *fname; - if (asprintf(&fname, "/dev/shm/firejail/%d-bandwidth", (int) pid) == -1) + if (asprintf(&fname, "%s/%d-bandwidth", RUN_FIREJAIL_BANDWIDTH_DIR, (int) pid) == -1) errExit("asprintf"); // if the file already exists, do nothing @@ -157,33 +140,33 @@ static void shm_create_bandwidth_file(pid_t pid) { errExit("chown"); } else { - fprintf(stderr, "Error: cannot create bandwidth file in /dev/shm/firejail directory\n"); + fprintf(stderr, "Error: cannot create bandwidth file\n"); exit(1); } free(fname); } -// delete shm bandwidth file -void bandwidth_shm_del_file(pid_t pid) { +// delete bandwidth file +void bandwidth_del_run_file(pid_t pid) { char *fname; - if (asprintf(&fname, "/dev/shm/firejail/%d-bandwidth", (int) pid) == -1) + if (asprintf(&fname, "%s/%d-bandwidth", RUN_FIREJAIL_BANDWIDTH_DIR, (int) pid) == -1) errExit("asprintf"); unlink(fname); free(fname); } -void network_shm_del_file(pid_t pid) { +void network_del_run_file(pid_t pid) { char *fname; - if (asprintf(&fname, "/dev/shm/firejail/%d-netmap", (int) pid) == -1) + if (asprintf(&fname, "%s/%d-netmap", RUN_FIREJAIL_NETWORK_DIR, (int) pid) == -1) errExit("asprintf"); unlink(fname); free(fname); } -void network_shm_set_file(pid_t pid) { +void network_set_run_file(pid_t pid) { char *fname; - if (asprintf(&fname, "/dev/shm/firejail/%d-netmap", (int) pid) == -1) + if (asprintf(&fname, "%s/%d-netmap", RUN_FIREJAIL_NETWORK_DIR, (int) pid) == -1) errExit("asprintf"); // create an empty file and set mod and ownership @@ -205,7 +188,7 @@ void network_shm_set_file(pid_t pid) { errExit("chown"); } else { - fprintf(stderr, "Error: cannot create network map file in /dev/shm/firejail directory\n"); + fprintf(stderr, "Error: cannot create network map file\n"); exit(1); } @@ -213,11 +196,11 @@ void network_shm_set_file(pid_t pid) { } -void shm_read_bandwidth_file(pid_t pid) { +static void read_bandwidth_file(pid_t pid) { assert(ifbw == NULL); char *fname; - if (asprintf(&fname, "/dev/shm/firejail/%d-bandwidth", (int) pid) == -1) + if (asprintf(&fname, "%s/%d-bandwidth", RUN_FIREJAIL_BANDWIDTH_DIR, (int) pid) == -1) errExit("asprintf"); FILE *fp = fopen(fname, "r"); @@ -248,12 +231,12 @@ void shm_read_bandwidth_file(pid_t pid) { } } -void shm_write_bandwidth_file(pid_t pid) { +static void write_bandwidth_file(pid_t pid) { if (ifbw == NULL) return; // nothing to do char *fname; - if (asprintf(&fname, "/dev/shm/firejail/%d-bandwidth", (int) pid) == -1) + if (asprintf(&fname, "%s/%d-bandwidth", RUN_FIREJAIL_BANDWIDTH_DIR, (int) pid) == -1) errExit("asprintf"); FILE *fp = fopen(fname, "w"); @@ -279,33 +262,30 @@ errout: // add or remove interfaces //*********************************** -// remove interface from shm file -void bandwidth_shm_remove(pid_t pid, const char *dev) { - // create bandwidth directory & file in case they are not in the filesystem yet - shm_create_firejail_dir(); - shm_create_bandwidth_file(pid); +// remove interface from run file +void bandwidth_remove(pid_t pid, const char *dev) { + bandwidth_create_run_file(pid); // read bandwidth file - shm_read_bandwidth_file(pid); + read_bandwidth_file(pid); // find the element and remove it IFBW *elem = ifbw_find(dev); if (elem) { ifbw_remove(elem); - shm_write_bandwidth_file(pid) ; + write_bandwidth_file(pid) ; } // remove the file if there are no entries in the list if (ifbw == NULL) { - bandwidth_shm_del_file(pid); + bandwidth_del_run_file(pid); } } -// add interface to shm file -void bandwidth_shm_set(pid_t pid, const char *dev, int down, int up) { +// add interface to run file +void bandwidth_set(pid_t pid, const char *dev, int down, int up) { // create bandwidth directory & file in case they are not in the filesystem yet - shm_create_firejail_dir(); - shm_create_bandwidth_file(pid); + bandwidth_create_run_file(pid); // create the new text entry char *txt; @@ -313,7 +293,7 @@ void bandwidth_shm_set(pid_t pid, const char *dev, int down, int up) { errExit("asprintf"); // read bandwidth file - shm_read_bandwidth_file(pid); + read_bandwidth_file(pid); // look for an existing entry and replace the text IFBW *ptr = ifbw_find(dev); @@ -333,7 +313,7 @@ void bandwidth_shm_set(pid_t pid, const char *dev, int down, int up) { // add it to the linked list ifbw_add(ifbw_new); } - shm_write_bandwidth_file(pid) ; + write_bandwidth_file(pid) ; } @@ -376,15 +356,14 @@ void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, in free(comm); // check network namespace - EUID_ROOT(); - char *cmd = pid_proc_cmdline(pid); - EUID_USER(); - if (!cmd || strstr(cmd, "--net") == NULL) { + char *name; + if (asprintf(&name, "/run/firejail/network/%d-netmap", pid) == -1) + errExit("asprintf"); + struct stat s; + if (stat(name, &s) == -1) { fprintf(stderr, "Error: the sandbox doesn't use a new network namespace\n"); exit(1); } - free(cmd); - //************************ // join the network namespace @@ -401,20 +380,20 @@ void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, in exit(1); } - // set shm file + // set run file if (strcmp(command, "set") == 0) - bandwidth_shm_set(pid, dev, down, up); + bandwidth_set(pid, dev, down, up); else if (strcmp(command, "clear") == 0) - bandwidth_shm_remove(pid, dev); + bandwidth_remove(pid, dev); //************************ // build command //************************ char *devname = NULL; if (dev) { - // read shm network map file + // read network map file char *fname; - if (asprintf(&fname, "/dev/shm/firejail/%d-netmap", (int) pid) == -1) + if (asprintf(&fname, "%s/%d-netmap", RUN_FIREJAIL_NETWORK_DIR, (int) pid) == -1) errExit("asprintf"); FILE *fp = fopen(fname, "r"); if (!fp) { @@ -449,7 +428,7 @@ void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, in } // build fshaper.sh command - cmd = NULL; + char *cmd = NULL; if (devname) { if (strcmp(command, "set") == 0) { if (asprintf(&cmd, "%s/firejail/fshaper.sh --%s %s %d %d", diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 92fd151c1..24ea53476 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -208,6 +208,7 @@ static inline int any_interface_configured(void) { else return 0; } +void clear_run_files(pid_t pid); extern int arg_private; // mount private /home extern int arg_debug; // print debug messages @@ -468,13 +469,11 @@ void netfilter(const char *fname); void netfilter6(const char *fname); // bandwidth.c -void shm_create_firejail_dir(void); -void bandwidth_shm_del_file(pid_t pid); -void bandwidth_shm_set(pid_t pid, const char *dev, int down, int up); +void bandwidth_del_run_file(pid_t pid); void bandwidth_name(const char *name, const char *command, const char *dev, int down, int up); void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, int up); -void network_shm_del_file(pid_t pid); -void network_shm_set_file(pid_t pid); +void network_del_run_file(pid_t pid); +void network_set_run_file(pid_t pid); // fs_etc.c void fs_check_etc_list(void); diff --git a/src/firejail/main.c b/src/firejail/main.c index b029ef21e..d33a8740d 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -105,27 +105,33 @@ int fullargc = 0; static pid_t child = 0; pid_t sandbox_pid; -static void set_name_file(uid_t pid); -static void delete_name_file(uid_t pid); -static void set_x11_file(uid_t pid, int display); -static void delete_x11_file(uid_t pid); +static void set_name_file(pid_t pid); +static void delete_name_file(pid_t pid); +static void set_x11_file(pid_t pid, int display); +static void delete_x11_file(pid_t pid); + +void clear_run_files(pid_t pid) { + bandwidth_del_run_file(pid); // bandwidth file + network_del_run_file(pid); // network map file + delete_name_file(pid); + delete_x11_file(pid); +} static void myexit(int rv) { logmsg("exiting..."); if (!arg_command && !arg_quiet) printf("\nparent is shutting down, bye...\n"); - + + // delete sandbox files in shared memory - bandwidth_shm_del_file(sandbox_pid); // bandwidth file - network_shm_del_file(sandbox_pid); // network map file - delete_name_file(sandbox_pid); - delete_x11_file(sandbox_pid); + EUID_ROOT(); + clear_run_files(sandbox_pid); exit(rv); } static void my_handler(int s){ -EUID_ROOT(); + EUID_ROOT(); if (!arg_quiet) printf("\nSignal %d caught, shutting down the child process\n", s); logsignal(s); @@ -615,7 +621,7 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { } -static void set_name_file(uid_t pid) { +static void set_name_file(pid_t pid) { char *fname; if (asprintf(&fname, "%s/%d", RUN_FIREJAIL_NAME_DIR, pid) == -1) errExit("asprintf"); @@ -637,7 +643,7 @@ static void set_name_file(uid_t pid) { } -static void delete_name_file(uid_t pid) { +static void delete_name_file(pid_t pid) { char *fname; if (asprintf(&fname, "%s/%d", RUN_FIREJAIL_NAME_DIR, pid) == -1) errExit("asprintf"); @@ -645,7 +651,7 @@ static void delete_name_file(uid_t pid) { (void) rv; } -static void set_x11_file(uid_t pid, int display) { +static void set_x11_file(pid_t pid, int display) { char *fname; if (asprintf(&fname, "%s/%d", RUN_FIREJAIL_X11_DIR, pid) == -1) errExit("asprintf"); @@ -667,7 +673,7 @@ static void set_x11_file(uid_t pid, int display) { } -static void delete_x11_file(uid_t pid) { +static void delete_x11_file(pid_t pid) { char *fname; if (asprintf(&fname, "%s/%d", RUN_FIREJAIL_X11_DIR, pid) == -1) errExit("asprintf"); @@ -772,9 +778,11 @@ int main(int argc, char **argv) { // check firejail directories EUID_ROOT(); fs_build_firejail_dir(); - // todo: deprecate shm functions - shm_create_firejail_dir(); - bandwidth_shm_del_file(sandbox_pid); + bandwidth_del_run_file(sandbox_pid); + network_del_run_file(sandbox_pid); + delete_name_file(sandbox_pid); + delete_x11_file(sandbox_pid); + EUID_USER(); //check if the parent is sshd daemon @@ -1926,7 +1934,7 @@ int main(int argc, char **argv) { check_network(&cfg.bridge3); // save network mapping in shared memory - network_shm_set_file(sandbox_pid); + network_set_run_file(sandbox_pid); EUID_USER(); } @@ -2089,6 +2097,7 @@ int main(int argc, char **argv) { EUID_USER(); int status = 0; waitpid(child, &status, 0); +printf("after wait\n"); // free globals #ifdef HAVE_SECCOMP diff --git a/src/firejail/shutdown.c b/src/firejail/shutdown.c index b7ef48c8d..94ca0a816 100644 --- a/src/firejail/shutdown.c +++ b/src/firejail/shutdown.c @@ -98,4 +98,6 @@ void shut(pid_t pid) { printf("Sending SIGKILL to %u\n", parent); kill(parent, SIGKILL); } + + clear_run_files(parent); } diff --git a/src/firemon/netstats.c b/src/firemon/netstats.c index 3b6c128ae..89e4202bd 100644 --- a/src/firemon/netstats.c +++ b/src/firemon/netstats.c @@ -117,8 +117,14 @@ static void print_proc(int index, int itv, int col) { } else ptrcmd = cmd; - // if the command doesn't have a --net= option, don't print - if (strstr(ptrcmd, "--net=") == NULL) { + + // check network namespace + char *name; + if (asprintf(&name, "/run/firejail/network/%d-netmap", index) == -1) + errExit("asprintf"); + struct stat s; + if (stat(name, &s) == -1) { + // the sandbox doesn't have a --net= option, don't print if (cmd) free(cmd); return; -- cgit v1.2.3-70-g09d2