diff options
-rw-r--r-- | src/firejail/firejail.h | 1 | ||||
-rw-r--r-- | src/firejail/fs_bin.c | 21 | ||||
-rw-r--r-- | src/firejail/fs_etc.c | 36 |
3 files changed, 38 insertions, 20 deletions
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); | |||
398 | void invalid_filename(const char *fname); | 398 | void invalid_filename(const char *fname); |
399 | uid_t get_tty_gid(void); | 399 | uid_t get_tty_gid(void); |
400 | uid_t get_audio_gid(void); | 400 | uid_t get_audio_gid(void); |
401 | int remove_directory(const char *path); | ||
401 | 402 | ||
402 | // fs_var.c | 403 | // fs_var.c |
403 | void fs_var_log(void); // mounting /var/log | 404 | 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) { | |||
149 | } | 149 | } |
150 | 150 | ||
151 | static void duplicate(char *fname) { | 151 | static void duplicate(char *fname) { |
152 | char *cmd; | ||
153 | char *path = check_dir_or_file(fname); | 152 | char *path = check_dir_or_file(fname); |
154 | if (!path) | 153 | if (!path) |
155 | return; | 154 | return; |
@@ -175,13 +174,21 @@ static void duplicate(char *fname) { | |||
175 | } | 174 | } |
176 | else { | 175 | else { |
177 | // copy the file | 176 | // copy the file |
178 | if (asprintf(&cmd, "%s -a %s %s/%s", RUN_CP_COMMAND, actual_path, RUN_BIN_DIR, fname) == -1) | ||
179 | errExit("asprintf"); | ||
180 | if (arg_debug) | 177 | if (arg_debug) |
181 | printf("%s\n", cmd); | 178 | printf("running: %s -a %s %s/%s", RUN_CP_COMMAND, actual_path, RUN_BIN_DIR, fname); |
182 | if (system(cmd)) | 179 | |
183 | errExit("system cp -a"); | 180 | pid_t child = fork(); |
184 | free(cmd); | 181 | if (child < 0) |
182 | errExit("fork"); | ||
183 | if (child == 0) { | ||
184 | char *f; | ||
185 | if (asprintf(&f, "%s/%s", RUN_BIN_DIR, fname) == -1) | ||
186 | errExit("asprintf"); | ||
187 | execlp(RUN_CP_COMMAND, RUN_CP_COMMAND, "-a", actual_path, f, NULL); | ||
188 | } | ||
189 | // wait for the child to finish | ||
190 | waitpid(child, NULL, 0); | ||
191 | |||
185 | } | 192 | } |
186 | free(actual_path); | 193 | free(actual_path); |
187 | } | 194 | } |
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 @@ | |||
28 | static int check_dir_or_file(const char *name) { | 28 | static int check_dir_or_file(const char *name) { |
29 | assert(name); | 29 | assert(name); |
30 | invalid_filename(name); | 30 | invalid_filename(name); |
31 | 31 | ||
32 | struct stat s; | 32 | struct stat s; |
33 | char *fname; | 33 | char *fname; |
34 | if (asprintf(&fname, "/etc/%s", name) == -1) | 34 | if (asprintf(&fname, "/etc/%s", name) == -1) |
@@ -40,7 +40,11 @@ static int check_dir_or_file(const char *name) { | |||
40 | printf("Warning: file %s not found.\n", fname); | 40 | printf("Warning: file %s not found.\n", fname); |
41 | return 0; | 41 | return 0; |
42 | } | 42 | } |
43 | 43 | ||
44 | // read access | ||
45 | if (access(fname, R_OK) == -1) | ||
46 | goto errexit; | ||
47 | |||
44 | // dir or regular file | 48 | // dir or regular file |
45 | if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode)) { | 49 | if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode)) { |
46 | free(fname); | 50 | free(fname); |
@@ -52,6 +56,8 @@ static int check_dir_or_file(const char *name) { | |||
52 | return 1; | 56 | return 1; |
53 | } | 57 | } |
54 | 58 | ||
59 | |||
60 | errexit: | ||
55 | fprintf(stderr, "Error: invalid file type, %s.\n", fname); | 61 | fprintf(stderr, "Error: invalid file type, %s.\n", fname); |
56 | exit(1); | 62 | exit(1); |
57 | } | 63 | } |
@@ -88,18 +94,22 @@ void fs_check_etc_list(void) { | |||
88 | } | 94 | } |
89 | 95 | ||
90 | static void duplicate(char *fname) { | 96 | static void duplicate(char *fname) { |
91 | char *cmd; | 97 | // copy the file |
92 | |||
93 | // copy the file - this code assumes ETC_DIR is actually MNT_DIR/etc | ||
94 | if (asprintf(&cmd, "%s -a --parents /etc/%s %s", RUN_CP_COMMAND, fname, RUN_MNT_DIR) == -1) | ||
95 | errExit("asprintf"); | ||
96 | if (arg_debug) | 98 | if (arg_debug) |
97 | printf("%s\n", cmd); | 99 | printf("running: %s -a --parents /etc/%s %s\n", RUN_CP_COMMAND, fname, RUN_MNT_DIR); |
98 | if (system(cmd)) | 100 | |
99 | fprintf(stderr, "Warning (fs_etc): error copying file /etc/%s, skipping...\n", fname); | 101 | pid_t child = fork(); |
102 | if (child < 0) | ||
103 | errExit("fork"); | ||
104 | if (child == 0) { | ||
105 | char *f; | ||
106 | if (asprintf(&f, "/etc/%s", fname) == -1) | ||
107 | errExit("asprintf"); | ||
108 | execlp(RUN_CP_COMMAND, RUN_CP_COMMAND, "-a", "--parents", f, RUN_MNT_DIR, NULL); | ||
109 | } | ||
110 | // wait for the child to finish | ||
111 | waitpid(child, NULL, 0); | ||
100 | 112 | ||
101 | free(cmd); | ||
102 | |||
103 | char *name; | 113 | char *name; |
104 | if (asprintf(&name, "/etc/%s", fname) == -1) | 114 | if (asprintf(&name, "/etc/%s", fname) == -1) |
105 | errExit("asprintf"); | 115 | errExit("asprintf"); |
@@ -133,7 +143,7 @@ void fs_private_etc_list(void) { | |||
133 | 143 | ||
134 | 144 | ||
135 | // copy the list of files in the new etc directory | 145 | // copy the list of files in the new etc directory |
136 | // using a new child process without root privileges | 146 | // using a new child process with root privileges |
137 | if (*private_list != '\0') { | 147 | if (*private_list != '\0') { |
138 | pid_t child = fork(); | 148 | pid_t child = fork(); |
139 | if (child < 0) | 149 | if (child < 0) |