aboutsummaryrefslogtreecommitdiffstats
path: root/src/firejail/fs_home.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/firejail/fs_home.c')
-rw-r--r--src/firejail/fs_home.c41
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//***********************************************************************************
435static char *check_dir_or_file(const char *name) { 433static 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
495static void duplicate(char *name) { 494static 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);