diff options
author | netblue30 <netblue30@yahoo.com> | 2016-11-17 09:59:15 -0500 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2016-11-17 09:59:15 -0500 |
commit | 4c2ed4eeafcacb380cba143d216811501ad57f33 (patch) | |
tree | 1167c64400d34601e754c13dd29d4fb557bca7b0 | |
parent | cleanup (diff) | |
download | firejail-4c2ed4eeafcacb380cba143d216811501ad57f33.tar.gz firejail-4c2ed4eeafcacb380cba143d216811501ad57f33.tar.zst firejail-4c2ed4eeafcacb380cba143d216811501ad57f33.zip |
fcopy part 3
-rw-r--r-- | src/fcopy/main.c | 4 | ||||
-rw-r--r-- | src/firejail/fs_etc.c | 109 | ||||
-rw-r--r-- | src/firejail/util.c | 2 |
3 files changed, 45 insertions, 70 deletions
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) { | |||
272 | } | 272 | } |
273 | 273 | ||
274 | int main(int argc, char **argv) { | 274 | int main(int argc, char **argv) { |
275 | #if 0 | 275 | //#if 0 |
276 | { | 276 | { |
277 | //system("cat /proc/self/status"); | 277 | //system("cat /proc/self/status"); |
278 | int i; | 278 | int i; |
@@ -280,7 +280,7 @@ for (i = 0; i < argc; i++) | |||
280 | printf("*%s* ", argv[i]); | 280 | printf("*%s* ", argv[i]); |
281 | printf("\n"); | 281 | printf("\n"); |
282 | } | 282 | } |
283 | #endif | 283 | //#endif |
284 | if (argc != 3) { | 284 | if (argc != 3) { |
285 | fprintf(stderr, "Error fcopy: files missing\n"); | 285 | fprintf(stderr, "Error fcopy: files missing\n"); |
286 | usage(); | 286 | 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 @@ | |||
21 | #include <sys/mount.h> | 21 | #include <sys/mount.h> |
22 | #include <sys/stat.h> | 22 | #include <sys/stat.h> |
23 | #include <sys/types.h> | 23 | #include <sys/types.h> |
24 | #include <sys/wait.h> | ||
25 | #include <unistd.h> | 24 | #include <unistd.h> |
26 | 25 | ||
27 | // return 0 if file not found, 1 if found | 26 | // return 0 if file not found, 1 if found |
28 | static int check_dir_or_file(const char *name) { | 27 | static int check_dir_or_file(const char *fname) { |
29 | assert(name); | 28 | assert(fname); |
30 | invalid_filename(name); | 29 | invalid_filename(fname); |
31 | 30 | ||
32 | struct stat s; | 31 | struct stat s; |
33 | char *fname; | ||
34 | if (asprintf(&fname, "/etc/%s", name) == -1) | ||
35 | errExit("asprintf"); | ||
36 | if (arg_debug) | 32 | if (arg_debug) |
37 | printf("Checking %s\n", fname); | 33 | printf("Checking %s\n", fname); |
38 | if (stat(fname, &s) == -1) { | 34 | if (stat(fname, &s) == -1) { |
@@ -46,16 +42,8 @@ static int check_dir_or_file(const char *name) { | |||
46 | goto errexit; | 42 | goto errexit; |
47 | 43 | ||
48 | // dir or regular file | 44 | // dir or regular file |
49 | if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode)) { | 45 | if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode) || !is_link(fname)) |
50 | free(fname); | 46 | return 1; // normal exit |
51 | return 1; | ||
52 | } | ||
53 | |||
54 | if (!is_link(fname)) { | ||
55 | free(fname); | ||
56 | return 1; | ||
57 | } | ||
58 | |||
59 | 47 | ||
60 | errexit: | 48 | errexit: |
61 | fprintf(stderr, "Error: invalid file type, %s.\n", fname); | 49 | fprintf(stderr, "Error: invalid file type, %s.\n", fname); |
@@ -63,30 +51,32 @@ errexit: | |||
63 | } | 51 | } |
64 | 52 | ||
65 | static void duplicate(char *fname) { | 53 | static void duplicate(char *fname) { |
66 | // copy the file | 54 | char *src; |
67 | if (arg_debug) | 55 | if (asprintf(&src, "/etc/%s", fname) == -1) |
68 | printf("running: %s -a --parents /etc/%s %s\n", RUN_CP_COMMAND, fname, RUN_MNT_DIR); | 56 | errExit("asprintf"); |
69 | 57 | if (check_dir_or_file(src) == 0) { | |
70 | pid_t child = fork(); | 58 | if (!arg_quiet) |
71 | if (child < 0) | 59 | fprintf(stderr, "Warning: skipping %s for private bin\n", fname); |
72 | errExit("fork"); | 60 | free(src); |
73 | if (child == 0) { | 61 | return; |
74 | char *f; | 62 | } |
75 | if (asprintf(&f, "/etc/%s", fname) == -1) | 63 | |
64 | |||
65 | struct stat s; | ||
66 | if (stat(src, &s) == 0 && S_ISDIR(s.st_mode)) { | ||
67 | // create the directory in RUN_ETC_DIR | ||
68 | char *dirname; | ||
69 | if (asprintf(&dirname, "%s/%s", RUN_ETC_DIR, fname) == -1) | ||
76 | errExit("asprintf"); | 70 | errExit("asprintf"); |
77 | clearenv(); | 71 | create_empty_dir_as_root(dirname, s.st_mode); |
78 | execlp(RUN_CP_COMMAND, RUN_CP_COMMAND, "-a", "--parents", f, RUN_MNT_DIR, NULL); | 72 | sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, src, dirname); |
79 | perror("execlp"); | 73 | free(dirname); |
80 | _exit(1); | ||
81 | } | 74 | } |
82 | // wait for the child to finish | 75 | else |
83 | waitpid(child, NULL, 0); | 76 | sbox_run(SBOX_ROOT| SBOX_SECCOMP, 3, PATH_FCOPY, src, RUN_ETC_DIR); |
84 | 77 | ||
85 | char *name; | 78 | fs_logger2("clone", src); |
86 | if (asprintf(&name, "/etc/%s", fname) == -1) | 79 | free(src); |
87 | errExit("asprintf"); | ||
88 | fs_logger2("clone", name); | ||
89 | free(name); | ||
90 | } | 80 | } |
91 | 81 | ||
92 | 82 | ||
@@ -110,39 +100,22 @@ void fs_private_etc_list(void) { | |||
110 | // copy the list of files in the new etc directory | 100 | // copy the list of files in the new etc directory |
111 | // using a new child process with root privileges | 101 | // using a new child process with root privileges |
112 | if (*private_list != '\0') { | 102 | if (*private_list != '\0') { |
113 | pid_t child = fork(); | 103 | if (arg_debug) |
114 | if (child < 0) | 104 | printf("Copying files in the new etc directory:\n"); |
115 | errExit("fork"); | 105 | |
116 | if (child == 0) { | 106 | // copy the list of files in the new home directory |
117 | if (arg_debug) | 107 | char *dlist = strdup(private_list); |
118 | printf("Copying files in the new etc directory:\n"); | 108 | if (!dlist) |
109 | errExit("strdup"); | ||
119 | 110 | ||
120 | // elevate privileges - files in the new /etc directory belong to root | 111 | |
121 | if (setreuid(0, 0) < 0) | 112 | char *ptr = strtok(dlist, ","); |
122 | errExit("setreuid"); | 113 | duplicate(ptr); |
123 | if (setregid(0, 0) < 0) | ||
124 | errExit("setregid"); | ||
125 | |||
126 | // copy the list of files in the new home directory | ||
127 | char *dlist = strdup(private_list); | ||
128 | if (!dlist) | ||
129 | errExit("strdup"); | ||
130 | |||
131 | 114 | ||
132 | char *ptr = strtok(dlist, ","); | 115 | while ((ptr = strtok(NULL, ",")) != NULL) |
133 | duplicate(ptr); | 116 | duplicate(ptr); |
134 | 117 | free(dlist); | |
135 | while ((ptr = strtok(NULL, ",")) != NULL) | 118 | fs_logger_print(); |
136 | duplicate(ptr); | ||
137 | free(dlist); | ||
138 | fs_logger_print(); | ||
139 | #ifdef HAVE_GCOV | ||
140 | __gcov_flush(); | ||
141 | #endif | ||
142 | _exit(0); | ||
143 | } | ||
144 | // wait for the child to finish | ||
145 | waitpid(child, NULL, 0); | ||
146 | } | 119 | } |
147 | 120 | ||
148 | if (arg_debug) | 121 | 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) { | |||
694 | 694 | ||
695 | void create_empty_dir_as_root(const char *dir, mode_t mode) { | 695 | void create_empty_dir_as_root(const char *dir, mode_t mode) { |
696 | assert(dir); | 696 | assert(dir); |
697 | mode &= 07777; | ||
697 | struct stat s; | 698 | struct stat s; |
698 | 699 | ||
699 | if (stat(dir, &s)) { | 700 | if (stat(dir, &s)) { |
@@ -709,6 +710,7 @@ void create_empty_dir_as_root(const char *dir, mode_t mode) { | |||
709 | 710 | ||
710 | void create_empty_file_as_root(const char *fname, mode_t mode) { | 711 | void create_empty_file_as_root(const char *fname, mode_t mode) { |
711 | assert(fname); | 712 | assert(fname); |
713 | mode &= 07777; | ||
712 | struct stat s; | 714 | struct stat s; |
713 | 715 | ||
714 | if (stat(fname, &s)) { | 716 | if (stat(fname, &s)) { |