From d0a8395d4037ed9f0576a8d7a041e432e5c5afba Mon Sep 17 00:00:00 2001 From: smitsohu Date: Wed, 17 Oct 2018 18:50:09 +0200 Subject: improve some error messages --- src/firejail/fs.c | 102 +++++++++++++++++++++++++++++-------------------- src/firejail/fs_home.c | 2 + 2 files changed, 62 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/firejail/fs.c b/src/firejail/fs.c index f70c5ac8a..3ce2c7571 100644 --- a/src/firejail/fs.c +++ b/src/firejail/fs.c @@ -1195,73 +1195,78 @@ void fs_check_chroot_dir(const char *rootdir) { } // check /dev - fd = openat(parentfd, "dev", O_PATH|O_CLOEXEC); + char *dir = "dev"; + fd = openat(parentfd, dir, O_PATH|O_CLOEXEC); if (fd == -1) { - fprintf(stderr, "Error: cannot open /dev in chroot directory\n"); - exit(1); + if (errno == ENOENT) + goto error1; + else + goto error2; } if (fstat(fd, &s) == -1) errExit("fstat"); - if (!S_ISDIR(s.st_mode) || s.st_uid != 0) { - fprintf(stderr, "Error: chroot /dev should be a directory owned by root\n"); - exit(1); - } + if (!S_ISDIR(s.st_mode) || s.st_uid != 0) + goto error3; close(fd); // check /var/tmp - fd = openat(parentfd, "var/tmp", O_PATH|O_CLOEXEC); + dir = "var/tmp"; + fd = openat(parentfd, dir, O_PATH|O_CLOEXEC); if (fd == -1) { - fprintf(stderr, "Error: cannot open /var/tmp in chroot directory\n"); - exit(1); + if (errno == ENOENT) + goto error1; + else + goto error2; } if (fstat(fd, &s) == -1) errExit("fstat"); - if (!S_ISDIR(s.st_mode) || s.st_uid != 0) { - fprintf(stderr, "Error: chroot /var/tmp should be a directory owned by root\n"); - exit(1); - } + if (!S_ISDIR(s.st_mode) || s.st_uid != 0) + goto error3; close(fd); // check /proc - fd = openat(parentfd, "proc", O_PATH|O_CLOEXEC); + dir = "proc"; + fd = openat(parentfd, dir, O_PATH|O_CLOEXEC); if (fd == -1) { - fprintf(stderr, "Error: cannot open /proc in chroot directory\n"); - exit(1); + if (errno == ENOENT) + goto error1; + else + goto error2; } if (fstat(fd, &s) == -1) errExit("fstat"); - if (!S_ISDIR(s.st_mode) || s.st_uid != 0) { - fprintf(stderr, "Error: chroot /proc should be a directory owned by root\n"); - exit(1); - } + if (!S_ISDIR(s.st_mode) || s.st_uid != 0) + goto error3; close(fd); // check /tmp - fd = openat(parentfd, "tmp", O_PATH|O_CLOEXEC); + dir = "tmp"; + fd = openat(parentfd, dir, O_PATH|O_CLOEXEC); if (fd == -1) { - fprintf(stderr, "Error: cannot open /tmp in chroot directory\n"); - exit(1); + if (errno == ENOENT) + goto error1; + else + goto error2; } if (fstat(fd, &s) == -1) errExit("fstat"); - if (!S_ISDIR(s.st_mode) || s.st_uid != 0) { - fprintf(stderr, "Error: chroot /tmp should be a directory owned by root\n"); - exit(1); - } + if (!S_ISDIR(s.st_mode) || s.st_uid != 0) + goto error3; close(fd); // check /etc - fd = openat(parentfd, "etc", O_PATH|O_CLOEXEC); + dir = "etc"; + fd = openat(parentfd, dir, O_PATH|O_CLOEXEC); if (fd == -1) { - fprintf(stderr, "Error: cannot open /etc in chroot directory\n"); - exit(1); + if (errno == ENOENT) + goto error1; + else + goto error2; } if (fstat(fd, &s) == -1) errExit("fstat"); - if (!S_ISDIR(s.st_mode) || s.st_uid != 0) { - fprintf(stderr, "Error: chroot /etc should be a directory owned by root\n"); - exit(1); - } + if (!S_ISDIR(s.st_mode) || s.st_uid != 0) + goto error3; if (((S_IWGRP|S_IWOTH) & s.st_mode) != 0) { fprintf(stderr, "Error: only root user should be given write permission on chroot /etc\n"); exit(1); @@ -1298,21 +1303,34 @@ void fs_check_chroot_dir(const char *rootdir) { // check x11 socket directory if (getenv("FIREJAIL_X11")) { - fd = openat(parentfd, "tmp/.X11-unix", O_PATH|O_CLOEXEC); + dir = "tmp/.X11-unix"; + fd = openat(parentfd, dir, O_PATH|O_CLOEXEC); if (fd == -1) { - fprintf(stderr, "Error: cannot open /tmp/.X11-unix in chroot directory\n"); - exit(1); + if (errno == ENOENT) + goto error1; + else + goto error2; } if (fstat(fd, &s) == -1) errExit("fstat"); - if (!S_ISDIR(s.st_mode) || s.st_uid != 0) { - fprintf(stderr, "Error: chroot /tmp/.X11-unix should be a directory owned by root\n"); - exit(1); - } + if (!S_ISDIR(s.st_mode) || s.st_uid != 0) + goto error3; close(fd); } close(parentfd); + return; + +error1: + fprintf(stderr, "Error: cannot find /%s in chroot directory\n", dir); + exit(1); +error2: + perror("open"); + fprintf(stderr, "Error: cannot open /%s in chroot directory\n", dir); + exit(1); +error3: + fprintf(stderr, "Error: chroot /%s should be a directory owned by root\n", dir); + exit(1); } // chroot into an existing directory; mount exiting /dev and update /etc/resolv.conf diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c index 47261d7c1..10232fa6e 100644 --- a/src/firejail/fs_home.c +++ b/src/firejail/fs_home.c @@ -393,6 +393,8 @@ static char *check_dir_or_file(const char *name) { // we allow only files in user home directory or symbolic links to files or directories owned by the user struct stat s; if (lstat(fname, &s) == 0 && S_ISLNK(s.st_mode)) { + if (strncmp(fname, cfg.homedir, strlen(cfg.homedir)) != 0 || fname[strlen(cfg.homedir)] != '/') + goto errexit; if (stat(fname, &s) == 0) { if (s.st_uid != getuid()) { fprintf(stderr, "Error: symbolic link %s to file or directory not owned by the user\n", fname); -- cgit v1.2.3-54-g00ecf