From 4c2ed4eeafcacb380cba143d216811501ad57f33 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Thu, 17 Nov 2016 09:59:15 -0500 Subject: fcopy part 3 --- src/fcopy/main.c | 4 +- src/firejail/fs_etc.c | 109 +++++++++++++++++++------------------------------- src/firejail/util.c | 2 + 3 files changed, 45 insertions(+), 70 deletions(-) (limited to 'src') diff --git a/src/fcopy/main.c b/src/fcopy/main.c index ca2643e7d..56d297c9a 100644 --- a/src/fcopy/main.c +++ b/src/fcopy/main.c @@ -272,7 +272,7 @@ static void usage(void) { } int main(int argc, char **argv) { -#if 0 +//#if 0 { //system("cat /proc/self/status"); int i; @@ -280,7 +280,7 @@ for (i = 0; i < argc; i++) printf("*%s* ", argv[i]); printf("\n"); } -#endif +//#endif if (argc != 3) { fprintf(stderr, "Error fcopy: files missing\n"); usage(); diff --git a/src/firejail/fs_etc.c b/src/firejail/fs_etc.c index 6a70d482c..7d4ffa938 100644 --- a/src/firejail/fs_etc.c +++ b/src/firejail/fs_etc.c @@ -21,18 +21,14 @@ #include #include #include -#include #include // return 0 if file not found, 1 if found -static int check_dir_or_file(const char *name) { - assert(name); - invalid_filename(name); +static int check_dir_or_file(const char *fname) { + assert(fname); + invalid_filename(fname); struct stat s; - char *fname; - if (asprintf(&fname, "/etc/%s", name) == -1) - errExit("asprintf"); if (arg_debug) printf("Checking %s\n", fname); if (stat(fname, &s) == -1) { @@ -46,16 +42,8 @@ static int check_dir_or_file(const char *name) { goto errexit; // dir or regular file - if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode)) { - free(fname); - return 1; - } - - if (!is_link(fname)) { - free(fname); - return 1; - } - + if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode) || !is_link(fname)) + return 1; // normal exit errexit: fprintf(stderr, "Error: invalid file type, %s.\n", fname); @@ -63,30 +51,32 @@ errexit: } static void duplicate(char *fname) { - // copy the file - if (arg_debug) - printf("running: %s -a --parents /etc/%s %s\n", RUN_CP_COMMAND, fname, RUN_MNT_DIR); - - pid_t child = fork(); - if (child < 0) - errExit("fork"); - if (child == 0) { - char *f; - if (asprintf(&f, "/etc/%s", fname) == -1) + char *src; + if (asprintf(&src, "/etc/%s", fname) == -1) + errExit("asprintf"); + if (check_dir_or_file(src) == 0) { + if (!arg_quiet) + fprintf(stderr, "Warning: skipping %s for private bin\n", fname); + free(src); + return; + } + + + struct stat s; + if (stat(src, &s) == 0 && S_ISDIR(s.st_mode)) { + // create the directory in RUN_ETC_DIR + char *dirname; + if (asprintf(&dirname, "%s/%s", RUN_ETC_DIR, fname) == -1) errExit("asprintf"); - clearenv(); - execlp(RUN_CP_COMMAND, RUN_CP_COMMAND, "-a", "--parents", f, RUN_MNT_DIR, NULL); - perror("execlp"); - _exit(1); + create_empty_dir_as_root(dirname, s.st_mode); + sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, src, dirname); + free(dirname); } - // wait for the child to finish - waitpid(child, NULL, 0); + else + sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, src, RUN_ETC_DIR); - char *name; - if (asprintf(&name, "/etc/%s", fname) == -1) - errExit("asprintf"); - fs_logger2("clone", name); - free(name); + fs_logger2("clone", src); + free(src); } @@ -110,39 +100,22 @@ void fs_private_etc_list(void) { // copy the list of files in the new etc directory // using a new child process with root privileges if (*private_list != '\0') { - pid_t child = fork(); - if (child < 0) - errExit("fork"); - if (child == 0) { - if (arg_debug) - printf("Copying files in the new etc directory:\n"); + if (arg_debug) + printf("Copying files in the new etc directory:\n"); + + // copy the list of files in the new home directory + char *dlist = strdup(private_list); + if (!dlist) + errExit("strdup"); - // elevate privileges - files in the new /etc directory belong to root - if (setreuid(0, 0) < 0) - errExit("setreuid"); - if (setregid(0, 0) < 0) - errExit("setregid"); - - // copy the list of files in the new home directory - char *dlist = strdup(private_list); - if (!dlist) - errExit("strdup"); - + + char *ptr = strtok(dlist, ","); + duplicate(ptr); - char *ptr = strtok(dlist, ","); + while ((ptr = strtok(NULL, ",")) != NULL) duplicate(ptr); - - while ((ptr = strtok(NULL, ",")) != NULL) - duplicate(ptr); - free(dlist); - fs_logger_print(); -#ifdef HAVE_GCOV - __gcov_flush(); -#endif - _exit(0); - } - // wait for the child to finish - waitpid(child, NULL, 0); + free(dlist); + fs_logger_print(); } if (arg_debug) diff --git a/src/firejail/util.c b/src/firejail/util.c index c56380ca1..03f52fabb 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c @@ -694,6 +694,7 @@ void flush_stdin(void) { void create_empty_dir_as_root(const char *dir, mode_t mode) { assert(dir); + mode &= 07777; struct stat s; if (stat(dir, &s)) { @@ -709,6 +710,7 @@ void create_empty_dir_as_root(const char *dir, mode_t mode) { void create_empty_file_as_root(const char *fname, mode_t mode) { assert(fname); + mode &= 07777; struct stat s; if (stat(fname, &s)) { -- cgit v1.2.3-54-g00ecf