aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2017-08-05 07:35:08 -0400
committerLibravatar netblue30 <netblue30@yahoo.com>2017-08-05 07:35:08 -0400
commitc55aafda50df45f42c6de0a25bbc79eb103e0711 (patch)
tree36847e9d88eb02f2fc98beb5ff1dee285ffe4466
parentMerge pull request #1435 from SpotComms/fc (diff)
downloadfirejail-c55aafda50df45f42c6de0a25bbc79eb103e0711.tar.gz
firejail-c55aafda50df45f42c6de0a25bbc79eb103e0711.tar.zst
firejail-c55aafda50df45f42c6de0a25bbc79eb103e0711.zip
private-lib: preliminary support for directories in private-lib list
-rw-r--r--src/firejail/fs_lib.c73
-rw-r--r--src/fldd/main.c7
2 files changed, 55 insertions, 25 deletions
diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c
index 94d87a151..890f8daf9 100644
--- a/src/firejail/fs_lib.c
+++ b/src/firejail/fs_lib.c
@@ -34,29 +34,26 @@ static const char * const lib_paths[] = {
34 NULL 34 NULL
35}; // Note: this array is duplicated in src/fldd/main.c 35}; // Note: this array is duplicated in src/fldd/main.c
36 36
37static void copy_libs(const char *exe, const char *dir, const char *file);
38
39static void duplicate(const char *fname, const char *private_run_dir) { 37static void duplicate(const char *fname, const char *private_run_dir) {
40 if (arg_debug) 38 if (arg_debug)
41 printf("copying %s to private %s\n", fname, private_run_dir); 39 printf("copying %s to private %s\n", fname, private_run_dir);
42 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 4, PATH_FCOPY, "--follow-link", fname, private_run_dir); 40
41 // copy only root-owned files
42 struct stat s;
43 if (stat(fname, &s) == 0 && s.st_uid == 0)
44 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 4, PATH_FCOPY, "--follow-link", fname, private_run_dir);
43} 45}
44 46
45 47
46// requires full path for exe 48// requires full path for lib
47static void copy_exe(const char *exe, const char *dir, const char *file) { 49static void copy_libs(const char *lib, const char *private_run_dir, const char *output_file) {
48 // if exe does not exist or the user does not have read access to it 50 // if library/executable does not exist or the user does not have read access to it
49 // print a warning and exit the function. 51 // print a warning and exit the function.
50 if (access(exe, R_OK)) { 52 if (access(lib, R_OK)) {
51 fwarning("cannot find %s executable for private-lib, skipping...\n", exe); 53 fwarning("cannot find %s for private-lib, skipping...\n", lib);
52 return; 54 return;
53 } 55 }
54 56
55 copy_libs(exe, dir, file);
56}
57
58// requires full path for lib
59static void copy_libs(const char *lib, const char *dir, const char *output_file) {
60 // create an empty RUN_LIB_FILE and allow the user to write to it 57 // create an empty RUN_LIB_FILE and allow the user to write to it
61 unlink(output_file); // in case is there 58 unlink(output_file); // in case is there
62 create_empty_file_as_root(output_file, 0644); 59 create_empty_file_as_root(output_file, 0644);
@@ -78,13 +75,35 @@ static void copy_libs(const char *lib, const char *dir, const char *output_file)
78 char *ptr = strchr(buf, '\n'); 75 char *ptr = strchr(buf, '\n');
79 if (ptr) 76 if (ptr)
80 *ptr = '\0'; 77 *ptr = '\0';
81 duplicate(buf, dir); 78 duplicate(buf, private_run_dir);
82 } 79 }
83 fclose(fp); 80 fclose(fp);
84} 81}
85 82
83static void copy_directory(const char *full_path, const char *dir_name, const char *private_run_dir) {
84 char *dest;
85 if (asprintf(&dest, "%s/%s", private_run_dir, dir_name) == -1)
86 errExit("asprintf");
87
88 // do nothing if the directory is already there
89 struct stat s;
90 if (stat(dest, &s) == 0) {
91 free(dest);
92 return;
93 }
94
95 // create new directory and mount the original on top of it
96 mkdir_attr(dest, 0755, 0, 0);
97
98 if (mount(full_path, dest, NULL, MS_BIND|MS_REC, NULL) < 0 ||
99 mount(NULL, dest, NULL, MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0)
100 errExit("mount bind");
101 fs_logger2("mount", full_path);
102 free(dest);
103}
104
86// return 1 if the file is valid 105// return 1 if the file is valid
87static char *valid_library(const char *lib) { 106static char *valid_file(const char *lib) {
88 // filename check 107 // filename check
89 int len = strlen(lib); 108 int len = strlen(lib);
90 if (strcspn(lib, "\\&!?\"'<>%^(){}[];,*") != (size_t)len || 109 if (strcspn(lib, "\\&!?\"'<>%^(){}[];,*") != (size_t)len ||
@@ -135,11 +154,11 @@ void fs_private_lib(void) {
135 154
136 // copy the libs in the new lib directory for the main exe 155 // copy the libs in the new lib directory for the main exe
137 if (cfg.original_program_index > 0) 156 if (cfg.original_program_index > 0)
138 copy_exe(cfg.original_argv[cfg.original_program_index], RUN_LIB_DIR, RUN_LIB_FILE); 157 copy_libs(cfg.original_argv[cfg.original_program_index], RUN_LIB_DIR, RUN_LIB_FILE);
139 158
140 // for the shell 159 // for the shell
141 if (!arg_shell_none) { 160 if (!arg_shell_none) {
142 copy_exe(cfg.shell, RUN_LIB_DIR, RUN_LIB_FILE); 161 copy_libs(cfg.shell, RUN_LIB_DIR, RUN_LIB_FILE);
143 // a shell is useless without ls command 162 // a shell is useless without ls command
144 copy_libs("/bin/ls", RUN_LIB_DIR, RUN_LIB_FILE); 163 copy_libs("/bin/ls", RUN_LIB_DIR, RUN_LIB_FILE);
145 } 164 }
@@ -154,18 +173,26 @@ void fs_private_lib(void) {
154 errExit("strdup"); 173 errExit("strdup");
155 174
156 char *ptr = strtok(dlist, ","); 175 char *ptr = strtok(dlist, ",");
157 char *lib = valid_library(ptr); 176 char *lib = valid_file(ptr);
158 if (lib) { 177 if (lib) {
159 duplicate(lib, RUN_LIB_DIR); 178 if (is_dir(lib))
160 copy_libs(lib, RUN_LIB_DIR, RUN_LIB_FILE); 179 copy_directory(lib, ptr, RUN_LIB_DIR);
180 else {
181 duplicate(lib, RUN_LIB_DIR);
182 copy_libs(lib, RUN_LIB_DIR, RUN_LIB_FILE);
183 }
161 free(lib); 184 free(lib);
162 } 185 }
163 186
164 while ((ptr = strtok(NULL, ",")) != NULL) { 187 while ((ptr = strtok(NULL, ",")) != NULL) {
165 lib = valid_library(ptr); 188 lib = valid_file(ptr);
166 if (lib) { 189 if (lib) {
167 duplicate(lib, RUN_LIB_DIR); 190 if (is_dir(lib))
168 copy_libs(lib, RUN_LIB_DIR, RUN_LIB_FILE); 191 copy_directory(lib, ptr, RUN_LIB_DIR);
192 else {
193 duplicate(lib, RUN_LIB_DIR);
194 copy_libs(lib, RUN_LIB_DIR, RUN_LIB_FILE);
195 }
169 free(lib); 196 free(lib);
170 } 197 }
171 } 198 }
diff --git a/src/fldd/main.c b/src/fldd/main.c
index 8b54242a4..1c6b3dd25 100644
--- a/src/fldd/main.c
+++ b/src/fldd/main.c
@@ -105,7 +105,7 @@ static void copy_libs_for_exe(const char *exe) {
105 f = open(exe, O_RDONLY); 105 f = open(exe, O_RDONLY);
106 if (f < 0) { 106 if (f < 0) {
107 if (!arg_quiet) 107 if (!arg_quiet)
108 fprintf(stderr, "Warning fldd: cannot open %s\n", exe); 108 fprintf(stderr, "Warning fldd: cannot open %s, skipping...\n", exe);
109 return; 109 return;
110 } 110 }
111 111
@@ -202,7 +202,10 @@ static void copy_libs_for_lib(const char *lib) {
202 } 202 }
203 free(fname); 203 free(fname);
204 } 204 }
205 errExit("library not found"); 205
206 // log a warning and continue
207 if (!arg_quiet)
208 fprintf(stderr, "Warning fldd: cannot find %s, skipping...\n", lib);
206} 209}
207 210
208static void usage(void) { 211static void usage(void) {