diff options
author | netblue30 <netblue30@yahoo.com> | 2016-11-16 16:40:12 -0500 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2016-11-16 16:40:12 -0500 |
commit | 98159c098b6afedfed20eecdc80719dae1f914ff (patch) | |
tree | d44407914904e81dcb4bd582bdae11e558705c3d /src | |
parent | fcopy part 1 (diff) | |
download | firejail-98159c098b6afedfed20eecdc80719dae1f914ff.tar.gz firejail-98159c098b6afedfed20eecdc80719dae1f914ff.tar.zst firejail-98159c098b6afedfed20eecdc80719dae1f914ff.zip |
fcopy part 2
Diffstat (limited to 'src')
-rw-r--r-- | src/fcopy/main.c | 36 | ||||
-rw-r--r-- | src/firejail/firejail.h | 4 | ||||
-rw-r--r-- | src/firejail/fs_etc.c | 31 | ||||
-rw-r--r-- | src/firejail/fs_home.c | 269 | ||||
-rw-r--r-- | src/firejail/main.c | 2 | ||||
-rw-r--r-- | src/firejail/profile.c | 2 | ||||
-rw-r--r-- | src/firejail/util.c | 7 |
7 files changed, 74 insertions, 277 deletions
diff --git a/src/fcopy/main.c b/src/fcopy/main.c index 4437b90e5..82d829bba 100644 --- a/src/fcopy/main.c +++ b/src/fcopy/main.c | |||
@@ -130,10 +130,16 @@ static int fs_copydir(const char *infname, const struct stat *st, int ftype, str | |||
130 | if (size_limit_reached) | 130 | if (size_limit_reached) |
131 | return 0; | 131 | return 0; |
132 | 132 | ||
133 | |||
133 | char *outfname; | 134 | char *outfname; |
134 | if (asprintf(&outfname, "%s%s", outpath, infname + strlen(inpath)) == -1) | 135 | if (asprintf(&outfname, "%s%s", outpath, infname + strlen(inpath)) == -1) |
135 | errExit("asprintf"); | 136 | errExit("asprintf"); |
136 | 137 | ||
138 | //printf("outpaht %s\n", outpath); | ||
139 | //printf("inpath %s\n", inpath); | ||
140 | //printf("infname %s\n", infname); | ||
141 | //printf("outfname %s\n\n", outfname); | ||
142 | |||
137 | // don't copy it if we already have the file | 143 | // don't copy it if we already have the file |
138 | struct stat s; | 144 | struct stat s; |
139 | if (stat(outfname, &s) == 0) { | 145 | if (stat(outfname, &s) == 0) { |
@@ -265,7 +271,7 @@ static void duplicate_link(const char *src, const char *dest, struct stat *s) { | |||
265 | static void usage(void) { | 271 | static void usage(void) { |
266 | printf("Usage: fcopy src dest\n"); | 272 | printf("Usage: fcopy src dest\n"); |
267 | printf("Copy src file in dest directory. If src is a directory, copy all the files in\n"); | 273 | printf("Copy src file in dest directory. If src is a directory, copy all the files in\n"); |
268 | printf("src recoursively\n"); | 274 | printf("src recoursively. If the destination directory does not exist, it will be created.\n"); |
269 | } | 275 | } |
270 | 276 | ||
271 | int main(int argc, char **argv) { | 277 | int main(int argc, char **argv) { |
@@ -276,25 +282,16 @@ int i; | |||
276 | for (i = 0; i < argc; i++) | 282 | for (i = 0; i < argc; i++) |
277 | printf("*%s* ", argv[i]); | 283 | printf("*%s* ", argv[i]); |
278 | printf("\n"); | 284 | printf("\n"); |
279 | } | 285 | } |
280 | #endif | 286 | #endif |
281 | if (argc != 3) { | 287 | if (argc != 3) { |
282 | fprintf(stderr, "Error fcopy: files missing\n"); | 288 | fprintf(stderr, "Error fcopy: files missing\n"); |
283 | usage(); | 289 | usage(); |
284 | exit(1); | 290 | exit(1); |
285 | } | 291 | } |
286 | 292 | ||
287 | int i; | ||
288 | int index = 1; | ||
289 | for (i = 1; i < (argc - 2); i++) { | ||
290 | if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") ==0) { | ||
291 | usage(); | ||
292 | return 0; | ||
293 | } | ||
294 | } | ||
295 | |||
296 | // check the two files; remove ending / | 293 | // check the two files; remove ending / |
297 | char *src = argv[index]; | 294 | char *src = argv[1]; |
298 | int len = strlen(src); | 295 | int len = strlen(src); |
299 | if (src[len - 1] == '/') | 296 | if (src[len - 1] == '/') |
300 | src[len - 1] = '\0'; | 297 | src[len - 1] = '\0'; |
@@ -303,7 +300,7 @@ printf("\n"); | |||
303 | exit(1); | 300 | exit(1); |
304 | } | 301 | } |
305 | 302 | ||
306 | char *dest = argv[index + 1]; | 303 | char *dest = argv[2]; |
307 | len = strlen(dest); | 304 | len = strlen(dest); |
308 | if (dest[len - 1] == '/') | 305 | if (dest[len - 1] == '/') |
309 | dest[len - 1] = '\0'; | 306 | dest[len - 1] = '\0'; |
@@ -313,14 +310,11 @@ printf("\n"); | |||
313 | } | 310 | } |
314 | 311 | ||
315 | 312 | ||
316 | // the destination should be a directory; remove ending / | 313 | // the destination should be a directory; |
317 | struct stat s; | 314 | struct stat s; |
318 | if (stat(dest, &s) == -1) { | 315 | if (stat(dest, &s) == -1 || |
319 | fprintf(stderr, "Error fcopy: cannot find destination directory\n"); | 316 | !S_ISDIR(s.st_mode)) { |
320 | exit(1); | 317 | fprintf(stderr, "Error fcopy: invalid destination directory\n"); |
321 | } | ||
322 | if (S_ISDIR(s.st_mode) == -1) { | ||
323 | fprintf(stderr, "Error fcopy: the destination should be a directory\n"); | ||
324 | exit(1); | 318 | exit(1); |
325 | } | 319 | } |
326 | 320 | ||
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index d7ba539e6..80627fda8 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -490,8 +490,6 @@ void fs_private_template(void); | |||
490 | void fs_check_private_dir(void); | 490 | void fs_check_private_dir(void); |
491 | // check new private template home directory (--private-template= option) exit if it fails | 491 | // check new private template home directory (--private-template= option) exit if it fails |
492 | void fs_check_private_template(void); | 492 | void fs_check_private_template(void); |
493 | // check directory list specified by user (--private-home option) - exit if it fails | ||
494 | void fs_check_home_list(void); | ||
495 | void fs_private_home_list(void); | 493 | void fs_private_home_list(void); |
496 | 494 | ||
497 | 495 | ||
@@ -557,7 +555,6 @@ void network_del_run_file(pid_t pid); | |||
557 | void network_set_run_file(pid_t pid); | 555 | void network_set_run_file(pid_t pid); |
558 | 556 | ||
559 | // fs_etc.c | 557 | // fs_etc.c |
560 | void fs_check_etc_list(void); | ||
561 | void fs_private_etc_list(void); | 558 | void fs_private_etc_list(void); |
562 | 559 | ||
563 | // no_sandbox.c | 560 | // no_sandbox.c |
@@ -681,6 +678,7 @@ void build_cmdline(char **command_line, char **window_title, int argc, char **ar | |||
681 | #define PATH_FNET (LIBDIR "/firejail/fnet") | 678 | #define PATH_FNET (LIBDIR "/firejail/fnet") |
682 | #define PATH_FIREMON (PREFIX "/bin/firemon") | 679 | #define PATH_FIREMON (PREFIX "/bin/firemon") |
683 | #define PATH_FSECCOMP (LIBDIR "/firejail/fseccomp") | 680 | #define PATH_FSECCOMP (LIBDIR "/firejail/fseccomp") |
681 | #define PATH_FCOPY (LIBDIR "/firejail/fcopy") | ||
684 | // bitmapped filters for sbox_run | 682 | // bitmapped filters for sbox_run |
685 | #define SBOX_ROOT (1 << 0) // run the sandbox as root | 683 | #define SBOX_ROOT (1 << 0) // run the sandbox as root |
686 | #define SBOX_USER (1 << 1) // run the sandbox as a regular user | 684 | #define SBOX_USER (1 << 1) // run the sandbox as a regular user |
diff --git a/src/firejail/fs_etc.c b/src/firejail/fs_etc.c index 7e18840fd..6a70d482c 100644 --- a/src/firejail/fs_etc.c +++ b/src/firejail/fs_etc.c | |||
@@ -62,37 +62,6 @@ errexit: | |||
62 | exit(1); | 62 | exit(1); |
63 | } | 63 | } |
64 | 64 | ||
65 | void fs_check_etc_list(void) { | ||
66 | EUID_ASSERT(); | ||
67 | if (strstr(cfg.etc_private_keep, "..")) { | ||
68 | fprintf(stderr, "Error: invalid private etc list\n"); | ||
69 | exit(1); | ||
70 | } | ||
71 | |||
72 | char *dlist = strdup(cfg.etc_private_keep); | ||
73 | if (!dlist) | ||
74 | errExit("strdup"); | ||
75 | |||
76 | // build a new list only with the files found | ||
77 | char *newlist = malloc(strlen(cfg.etc_private_keep) + 1); | ||
78 | if (!newlist) | ||
79 | errExit("malloc"); | ||
80 | *newlist = '\0'; | ||
81 | |||
82 | char *ptr = strtok(dlist, ","); | ||
83 | if (check_dir_or_file(ptr)) | ||
84 | strcat(newlist, ptr); | ||
85 | while ((ptr = strtok(NULL, ",")) != NULL) { | ||
86 | if (check_dir_or_file(ptr)) { | ||
87 | strcat(newlist, ","); | ||
88 | strcat(newlist, ptr); | ||
89 | } | ||
90 | } | ||
91 | cfg.etc_private_keep = newlist; | ||
92 | |||
93 | free(dlist); | ||
94 | } | ||
95 | |||
96 | static void duplicate(char *fname) { | 65 | static void duplicate(char *fname) { |
97 | // copy the file | 66 | // copy the file |
98 | if (arg_debug) | 67 | if (arg_debug) |
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c index 242482d26..d8cd9ce4d 100644 --- a/src/firejail/fs_home.c +++ b/src/firejail/fs_home.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include <sys/wait.h> | 28 | #include <sys/wait.h> |
29 | #include <unistd.h> | 29 | #include <unistd.h> |
30 | #include <grp.h> | 30 | #include <grp.h> |
31 | #include <ftw.h> | 31 | //#include <ftw.h> |
32 | 32 | ||
33 | static void skel(const char *homedir, uid_t u, gid_t g) { | 33 | static void skel(const char *homedir, uid_t u, gid_t g) { |
34 | char *fname; | 34 | char *fname; |
@@ -349,106 +349,6 @@ void fs_check_private_dir(void) { | |||
349 | //*********************************************************************************** | 349 | //*********************************************************************************** |
350 | // --private-home | 350 | // --private-home |
351 | //*********************************************************************************** | 351 | //*********************************************************************************** |
352 | #define PRIVATE_COPY_LIMIT (500 * 1024 *1024) | ||
353 | static int size_limit_reached = 0; | ||
354 | static unsigned file_cnt = 0; | ||
355 | static unsigned size_cnt = 0; | ||
356 | static char *check_dir_or_file(const char *name); | ||
357 | |||
358 | int fs_copydir(const char *path, const struct stat *st, int ftype, struct FTW *sftw) { | ||
359 | (void) st; | ||
360 | (void) sftw; | ||
361 | if (size_limit_reached) | ||
362 | return 0; | ||
363 | |||
364 | struct stat s; | ||
365 | char *dest; | ||
366 | if (asprintf(&dest, "%s%s", RUN_HOME_DIR, path + strlen(cfg.homedir)) == -1) | ||
367 | errExit("asprintf"); | ||
368 | |||
369 | // don't copy it if we already have the file | ||
370 | if (stat(dest, &s) == 0) { | ||
371 | free(dest); | ||
372 | return 0; | ||
373 | } | ||
374 | |||
375 | // extract mode and ownership | ||
376 | if (stat(path, &s) != 0) { | ||
377 | free(dest); | ||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | // check uid | ||
382 | if (s.st_uid != firejail_uid || s.st_gid != firejail_gid) { | ||
383 | free(dest); | ||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | if ((s.st_size + size_cnt) > PRIVATE_COPY_LIMIT) { | ||
388 | size_limit_reached = 1; | ||
389 | free(dest); | ||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | file_cnt++; | ||
394 | size_cnt += s.st_size; | ||
395 | |||
396 | if(ftype == FTW_F) | ||
397 | copy_file(path, dest, firejail_uid, firejail_gid, s.st_mode); | ||
398 | else if (ftype == FTW_D) { | ||
399 | if (mkdir(dest, s.st_mode) == -1) | ||
400 | errExit("mkdir"); | ||
401 | if (set_perms(dest, firejail_uid, firejail_gid, s.st_mode)) | ||
402 | errExit("set_perms"); | ||
403 | #if 0 | ||
404 | struct stat s2; | ||
405 | if (stat(dest, &s2) == 0) { | ||
406 | printf("%s\t", dest); | ||
407 | printf((S_ISDIR(s.st_mode)) ? "d" : "-"); | ||
408 | printf((s.st_mode & S_IRUSR) ? "r" : "-"); | ||
409 | printf((s.st_mode & S_IWUSR) ? "w" : "-"); | ||
410 | printf((s.st_mode & S_IXUSR) ? "x" : "-"); | ||
411 | printf((s.st_mode & S_IRGRP) ? "r" : "-"); | ||
412 | printf((s.st_mode & S_IWGRP) ? "w" : "-"); | ||
413 | printf((s.st_mode & S_IXGRP) ? "x" : "-"); | ||
414 | printf((s.st_mode & S_IROTH) ? "r" : "-"); | ||
415 | printf((s.st_mode & S_IWOTH) ? "w" : "-"); | ||
416 | printf((s.st_mode & S_IXOTH) ? "x" : "-"); | ||
417 | printf("\n"); | ||
418 | } | ||
419 | #endif | ||
420 | |||
421 | fs_logger2("clone", path); | ||
422 | } | ||
423 | |||
424 | free(dest); | ||
425 | return(0); | ||
426 | } | ||
427 | |||
428 | static void duplicate(char *name) { | ||
429 | char *fname = check_dir_or_file(name); | ||
430 | |||
431 | if (arg_debug) | ||
432 | printf("Private home: duplicating %s\n", fname); | ||
433 | assert(strncmp(fname, cfg.homedir, strlen(cfg.homedir)) == 0); | ||
434 | |||
435 | struct stat s; | ||
436 | if (stat(fname, &s) == -1) { | ||
437 | free(fname); | ||
438 | return; | ||
439 | } | ||
440 | |||
441 | if(nftw(fname, fs_copydir, 1, FTW_PHYS) != 0) { | ||
442 | fprintf(stderr, "Error: unable to copy template dir\n"); | ||
443 | exit(1); | ||
444 | } | ||
445 | fs_logger_print(); // save the current log | ||
446 | |||
447 | free(fname); | ||
448 | } | ||
449 | |||
450 | |||
451 | |||
452 | static char *check_dir_or_file(const char *name) { | 352 | static char *check_dir_or_file(const char *name) { |
453 | assert(name); | 353 | assert(name); |
454 | struct stat s; | 354 | struct stat s; |
@@ -461,10 +361,7 @@ static char *check_dir_or_file(const char *name) { | |||
461 | 361 | ||
462 | // expand home directory | 362 | // expand home directory |
463 | char *fname = expand_home(name, cfg.homedir); | 363 | char *fname = expand_home(name, cfg.homedir); |
464 | if (!fname) { | 364 | assert(fname); |
465 | fprintf(stderr, "Error: file %s not found.\n", name); | ||
466 | exit(1); | ||
467 | } | ||
468 | 365 | ||
469 | // If it doesn't start with '/', it must be relative to homedir | 366 | // If it doesn't start with '/', it must be relative to homedir |
470 | if (fname[0] != '/') { | 367 | if (fname[0] != '/') { |
@@ -475,31 +372,19 @@ static char *check_dir_or_file(const char *name) { | |||
475 | fname = tmp; | 372 | fname = tmp; |
476 | } | 373 | } |
477 | 374 | ||
478 | // check the file is in user home directory | 375 | // check the file is in user home directory, a full home directory is not allowed |
479 | char *rname = realpath(fname, NULL); | 376 | char *rname = realpath(fname, NULL); |
480 | if (!rname) { | 377 | if (!rname || |
378 | strncmp(rname, cfg.homedir, strlen(cfg.homedir)) != 0 || | ||
379 | strcmp(rname, cfg.homedir) == 0) { | ||
481 | fprintf(stderr, "Error: invalid file %s\n", name); | 380 | fprintf(stderr, "Error: invalid file %s\n", name); |
482 | exit(1); | 381 | exit(1); |
483 | } | 382 | } |
484 | if (strncmp(rname, cfg.homedir, strlen(cfg.homedir)) != 0) { | ||
485 | fprintf(stderr, "Error: file %s is not in user home directory\n", name); | ||
486 | exit(1); | ||
487 | } | ||
488 | |||
489 | // a full home directory is not allowed | ||
490 | if (strcmp(rname, cfg.homedir) == 0) { | ||
491 | fprintf(stderr, "Error: invalid directory %s\n", rname); | ||
492 | exit(1); | ||
493 | } | ||
494 | 383 | ||
495 | // only top files and directories in user home are allowed | 384 | // only top files and directories in user home are allowed |
496 | char *ptr = rname + strlen(cfg.homedir); | 385 | char *ptr = rname + strlen(cfg.homedir); |
497 | if (*ptr == '\0') { | 386 | assert(*ptr != '\0'); |
498 | fprintf(stderr, "Error: invalid file %s\n", name); | 387 | ptr = strchr(++ptr, '/'); |
499 | exit(1); | ||
500 | } | ||
501 | ptr++; | ||
502 | ptr = strchr(ptr, '/'); | ||
503 | if (ptr) { | 388 | if (ptr) { |
504 | if (*ptr != '\0') { | 389 | if (*ptr != '\0') { |
505 | fprintf(stderr, "Error: only top files and directories in user home are allowed\n"); | 390 | fprintf(stderr, "Error: only top files and directories in user home are allowed\n"); |
@@ -507,55 +392,42 @@ static char *check_dir_or_file(const char *name) { | |||
507 | } | 392 | } |
508 | } | 393 | } |
509 | 394 | ||
510 | if (stat(fname, &s) == -1) { | 395 | free(fname); |
511 | fprintf(stderr, "Error: file %s not found.\n", fname); | 396 | return rname; |
512 | exit(1); | ||
513 | } | ||
514 | |||
515 | // check uid | ||
516 | uid_t uid = getuid(); | ||
517 | gid_t gid = getgid(); | ||
518 | if (s.st_uid != uid || s.st_gid != gid) { | ||
519 | fprintf(stderr, "Error: only files or directories created by the current user are allowed.\n"); | ||
520 | exit(1); | ||
521 | } | ||
522 | |||
523 | // dir or regular file | ||
524 | if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode)) { | ||
525 | free(fname); | ||
526 | return rname; // regular exit from the function | ||
527 | } | ||
528 | |||
529 | fprintf(stderr, "Error: invalid file type, %s.\n", fname); | ||
530 | exit(1); | ||
531 | } | 397 | } |
532 | 398 | ||
399 | static void duplicate(char *name) { | ||
400 | char *fname = check_dir_or_file(name); | ||
401 | char *dest = RUN_HOME_DIR; | ||
533 | 402 | ||
534 | // check directory list specified by user (--private-home option) - exit if it fails | 403 | if (arg_debug) |
535 | void fs_check_home_list(void) { | 404 | printf("Private home: duplicating %s\n", fname); |
536 | if (strstr(cfg.home_private_keep, "..")) { | 405 | assert(strncmp(fname, cfg.homedir, strlen(cfg.homedir)) == 0); |
537 | fprintf(stderr, "Error: invalid private-home list\n"); | ||
538 | exit(1); | ||
539 | } | ||
540 | |||
541 | char *dlist = strdup(cfg.home_private_keep); | ||
542 | if (!dlist) | ||
543 | errExit("strdup"); | ||
544 | |||
545 | char *ptr = strtok(dlist, ","); | ||
546 | char *tmp = check_dir_or_file(ptr); | ||
547 | free(tmp); | ||
548 | 406 | ||
549 | while ((ptr = strtok(NULL, ",")) != NULL) { | 407 | struct stat s; |
550 | tmp = check_dir_or_file(ptr); | 408 | if (stat(fname, &s) == -1) { |
551 | free(tmp); | 409 | free(fname); |
410 | return; | ||
411 | } | ||
412 | else if (S_ISDIR(s.st_mode)) { | ||
413 | // create the directory in RUN_HOME_DIR | ||
414 | char *name; | ||
415 | char *ptr = strrchr(fname, '/'); | ||
416 | ptr++; | ||
417 | if (asprintf(&name, "%s/%s", RUN_HOME_DIR, ptr) == -1) | ||
418 | errExit("asprintf"); | ||
419 | mkdir_attr(name, 0755, getuid(), getgid()); | ||
420 | sbox_run(SBOX_USER| SBOX_CAPS_NONE | SBOX_SECCOMP, 3, PATH_FCOPY, fname, name); | ||
421 | free(name); | ||
552 | } | 422 | } |
423 | else | ||
424 | sbox_run(SBOX_USER| SBOX_CAPS_NONE | SBOX_SECCOMP, 3, PATH_FCOPY, fname, RUN_HOME_DIR); | ||
425 | fs_logger2("clone", fname); | ||
426 | fs_logger_print(); // save the current log | ||
553 | 427 | ||
554 | free(dlist); | 428 | free(fname); |
555 | } | 429 | } |
556 | 430 | ||
557 | |||
558 | |||
559 | // private mode (--private-home=list): | 431 | // private mode (--private-home=list): |
560 | // mount homedir on top of /home/user, | 432 | // mount homedir on top of /home/user, |
561 | // tmpfs on top of /root in nonroot mode, | 433 | // tmpfs on top of /root in nonroot mode, |
@@ -571,8 +443,8 @@ void fs_private_home_list(void) { | |||
571 | int xflag = store_xauthority(); | 443 | int xflag = store_xauthority(); |
572 | int aflag = store_asoundrc(); | 444 | int aflag = store_asoundrc(); |
573 | 445 | ||
574 | uid_t u = firejail_uid; | 446 | uid_t uid = getuid(); |
575 | gid_t g = firejail_gid; | 447 | gid_t gid = getgid(); |
576 | struct stat s; | 448 | struct stat s; |
577 | if (stat(homedir, &s) == -1) { | 449 | if (stat(homedir, &s) == -1) { |
578 | fprintf(stderr, "Error: cannot find user home directory\n"); | 450 | fprintf(stderr, "Error: cannot find user home directory\n"); |
@@ -580,59 +452,24 @@ void fs_private_home_list(void) { | |||
580 | } | 452 | } |
581 | 453 | ||
582 | // create /run/firejail/mnt/home directory | 454 | // create /run/firejail/mnt/home directory |
583 | int rv = mkdir(RUN_HOME_DIR, 0755); | 455 | mkdir_attr(RUN_HOME_DIR, 0755, uid, gid); |
584 | if (rv == -1) | ||
585 | errExit("mkdir"); | ||
586 | if (set_perms(RUN_HOME_DIR, u, g, 0755)) | ||
587 | errExit("set_perms"); | ||
588 | ASSERT_PERMS(RUN_HOME_DIR, u, g, 0755); | ||
589 | |||
590 | fs_logger_print(); // save the current log | 456 | fs_logger_print(); // save the current log |
591 | 457 | ||
458 | if (arg_debug) | ||
459 | printf("Copying files in the new home:\n"); | ||
460 | |||
592 | // copy the list of files in the new home directory | 461 | // copy the list of files in the new home directory |
593 | // using a new child process without root privileges | 462 | char *dlist = strdup(cfg.home_private_keep); |
594 | pid_t child = fork(); | 463 | if (!dlist) |
595 | if (child < 0) | 464 | errExit("strdup"); |
596 | errExit("fork"); | 465 | |
597 | if (child == 0) { | 466 | char *ptr = strtok(dlist, ","); |
598 | if (arg_debug) | 467 | duplicate(ptr); |
599 | printf("Copying files in the new home:\n"); | 468 | while ((ptr = strtok(NULL, ",")) != NULL) |
600 | |||
601 | // drop privileges | ||
602 | if (setgroups(0, NULL) < 0) | ||
603 | errExit("setgroups"); | ||
604 | if (setgid(getgid()) < 0) | ||
605 | errExit("setgid/getgid"); | ||
606 | if (setuid(getuid()) < 0) | ||
607 | errExit("setuid/getuid"); | ||
608 | |||
609 | // copy the list of files in the new home directory | ||
610 | char *dlist = strdup(cfg.home_private_keep); | ||
611 | if (!dlist) | ||
612 | errExit("strdup"); | ||
613 | |||
614 | char *ptr = strtok(dlist, ","); | ||
615 | duplicate(ptr); | 469 | duplicate(ptr); |
616 | while ((ptr = strtok(NULL, ",")) != NULL) | ||
617 | duplicate(ptr); | ||
618 | |||
619 | if (!arg_quiet) { | ||
620 | if (size_limit_reached) | ||
621 | fprintf(stderr, "Warning: private-home copy limit of %u MB reached, not all the files were copied\n", | ||
622 | PRIVATE_COPY_LIMIT / (1024 *1024)); | ||
623 | else | ||
624 | printf("Private home: %u files, total size %u bytes\n", file_cnt, size_cnt); | ||
625 | } | ||
626 | 470 | ||
627 | fs_logger_print(); // save the current log | 471 | fs_logger_print(); // save the current log |
628 | free(dlist); | 472 | free(dlist); |
629 | #ifdef HAVE_GCOV | ||
630 | __gcov_flush(); | ||
631 | #endif | ||
632 | _exit(0); | ||
633 | } | ||
634 | // wait for the child to finish | ||
635 | waitpid(child, NULL, 0); | ||
636 | 473 | ||
637 | if (arg_debug) | 474 | if (arg_debug) |
638 | printf("Mount-bind %s on top of %s\n", RUN_HOME_DIR, homedir); | 475 | printf("Mount-bind %s on top of %s\n", RUN_HOME_DIR, homedir); |
@@ -640,7 +477,7 @@ void fs_private_home_list(void) { | |||
640 | if (mount(RUN_HOME_DIR, homedir, NULL, MS_BIND|MS_REC, NULL) < 0) | 477 | if (mount(RUN_HOME_DIR, homedir, NULL, MS_BIND|MS_REC, NULL) < 0) |
641 | errExit("mount bind"); | 478 | errExit("mount bind"); |
642 | 479 | ||
643 | if (u != 0) { | 480 | if (uid != 0) { |
644 | // mask /root | 481 | // mask /root |
645 | if (arg_debug) | 482 | if (arg_debug) |
646 | printf("Mounting a new /root directory\n"); | 483 | printf("Mounting a new /root directory\n"); |
@@ -655,7 +492,7 @@ void fs_private_home_list(void) { | |||
655 | errExit("mounting home directory"); | 492 | errExit("mounting home directory"); |
656 | } | 493 | } |
657 | 494 | ||
658 | skel(homedir, u, g); | 495 | skel(homedir, uid, gid); |
659 | if (xflag) | 496 | if (xflag) |
660 | copy_xauthority(); | 497 | copy_xauthority(); |
661 | if (aflag) | 498 | if (aflag) |
diff --git a/src/firejail/main.c b/src/firejail/main.c index ec0c31285..5bfa04cc9 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -1601,7 +1601,6 @@ int main(int argc, char **argv) { | |||
1601 | 1601 | ||
1602 | // extract private home dirname | 1602 | // extract private home dirname |
1603 | cfg.home_private_keep = argv[i] + 15; | 1603 | cfg.home_private_keep = argv[i] + 15; |
1604 | fs_check_home_list(); | ||
1605 | arg_private = 1; | 1604 | arg_private = 1; |
1606 | } | 1605 | } |
1607 | else { | 1606 | else { |
@@ -1625,7 +1624,6 @@ int main(int argc, char **argv) { | |||
1625 | fprintf(stderr, "Error: invalid private-etc option\n"); | 1624 | fprintf(stderr, "Error: invalid private-etc option\n"); |
1626 | exit(1); | 1625 | exit(1); |
1627 | } | 1626 | } |
1628 | fs_check_etc_list(); | ||
1629 | arg_private_etc = 1; | 1627 | arg_private_etc = 1; |
1630 | } | 1628 | } |
1631 | else if (strncmp(argv[i], "--private-bin=", 14) == 0) { | 1629 | else if (strncmp(argv[i], "--private-bin=", 14) == 0) { |
diff --git a/src/firejail/profile.c b/src/firejail/profile.c index 0fd45d1ef..693b1dc30 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c | |||
@@ -173,7 +173,6 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
173 | #ifdef HAVE_PRIVATE_HOME | 173 | #ifdef HAVE_PRIVATE_HOME |
174 | if (checkcfg(CFG_PRIVATE_HOME)) { | 174 | if (checkcfg(CFG_PRIVATE_HOME)) { |
175 | cfg.home_private_keep = ptr + 13; | 175 | cfg.home_private_keep = ptr + 13; |
176 | fs_check_home_list(); | ||
177 | arg_private = 1; | 176 | arg_private = 1; |
178 | } | 177 | } |
179 | else | 178 | else |
@@ -737,7 +736,6 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
737 | exit(1); | 736 | exit(1); |
738 | } | 737 | } |
739 | cfg.etc_private_keep = ptr + 12; | 738 | cfg.etc_private_keep = ptr + 12; |
740 | fs_check_etc_list(); | ||
741 | arg_private_etc = 1; | 739 | arg_private_etc = 1; |
742 | 740 | ||
743 | return 0; | 741 | return 0; |
diff --git a/src/firejail/util.c b/src/firejail/util.c index 027f1cd47..c56380ca1 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c | |||
@@ -562,7 +562,10 @@ char *expand_home(const char *path, const char* homedir) { | |||
562 | return new_name; | 562 | return new_name; |
563 | } | 563 | } |
564 | 564 | ||
565 | return strdup(path); | 565 | char *rv = strdup(path); |
566 | if (!rv) | ||
567 | errExit("strdup"); | ||
568 | return rv; | ||
566 | } | 569 | } |
567 | 570 | ||
568 | 571 | ||
@@ -625,7 +628,7 @@ uid_t pid_get_uid(pid_t pid) { | |||
625 | 628 | ||
626 | 629 | ||
627 | void invalid_filename(const char *fname) { | 630 | void invalid_filename(const char *fname) { |
628 | EUID_ASSERT(); | 631 | // EUID_ASSERT(); |
629 | assert(fname); | 632 | assert(fname); |
630 | const char *ptr = fname; | 633 | const char *ptr = fname; |
631 | 634 | ||