diff options
author | smitsohu <smitsohu@gmail.com> | 2019-11-14 11:12:25 +0100 |
---|---|---|
committer | smitsohu <smitsohu@gmail.com> | 2019-11-14 11:12:25 +0100 |
commit | eb7a2bfb86d34e448e41fcee5388632bff9edbb5 (patch) | |
tree | 5d73cad6218bfda100e66037214cb94ffe0b5d38 /src/firejail/fs_home.c | |
parent | readme/relnotes updates (diff) | |
download | firejail-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/firejail/fs_home.c')
-rw-r--r-- | src/firejail/fs_home.c | 66 |
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"); |