summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@yahoo.com>2016-11-16 16:40:12 -0500
committerLibravatar netblue30 <netblue30@yahoo.com>2016-11-16 16:40:12 -0500
commit98159c098b6afedfed20eecdc80719dae1f914ff (patch)
treed44407914904e81dcb4bd582bdae11e558705c3d
parentfcopy part 1 (diff)
downloadfirejail-98159c098b6afedfed20eecdc80719dae1f914ff.tar.gz
firejail-98159c098b6afedfed20eecdc80719dae1f914ff.tar.zst
firejail-98159c098b6afedfed20eecdc80719dae1f914ff.zip
fcopy part 2
-rwxr-xr-xgcov.sh28
-rw-r--r--src/fcopy/main.c36
-rw-r--r--src/firejail/firejail.h4
-rw-r--r--src/firejail/fs_etc.c31
-rw-r--r--src/firejail/fs_home.c269
-rw-r--r--src/firejail/main.c2
-rw-r--r--src/firejail/profile.c2
-rw-r--r--src/firejail/util.c7
-rwxr-xr-xtest/fcopy/cmdline.exp10
-rwxr-xr-xtest/fcopy/filecopy.exp6
-rwxr-xr-xtest/fcopy/linkcopy.exp46
11 files changed, 101 insertions, 340 deletions
diff --git a/gcov.sh b/gcov.sh
index 6f668d65f..900b7ca41 100755
--- a/gcov.sh
+++ b/gcov.sh
@@ -1,22 +1,28 @@
1#!/bin/bash 1#!/bin/bash
2 2
3gcov_init() {
4 USER=`whoami`
5 firejail --help
6 firemon --help
7 /usr/lib/firejail/fnet --help
8 /usr/lib/firejail/fseccomp --help
9 /usr/lib/firejail/ftee --help
10 /usr/lib/firejail/fcopy --help
11 firecfg --help
12 sudo chown $USER:$USER `find .`
13}
14
3generate() { 15generate() {
4 lcov --capture -d src/firejail -d src/firemon -d src/fseccomp -d src/fnet -d src/ftee -d src/lib -d src/firecfg --output-file gcov-file 16 lcov --capture -d src/firejail -d src/firemon -d src/fcopy -d src/fseccomp -d src/fnet -d src/ftee -d src/lib -d src/firecfg --output-file gcov-file
5 rm -fr gcov-dir 17 rm -fr gcov-dir
6 genhtml gcov-file --output-directory gcov-dir 18 genhtml gcov-file --output-directory gcov-dir
7} 19}
8 20
9# init 21gcov_init
10USER=`whoami`
11firejail --help
12firemon --help
13/usr/lib/firejail/fnet --help
14/usr/lib/firejail/fseccomp --help
15/usr/lib/firejail/ftee --help
16/usr/lib/firejail/fcopy --help
17firecfg --help
18sudo chown $USER:$USER `find .`
19generate 22generate
23echo "press any key to continue, or Ctrl-C to exit"
24read text
25
20 26
21# running tests 27# running tests
22make test-root 28make test-root
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) {
265static void usage(void) { 271static 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
271int main(int argc, char **argv) { 277int main(int argc, char **argv) {
@@ -276,25 +282,16 @@ int i;
276for (i = 0; i < argc; i++) 282for (i = 0; i < argc; i++)
277 printf("*%s* ", argv[i]); 283 printf("*%s* ", argv[i]);
278printf("\n"); 284printf("\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);
490void fs_check_private_dir(void); 490void 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
492void fs_check_private_template(void); 492void fs_check_private_template(void);
493// check directory list specified by user (--private-home option) - exit if it fails
494void fs_check_home_list(void);
495void fs_private_home_list(void); 493void fs_private_home_list(void);
496 494
497 495
@@ -557,7 +555,6 @@ void network_del_run_file(pid_t pid);
557void network_set_run_file(pid_t pid); 555void network_set_run_file(pid_t pid);
558 556
559// fs_etc.c 557// fs_etc.c
560void fs_check_etc_list(void);
561void fs_private_etc_list(void); 558void 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
65void 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
96static void duplicate(char *fname) { 65static 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
33static void skel(const char *homedir, uid_t u, gid_t g) { 33static 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)
353static int size_limit_reached = 0;
354static unsigned file_cnt = 0;
355static unsigned size_cnt = 0;
356static char *check_dir_or_file(const char *name);
357
358int 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
404struct stat s2;
405if (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
428static 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
452static char *check_dir_or_file(const char *name) { 352static 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
399static 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)
535void 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
627void invalid_filename(const char *fname) { 630void 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
diff --git a/test/fcopy/cmdline.exp b/test/fcopy/cmdline.exp
index 95e221321..24bb19351 100755
--- a/test/fcopy/cmdline.exp
+++ b/test/fcopy/cmdline.exp
@@ -43,14 +43,4 @@ expect {
43} 43}
44after 100 44after 100
45 45
46send -- "/usr/lib/firejail/fcopy foo1 foo2\r"
47expect {
48 timeout {puts "TESTING ERROR 6\n";exit}
49 "cannot find destination directory"
50}
51after 100
52
53
54
55
56puts "\nall done\n" 46puts "\nall done\n"
diff --git a/test/fcopy/filecopy.exp b/test/fcopy/filecopy.exp
index 9927e18fe..d1f0a4424 100755
--- a/test/fcopy/filecopy.exp
+++ b/test/fcopy/filecopy.exp
@@ -13,7 +13,7 @@ match_max 100000
13send -- "rm -fr dest/*\r" 13send -- "rm -fr dest/*\r"
14after 100 14after 100
15 15
16send -- "/usr/lib/firejail/fcopy src/dircopy.exp dest\r" 16send -- "/usr/lib/firejail/fcopy dircopy.exp dest\r"
17after 100 17after 100
18 18
19send -- "find dest\r" 19send -- "find dest\r"
@@ -31,7 +31,7 @@ after 100
31send -- "ls -al dest\r" 31send -- "ls -al dest\r"
32expect { 32expect {
33 timeout {puts "TESTING ERROR 2\n";exit} 33 timeout {puts "TESTING ERROR 2\n";exit}
34 "lrwxrwxrwx" 34 "rwxr-xr-x"
35} 35}
36after 100 36after 100
37 37
@@ -45,7 +45,7 @@ expect {
45send -- "file dest/dircopy.exp\r" 45send -- "file dest/dircopy.exp\r"
46expect { 46expect {
47 timeout {puts "TESTING ERROR 5\n";exit} 47 timeout {puts "TESTING ERROR 5\n";exit}
48 "symbolic link" 48 "ASCII text"
49} 49}
50 50
51send -- "rm -fr dest/*\r" 51send -- "rm -fr dest/*\r"
diff --git a/test/fcopy/linkcopy.exp b/test/fcopy/linkcopy.exp
index b87f24a59..9927e18fe 100755
--- a/test/fcopy/linkcopy.exp
+++ b/test/fcopy/linkcopy.exp
@@ -13,7 +13,7 @@ match_max 100000
13send -- "rm -fr dest/*\r" 13send -- "rm -fr dest/*\r"
14after 100 14after 100
15 15
16send -- "/usr/lib/firejail/fcopy src dest\r" 16send -- "/usr/lib/firejail/fcopy src/dircopy.exp dest\r"
17after 100 17after 100
18 18
19send -- "find dest\r" 19send -- "find dest\r"
@@ -23,60 +23,28 @@ expect {
23} 23}
24expect { 24expect {
25 timeout {puts "TESTING ERROR 1\n";exit} 25 timeout {puts "TESTING ERROR 1\n";exit}
26 "dest/a"
27}
28expect {
29 timeout {puts "TESTING ERROR 2\n";exit}
30 "dest/a/b"
31}
32expect {
33 timeout {puts "TESTING ERROR 3\n";exit}
34 "dest/a/b/file4"
35}
36expect {
37 timeout {puts "TESTING ERROR 4\n";exit}
38 "dest/a/file3"
39}
40expect {
41 timeout {puts "TESTING ERROR 5\n";exit}
42 "dest/dircopy.exp" 26 "dest/dircopy.exp"
43} 27}
44expect {
45 timeout {puts "TESTING ERROR 6\n";exit}
46 "dest/file2"
47}
48expect {
49 timeout {puts "TESTING ERROR 7\n";exit}
50 "dest/file1"
51}
52after 100 28after 100
53 29
54 30
55send -- "ls -al dest\r" 31send -- "ls -al dest\r"
56expect { 32expect {
57 timeout {puts "TESTING ERROR 8\n";exit} 33 timeout {puts "TESTING ERROR 2\n";exit}
58 "drwx--x--x" 34 "lrwxrwxrwx"
59}
60expect {
61 timeout {puts "TESTING ERROR 9\n";exit}
62 "rwxrwxrwx"
63}
64expect {
65 timeout {puts "TESTING ERROR 10\n";exit}
66 "rw-r--r--"
67} 35}
68after 100 36after 100
69 37
70send -- "diff -q src/a/b/file4 dest/a/b/file4; echo done\r" 38send -- "diff -q dircopy.exp dest/dircopy.exp; echo done\r"
71expect { 39expect {
72 timeout {puts "TESTING ERROR 11\n";exit} 40 timeout {puts "TESTING ERROR 3\n";exit}
73 "differ" {puts "TESTING ERROR 12\n";exit} 41 "differ" {puts "TESTING ERROR 4\n";exit}
74 "done" 42 "done"
75} 43}
76 44
77send -- "file dest/dircopy.exp\r" 45send -- "file dest/dircopy.exp\r"
78expect { 46expect {
79 timeout {puts "TESTING ERROR 13\n";exit} 47 timeout {puts "TESTING ERROR 5\n";exit}
80 "symbolic link" 48 "symbolic link"
81} 49}
82 50