aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar smitsohu <smitsohu@gmail.com>2019-11-14 11:12:25 +0100
committerLibravatar smitsohu <smitsohu@gmail.com>2019-11-14 11:12:25 +0100
commiteb7a2bfb86d34e448e41fcee5388632bff9edbb5 (patch)
tree5d73cad6218bfda100e66037214cb94ffe0b5d38 /src
parentreadme/relnotes updates (diff)
downloadfirejail-eb7a2bfb86d34e448e41fcee5388632bff9edbb5.tar.gz
firejail-eb7a2bfb86d34e448e41fcee5388632bff9edbb5.tar.zst
firejail-eb7a2bfb86d34e448e41fcee5388632bff9edbb5.zip
simplify private option ownership checks and make them more consistent
allowing private and home directory to be owned by different users if the home directory is inside /home was thought to add flexibility, but the scenario is maybe a bit too exotic, and ignoring it paves the way for a simplification
Diffstat (limited to 'src')
-rw-r--r--src/firejail/fs_home.c66
1 files changed, 26 insertions, 40 deletions
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c
index 2e8a8ad96..060152e55 100644
--- a/src/firejail/fs_home.c
+++ b/src/firejail/fs_home.c
@@ -250,9 +250,6 @@ void fs_private_homedir(void) {
250 int xflag = store_xauthority(); 250 int xflag = store_xauthority();
251 int aflag = store_asoundrc(); 251 int aflag = store_asoundrc();
252 252
253 // home directory outside /home?
254 int oflag = (strncmp(homedir, "/home/", 6) != 0);
255
256 uid_t u = getuid(); 253 uid_t u = getuid();
257 gid_t g = getgid(); 254 gid_t g = getgid();
258 255
@@ -266,28 +263,22 @@ void fs_private_homedir(void) {
266 int dst = safe_fd(homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); 263 int dst = safe_fd(homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
267 if (dst == -1) 264 if (dst == -1)
268 errExit("opening home directory"); 265 errExit("opening home directory");
269 if (u != 0) { 266 // both mount source and target should be owned by the user
270 struct stat s; 267 struct stat s;
271 // sometimes system users are assigned home directories like /, /proc, ... 268 if (fstat(src, &s) == -1)
272 // require that a home directory outside /home is owned by the user 269 errExit("fstat");
273 if (oflag) { 270 if (s.st_uid != u) {
274 if (fstat(dst, &s) == -1) 271 fprintf(stderr, "Error: private directory is not owned by the current user\n");
275 errExit("fstat"); 272 exit(1);
276 if (s.st_uid != u) { 273 }
277 fprintf(stderr, "Error: cannot mount private directory:\n" 274 if ((S_IRWXU & s.st_mode) != S_IRWXU)
278 "Home directory is not owned by the current user\n"); 275 fwarning("no full permissions on private directory\n");
279 exit(1); 276 if (fstat(dst, &s) == -1)
280 } 277 errExit("fstat");
281 } 278 if (s.st_uid != u) {
282 // check if new home directory is owned by the user 279 fprintf(stderr, "Error: cannot mount private directory:\n"
283 if (fstat(src, &s) == -1) 280 "Home directory is not owned by the current user\n");
284 errExit("fstat"); 281 exit(1);
285 if (s.st_uid != u) {
286 fprintf(stderr, "Error: private directory is not owned by the current user\n");
287 exit(1);
288 }
289 if ((S_IRWXU & s.st_mode) != S_IRWXU)
290 fwarning("no full permissions on private directory\n");
291 } 282 }
292 // mount via the links in /proc/self/fd 283 // mount via the links in /proc/self/fd
293 char *proc_src, *proc_dst; 284 char *proc_src, *proc_dst;
@@ -324,7 +315,7 @@ void fs_private_homedir(void) {
324 errExit("mounting home directory"); 315 errExit("mounting home directory");
325 fs_logger("tmpfs /root"); 316 fs_logger("tmpfs /root");
326 } 317 }
327 if (oflag) { 318 if (u == 0 || strncmp(homedir, "/home/", 6) != 0) {
328 // mask /home 319 // mask /home
329 if (arg_debug) 320 if (arg_debug)
330 printf("Mounting a new /home directory\n"); 321 printf("Mounting a new /home directory\n");
@@ -546,9 +537,6 @@ void fs_private_home_list(void) {
546 int xflag = store_xauthority(); 537 int xflag = store_xauthority();
547 int aflag = store_asoundrc(); 538 int aflag = store_asoundrc();
548 539
549 // home directory outside /home?
550 int oflag = (strncmp(homedir, "/home/", 6) != 0);
551
552 uid_t uid = getuid(); 540 uid_t uid = getuid();
553 gid_t gid = getgid(); 541 gid_t gid = getgid();
554 542
@@ -582,16 +570,14 @@ void fs_private_home_list(void) {
582 int fd = safe_fd(homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); 570 int fd = safe_fd(homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
583 if (fd == -1) 571 if (fd == -1)
584 errExit("opening home directory"); 572 errExit("opening home directory");
585 if (uid != 0 && oflag) { 573 // home directory should be owned by the user
586 // home directory outside /home should be owned by the user 574 struct stat s;
587 struct stat s; 575 if (fstat(fd, &s) == -1)
588 if (fstat(fd, &s) == -1) 576 errExit("fstat");
589 errExit("fstat"); 577 if (s.st_uid != uid) {
590 if (s.st_uid != uid) { 578 fprintf(stderr, "Error: cannot mount private directory:\n"
591 fprintf(stderr, "Error: cannot mount private directory:\n" 579 "Home directory is not owned by the current user\n");
592 "Home directory is not owned by the current user\n"); 580 exit(1);
593 exit(1);
594 }
595 } 581 }
596 // mount using the file descriptor 582 // mount using the file descriptor
597 char *proc; 583 char *proc;
@@ -614,7 +600,7 @@ void fs_private_home_list(void) {
614 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=700,gid=0") < 0) 600 if (mount("tmpfs", "/root", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=700,gid=0") < 0)
615 errExit("mounting home directory"); 601 errExit("mounting home directory");
616 } 602 }
617 if (oflag) { 603 if (uid == 0 || strncmp(homedir, "/home/", 6) != 0) {
618 // mask /home 604 // mask /home
619 if (arg_debug) 605 if (arg_debug)
620 printf("Mounting a new /home directory\n"); 606 printf("Mounting a new /home directory\n");