aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/firejail/util.c')
-rw-r--r--src/firejail/util.c89
1 files changed, 83 insertions, 6 deletions
diff --git a/src/firejail/util.c b/src/firejail/util.c
index 44f1cbd02..b8643ff60 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -417,6 +417,13 @@ int is_dir(const char *fname) {
417 if (*fname == '\0') 417 if (*fname == '\0')
418 return 0; 418 return 0;
419 419
420 int called_as_root = 0;
421 if (geteuid() == 0)
422 called_as_root = 1;
423
424 if (called_as_root)
425 EUID_USER();
426
420 // if fname doesn't end in '/', add one 427 // if fname doesn't end in '/', add one
421 int rv; 428 int rv;
422 struct stat s; 429 struct stat s;
@@ -432,6 +439,9 @@ int is_dir(const char *fname) {
432 free(tmp); 439 free(tmp);
433 } 440 }
434 441
442 if (called_as_root)
443 EUID_ROOT();
444
435 if (rv == -1) 445 if (rv == -1)
436 return 0; 446 return 0;
437 447
@@ -447,6 +457,14 @@ int is_link(const char *fname) {
447 if (*fname == '\0') 457 if (*fname == '\0')
448 return 0; 458 return 0;
449 459
460 int called_as_root = 0;
461 if (geteuid() == 0)
462 called_as_root = 1;
463
464 if (called_as_root)
465 EUID_USER();
466
467 // remove trailing '/' if any
450 char *tmp = strdup(fname); 468 char *tmp = strdup(fname);
451 if (!tmp) 469 if (!tmp)
452 errExit("strdup"); 470 errExit("strdup");
@@ -456,9 +474,66 @@ int is_link(const char *fname) {
456 ssize_t rv = readlink(tmp, &c, 1); 474 ssize_t rv = readlink(tmp, &c, 1);
457 free(tmp); 475 free(tmp);
458 476
477 if (called_as_root)
478 EUID_ROOT();
479
459 return (rv != -1); 480 return (rv != -1);
460} 481}
461 482
483char *realpath_as_user(const char *fname) {
484 assert(fname);
485
486 int called_as_root = 0;
487 if (geteuid() == 0)
488 called_as_root = 1;
489
490 if (called_as_root)
491 EUID_USER();
492
493 char *rv = realpath(fname, NULL);
494
495 if (called_as_root)
496 EUID_ROOT();
497
498 return rv;
499}
500
501int stat_as_user(const char *fname, struct stat *s) {
502 assert(fname);
503
504 int called_as_root = 0;
505 if (geteuid() == 0)
506 called_as_root = 1;
507
508 if (called_as_root)
509 EUID_USER();
510
511 int rv = stat(fname, s);
512
513 if (called_as_root)
514 EUID_ROOT();
515
516 return rv;
517}
518
519int lstat_as_user(const char *fname, struct stat *s) {
520 assert(fname);
521
522 int called_as_root = 0;
523 if (geteuid() == 0)
524 called_as_root = 1;
525
526 if (called_as_root)
527 EUID_USER();
528
529 int rv = lstat(fname, s);
530
531 if (called_as_root)
532 EUID_ROOT();
533
534 return rv;
535}
536
462// remove all slashes and single dots from the end of a path 537// remove all slashes and single dots from the end of a path
463// for example /foo/bar///././. -> /foo/bar 538// for example /foo/bar///././. -> /foo/bar
464void trim_trailing_slash_or_dot(char *path) { 539void trim_trailing_slash_or_dot(char *path) {
@@ -891,14 +966,13 @@ static int remove_callback(const char *fpath, const struct stat *sb, int typefla
891 966
892int remove_overlay_directory(void) { 967int remove_overlay_directory(void) {
893 EUID_ASSERT(); 968 EUID_ASSERT();
894 struct stat s;
895 sleep(1); 969 sleep(1);
896 970
897 char *path; 971 char *path;
898 if (asprintf(&path, "%s/.firejail", cfg.homedir) == -1) 972 if (asprintf(&path, "%s/.firejail", cfg.homedir) == -1)
899 errExit("asprintf"); 973 errExit("asprintf");
900 974
901 if (lstat(path, &s) == 0) { 975 if (access(path, F_OK) == 0) {
902 pid_t child = fork(); 976 pid_t child = fork();
903 if (child < 0) 977 if (child < 0)
904 errExit("fork"); 978 errExit("fork");
@@ -909,6 +983,7 @@ int remove_overlay_directory(void) {
909 fprintf(stderr, "Error: cannot open %s\n", path); 983 fprintf(stderr, "Error: cannot open %s\n", path);
910 _exit(1); 984 _exit(1);
911 } 985 }
986 struct stat s;
912 if (fstat(fd, &s) == -1) 987 if (fstat(fd, &s) == -1)
913 errExit("fstat"); 988 errExit("fstat");
914 if (!S_ISDIR(s.st_mode)) { 989 if (!S_ISDIR(s.st_mode)) {
@@ -944,7 +1019,7 @@ int remove_overlay_directory(void) {
944 // wait for the child to finish 1019 // wait for the child to finish
945 waitpid(child, NULL, 0); 1020 waitpid(child, NULL, 0);
946 // check if ~/.firejail was deleted 1021 // check if ~/.firejail was deleted
947 if (stat(path, &s) == 0) 1022 if (access(path, F_OK) == 0)
948 return 1; 1023 return 1;
949 } 1024 }
950 return 0; 1025 return 0;
@@ -977,9 +1052,8 @@ void flush_stdin(void) {
977int create_empty_dir_as_user(const char *dir, mode_t mode) { 1052int create_empty_dir_as_user(const char *dir, mode_t mode) {
978 assert(dir); 1053 assert(dir);
979 mode &= 07777; 1054 mode &= 07777;
980 struct stat s;
981 1055
982 if (stat(dir, &s)) { 1056 if (access(dir, F_OK) != 0) {
983 if (arg_debug) 1057 if (arg_debug)
984 printf("Creating empty %s directory\n", dir); 1058 printf("Creating empty %s directory\n", dir);
985 pid_t child = fork(); 1059 pid_t child = fork();
@@ -1001,7 +1075,7 @@ int create_empty_dir_as_user(const char *dir, mode_t mode) {
1001 _exit(0); 1075 _exit(0);
1002 } 1076 }
1003 waitpid(child, NULL, 0); 1077 waitpid(child, NULL, 0);
1004 if (stat(dir, &s) == 0) 1078 if (access(dir, F_OK) == 0)
1005 return 1; 1079 return 1;
1006 } 1080 }
1007 return 0; 1081 return 0;
@@ -1113,8 +1187,11 @@ unsigned extract_timeout(const char *str) {
1113 1187
1114void disable_file_or_dir(const char *fname) { 1188void disable_file_or_dir(const char *fname) {
1115 assert(fname); 1189 assert(fname);
1190 assert(geteuid() == 0);
1116 1191
1192 EUID_USER();
1117 int fd = open(fname, O_PATH|O_CLOEXEC); 1193 int fd = open(fname, O_PATH|O_CLOEXEC);
1194 EUID_ROOT();
1118 if (fd < 0) 1195 if (fd < 0)
1119 return; 1196 return;
1120 1197