aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/fs_lib.c
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2018-05-20 13:05:36 -0400
committerLibravatar netblue30 <netblue30@yahoo.com>2018-05-20 13:05:36 -0400
commit259f818c93664bcc6068303764f6d995cd129c8e (patch)
treeec2d037f66d7a3c0f782e94dc8db022e01e76b37 /src/firejail/fs_lib.c
parentreverted commit 5a3eefa6e70e824f545add9169202f788a9ce14d, issue #1948 (diff)
downloadfirejail-259f818c93664bcc6068303764f6d995cd129c8e.tar.gz
firejail-259f818c93664bcc6068303764f6d995cd129c8e.tar.zst
firejail-259f818c93664bcc6068303764f6d995cd129c8e.zip
private-lib cleanup
Diffstat (limited to 'src/firejail/fs_lib.c')
-rw-r--r--src/firejail/fs_lib.c171
1 files changed, 71 insertions, 100 deletions
diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c
index 4f8a98fe4..ec12ff01b 100644
--- a/src/firejail/fs_lib.c
+++ b/src/firejail/fs_lib.c
@@ -83,7 +83,7 @@ void fslib_duplicate(const char *full_path) {
83 free(name); 83 free(name);
84 84
85 if (arg_debug || arg_debug_private_lib) 85 if (arg_debug || arg_debug_private_lib)
86 printf("copying %s to private %s\n", full_path, dest_dir); 86 printf(" copying %s to private %s\n", full_path, dest_dir);
87 87
88 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 4, PATH_FCOPY, "--follow-link", full_path, dest_dir); 88 sbox_run(SBOX_ROOT| SBOX_SECCOMP, 4, PATH_FCOPY, "--follow-link", full_path, dest_dir);
89 report_duplication(full_path); 89 report_duplication(full_path);
@@ -97,7 +97,7 @@ void fslib_duplicate(const char *full_path) {
97void fslib_copy_libs(const char *full_path) { 97void fslib_copy_libs(const char *full_path) {
98 assert(full_path); 98 assert(full_path);
99 if (arg_debug || arg_debug_private_lib) 99 if (arg_debug || arg_debug_private_lib)
100 printf("fslib_copy_libs %s\n", full_path); 100 printf(" fslib_copy_libs %s\n", full_path);
101 101
102 // if library/executable does not exist or the user does not have read access to it 102 // if library/executable does not exist or the user does not have read access to it
103 // print a warning and exit the function. 103 // print a warning and exit the function.
@@ -115,7 +115,7 @@ void fslib_copy_libs(const char *full_path) {
115 115
116 // run fldd to extact the list of files 116 // run fldd to extact the list of files
117 if (arg_debug || arg_debug_private_lib) 117 if (arg_debug || arg_debug_private_lib)
118 printf("running fldd %s\n", full_path); 118 printf(" running fldd %s\n", full_path);
119 sbox_run(SBOX_USER | SBOX_SECCOMP | SBOX_CAPS_NONE, 3, PATH_FLDD, full_path, RUN_LIB_FILE); 119 sbox_run(SBOX_USER | SBOX_SECCOMP | SBOX_CAPS_NONE, 3, PATH_FLDD, full_path, RUN_LIB_FILE);
120 120
121 // open the list of libraries and install them on by one 121 // open the list of libraries and install them on by one
@@ -138,7 +138,7 @@ void fslib_copy_libs(const char *full_path) {
138void fslib_copy_dir(const char *full_path) { 138void fslib_copy_dir(const char *full_path) {
139 assert(full_path); 139 assert(full_path);
140 if (arg_debug || arg_debug_private_lib) 140 if (arg_debug || arg_debug_private_lib)
141 printf("fslib_copy_dir %s\n", full_path); 141 printf(" fslib_copy_dir %s\n", full_path);
142 142
143 // do nothing if the directory does not exist or is not owned by root 143 // do nothing if the directory does not exist or is not owned by root
144 struct stat s; 144 struct stat s;
@@ -172,8 +172,10 @@ void fslib_copy_dir(const char *full_path) {
172} 172}
173 173
174 174
175// return 1 if the file is valid 175
176static char *valid_file(const char *lib) { 176static void install_list_entry(const char *lib) {
177 char *fname = NULL;
178
177 // filename check 179 // filename check
178 int len = strlen(lib); 180 int len = strlen(lib);
179 if (strcspn(lib, "\\&!?\"'<>%^(){}[];,*") != (size_t)len || 181 if (strcspn(lib, "\\&!?\"'<>%^(){}[];,*") != (size_t)len ||
@@ -182,31 +184,68 @@ static char *valid_file(const char *lib) {
182 exit(1); 184 exit(1);
183 } 185 }
184 186
187 // if this is a full path, use it as is
188 if (*lib == '/') {
189 fname = strdup(lib);
190 goto load_library;
191 }
192
193
185 // find the library 194 // find the library
186 int i; 195 int i;
187 for (i = 0; default_lib_paths[i]; i++) { 196 for (i = 0; default_lib_paths[i]; i++) {
188 char *fname;
189 if (asprintf(&fname, "%s/%s", default_lib_paths[i], lib) == -1) 197 if (asprintf(&fname, "%s/%s", default_lib_paths[i], lib) == -1)
190 errExit("asprintf"); 198 errExit("asprintf");
191 199
192 // existing file owned by root, read access 200 // existing file owned by root, read access
193 struct stat s; 201 struct stat s;
194 if (stat(fname, &s) == 0 && s.st_uid == 0 && !access(fname, R_OK)) { 202 if (stat(fname, &s) == 0 && s.st_uid == 0 && !access(fname, R_OK)) {
195 if (is_dir(fname)) 203 // load directories and regular 64 bit libraries
196 return fname; 204 if (is_dir(fname) || is_lib_64(fname))
197 // for regular libraries check if it is 64bit 205 goto load_library;
198 if (is_lib_64(fname))
199 return fname;
200 // if not 64bit, continue searching 206 // if not 64bit, continue searching
201 } 207 }
202 free(fname); 208 free(fname);
203 } 209 }
204 210
205 fwarning("%s library not found, skipping...\n", lib); 211// fwarning("%s library not found, skipping...\n", lib);
206 return NULL; 212 return;
213
214load_library:
215 if (fname) {
216 if (is_dir(fname))
217 fslib_copy_dir(fname);
218 else {
219 if (strstr(fname, ".so") ||
220 access(fname, X_OK) != 0) // don't duplicate executables
221 fslib_duplicate(fname);
222
223 fslib_copy_libs(fname);
224 }
225 free(fname);
226 }
207} 227}
208 228
209 229
230void fslib_install_list(const char *lib_list) {
231 if (arg_debug || arg_debug_private_lib)
232 printf(" fslib_install_list %s\n", lib_list);
233
234 char *dlist = strdup(lib_list);
235 if (!dlist)
236 errExit("strdup");
237
238 char *ptr = strtok(dlist, ",");
239 install_list_entry(ptr);
240
241 while ((ptr = strtok(NULL, ",")) != NULL)
242 install_list_entry(ptr);
243 free(dlist);
244 fs_logger_print();
245}
246
247
248
210static void mount_directories(void) { 249static void mount_directories(void) {
211 if (arg_debug || arg_debug_private_lib) 250 if (arg_debug || arg_debug_private_lib)
212 printf("Mount-bind %s on top of /lib /lib64 /usr/lib\n", RUN_LIB_DIR); 251 printf("Mount-bind %s on top of /lib /lib64 /usr/lib\n", RUN_LIB_DIR);
@@ -264,7 +303,7 @@ void fs_private_lib(void) {
264 303
265 // install standard C libraries 304 // install standard C libraries
266 if (arg_debug || arg_debug_private_lib) 305 if (arg_debug || arg_debug_private_lib)
267 printf("*** Installing standard C library\n"); 306 printf("Installing standard C library\n");
268 fslib_install_stdc(); 307 fslib_install_stdc();
269 308
270 // start timetrace 309 // start timetrace
@@ -273,116 +312,48 @@ void fs_private_lib(void) {
273 // copy the libs in the new lib directory for the main exe 312 // copy the libs in the new lib directory for the main exe
274 if (cfg.original_program_index > 0) { 313 if (cfg.original_program_index > 0) {
275 if (arg_debug || arg_debug_private_lib) 314 if (arg_debug || arg_debug_private_lib)
276 printf("*** Installing sandboxed program libraries\n"); 315 printf("Installing sandboxed program libraries\n");
277 fslib_copy_libs(cfg.original_argv[cfg.original_program_index]); 316 fslib_install_list(cfg.original_argv[cfg.original_program_index]);
278 } 317 }
279 318
280 // for the shell 319 // for the shell
281 if (!arg_shell_none) { 320 if (!arg_shell_none) {
282 if (arg_debug || arg_debug_private_lib) 321 if (arg_debug || arg_debug_private_lib)
283 printf("*** Installing shell libraries\n"); 322 printf("Installing shell libraries\n");
284 fslib_copy_libs(cfg.shell); 323
285 // a shell is useless without ls command 324 fslib_install_list(cfg.shell);
286 fslib_copy_libs("/bin/ls"); 325 // a shell is useless without some basic commands
326 fslib_install_list("/bin/ls,/bin/cat,/bin/mv,/bin/rm");
327
287 } 328 }
288 329
289 // for the listed libs and directories 330 // for the listed libs and directories
290 if (private_list && *private_list != '\0') { 331 if (private_list && *private_list != '\0') {
291 if (arg_debug || arg_debug_private_lib) 332 if (arg_debug || arg_debug_private_lib)
292 printf("*** Processing private-lib files (%s)\n", private_list); 333 printf("Processing private-lib files\n");
293 334 fslib_install_list(private_list);
294 char *dlist = strdup(private_list);
295 if (!dlist)
296 errExit("strdup");
297
298 char *ptr = strtok(dlist, ",");
299 char *lib = valid_file(ptr);
300 if (lib) {
301 if (is_dir(lib))
302 fslib_copy_dir(lib);
303 else {
304 fslib_duplicate(lib);
305 fslib_copy_libs(lib);
306 }
307 free(lib);
308 }
309
310 while ((ptr = strtok(NULL, ",")) != NULL) {
311 lib = valid_file(ptr);
312 if (lib) {
313 if (is_dir(lib))
314 fslib_copy_dir(lib);
315 else {
316 fslib_duplicate(lib);
317 fslib_copy_libs(lib);
318 }
319 free(lib);
320 }
321 }
322 free(dlist);
323 fs_logger_print();
324 } 335 }
325 336
326 // for private-bin files 337 // for private-bin files
327 if (arg_private_bin) { 338 if (arg_private_bin) {
328 if (arg_debug || arg_debug_private_lib) 339 if (arg_debug || arg_debug_private_lib)
329 printf("*** Processing private-bin files\n"); 340 printf("Processing private-bin files\n");
330 FILE *fp = fopen(RUN_LIB_BIN, "r"); 341 fslib_install_list(cfg.bin_private_lib);
331 if (fp) {
332 char buf[MAXBUF];
333 while (fgets(buf, MAXBUF, fp)) {
334 // remove \n
335 char *ptr = strchr(buf, '\n');
336 if (ptr)
337 *ptr = '\0';
338
339 // copy libraries for this program
340 fslib_copy_libs(buf);
341
342 // load program data from /usr/lib/program or from /usr/lib/x86_64-linux-gnu
343 ptr = strrchr(buf, '/');
344 if (ptr && *(ptr + 1) != '\0') {
345 ptr++;
346
347 // /usr/lib/program
348 char *name;
349 if (asprintf(&name, "/usr/lib/%s", ptr) == -1)
350 errExit("asprintf");
351 if (is_dir(name))
352 fslib_copy_dir(name);
353 free(name);
354
355 // /usr/lib/x86_linux-gnu - debian & friends
356 if (asprintf(&name, "/usr/lib/x86_64-linux-gnu/%s", ptr) == -1)
357 errExit("asprintf");
358 if (is_dir(name))
359 fslib_copy_dir(name);
360 free(name);
361
362 // /usr/lib64 - CentOS, Fedora
363 if (asprintf(&name, "/usr/lib64/%s", ptr) == -1)
364 errExit("asprintf");
365 if (is_dir(name))
366 fslib_copy_dir(name);
367 free(name);
368 }
369 }
370 fclose(fp);
371 }
372 } 342 }
373 fmessage("Program libraries installed in %0.2f ms\n", timetrace_end()); 343 fmessage("Program libraries installed in %0.2f ms\n", timetrace_end());
374 344
375 // install the reset of the system libraries 345 // install the reset of the system libraries
376 if (arg_debug || arg_debug_private_lib) 346 if (arg_debug || arg_debug_private_lib)
377 printf("*** Installing system libraries\n"); 347 printf("Installing system libraries\n");
378 fslib_install_system(); 348 fslib_install_system();
379 349
350 // bring in firejail directory for --trace and seccomp post exec
351 // bring in firejail executable libraries in case we are redirected here by a firejail symlink from /usr/local/bin/firejail
352 fslib_install_list("/usr/bin/firejail,firejail"); // todo: use the installed path for the executable
353
380 fmessage("Installed %d %s and %d %s\n", lib_cnt, (lib_cnt == 1)? "library": "libraries", 354 fmessage("Installed %d %s and %d %s\n", lib_cnt, (lib_cnt == 1)? "library": "libraries",
381 dir_cnt, (dir_cnt == 1)? "directory": "directories"); 355 dir_cnt, (dir_cnt == 1)? "directory": "directories");
382 356
383 // bring in firejail directory for --trace and seccomp post exec
384 fslib_copy_dir(LIBDIR "/firejail");
385
386 // mount lib filesystem 357 // mount lib filesystem
387 mount_directories(); 358 mount_directories();
388} 359}