improve some error messages

This commit is contained in:
smitsohu 2018-10-17 18:50:09 +02:00
parent 520c94af9a
commit d0a8395d40
2 changed files with 62 additions and 42 deletions

View file

@ -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

View file

@ -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);