diff options
author | smitsohu <smitsohu@gmail.com> | 2021-05-03 01:09:05 +0200 |
---|---|---|
committer | smitsohu <smitsohu@gmail.com> | 2021-05-03 01:20:53 +0200 |
commit | 923d7ada73f9600cda12a4ceb59b90928e4ce0d6 (patch) | |
tree | 834d6a23c22ad5e7fb1b74d4c25c3a6f6d462584 /src | |
parent | enhance clean_pathname function (diff) | |
download | firejail-923d7ada73f9600cda12a4ceb59b90928e4ce0d6.tar.gz firejail-923d7ada73f9600cda12a4ceb59b90928e4ce0d6.tar.zst firejail-923d7ada73f9600cda12a4ceb59b90928e4ce0d6.zip |
introduce safer_openat function
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/chroot.c | 8 | ||||
-rw-r--r-- | src/firejail/dbus.c | 2 | ||||
-rw-r--r-- | src/firejail/firejail.h | 2 | ||||
-rw-r--r-- | src/firejail/fs.c | 10 | ||||
-rw-r--r-- | src/firejail/fs_home.c | 6 | ||||
-rw-r--r-- | src/firejail/fs_whitelist.c | 12 | ||||
-rw-r--r-- | src/firejail/pulseaudio.c | 2 | ||||
-rw-r--r-- | src/firejail/restrict_users.c | 2 | ||||
-rw-r--r-- | src/firejail/util.c | 45 | ||||
-rw-r--r-- | src/firejail/x11.c | 10 |
10 files changed, 51 insertions, 48 deletions
diff --git a/src/firejail/chroot.c b/src/firejail/chroot.c index d7e96cf4c..757ffb1f7 100644 --- a/src/firejail/chroot.c +++ b/src/firejail/chroot.c | |||
@@ -131,9 +131,9 @@ void fs_chroot(const char *rootdir) { | |||
131 | assert(rootdir); | 131 | assert(rootdir); |
132 | 132 | ||
133 | // fails if there is any symlink or if rootdir is not a directory | 133 | // fails if there is any symlink or if rootdir is not a directory |
134 | int parentfd = safe_fd(rootdir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); | 134 | int parentfd = safer_openat(-1, rootdir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); |
135 | if (parentfd == -1) | 135 | if (parentfd == -1) |
136 | errExit("safe_fd"); | 136 | errExit("safer_openat"); |
137 | // rootdir has to be owned by root and is not allowed to be generally writable, | 137 | // rootdir has to be owned by root and is not allowed to be generally writable, |
138 | // this also excludes /tmp and friends | 138 | // this also excludes /tmp and friends |
139 | struct stat s; | 139 | struct stat s; |
@@ -215,12 +215,12 @@ void fs_chroot(const char *rootdir) { | |||
215 | 215 | ||
216 | if (arg_debug) | 216 | if (arg_debug) |
217 | printf("Mounting %s on chroot %s\n", orig_pulse, orig_pulse); | 217 | printf("Mounting %s on chroot %s\n", orig_pulse, orig_pulse); |
218 | int src = safe_fd(orig_pulse, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); | 218 | int src = safer_openat(-1, orig_pulse, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); |
219 | if (src == -1) { | 219 | if (src == -1) { |
220 | fprintf(stderr, "Error: cannot open %s\n", orig_pulse); | 220 | fprintf(stderr, "Error: cannot open %s\n", orig_pulse); |
221 | exit(1); | 221 | exit(1); |
222 | } | 222 | } |
223 | int dst = safe_fd(pulse, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); | 223 | int dst = safer_openat(-1, pulse, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); |
224 | if (dst == -1) { | 224 | if (dst == -1) { |
225 | fprintf(stderr, "Error: cannot open %s\n", pulse); | 225 | fprintf(stderr, "Error: cannot open %s\n", pulse); |
226 | exit(1); | 226 | exit(1); |
diff --git a/src/firejail/dbus.c b/src/firejail/dbus.c index 658b84537..b8aa2c974 100644 --- a/src/firejail/dbus.c +++ b/src/firejail/dbus.c | |||
@@ -416,7 +416,7 @@ void dbus_proxy_stop(void) { | |||
416 | } | 416 | } |
417 | 417 | ||
418 | static void socket_overlay(char *socket_path, char *proxy_path) { | 418 | static void socket_overlay(char *socket_path, char *proxy_path) { |
419 | int fd = safe_fd(proxy_path, O_PATH | O_NOFOLLOW | O_CLOEXEC); | 419 | int fd = safer_openat(-1, proxy_path, O_PATH | O_NOFOLLOW | O_CLOEXEC); |
420 | if (fd == -1) | 420 | if (fd == -1) |
421 | errExit("opening DBus proxy socket"); | 421 | errExit("opening DBus proxy socket"); |
422 | struct stat s; | 422 | struct stat s; |
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index ca4c988fa..6691b9570 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -528,7 +528,7 @@ void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid); | |||
528 | unsigned extract_timeout(const char *str); | 528 | unsigned extract_timeout(const char *str); |
529 | void disable_file_or_dir(const char *fname); | 529 | void disable_file_or_dir(const char *fname); |
530 | void disable_file_path(const char *path, const char *file); | 530 | void disable_file_path(const char *path, const char *file); |
531 | int safe_fd(const char *path, int flags); | 531 | int safer_openat(int dirfd, const char *path, int flags); |
532 | int has_handler(pid_t pid, int signal); | 532 | int has_handler(pid_t pid, int signal); |
533 | void enter_network_namespace(pid_t pid); | 533 | void enter_network_namespace(pid_t pid); |
534 | int read_pid(const char *name, pid_t *pid); | 534 | int read_pid(const char *name, pid_t *pid); |
diff --git a/src/firejail/fs.c b/src/firejail/fs.c index fc67a15f3..09de11de9 100644 --- a/src/firejail/fs.c +++ b/src/firejail/fs.c | |||
@@ -453,7 +453,7 @@ void fs_tmpfs(const char *dir, unsigned check_owner) { | |||
453 | if (arg_debug) | 453 | if (arg_debug) |
454 | printf("Mounting tmpfs on %s, check owner: %s\n", dir, (check_owner)? "yes": "no"); | 454 | printf("Mounting tmpfs on %s, check owner: %s\n", dir, (check_owner)? "yes": "no"); |
455 | // get a file descriptor for dir, fails if there is any symlink | 455 | // get a file descriptor for dir, fails if there is any symlink |
456 | int fd = safe_fd(dir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); | 456 | int fd = safer_openat(-1, dir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); |
457 | if (fd == -1) | 457 | if (fd == -1) |
458 | errExit("while opening directory"); | 458 | errExit("while opening directory"); |
459 | struct stat s; | 459 | struct stat s; |
@@ -493,7 +493,7 @@ static void fs_remount_simple(const char *path, OPERATION op) { | |||
493 | assert(path); | 493 | assert(path); |
494 | 494 | ||
495 | // open path without following symbolic links | 495 | // open path without following symbolic links |
496 | int fd1 = safe_fd(path, O_PATH|O_NOFOLLOW|O_CLOEXEC); | 496 | int fd1 = safer_openat(-1, path, O_PATH|O_NOFOLLOW|O_CLOEXEC); |
497 | if (fd1 == -1) | 497 | if (fd1 == -1) |
498 | goto out; | 498 | goto out; |
499 | struct stat s1; | 499 | struct stat s1; |
@@ -559,7 +559,7 @@ static void fs_remount_simple(const char *path, OPERATION op) { | |||
559 | 559 | ||
560 | // mount --bind -o remount,ro path | 560 | // mount --bind -o remount,ro path |
561 | // need to open path again without following symbolic links | 561 | // need to open path again without following symbolic links |
562 | int fd2 = safe_fd(path, O_PATH|O_NOFOLLOW|O_CLOEXEC); | 562 | int fd2 = safer_openat(-1, path, O_PATH|O_NOFOLLOW|O_CLOEXEC); |
563 | if (fd2 == -1) | 563 | if (fd2 == -1) |
564 | errExit("open"); | 564 | errExit("open"); |
565 | struct stat s2; | 565 | struct stat s2; |
@@ -992,9 +992,9 @@ void fs_overlayfs(void) { | |||
992 | char *firejail; | 992 | char *firejail; |
993 | if (asprintf(&firejail, "%s/.firejail", cfg.homedir) == -1) | 993 | if (asprintf(&firejail, "%s/.firejail", cfg.homedir) == -1) |
994 | errExit("asprintf"); | 994 | errExit("asprintf"); |
995 | int fd = safe_fd(firejail, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); | 995 | int fd = safer_openat(-1, firejail, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); |
996 | if (fd == -1) | 996 | if (fd == -1) |
997 | errExit("safe_fd"); | 997 | errExit("safer_openat"); |
998 | free(firejail); | 998 | free(firejail); |
999 | // create basedir if it doesn't exist | 999 | // create basedir if it doesn't exist |
1000 | // the new directory will be owned by root | 1000 | // the new directory will be owned by root |
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c index 46f32d7ad..e3b044a3b 100644 --- a/src/firejail/fs_home.c +++ b/src/firejail/fs_home.c | |||
@@ -262,10 +262,10 @@ void fs_private_homedir(void) { | |||
262 | if (arg_debug) | 262 | if (arg_debug) |
263 | printf("Mount-bind %s on top of %s\n", private_homedir, homedir); | 263 | printf("Mount-bind %s on top of %s\n", private_homedir, homedir); |
264 | // get file descriptors for homedir and private_homedir, fails if there is any symlink | 264 | // get file descriptors for homedir and private_homedir, fails if there is any symlink |
265 | int src = safe_fd(private_homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); | 265 | int src = safer_openat(-1, private_homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); |
266 | if (src == -1) | 266 | if (src == -1) |
267 | errExit("opening private directory"); | 267 | errExit("opening private directory"); |
268 | int dst = safe_fd(homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); | 268 | int dst = safer_openat(-1, homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); |
269 | if (dst == -1) | 269 | if (dst == -1) |
270 | errExit("opening home directory"); | 270 | errExit("opening home directory"); |
271 | // both mount source and target should be owned by the user | 271 | // both mount source and target should be owned by the user |
@@ -576,7 +576,7 @@ void fs_private_home_list(void) { | |||
576 | if (arg_debug) | 576 | if (arg_debug) |
577 | printf("Mount-bind %s on top of %s\n", RUN_HOME_DIR, homedir); | 577 | printf("Mount-bind %s on top of %s\n", RUN_HOME_DIR, homedir); |
578 | 578 | ||
579 | int fd = safe_fd(homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); | 579 | int fd = safer_openat(-1, homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); |
580 | if (fd == -1) | 580 | if (fd == -1) |
581 | errExit("opening home directory"); | 581 | errExit("opening home directory"); |
582 | // home directory should be owned by the user | 582 | // home directory should be owned by the user |
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c index 698d47b69..23310d92d 100644 --- a/src/firejail/fs_whitelist.c +++ b/src/firejail/fs_whitelist.c | |||
@@ -28,7 +28,7 @@ | |||
28 | 28 | ||
29 | #include <fcntl.h> | 29 | #include <fcntl.h> |
30 | #ifndef O_PATH | 30 | #ifndef O_PATH |
31 | # define O_PATH 010000000 | 31 | #define O_PATH 010000000 |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | // mountinfo functionality test; | 34 | // mountinfo functionality test; |
@@ -220,7 +220,7 @@ static void whitelist_path(ProfileEntry *entry) { | |||
220 | // confirm again the mount source exists and there is no symlink | 220 | // confirm again the mount source exists and there is no symlink |
221 | struct stat wfilestat; | 221 | struct stat wfilestat; |
222 | EUID_USER(); | 222 | EUID_USER(); |
223 | int fd = safe_fd(wfile, O_PATH|O_NOFOLLOW|O_CLOEXEC); | 223 | int fd = safer_openat(-1, wfile, O_PATH|O_NOFOLLOW|O_CLOEXEC); |
224 | EUID_ROOT(); | 224 | EUID_ROOT(); |
225 | if (fd == -1) { | 225 | if (fd == -1) { |
226 | if (arg_debug || arg_debug_whitelists) | 226 | if (arg_debug || arg_debug_whitelists) |
@@ -317,9 +317,9 @@ static void whitelist_path(ProfileEntry *entry) { | |||
317 | if (mptr->dir == strrchr(mptr->dir, '/')) | 317 | if (mptr->dir == strrchr(mptr->dir, '/')) |
318 | errLogExit("invalid whitelist mount"); | 318 | errLogExit("invalid whitelist mount"); |
319 | // confirm the right file was mounted by comparing device and inode numbers | 319 | // confirm the right file was mounted by comparing device and inode numbers |
320 | int fd4 = safe_fd(path, O_PATH|O_NOFOLLOW|O_CLOEXEC); | 320 | int fd4 = safer_openat(-1, path, O_PATH|O_NOFOLLOW|O_CLOEXEC); |
321 | if (fd4 == -1) | 321 | if (fd4 == -1) |
322 | errExit("safe_fd"); | 322 | errExit("safer_openat"); |
323 | struct stat s; | 323 | struct stat s; |
324 | if (fstat(fd4, &s) == -1) | 324 | if (fstat(fd4, &s) == -1) |
325 | errExit("fstat"); | 325 | errExit("fstat"); |
@@ -1059,9 +1059,9 @@ void fs_whitelist(void) { | |||
1059 | if (stat(cfg.homedir, &s) == 0) { | 1059 | if (stat(cfg.homedir, &s) == 0) { |
1060 | // keep a copy of real home dir in RUN_WHITELIST_HOME_USER_DIR | 1060 | // keep a copy of real home dir in RUN_WHITELIST_HOME_USER_DIR |
1061 | mkdir_attr(RUN_WHITELIST_HOME_USER_DIR, 0755, getuid(), getgid()); | 1061 | mkdir_attr(RUN_WHITELIST_HOME_USER_DIR, 0755, getuid(), getgid()); |
1062 | int fd = safe_fd(cfg.homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); | 1062 | int fd = safer_openat(-1, cfg.homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); |
1063 | if (fd == -1) | 1063 | if (fd == -1) |
1064 | errExit("safe_fd"); | 1064 | errExit("safer_openat"); |
1065 | char *proc; | 1065 | char *proc; |
1066 | if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1) | 1066 | if (asprintf(&proc, "/proc/self/fd/%d", fd) == -1) |
1067 | errExit("asprintf"); | 1067 | errExit("asprintf"); |
diff --git a/src/firejail/pulseaudio.c b/src/firejail/pulseaudio.c index 4b9203c36..a50134893 100644 --- a/src/firejail/pulseaudio.c +++ b/src/firejail/pulseaudio.c | |||
@@ -131,7 +131,7 @@ void pulseaudio_init(void) { | |||
131 | 131 | ||
132 | // if ~/.config/pulse exists and there are no symbolic links, mount the new directory | 132 | // if ~/.config/pulse exists and there are no symbolic links, mount the new directory |
133 | // else set environment variable | 133 | // else set environment variable |
134 | int fd = safe_fd(homeusercfg, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); | 134 | int fd = safer_openat(-1, homeusercfg, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); |
135 | if (fd == -1) { | 135 | if (fd == -1) { |
136 | pulseaudio_fallback(pulsecfg); | 136 | pulseaudio_fallback(pulsecfg); |
137 | goto out; | 137 | goto out; |
diff --git a/src/firejail/restrict_users.c b/src/firejail/restrict_users.c index a0ca4c02c..8368d84a1 100644 --- a/src/firejail/restrict_users.c +++ b/src/firejail/restrict_users.c | |||
@@ -73,7 +73,7 @@ static void sanitize_home(void) { | |||
73 | if (arg_debug) | 73 | if (arg_debug) |
74 | printf("Cleaning /home directory\n"); | 74 | printf("Cleaning /home directory\n"); |
75 | // open user home directory in order to keep it around | 75 | // open user home directory in order to keep it around |
76 | int fd = safe_fd(cfg.homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); | 76 | int fd = safer_openat(-1, cfg.homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); |
77 | if (fd == -1) | 77 | if (fd == -1) |
78 | goto errout; | 78 | goto errout; |
79 | if (fstat(fd, &s) == -1) { // FUSE | 79 | if (fstat(fd, &s) == -1) { // FUSE |
diff --git a/src/firejail/util.c b/src/firejail/util.c index 8966521cb..d16354d9d 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c | |||
@@ -915,9 +915,9 @@ int remove_overlay_directory(void) { | |||
915 | errExit("fork"); | 915 | errExit("fork"); |
916 | if (child == 0) { | 916 | if (child == 0) { |
917 | // open ~/.firejail, fails if there is any symlink | 917 | // open ~/.firejail, fails if there is any symlink |
918 | int fd = safe_fd(path, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); | 918 | int fd = safer_openat(-1, path, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); |
919 | if (fd == -1) | 919 | if (fd == -1) |
920 | errExit("safe_fd"); | 920 | errExit("safer_openat"); |
921 | // chdir to ~/.firejail | 921 | // chdir to ~/.firejail |
922 | if (fchdir(fd) == -1) | 922 | if (fchdir(fd) == -1) |
923 | errExit("fchdir"); | 923 | errExit("fchdir"); |
@@ -1136,13 +1136,13 @@ void disable_file_path(const char *path, const char *file) { | |||
1136 | } | 1136 | } |
1137 | 1137 | ||
1138 | // open an existing file without following any symbolic link | 1138 | // open an existing file without following any symbolic link |
1139 | int safe_fd(const char *path, int flags) { | 1139 | // relative paths are interpreted relative to dirfd |
1140 | flags |= O_NOFOLLOW; | 1140 | // ignore dirfd if path is absolute |
1141 | // https://web.archive.org/web/20180419120236/https://blogs.gnome.org/jamesh/2018/04/19/secure-mounts | ||
1142 | int safer_openat(int dirfd, const char *path, int flags) { | ||
1141 | assert(path); | 1143 | assert(path); |
1142 | if (*path != '/' || strstr(path, "..")) { | 1144 | flags |= O_NOFOLLOW; |
1143 | fprintf(stderr, "Error: invalid path %s\n", path); | 1145 | |
1144 | exit(1); | ||
1145 | } | ||
1146 | int fd = -1; | 1146 | int fd = -1; |
1147 | 1147 | ||
1148 | #ifdef __NR_openat2 // kernel 5.6 or better | 1148 | #ifdef __NR_openat2 // kernel 5.6 or better |
@@ -1150,7 +1150,7 @@ int safe_fd(const char *path, int flags) { | |||
1150 | memset(&oh, 0, sizeof(oh)); | 1150 | memset(&oh, 0, sizeof(oh)); |
1151 | oh.flags = flags; | 1151 | oh.flags = flags; |
1152 | oh.resolve = RESOLVE_NO_SYMLINKS; | 1152 | oh.resolve = RESOLVE_NO_SYMLINKS; |
1153 | fd = syscall(__NR_openat2, -1, path, &oh, sizeof(struct open_how)); | 1153 | fd = syscall(__NR_openat2, dirfd, path, &oh, sizeof(struct open_how)); |
1154 | if (fd != -1 || errno != ENOSYS) | 1154 | if (fd != -1 || errno != ENOSYS) |
1155 | return fd; | 1155 | return fd; |
1156 | #endif | 1156 | #endif |
@@ -1161,18 +1161,23 @@ int safe_fd(const char *path, int flags) { | |||
1161 | if (!dup) | 1161 | if (!dup) |
1162 | errExit("strdup"); | 1162 | errExit("strdup"); |
1163 | char *tok = strtok(dup, "/"); | 1163 | char *tok = strtok(dup, "/"); |
1164 | if (!tok) { // root directory | 1164 | if (!tok) { // nothing to do, path is either empty string or the root directory |
1165 | free(dup); | 1165 | free(dup); |
1166 | return open("/", flags); | 1166 | return openat(dirfd, path, flags); |
1167 | } | 1167 | } |
1168 | char *last_tok = EMPTY_STRING; | 1168 | char *last_tok = EMPTY_STRING; |
1169 | int parentfd = open("/", O_PATH|O_CLOEXEC); | 1169 | |
1170 | int parentfd; | ||
1171 | if (path[0] == '/') | ||
1172 | parentfd = open("/", O_PATH|O_CLOEXEC); | ||
1173 | else | ||
1174 | parentfd = fcntl(dirfd, F_DUPFD_CLOEXEC, 0); | ||
1170 | if (parentfd == -1) | 1175 | if (parentfd == -1) |
1171 | errExit("open"); | 1176 | errExit("open/fcntl"); |
1172 | 1177 | ||
1173 | while(1) { | 1178 | while (1) { |
1174 | // open path component, assuming it is a directory; this fails with ENOTDIR if it is a symbolic link | 1179 | // open path component, assuming it is a directory; this fails with ENOTDIR if it is a symbolic link |
1175 | // if token is a single dot, the previous directory is reopened | 1180 | // if token is a single dot, the directory referred to by parentfd is reopened |
1176 | fd = openat(parentfd, tok, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); | 1181 | fd = openat(parentfd, tok, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); |
1177 | if (fd == -1) { | 1182 | if (fd == -1) { |
1178 | // if the following token is NULL, the current token is the final path component | 1183 | // if the following token is NULL, the current token is the final path component |
@@ -1303,13 +1308,11 @@ pid_t require_pid(const char *name) { | |||
1303 | // return 1 if there is a link somewhere in path of directory | 1308 | // return 1 if there is a link somewhere in path of directory |
1304 | static int has_link(const char *dir) { | 1309 | static int has_link(const char *dir) { |
1305 | assert(dir); | 1310 | assert(dir); |
1306 | int fd = safe_fd(dir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); | 1311 | int fd = safer_openat(-1, dir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); |
1307 | if (fd == -1) { | 1312 | if (fd != -1) |
1308 | if ((errno == ELOOP || errno == ENOTDIR) && is_dir(dir)) | ||
1309 | return 1; | ||
1310 | } | ||
1311 | else | ||
1312 | close(fd); | 1313 | close(fd); |
1314 | else if (errno == ELOOP || (errno == ENOTDIR && is_dir(dir))) | ||
1315 | return 1; | ||
1313 | return 0; | 1316 | return 0; |
1314 | } | 1317 | } |
1315 | 1318 | ||
diff --git a/src/firejail/x11.c b/src/firejail/x11.c index 1dabf272e..da0acc69c 100644 --- a/src/firejail/x11.c +++ b/src/firejail/x11.c | |||
@@ -1239,9 +1239,9 @@ void x11_xorg(void) { | |||
1239 | } | 1239 | } |
1240 | } | 1240 | } |
1241 | // get a file descriptor for ~/.Xauthority | 1241 | // get a file descriptor for ~/.Xauthority |
1242 | int dst = safe_fd(dest, O_PATH|O_NOFOLLOW|O_CLOEXEC); | 1242 | int dst = safer_openat(-1, dest, O_PATH|O_NOFOLLOW|O_CLOEXEC); |
1243 | if (dst == -1) | 1243 | if (dst == -1) |
1244 | errExit("safe_fd"); | 1244 | errExit("safer_openat"); |
1245 | // check if the actual mount destination is a user owned regular file | 1245 | // check if the actual mount destination is a user owned regular file |
1246 | if (fstat(dst, &s) == -1) | 1246 | if (fstat(dst, &s) == -1) |
1247 | errExit("fstat"); | 1247 | errExit("fstat"); |
@@ -1263,9 +1263,9 @@ void x11_xorg(void) { | |||
1263 | fs_remount(RUN_XAUTHORITY_SEC_DIR, MOUNT_NOEXEC, 0); | 1263 | fs_remount(RUN_XAUTHORITY_SEC_DIR, MOUNT_NOEXEC, 0); |
1264 | 1264 | ||
1265 | // get a file descriptor for the new Xauthority file | 1265 | // get a file descriptor for the new Xauthority file |
1266 | int src = safe_fd(tmpfname, O_PATH|O_NOFOLLOW|O_CLOEXEC); | 1266 | int src = safer_openat(-1, tmpfname, O_PATH|O_NOFOLLOW|O_CLOEXEC); |
1267 | if (src == -1) | 1267 | if (src == -1) |
1268 | errExit("safe_fd"); | 1268 | errExit("safer_openat"); |
1269 | if (fstat(src, &s) == -1) | 1269 | if (fstat(src, &s) == -1) |
1270 | errExit("fstat"); | 1270 | errExit("fstat"); |
1271 | if (!S_ISREG(s.st_mode)) { | 1271 | if (!S_ISREG(s.st_mode)) { |
@@ -1373,7 +1373,7 @@ void fs_x11(void) { | |||
1373 | char *wx11file; | 1373 | char *wx11file; |
1374 | if (asprintf(&wx11file, "%s/X%d", RUN_WHITELIST_X11_DIR, display) == -1) | 1374 | if (asprintf(&wx11file, "%s/X%d", RUN_WHITELIST_X11_DIR, display) == -1) |
1375 | errExit("asprintf"); | 1375 | errExit("asprintf"); |
1376 | fd = safe_fd(wx11file, O_PATH|O_NOFOLLOW|O_CLOEXEC); | 1376 | fd = safer_openat(-1, wx11file, O_PATH|O_NOFOLLOW|O_CLOEXEC); |
1377 | if (fd == -1) | 1377 | if (fd == -1) |
1378 | errExit("opening X11 socket"); | 1378 | errExit("opening X11 socket"); |
1379 | // confirm once more we are mounting a socket | 1379 | // confirm once more we are mounting a socket |