1 /* SPDX-License-Identifier: LGPL-2.1+ */
6 #include <linux/falloc.h>
7 #include <linux/magic.h>
10 #include "alloc-util.h"
11 #include "blockdev-util.h"
12 #include "dirent-util.h"
16 #include "locale-util.h"
19 #include "missing_fcntl.h"
20 #include "missing_fs.h"
21 #include "missing_syscall.h"
23 #include "parse-util.h"
24 #include "path-util.h"
25 #include "process-util.h"
26 #include "random-util.h"
27 #include "stat-util.h"
28 #include "stdio-util.h"
29 #include "string-util.h"
31 #include "time-util.h"
32 #include "tmpfile-util.h"
33 #include "user-util.h"
36 int unlink_noerrno(const char *path
) {
47 int rmdir_parents(const char *path
, const char *stop
) {
56 /* Skip trailing slashes */
57 while (l
> 0 && path
[l
-1] == '/')
63 /* Skip last component */
64 while (l
> 0 && path
[l
-1] != '/')
67 /* Skip trailing slashes */
68 while (l
> 0 && path
[l
-1] == '/')
78 if (path_startswith(stop
, t
)) {
94 int rename_noreplace(int olddirfd
, const char *oldpath
, int newdirfd
, const char *newpath
) {
97 /* Try the ideal approach first */
98 if (renameat2(olddirfd
, oldpath
, newdirfd
, newpath
, RENAME_NOREPLACE
) >= 0)
101 /* renameat2() exists since Linux 3.15, btrfs and FAT added support for it later. If it is not implemented,
102 * fall back to a different method. */
103 if (!IN_SET(errno
, EINVAL
, ENOSYS
, ENOTTY
))
106 /* Let's try to use linkat()+unlinkat() as fallback. This doesn't work on directories and on some file systems
107 * that do not support hard links (such as FAT, most prominently), but for files it's pretty close to what we
108 * want — though not atomic (i.e. for a short period both the new and the old filename will exist). */
109 if (linkat(olddirfd
, oldpath
, newdirfd
, newpath
, 0) >= 0) {
111 if (unlinkat(olddirfd
, oldpath
, 0) < 0) {
112 r
= -errno
; /* Backup errno before the following unlinkat() alters it */
113 (void) unlinkat(newdirfd
, newpath
, 0);
120 if (!IN_SET(errno
, EINVAL
, ENOSYS
, ENOTTY
, EPERM
)) /* FAT returns EPERM on link()… */
123 /* OK, neither RENAME_NOREPLACE nor linkat()+unlinkat() worked. Let's then fallback to the racy TOCTOU
124 * vulnerable accessat(F_OK) check followed by classic, replacing renameat(), we have nothing better. */
126 if (faccessat(newdirfd
, newpath
, F_OK
, AT_SYMLINK_NOFOLLOW
) >= 0)
131 if (renameat(olddirfd
, oldpath
, newdirfd
, newpath
) < 0)
137 int readlinkat_malloc(int fd
, const char *p
, char **ret
) {
138 size_t l
= FILENAME_MAX
+1;
152 n
= readlinkat(fd
, p
, c
, l
-1);
159 if ((size_t) n
< l
-1) {
170 int readlink_malloc(const char *p
, char **ret
) {
171 return readlinkat_malloc(AT_FDCWD
, p
, ret
);
174 int readlink_value(const char *p
, char **ret
) {
175 _cleanup_free_
char *link
= NULL
;
179 r
= readlink_malloc(p
, &link
);
183 value
= basename(link
);
187 value
= strdup(value
);
196 int readlink_and_make_absolute(const char *p
, char **r
) {
197 _cleanup_free_
char *target
= NULL
;
204 j
= readlink_malloc(p
, &target
);
208 k
= file_in_same_dir(p
, target
);
216 int chmod_and_chown(const char *path
, mode_t mode
, uid_t uid
, gid_t gid
) {
217 _cleanup_close_
int fd
= -1;
221 fd
= open(path
, O_PATH
|O_CLOEXEC
|O_NOFOLLOW
); /* Let's acquire an O_PATH fd, as precaution to change
222 * mode/owner on the same file */
226 return fchmod_and_chown(fd
, mode
, uid
, gid
);
229 int fchmod_and_chown(int fd
, mode_t mode
, uid_t uid
, gid_t gid
) {
230 bool do_chown
, do_chmod
;
233 /* Change ownership and access mode of the specified fd. Tries to do so safely, ensuring that at no
234 * point in time the access mode is above the old access mode under the old ownership or the new
235 * access mode under the new ownership. Note: this call tries hard to leave the access mode
236 * unaffected if the uid/gid is changed, i.e. it undoes implicit suid/sgid dropping the kernel does
239 * This call is happy with O_PATH fds. */
241 if (fstat(fd
, &st
) < 0)
245 (uid
!= UID_INVALID
&& st
.st_uid
!= uid
) ||
246 (gid
!= GID_INVALID
&& st
.st_gid
!= gid
);
249 !S_ISLNK(st
.st_mode
) && /* chmod is not defined on symlinks */
250 ((mode
!= MODE_INVALID
&& ((st
.st_mode
^ mode
) & 07777) != 0) ||
251 do_chown
); /* If we change ownership, make sure we reset the mode afterwards, since chown()
252 * modifies the access mode too */
254 if (mode
== MODE_INVALID
)
255 mode
= st
.st_mode
; /* If we only shall do a chown(), save original mode, since chown() might break it. */
256 else if ((mode
& S_IFMT
) != 0 && ((mode
^ st
.st_mode
) & S_IFMT
) != 0)
257 return -EINVAL
; /* insist on the right file type if it was specified */
259 if (do_chown
&& do_chmod
) {
260 mode_t minimal
= st
.st_mode
& mode
; /* the subset of the old and the new mask */
262 if (((minimal
^ st
.st_mode
) & 07777) != 0)
263 if (fchmod_opath(fd
, minimal
& 07777) < 0)
268 if (fchownat(fd
, "", uid
, gid
, AT_EMPTY_PATH
) < 0)
272 if (fchmod_opath(fd
, mode
& 07777) < 0)
275 return do_chown
|| do_chmod
;
278 int chmod_and_chown_unsafe(const char *path
, mode_t mode
, uid_t uid
, gid_t gid
) {
279 bool do_chown
, do_chmod
;
284 /* Change ownership and access mode of the specified path, see description of fchmod_and_chown().
285 * Should only be used on trusted paths. */
287 if (lstat(path
, &st
) < 0)
291 (uid
!= UID_INVALID
&& st
.st_uid
!= uid
) ||
292 (gid
!= GID_INVALID
&& st
.st_gid
!= gid
);
295 !S_ISLNK(st
.st_mode
) && /* chmod is not defined on symlinks */
296 ((mode
!= MODE_INVALID
&& ((st
.st_mode
^ mode
) & 07777) != 0) ||
297 do_chown
); /* If we change ownership, make sure we reset the mode afterwards, since chown()
298 * modifies the access mode too */
300 if (mode
== MODE_INVALID
)
301 mode
= st
.st_mode
; /* If we only shall do a chown(), save original mode, since chown() might break it. */
302 else if ((mode
& S_IFMT
) != 0 && ((mode
^ st
.st_mode
) & S_IFMT
) != 0)
303 return -EINVAL
; /* insist on the right file type if it was specified */
305 if (do_chown
&& do_chmod
) {
306 mode_t minimal
= st
.st_mode
& mode
; /* the subset of the old and the new mask */
308 if (((minimal
^ st
.st_mode
) & 07777) != 0)
309 if (chmod(path
, minimal
& 07777) < 0)
314 if (lchown(path
, uid
, gid
) < 0)
318 if (chmod(path
, mode
& 07777) < 0)
321 return do_chown
|| do_chmod
;
324 int fchmod_umask(int fd
, mode_t m
) {
329 r
= fchmod(fd
, m
& (~u
)) < 0 ? -errno
: 0;
335 int fchmod_opath(int fd
, mode_t m
) {
336 char procfs_path
[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
338 /* This function operates also on fd that might have been opened with
339 * O_PATH. Indeed fchmodat() doesn't have the AT_EMPTY_PATH flag like
340 * fchownat() does. */
342 xsprintf(procfs_path
, "/proc/self/fd/%i", fd
);
343 if (chmod(procfs_path
, m
) < 0) {
347 if (proc_mounted() == 0)
348 return -ENOSYS
; /* if we have no /proc/, the concept is not implementable */
356 int fd_warn_permissions(const char *path
, int fd
) {
359 if (fstat(fd
, &st
) < 0)
362 /* Don't complain if we are reading something that is not a file, for example /dev/null */
363 if (!S_ISREG(st
.st_mode
))
366 if (st
.st_mode
& 0111)
367 log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path
);
369 if (st
.st_mode
& 0002)
370 log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path
);
372 if (getpid_cached() == 1 && (st
.st_mode
& 0044) != 0044)
373 log_warning("Configuration file %s is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.", path
);
378 int touch_file(const char *path
, bool parents
, usec_t stamp
, uid_t uid
, gid_t gid
, mode_t mode
) {
379 char fdpath
[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
380 _cleanup_close_
int fd
= -1;
385 /* Note that touch_file() does not follow symlinks: if invoked on an existing symlink, then it is the symlink
386 * itself which is updated, not its target
388 * Returns the first error we encounter, but tries to apply as much as possible. */
391 (void) mkdir_parents(path
, 0755);
393 /* Initially, we try to open the node with O_PATH, so that we get a reference to the node. This is useful in
394 * case the path refers to an existing device or socket node, as we can open it successfully in all cases, and
395 * won't trigger any driver magic or so. */
396 fd
= open(path
, O_PATH
|O_CLOEXEC
|O_NOFOLLOW
);
401 /* if the node doesn't exist yet, we create it, but with O_EXCL, so that we only create a regular file
402 * here, and nothing else */
403 fd
= open(path
, O_WRONLY
|O_CREAT
|O_EXCL
|O_CLOEXEC
, IN_SET(mode
, 0, MODE_INVALID
) ? 0644 : mode
);
408 /* Let's make a path from the fd, and operate on that. With this logic, we can adjust the access mode,
409 * ownership and time of the file node in all cases, even if the fd refers to an O_PATH object — which is
410 * something fchown(), fchmod(), futimensat() don't allow. */
411 xsprintf(fdpath
, "/proc/self/fd/%i", fd
);
413 ret
= fchmod_and_chown(fd
, mode
, uid
, gid
);
415 if (stamp
!= USEC_INFINITY
) {
416 struct timespec ts
[2];
418 timespec_store(&ts
[0], stamp
);
420 r
= utimensat(AT_FDCWD
, fdpath
, ts
, 0);
422 r
= utimensat(AT_FDCWD
, fdpath
, NULL
, 0);
423 if (r
< 0 && ret
>= 0)
429 int touch(const char *path
) {
430 return touch_file(path
, false, USEC_INFINITY
, UID_INVALID
, GID_INVALID
, MODE_INVALID
);
433 int symlink_idempotent(const char *from
, const char *to
, bool make_relative
) {
434 _cleanup_free_
char *relpath
= NULL
;
441 _cleanup_free_
char *parent
= NULL
;
443 parent
= dirname_malloc(to
);
447 r
= path_make_relative(parent
, from
, &relpath
);
454 if (symlink(from
, to
) < 0) {
455 _cleanup_free_
char *p
= NULL
;
460 r
= readlink_malloc(to
, &p
);
461 if (r
== -EINVAL
) /* Not a symlink? In that case return the original error we encountered: -EEXIST */
463 if (r
< 0) /* Any other error? In that case propagate it as is */
466 if (!streq(p
, from
)) /* Not the symlink we want it to be? In that case, propagate the original -EEXIST */
473 int symlink_atomic(const char *from
, const char *to
) {
474 _cleanup_free_
char *t
= NULL
;
480 r
= tempfn_random(to
, NULL
, &t
);
484 if (symlink(from
, t
) < 0)
487 if (rename(t
, to
) < 0) {
495 int mknod_atomic(const char *path
, mode_t mode
, dev_t dev
) {
496 _cleanup_free_
char *t
= NULL
;
501 r
= tempfn_random(path
, NULL
, &t
);
505 if (mknod(t
, mode
, dev
) < 0)
508 if (rename(t
, path
) < 0) {
516 int mkfifo_atomic(const char *path
, mode_t mode
) {
517 _cleanup_free_
char *t
= NULL
;
522 r
= tempfn_random(path
, NULL
, &t
);
526 if (mkfifo(t
, mode
) < 0)
529 if (rename(t
, path
) < 0) {
537 int mkfifoat_atomic(int dirfd
, const char *path
, mode_t mode
) {
538 _cleanup_free_
char *t
= NULL
;
543 if (path_is_absolute(path
))
544 return mkfifo_atomic(path
, mode
);
546 /* We're only interested in the (random) filename. */
547 r
= tempfn_random_child("", NULL
, &t
);
551 if (mkfifoat(dirfd
, t
, mode
) < 0)
554 if (renameat(dirfd
, t
, dirfd
, path
) < 0) {
562 int get_files_in_directory(const char *path
, char ***list
) {
563 _cleanup_closedir_
DIR *d
= NULL
;
565 size_t bufsize
= 0, n
= 0;
566 _cleanup_strv_free_
char **l
= NULL
;
570 /* Returns all files in a directory in *list, and the number
571 * of files as return value. If list is NULL returns only the
578 FOREACH_DIRENT_ALL(de
, d
, return -errno
) {
579 dirent_ensure_type(d
, de
);
581 if (!dirent_is_file(de
))
585 /* one extra slot is needed for the terminating NULL */
586 if (!GREEDY_REALLOC(l
, bufsize
, n
+ 2))
589 l
[n
] = strdup(de
->d_name
);
604 static int getenv_tmp_dir(const char **ret_path
) {
610 /* We use the same order of environment variables python uses in tempfile.gettempdir():
611 * https://docs.python.org/3/library/tempfile.html#tempfile.gettempdir */
612 FOREACH_STRING(n
, "TMPDIR", "TEMP", "TMP") {
615 e
= secure_getenv(n
);
618 if (!path_is_absolute(e
)) {
622 if (!path_is_normalized(e
)) {
639 /* Remember first error, to make this more debuggable */
651 static int tmp_dir_internal(const char *def
, const char **ret
) {
658 r
= getenv_tmp_dir(&e
);
664 k
= is_dir(def
, true);
668 return r
< 0 ? r
: k
;
674 int var_tmp_dir(const char **ret
) {
676 /* Returns the location for "larger" temporary files, that is backed by physical storage if available, and thus
677 * even might survive a boot: /var/tmp. If $TMPDIR (or related environment variables) are set, its value is
678 * returned preferably however. Note that both this function and tmp_dir() below are affected by $TMPDIR,
679 * making it a variable that overrides all temporary file storage locations. */
681 return tmp_dir_internal("/var/tmp", ret
);
684 int tmp_dir(const char **ret
) {
686 /* Similar to var_tmp_dir() above, but returns the location for "smaller" temporary files, which is usually
687 * backed by an in-memory file system: /tmp. */
689 return tmp_dir_internal("/tmp", ret
);
692 int unlink_or_warn(const char *filename
) {
693 if (unlink(filename
) < 0 && errno
!= ENOENT
)
694 /* If the file doesn't exist and the fs simply was read-only (in which
695 * case unlink() returns EROFS even if the file doesn't exist), don't
697 if (errno
!= EROFS
|| access(filename
, F_OK
) >= 0)
698 return log_error_errno(errno
, "Failed to remove \"%s\": %m", filename
);
703 int inotify_add_watch_fd(int fd
, int what
, uint32_t mask
) {
704 char path
[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
707 /* This is like inotify_add_watch(), except that the file to watch is not referenced by a path, but by an fd */
708 xsprintf(path
, "/proc/self/fd/%i", what
);
710 wd
= inotify_add_watch(fd
, path
, mask
);
717 int inotify_add_watch_and_warn(int fd
, const char *pathname
, uint32_t mask
) {
720 wd
= inotify_add_watch(fd
, pathname
, mask
);
723 return log_error_errno(errno
, "Failed to add a watch for %s: inotify watch limit reached", pathname
);
725 return log_error_errno(errno
, "Failed to add a watch for %s: %m", pathname
);
731 static bool unsafe_transition(const struct stat
*a
, const struct stat
*b
) {
732 /* Returns true if the transition from a to b is safe, i.e. that we never transition from unprivileged to
733 * privileged files or directories. Why bother? So that unprivileged code can't symlink to privileged files
734 * making us believe we read something safe even though it isn't safe in the specific context we open it in. */
736 if (a
->st_uid
== 0) /* Transitioning from privileged to unprivileged is always fine */
739 return a
->st_uid
!= b
->st_uid
; /* Otherwise we need to stay within the same UID */
742 static int log_unsafe_transition(int a
, int b
, const char *path
, unsigned flags
) {
743 _cleanup_free_
char *n1
= NULL
, *n2
= NULL
;
745 if (!FLAGS_SET(flags
, CHASE_WARN
))
748 (void) fd_get_path(a
, &n1
);
749 (void) fd_get_path(b
, &n2
);
751 return log_warning_errno(SYNTHETIC_ERRNO(ENOLINK
),
752 "Detected unsafe path transition %s %s %s during canonicalization of %s.",
753 n1
, special_glyph(SPECIAL_GLYPH_ARROW
), n2
, path
);
756 static int log_autofs_mount_point(int fd
, const char *path
, unsigned flags
) {
757 _cleanup_free_
char *n1
= NULL
;
759 if (!FLAGS_SET(flags
, CHASE_WARN
))
762 (void) fd_get_path(fd
, &n1
);
764 return log_warning_errno(SYNTHETIC_ERRNO(EREMOTE
),
765 "Detected autofs mount point %s during canonicalization of %s.",
769 int chase_symlinks(const char *path
, const char *original_root
, unsigned flags
, char **ret_path
, int *ret_fd
) {
770 _cleanup_free_
char *buffer
= NULL
, *done
= NULL
, *root
= NULL
;
771 _cleanup_close_
int fd
= -1;
772 unsigned max_follow
= CHASE_SYMLINKS_MAX
; /* how many symlinks to follow before giving up and returning ELOOP */
773 struct stat previous_stat
;
780 /* Either the file may be missing, or we return an fd to the final object, but both make no sense */
781 if ((flags
& CHASE_NONEXISTENT
) && ret_fd
)
784 if ((flags
& CHASE_STEP
) && ret_fd
)
790 /* This is a lot like canonicalize_file_name(), but takes an additional "root" parameter, that allows following
791 * symlinks relative to a root directory, instead of the root of the host.
793 * Note that "root" primarily matters if we encounter an absolute symlink. It is also used when following
794 * relative symlinks to ensure they cannot be used to "escape" the root directory. The path parameter passed is
795 * assumed to be already prefixed by it, except if the CHASE_PREFIX_ROOT flag is set, in which case it is first
796 * prefixed accordingly.
798 * Algorithmically this operates on two path buffers: "done" are the components of the path we already
799 * processed and resolved symlinks, "." and ".." of. "todo" are the components of the path we still need to
800 * process. On each iteration, we move one component from "todo" to "done", processing it's special meaning
801 * each time. The "todo" path always starts with at least one slash, the "done" path always ends in no
802 * slash. We always keep an O_PATH fd to the component we are currently processing, thus keeping lookup races
805 * Suggested usage: whenever you want to canonicalize a path, use this function. Pass the absolute path you got
806 * as-is: fully qualified and relative to your host's root. Optionally, specify the root parameter to tell this
807 * function what to do when encountering a symlink with an absolute path as directory: prefix it by the
810 * There are five ways to invoke this function:
812 * 1. Without CHASE_STEP or ret_fd: in this case the path is resolved and the normalized path is
813 * returned in `ret_path`. The return value is < 0 on error. If CHASE_NONEXISTENT is also set, 0
814 * is returned if the file doesn't exist, > 0 otherwise. If CHASE_NONEXISTENT is not set, >= 0 is
815 * returned if the destination was found, -ENOENT if it wasn't.
817 * 2. With ret_fd: in this case the destination is opened after chasing it as O_PATH and this file
818 * descriptor is returned as return value. This is useful to open files relative to some root
819 * directory. Note that the returned O_PATH file descriptors must be converted into a regular one (using
820 * fd_reopen() or such) before it can be used for reading/writing. ret_fd may not be combined with
823 * 3. With CHASE_STEP: in this case only a single step of the normalization is executed, i.e. only the first
824 * symlink or ".." component of the path is resolved, and the resulting path is returned. This is useful if
825 * a caller wants to trace the a path through the file system verbosely. Returns < 0 on error, > 0 if the
826 * path is fully normalized, and == 0 for each normalization step. This may be combined with
827 * CHASE_NONEXISTENT, in which case 1 is returned when a component is not found.
829 * 4. With CHASE_SAFE: in this case the path must not contain unsafe transitions, i.e. transitions from
830 * unprivileged to privileged files or directories. In such cases the return value is -ENOLINK. If
831 * CHASE_WARN is also set, a warning describing the unsafe transition is emitted.
833 * 5. With CHASE_NO_AUTOFS: in this case if an autofs mount point is encountered, path normalization
834 * is aborted and -EREMOTE is returned. If CHASE_WARN is also set, a warning showing the path of
835 * the mount point is emitted.
838 /* A root directory of "/" or "" is identical to none */
839 if (empty_or_root(original_root
))
840 original_root
= NULL
;
842 if (!original_root
&& !ret_path
&& !(flags
& (CHASE_NONEXISTENT
|CHASE_NO_AUTOFS
|CHASE_SAFE
|CHASE_STEP
)) && ret_fd
) {
843 /* Shortcut the ret_fd case if the caller isn't interested in the actual path and has no root set
844 * and doesn't care about any of the other special features we provide either. */
845 r
= open(path
, O_PATH
|O_CLOEXEC
|((flags
& CHASE_NOFOLLOW
) ? O_NOFOLLOW
: 0));
854 r
= path_make_absolute_cwd(original_root
, &root
);
858 /* Simplify the root directory, so that it has no duplicate slashes and nothing at the
859 * end. While we won't resolve the root path we still simplify it. Note that dropping the
860 * trailing slash should not change behaviour, since when opening it we specify O_DIRECTORY
861 * anyway. Moreover at the end of this function after processing everything we'll always turn
862 * the empty string back to "/". */
863 delete_trailing_chars(root
, "/");
864 path_simplify(root
, true);
866 if (flags
& CHASE_PREFIX_ROOT
) {
867 /* We don't support relative paths in combination with a root directory */
868 if (!path_is_absolute(path
))
871 path
= prefix_roota(root
, path
);
875 r
= path_make_absolute_cwd(path
, &buffer
);
879 fd
= open(root
?: "/", O_CLOEXEC
|O_DIRECTORY
|O_PATH
);
883 if (flags
& CHASE_SAFE
) {
884 if (fstat(fd
, &previous_stat
) < 0)
889 _cleanup_free_
char *absolute
= NULL
;
892 /* If we are operating on a root directory, let's take the root directory as it is. */
894 e
= path_startswith(buffer
, root
);
896 return log_full_errno(flags
& CHASE_WARN
? LOG_WARNING
: LOG_DEBUG
,
897 SYNTHETIC_ERRNO(ECHRNG
),
898 "Specified path '%s' is outside of specified root directory '%s', refusing to resolve.",
905 /* Make sure "todo" starts with a slash */
906 absolute
= strjoin("/", e
);
910 free_and_replace(buffer
, absolute
);
915 _cleanup_free_
char *first
= NULL
;
916 _cleanup_close_
int child
= -1;
920 /* Determine length of first component in the path */
921 n
= strspn(todo
, "/"); /* The slashes */
924 /* If we are looking at more than a single slash then skip all but one, so that when
925 * we are done with everything we have a normalized path with only single slashes
926 * separating the path components. */
931 m
= n
+ strcspn(todo
+ n
, "/"); /* The entire length of the component */
933 /* Extract the first component. */
934 first
= strndup(todo
, m
);
940 /* Empty? Then we reached the end. */
944 /* Just a single slash? Then we reached the end. */
945 if (path_equal(first
, "/")) {
946 /* Preserve the trailing slash */
948 if (flags
& CHASE_TRAIL_SLASH
)
949 if (!strextend(&done
, "/", NULL
))
955 /* Just a dot? Then let's eat this up. */
956 if (path_equal(first
, "/."))
959 /* Two dots? Then chop off the last bit of what we already found out. */
960 if (path_equal(first
, "/..")) {
961 _cleanup_free_
char *parent
= NULL
;
962 _cleanup_close_
int fd_parent
= -1;
964 /* If we already are at the top, then going up will not change anything. This is in-line with
965 * how the kernel handles this. */
966 if (empty_or_root(done
))
969 parent
= dirname_malloc(done
);
973 /* Don't allow this to leave the root dir. */
975 path_startswith(done
, root
) &&
976 !path_startswith(parent
, root
))
979 free_and_replace(done
, parent
);
981 if (flags
& CHASE_STEP
)
984 fd_parent
= openat(fd
, "..", O_CLOEXEC
|O_NOFOLLOW
|O_PATH
);
988 if (flags
& CHASE_SAFE
) {
989 if (fstat(fd_parent
, &st
) < 0)
992 if (unsafe_transition(&previous_stat
, &st
))
993 return log_unsafe_transition(fd
, fd_parent
, path
, flags
);
999 fd
= TAKE_FD(fd_parent
);
1004 /* Otherwise let's see what this is. */
1005 child
= openat(fd
, first
+ n
, O_CLOEXEC
|O_NOFOLLOW
|O_PATH
);
1008 if (errno
== ENOENT
&&
1009 (flags
& CHASE_NONEXISTENT
) &&
1010 (isempty(todo
) || path_is_normalized(todo
))) {
1012 /* If CHASE_NONEXISTENT is set, and the path does not exist, then that's OK, return
1013 * what we got so far. But don't allow this if the remaining path contains "../ or "./"
1014 * or something else weird. */
1016 /* If done is "/", as first also contains slash at the head, then remove this redundant slash. */
1017 if (streq_ptr(done
, "/"))
1020 if (!strextend(&done
, first
, todo
, NULL
))
1030 if (fstat(child
, &st
) < 0)
1032 if ((flags
& CHASE_SAFE
) &&
1033 unsafe_transition(&previous_stat
, &st
))
1034 return log_unsafe_transition(fd
, child
, path
, flags
);
1038 if ((flags
& CHASE_NO_AUTOFS
) &&
1039 fd_is_fs_type(child
, AUTOFS_SUPER_MAGIC
) > 0)
1040 return log_autofs_mount_point(child
, path
, flags
);
1042 if (S_ISLNK(st
.st_mode
) && !((flags
& CHASE_NOFOLLOW
) && isempty(todo
))) {
1044 _cleanup_free_
char *destination
= NULL
;
1046 /* This is a symlink, in this case read the destination. But let's make sure we don't follow
1047 * symlinks without bounds. */
1048 if (--max_follow
<= 0)
1051 r
= readlinkat_malloc(fd
, first
+ n
, &destination
);
1054 if (isempty(destination
))
1057 if (path_is_absolute(destination
)) {
1059 /* An absolute destination. Start the loop from the beginning, but use the root
1060 * directory as base. */
1063 fd
= open(root
?: "/", O_CLOEXEC
|O_DIRECTORY
|O_PATH
);
1067 if (flags
& CHASE_SAFE
) {
1068 if (fstat(fd
, &st
) < 0)
1071 if (unsafe_transition(&previous_stat
, &st
))
1072 return log_unsafe_transition(child
, fd
, path
, flags
);
1079 /* Note that we do not revalidate the root, we take it as is. */
1083 done
= strdup(root
);
1088 /* Prefix what's left to do with what we just read, and start the loop again, but
1089 * remain in the current directory. */
1090 joined
= path_join(destination
, todo
);
1092 joined
= path_join("/", destination
, todo
);
1097 todo
= buffer
= joined
;
1099 if (flags
& CHASE_STEP
)
1105 /* If this is not a symlink, then let's just add the name we read to what we already verified. */
1107 done
= TAKE_PTR(first
);
1109 /* If done is "/", as first also contains slash at the head, then remove this redundant slash. */
1110 if (streq(done
, "/"))
1113 if (!strextend(&done
, first
, NULL
))
1117 /* And iterate again, but go one directory further down. */
1119 fd
= TAKE_FD(child
);
1123 /* Special case, turn the empty string into "/", to indicate the root directory. */
1130 *ret_path
= TAKE_PTR(done
);
1133 /* Return the O_PATH fd we currently are looking to the caller. It can translate it to a
1134 * proper fd by opening /proc/self/fd/xyz. */
1137 *ret_fd
= TAKE_FD(fd
);
1140 if (flags
& CHASE_STEP
)
1149 c
= strjoin(strempty(done
), todo
);
1159 int chase_symlinks_and_open(
1162 unsigned chase_flags
,
1166 _cleanup_close_
int path_fd
= -1;
1167 _cleanup_free_
char *p
= NULL
;
1170 if (chase_flags
& CHASE_NONEXISTENT
)
1173 if (empty_or_root(root
) && !ret_path
&& (chase_flags
& (CHASE_NO_AUTOFS
|CHASE_SAFE
)) == 0) {
1174 /* Shortcut this call if none of the special features of this call are requested */
1175 r
= open(path
, open_flags
);
1182 r
= chase_symlinks(path
, root
, chase_flags
, ret_path
? &p
: NULL
, &path_fd
);
1185 assert(path_fd
>= 0);
1187 r
= fd_reopen(path_fd
, open_flags
);
1192 *ret_path
= TAKE_PTR(p
);
1197 int chase_symlinks_and_opendir(
1200 unsigned chase_flags
,
1204 char procfs_path
[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
1205 _cleanup_close_
int path_fd
= -1;
1206 _cleanup_free_
char *p
= NULL
;
1212 if (chase_flags
& CHASE_NONEXISTENT
)
1215 if (empty_or_root(root
) && !ret_path
&& (chase_flags
& (CHASE_NO_AUTOFS
|CHASE_SAFE
)) == 0) {
1216 /* Shortcut this call if none of the special features of this call are requested */
1225 r
= chase_symlinks(path
, root
, chase_flags
, ret_path
? &p
: NULL
, &path_fd
);
1228 assert(path_fd
>= 0);
1230 xsprintf(procfs_path
, "/proc/self/fd/%i", path_fd
);
1231 d
= opendir(procfs_path
);
1236 *ret_path
= TAKE_PTR(p
);
1242 int chase_symlinks_and_stat(
1245 unsigned chase_flags
,
1247 struct stat
*ret_stat
,
1250 _cleanup_close_
int path_fd
= -1;
1251 _cleanup_free_
char *p
= NULL
;
1257 if (chase_flags
& CHASE_NONEXISTENT
)
1260 if (empty_or_root(root
) && !ret_path
&& (chase_flags
& (CHASE_NO_AUTOFS
|CHASE_SAFE
)) == 0) {
1261 /* Shortcut this call if none of the special features of this call are requested */
1262 if (stat(path
, ret_stat
) < 0)
1268 r
= chase_symlinks(path
, root
, chase_flags
, ret_path
? &p
: NULL
, &path_fd
);
1271 assert(path_fd
>= 0);
1273 if (fstat(path_fd
, ret_stat
) < 0)
1277 *ret_path
= TAKE_PTR(p
);
1279 *ret_fd
= TAKE_FD(path_fd
);
1284 int access_fd(int fd
, int mode
) {
1285 char p
[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(fd
) + 1];
1288 /* Like access() but operates on an already open fd */
1290 xsprintf(p
, "/proc/self/fd/%i", fd
);
1291 r
= access(p
, mode
);
1298 void unlink_tempfilep(char (*p
)[]) {
1299 /* If the file is created with mkstemp(), it will (almost always)
1300 * change the suffix. Treat this as a sign that the file was
1301 * successfully created. We ignore both the rare case where the
1302 * original suffix is used and unlink failures. */
1303 if (!endswith(*p
, ".XXXXXX"))
1304 (void) unlink_noerrno(*p
);
1307 int unlinkat_deallocate(int fd
, const char *name
, UnlinkDeallocateFlags flags
) {
1308 _cleanup_close_
int truncate_fd
= -1;
1312 assert((flags
& ~(UNLINK_REMOVEDIR
|UNLINK_ERASE
)) == 0);
1314 /* Operates like unlinkat() but also deallocates the file contents if it is a regular file and there's no other
1315 * link to it. This is useful to ensure that other processes that might have the file open for reading won't be
1316 * able to keep the data pinned on disk forever. This call is particular useful whenever we execute clean-up
1317 * jobs ("vacuuming"), where we want to make sure the data is really gone and the disk space released and
1318 * returned to the free pool.
1320 * Deallocation is preferably done by FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE (👊) if supported, which means
1321 * the file won't change size. That's a good thing since we shouldn't needlessly trigger SIGBUS in other
1322 * programs that have mmap()ed the file. (The assumption here is that changing file contents to all zeroes
1323 * underneath those programs is the better choice than simply triggering SIGBUS in them which truncation does.)
1324 * However if hole punching is not implemented in the kernel or file system we'll fall back to normal file
1325 * truncation (🔪), as our goal of deallocating the data space trumps our goal of being nice to readers (💐).
1327 * Note that we attempt deallocation, but failure to succeed with that is not considered fatal, as long as the
1328 * primary job – to delete the file – is accomplished. */
1330 if (!FLAGS_SET(flags
, UNLINK_REMOVEDIR
)) {
1331 truncate_fd
= openat(fd
, name
, O_WRONLY
|O_CLOEXEC
|O_NOCTTY
|O_NOFOLLOW
|O_NONBLOCK
);
1332 if (truncate_fd
< 0) {
1334 /* If this failed because the file doesn't exist propagate the error right-away. Also,
1335 * AT_REMOVEDIR wasn't set, and we tried to open the file for writing, which means EISDIR is
1336 * returned when this is a directory but we are not supposed to delete those, hence propagate
1337 * the error right-away too. */
1338 if (IN_SET(errno
, ENOENT
, EISDIR
))
1341 if (errno
!= ELOOP
) /* don't complain if this is a symlink */
1342 log_debug_errno(errno
, "Failed to open file '%s' for deallocation, ignoring: %m", name
);
1346 if (unlinkat(fd
, name
, FLAGS_SET(flags
, UNLINK_REMOVEDIR
) ? AT_REMOVEDIR
: 0) < 0)
1349 if (truncate_fd
< 0) /* Don't have a file handle, can't do more ☹️ */
1352 if (fstat(truncate_fd
, &st
) < 0) {
1353 log_debug_errno(errno
, "Failed to stat file '%s' for deallocation, ignoring: %m", name
);
1357 if (!S_ISREG(st
.st_mode
))
1360 if (FLAGS_SET(flags
, UNLINK_ERASE
) && st
.st_size
> 0 && st
.st_nlink
== 0) {
1361 uint64_t left
= st
.st_size
;
1362 char buffer
[64 * 1024];
1364 /* If erasing is requested, let's overwrite the file with random data once before deleting
1365 * it. This isn't going to give you shred(1) semantics, but hopefully should be good enough
1366 * for stuff backed by tmpfs at least.
1368 * Note that we only erase like this if the link count of the file is zero. If it is higher it
1369 * is still linked by someone else and we'll leave it to them to remove it securely
1372 random_bytes(buffer
, sizeof(buffer
));
1377 n
= write(truncate_fd
, buffer
, MIN(sizeof(buffer
), left
));
1379 log_debug_errno(errno
, "Failed to erase data in file '%s', ignoring.", name
);
1383 assert(left
>= (size_t) n
);
1387 /* Let's refresh metadata */
1388 if (fstat(truncate_fd
, &st
) < 0) {
1389 log_debug_errno(errno
, "Failed to stat file '%s' for deallocation, ignoring: %m", name
);
1394 /* Don't dallocate if there's nothing to deallocate or if the file is linked elsewhere */
1395 if (st
.st_blocks
== 0 || st
.st_nlink
> 0)
1398 /* If this is a regular file, it actually took up space on disk and there are no other links it's time to
1399 * punch-hole/truncate this to release the disk space. */
1401 bs
= MAX(st
.st_blksize
, 512);
1402 l
= DIV_ROUND_UP(st
.st_size
, bs
) * bs
; /* Round up to next block size */
1404 if (fallocate(truncate_fd
, FALLOC_FL_PUNCH_HOLE
|FALLOC_FL_KEEP_SIZE
, 0, l
) >= 0)
1405 return 0; /* Successfully punched a hole! 😊 */
1407 /* Fall back to truncation */
1408 if (ftruncate(truncate_fd
, 0) < 0) {
1409 log_debug_errno(errno
, "Failed to truncate file to 0, ignoring: %m");
1416 int fsync_directory_of_file(int fd
) {
1417 _cleanup_free_
char *path
= NULL
;
1418 _cleanup_close_
int dfd
= -1;
1421 r
= fd_verify_regular(fd
);
1425 r
= fd_get_path(fd
, &path
);
1427 log_debug_errno(r
, "Failed to query /proc/self/fd/%d%s: %m",
1429 r
== -EOPNOTSUPP
? ", ignoring" : "");
1431 if (r
== -EOPNOTSUPP
)
1432 /* If /proc is not available, we're most likely running in some
1433 * chroot environment, and syncing the directory is not very
1434 * important in that case. Let's just silently do nothing. */
1440 if (!path_is_absolute(path
))
1443 dfd
= open_parent(path
, O_CLOEXEC
, 0);
1453 int fsync_full(int fd
) {
1456 /* Sync both the file and the directory */
1458 r
= fsync(fd
) < 0 ? -errno
: 0;
1459 q
= fsync_directory_of_file(fd
);
1461 return r
< 0 ? r
: q
;
1464 int fsync_path_at(int at_fd
, const char *path
) {
1465 _cleanup_close_
int opened_fd
= -1;
1468 if (isempty(path
)) {
1469 if (at_fd
== AT_FDCWD
) {
1470 opened_fd
= open(".", O_RDONLY
|O_DIRECTORY
|O_CLOEXEC
);
1479 opened_fd
= openat(at_fd
, path
, O_RDONLY
|O_CLOEXEC
);
1492 int syncfs_path(int atfd
, const char *path
) {
1493 _cleanup_close_
int fd
= -1;
1497 fd
= openat(atfd
, path
, O_CLOEXEC
|O_RDONLY
|O_NONBLOCK
);
1507 int open_parent(const char *path
, int flags
, mode_t mode
) {
1508 _cleanup_free_
char *parent
= NULL
;
1513 if (path_equal(path
, "/")) /* requesting the parent of the root dir is fishy, let's prohibit that */
1516 parent
= dirname_malloc(path
);
1520 /* Let's insist on O_DIRECTORY since the parent of a file or directory is a directory. Except if we open an
1521 * O_TMPFILE file, because in that case we are actually create a regular file below the parent directory. */
1523 if (FLAGS_SET(flags
, O_PATH
))
1524 flags
|= O_DIRECTORY
;
1525 else if (!FLAGS_SET(flags
, O_TMPFILE
))
1526 flags
|= O_DIRECTORY
|O_RDONLY
;
1528 fd
= open(parent
, flags
, mode
);
1535 static int blockdev_is_encrypted(const char *sysfs_path
, unsigned depth_left
) {
1536 _cleanup_free_
char *p
= NULL
, *uuids
= NULL
;
1537 _cleanup_closedir_
DIR *d
= NULL
;
1538 int r
, found_encrypted
= false;
1542 if (depth_left
== 0)
1545 p
= path_join(sysfs_path
, "dm/uuid");
1549 r
= read_one_line_file(p
, &uuids
);
1554 /* The DM device's uuid attribute is prefixed with "CRYPT-" if this is a dm-crypt device. */
1555 if (startswith(uuids
, "CRYPT-"))
1559 /* Not a dm-crypt device itself. But maybe it is on top of one? Follow the links in the "slaves/"
1563 p
= path_join(sysfs_path
, "slaves");
1569 if (errno
== ENOENT
) /* Doesn't have slaves */
1576 _cleanup_free_
char *q
= NULL
;
1580 de
= readdir_no_dot(d
);
1585 break; /* No more slaves */
1588 q
= path_join(p
, de
->d_name
);
1592 r
= blockdev_is_encrypted(q
, depth_left
- 1);
1595 if (r
== 0) /* we found one that is not encrypted? then propagate that immediately */
1598 found_encrypted
= true;
1601 return found_encrypted
;
1604 int path_is_encrypted(const char *path
) {
1605 char p
[SYS_BLOCK_PATH_MAX(NULL
)];
1609 r
= get_block_device(path
, &devt
);
1612 if (r
== 0) /* doesn't have a block device */
1615 xsprintf_sys_block_path(p
, NULL
, devt
);
1617 return blockdev_is_encrypted(p
, 10 /* safety net: maximum recursion depth */);