diff options
Diffstat (limited to 'src/firejail/fs_home.c')
-rw-r--r-- | src/firejail/fs_home.c | 41 |
1 files changed, 21 insertions, 20 deletions
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c index ec6dab947..eab952eb8 100644 --- a/src/firejail/fs_home.c +++ b/src/firejail/fs_home.c | |||
@@ -42,15 +42,14 @@ static void skel(const char *homedir, uid_t u, gid_t g) { | |||
42 | // copy skel files | 42 | // copy skel files |
43 | if (asprintf(&fname, "%s/.zshrc", homedir) == -1) | 43 | if (asprintf(&fname, "%s/.zshrc", homedir) == -1) |
44 | errExit("asprintf"); | 44 | errExit("asprintf"); |
45 | struct stat s; | ||
46 | // don't copy it if we already have the file | 45 | // don't copy it if we already have the file |
47 | if (stat(fname, &s) == 0) | 46 | if (access(fname, F_OK) == 0) |
48 | return; | 47 | return; |
49 | if (is_link(fname)) { // stat on dangling symlinks fails, try again using lstat | 48 | if (is_link(fname)) { // access(3) on dangling symlinks fails, try again using lstat |
50 | fprintf(stderr, "Error: invalid %s file\n", fname); | 49 | fprintf(stderr, "Error: invalid %s file\n", fname); |
51 | exit(1); | 50 | exit(1); |
52 | } | 51 | } |
53 | if (stat("/etc/skel/.zshrc", &s) == 0) { | 52 | if (access("/etc/skel/.zshrc", R_OK) == 0) { |
54 | copy_file_as_user("/etc/skel/.zshrc", fname, u, g, 0644); // regular user | 53 | copy_file_as_user("/etc/skel/.zshrc", fname, u, g, 0644); // regular user |
55 | fs_logger("clone /etc/skel/.zshrc"); | 54 | fs_logger("clone /etc/skel/.zshrc"); |
56 | fs_logger2("clone", fname); | 55 | fs_logger2("clone", fname); |
@@ -67,16 +66,14 @@ static void skel(const char *homedir, uid_t u, gid_t g) { | |||
67 | // copy skel files | 66 | // copy skel files |
68 | if (asprintf(&fname, "%s/.cshrc", homedir) == -1) | 67 | if (asprintf(&fname, "%s/.cshrc", homedir) == -1) |
69 | errExit("asprintf"); | 68 | errExit("asprintf"); |
70 | struct stat s; | ||
71 | |||
72 | // don't copy it if we already have the file | 69 | // don't copy it if we already have the file |
73 | if (stat(fname, &s) == 0) | 70 | if (access(fname, F_OK) == 0) |
74 | return; | 71 | return; |
75 | if (is_link(fname)) { // stat on dangling symlinks fails, try again using lstat | 72 | if (is_link(fname)) { // access(3) on dangling symlinks fails, try again using lstat |
76 | fprintf(stderr, "Error: invalid %s file\n", fname); | 73 | fprintf(stderr, "Error: invalid %s file\n", fname); |
77 | exit(1); | 74 | exit(1); |
78 | } | 75 | } |
79 | if (stat("/etc/skel/.cshrc", &s) == 0) { | 76 | if (access("/etc/skel/.cshrc", R_OK) == 0) { |
80 | copy_file_as_user("/etc/skel/.cshrc", fname, u, g, 0644); // regular user | 77 | copy_file_as_user("/etc/skel/.cshrc", fname, u, g, 0644); // regular user |
81 | fs_logger("clone /etc/skel/.cshrc"); | 78 | fs_logger("clone /etc/skel/.cshrc"); |
82 | fs_logger2("clone", fname); | 79 | fs_logger2("clone", fname); |
@@ -93,15 +90,14 @@ static void skel(const char *homedir, uid_t u, gid_t g) { | |||
93 | // copy skel files | 90 | // copy skel files |
94 | if (asprintf(&fname, "%s/.bashrc", homedir) == -1) | 91 | if (asprintf(&fname, "%s/.bashrc", homedir) == -1) |
95 | errExit("asprintf"); | 92 | errExit("asprintf"); |
96 | struct stat s; | ||
97 | // don't copy it if we already have the file | 93 | // don't copy it if we already have the file |
98 | if (stat(fname, &s) == 0) | 94 | if (access(fname, F_OK) == 0) |
99 | return; | 95 | return; |
100 | if (is_link(fname)) { // stat on dangling symlinks fails, try again using lstat | 96 | if (is_link(fname)) { // access(3) on dangling symlinks fails, try again using lstat |
101 | fprintf(stderr, "Error: invalid %s file\n", fname); | 97 | fprintf(stderr, "Error: invalid %s file\n", fname); |
102 | exit(1); | 98 | exit(1); |
103 | } | 99 | } |
104 | if (stat("/etc/skel/.bashrc", &s) == 0) { | 100 | if (access("/etc/skel/.bashrc", R_OK) == 0) { |
105 | copy_file_as_user("/etc/skel/.bashrc", fname, u, g, 0644); // regular user | 101 | copy_file_as_user("/etc/skel/.bashrc", fname, u, g, 0644); // regular user |
106 | fs_logger("clone /etc/skel/.bashrc"); | 102 | fs_logger("clone /etc/skel/.bashrc"); |
107 | fs_logger2("clone", fname); | 103 | fs_logger2("clone", fname); |
@@ -122,8 +118,8 @@ static int store_xauthority(void) { | |||
122 | errExit("asprintf"); | 118 | errExit("asprintf"); |
123 | 119 | ||
124 | struct stat s; | 120 | struct stat s; |
125 | if (stat(src, &s) == 0) { | 121 | if (lstat_as_user(src, &s) == 0) { |
126 | if (is_link(src)) { | 122 | if (S_ISLNK(s.st_mode)) { |
127 | fwarning("invalid .Xauthority file\n"); | 123 | fwarning("invalid .Xauthority file\n"); |
128 | free(src); | 124 | free(src); |
129 | return 0; | 125 | return 0; |
@@ -161,11 +157,11 @@ static int store_asoundrc(void) { | |||
161 | errExit("asprintf"); | 157 | errExit("asprintf"); |
162 | 158 | ||
163 | struct stat s; | 159 | struct stat s; |
164 | if (stat(src, &s) == 0) { | 160 | if (lstat_as_user(src, &s) == 0) { |
165 | if (is_link(src)) { | 161 | if (S_ISLNK(s.st_mode)) { |
166 | // make sure the real path of the file is inside the home directory | 162 | // make sure the real path of the file is inside the home directory |
167 | /* coverity[toctou] */ | 163 | /* coverity[toctou] */ |
168 | char* rp = realpath(src, NULL); | 164 | char *rp = realpath_as_user(src); |
169 | if (!rp) { | 165 | if (!rp) { |
170 | fprintf(stderr, "Error: Cannot access %s\n", src); | 166 | fprintf(stderr, "Error: Cannot access %s\n", src); |
171 | exit(1); | 167 | exit(1); |
@@ -263,6 +259,7 @@ void fs_private_homedir(void) { | |||
263 | if (arg_debug) | 259 | if (arg_debug) |
264 | printf("Mount-bind %s on top of %s\n", private_homedir, homedir); | 260 | printf("Mount-bind %s on top of %s\n", private_homedir, homedir); |
265 | // get file descriptors for homedir and private_homedir, fails if there is any symlink | 261 | // get file descriptors for homedir and private_homedir, fails if there is any symlink |
262 | EUID_USER(); | ||
266 | int src = safer_openat(-1, private_homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); | 263 | int src = safer_openat(-1, private_homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); |
267 | if (src == -1) | 264 | if (src == -1) |
268 | errExit("opening private directory"); | 265 | errExit("opening private directory"); |
@@ -287,6 +284,7 @@ void fs_private_homedir(void) { | |||
287 | exit(1); | 284 | exit(1); |
288 | } | 285 | } |
289 | // mount via the links in /proc/self/fd | 286 | // mount via the links in /proc/self/fd |
287 | EUID_ROOT(); | ||
290 | if (bind_mount_by_fd(src, dst)) | 288 | if (bind_mount_by_fd(src, dst)) |
291 | errExit("mount bind"); | 289 | errExit("mount bind"); |
292 | 290 | ||
@@ -433,6 +431,7 @@ void fs_check_private_cwd(const char *dir) { | |||
433 | // --private-home | 431 | // --private-home |
434 | //*********************************************************************************** | 432 | //*********************************************************************************** |
435 | static char *check_dir_or_file(const char *name) { | 433 | static char *check_dir_or_file(const char *name) { |
434 | EUID_ASSERT(); | ||
436 | assert(name); | 435 | assert(name); |
437 | 436 | ||
438 | // basic checks | 437 | // basic checks |
@@ -493,6 +492,7 @@ errexit: | |||
493 | } | 492 | } |
494 | 493 | ||
495 | static void duplicate(char *name) { | 494 | static void duplicate(char *name) { |
495 | EUID_ASSERT(); | ||
496 | char *fname = check_dir_or_file(name); | 496 | char *fname = check_dir_or_file(name); |
497 | 497 | ||
498 | if (arg_debug) | 498 | if (arg_debug) |
@@ -548,10 +548,10 @@ void fs_private_home_list(void) { | |||
548 | selinux_relabel_path(RUN_HOME_DIR, homedir); | 548 | selinux_relabel_path(RUN_HOME_DIR, homedir); |
549 | fs_logger_print(); // save the current log | 549 | fs_logger_print(); // save the current log |
550 | 550 | ||
551 | // copy the list of files in the new home directory | ||
552 | EUID_USER(); | ||
551 | if (arg_debug) | 553 | if (arg_debug) |
552 | printf("Copying files in the new home:\n"); | 554 | printf("Copying files in the new home:\n"); |
553 | |||
554 | // copy the list of files in the new home directory | ||
555 | char *dlist = strdup(cfg.home_private_keep); | 555 | char *dlist = strdup(cfg.home_private_keep); |
556 | if (!dlist) | 556 | if (!dlist) |
557 | errExit("strdup"); | 557 | errExit("strdup"); |
@@ -584,6 +584,7 @@ void fs_private_home_list(void) { | |||
584 | exit(1); | 584 | exit(1); |
585 | } | 585 | } |
586 | // mount using the file descriptor | 586 | // mount using the file descriptor |
587 | EUID_ROOT(); | ||
587 | if (bind_mount_path_to_fd(RUN_HOME_DIR, fd)) | 588 | if (bind_mount_path_to_fd(RUN_HOME_DIR, fd)) |
588 | errExit("mount bind"); | 589 | errExit("mount bind"); |
589 | close(fd); | 590 | close(fd); |