diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 333cd92f4..16b9d468f 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -398,6 +398,7 @@ uid_t pid_get_uid(pid_t pid); void invalid_filename(const char *fname); uid_t get_tty_gid(void); uid_t get_audio_gid(void); +int remove_directory(const char *path); // fs_var.c void fs_var_log(void); // mounting /var/log diff --git a/src/firejail/fs_bin.c b/src/firejail/fs_bin.c index cc2aa8f4d..6bd407346 100644 --- a/src/firejail/fs_bin.c +++ b/src/firejail/fs_bin.c @@ -149,7 +149,6 @@ void fs_check_bin_list(void) { } static void duplicate(char *fname) { - char *cmd; char *path = check_dir_or_file(fname); if (!path) return; @@ -175,13 +174,21 @@ static void duplicate(char *fname) { } else { // copy the file - if (asprintf(&cmd, "%s -a %s %s/%s", RUN_CP_COMMAND, actual_path, RUN_BIN_DIR, fname) == -1) - errExit("asprintf"); if (arg_debug) - printf("%s\n", cmd); - if (system(cmd)) - errExit("system cp -a"); - free(cmd); + printf("running: %s -a %s %s/%s", RUN_CP_COMMAND, actual_path, RUN_BIN_DIR, fname); + + pid_t child = fork(); + if (child < 0) + errExit("fork"); + if (child == 0) { + char *f; + if (asprintf(&f, "%s/%s", RUN_BIN_DIR, fname) == -1) + errExit("asprintf"); + execlp(RUN_CP_COMMAND, RUN_CP_COMMAND, "-a", actual_path, f, NULL); + } + // wait for the child to finish + waitpid(child, NULL, 0); + } free(actual_path); } diff --git a/src/firejail/fs_etc.c b/src/firejail/fs_etc.c index 2ff36f5d2..6b9a4395b 100644 --- a/src/firejail/fs_etc.c +++ b/src/firejail/fs_etc.c @@ -28,7 +28,7 @@ static int check_dir_or_file(const char *name) { assert(name); invalid_filename(name); - + struct stat s; char *fname; if (asprintf(&fname, "/etc/%s", name) == -1) @@ -40,7 +40,11 @@ static int check_dir_or_file(const char *name) { printf("Warning: file %s not found.\n", fname); return 0; } - + + // read access + if (access(fname, R_OK) == -1) + goto errexit; + // dir or regular file if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode)) { free(fname); @@ -52,6 +56,8 @@ static int check_dir_or_file(const char *name) { return 1; } + +errexit: fprintf(stderr, "Error: invalid file type, %s.\n", fname); exit(1); } @@ -88,18 +94,22 @@ void fs_check_etc_list(void) { } static void duplicate(char *fname) { - char *cmd; - - // copy the file - this code assumes ETC_DIR is actually MNT_DIR/etc - if (asprintf(&cmd, "%s -a --parents /etc/%s %s", RUN_CP_COMMAND, fname, RUN_MNT_DIR) == -1) - errExit("asprintf"); + // copy the file if (arg_debug) - printf("%s\n", cmd); - if (system(cmd)) - fprintf(stderr, "Warning (fs_etc): error copying file /etc/%s, skipping...\n", fname); + 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) + errExit("asprintf"); + execlp(RUN_CP_COMMAND, RUN_CP_COMMAND, "-a", "--parents", f, RUN_MNT_DIR, NULL); + } + // wait for the child to finish + waitpid(child, NULL, 0); - free(cmd); - char *name; if (asprintf(&name, "/etc/%s", fname) == -1) errExit("asprintf"); @@ -133,7 +143,7 @@ void fs_private_etc_list(void) { // copy the list of files in the new etc directory - // using a new child process without root privileges + // using a new child process with root privileges if (*private_list != '\0') { pid_t child = fork(); if (child < 0)