1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2010 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
27 #include <linux/magic.h>
31 #include "alloc-util.h"
32 #include "dirent-util.h"
38 //#include "missing.h"
40 #include "parse-util.h"
41 #include "path-util.h"
42 //#include "process-util.h"
43 #include "stat-util.h"
44 #include "stdio-util.h"
45 #include "string-util.h"
47 //#include "time-util.h"
48 #include "user-util.h"
51 /// Additional includes needed by elogind
52 #include "process-util.h"
54 int unlink_noerrno(const char *path) {
65 #if 0 /// UNNEEDED by elogind
66 int rmdir_parents(const char *path, const char *stop) {
75 /* Skip trailing slashes */
76 while (l > 0 && path[l-1] == '/')
82 /* Skip last component */
83 while (l > 0 && path[l-1] != '/')
86 /* Skip trailing slashes */
87 while (l > 0 && path[l-1] == '/')
97 if (path_startswith(stop, t)) {
113 int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
117 ret = renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE);
121 /* renameat2() exists since Linux 3.15, btrfs added support for it later.
122 * If it is not implemented, fallback to another method. */
123 if (!IN_SET(errno, EINVAL, ENOSYS))
126 /* The link()/unlink() fallback does not work on directories. But
127 * renameat() without RENAME_NOREPLACE gives the same semantics on
128 * directories, except when newpath is an *empty* directory. This is
130 ret = fstatat(olddirfd, oldpath, &buf, AT_SYMLINK_NOFOLLOW);
131 if (ret >= 0 && S_ISDIR(buf.st_mode)) {
132 ret = renameat(olddirfd, oldpath, newdirfd, newpath);
133 return ret >= 0 ? 0 : -errno;
136 /* If it is not a directory, use the link()/unlink() fallback. */
137 ret = linkat(olddirfd, oldpath, newdirfd, newpath, 0);
141 ret = unlinkat(olddirfd, oldpath, 0);
143 /* backup errno before the following unlinkat() alters it */
145 (void) unlinkat(newdirfd, newpath, 0);
154 int readlinkat_malloc(int fd, const char *p, char **ret) {
169 n = readlinkat(fd, p, c, l-1);
176 if ((size_t) n < l-1) {
187 int readlink_malloc(const char *p, char **ret) {
188 return readlinkat_malloc(AT_FDCWD, p, ret);
191 #if 0 /// UNNEEDED by elogind
192 int readlink_value(const char *p, char **ret) {
193 _cleanup_free_ char *link = NULL;
197 r = readlink_malloc(p, &link);
201 value = basename(link);
205 value = strdup(value);
215 int readlink_and_make_absolute(const char *p, char **r) {
216 _cleanup_free_ char *target = NULL;
223 j = readlink_malloc(p, &target);
227 k = file_in_same_dir(p, target);
235 #if 0 /// UNNEEDED by elogind
237 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
240 /* Under the assumption that we are running privileged we
241 * first change the access mode and only then hand out
242 * ownership to avoid a window where access is too open. */
244 if (mode != MODE_INVALID)
245 if (chmod(path, mode) < 0)
248 if (uid != UID_INVALID || gid != GID_INVALID)
249 if (chown(path, uid, gid) < 0)
255 int fchmod_umask(int fd, mode_t m) {
260 r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
266 int fd_warn_permissions(const char *path, int fd) {
269 if (fstat(fd, &st) < 0)
272 if (st.st_mode & 0111)
273 log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
275 if (st.st_mode & 0002)
276 log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
278 if (getpid_cached() == 1 && (st.st_mode & 0044) != 0044)
279 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);
284 int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
285 char fdpath[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
286 _cleanup_close_ int fd = -1;
291 /* Note that touch_file() does not follow symlinks: if invoked on an existing symlink, then it is the symlink
292 * itself which is updated, not its target
294 * Returns the first error we encounter, but tries to apply as much as possible. */
297 (void) mkdir_parents(path, 0755);
299 /* Initially, we try to open the node with O_PATH, so that we get a reference to the node. This is useful in
300 * case the path refers to an existing device or socket node, as we can open it successfully in all cases, and
301 * won't trigger any driver magic or so. */
302 fd = open(path, O_PATH|O_CLOEXEC|O_NOFOLLOW);
307 /* if the node doesn't exist yet, we create it, but with O_EXCL, so that we only create a regular file
308 * here, and nothing else */
309 fd = open(path, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, IN_SET(mode, 0, MODE_INVALID) ? 0644 : mode);
314 /* Let's make a path from the fd, and operate on that. With this logic, we can adjust the access mode,
315 * ownership and time of the file node in all cases, even if the fd refers to an O_PATH object â which is
316 * something fchown(), fchmod(), futimensat() don't allow. */
317 xsprintf(fdpath, "/proc/self/fd/%i", fd);
319 if (mode != MODE_INVALID)
320 if (chmod(fdpath, mode) < 0)
323 if (uid_is_valid(uid) || gid_is_valid(gid))
324 if (chown(fdpath, uid, gid) < 0 && ret >= 0)
327 if (stamp != USEC_INFINITY) {
328 struct timespec ts[2];
330 timespec_store(&ts[0], stamp);
332 r = utimensat(AT_FDCWD, fdpath, ts, 0);
334 r = utimensat(AT_FDCWD, fdpath, NULL, 0);
335 if (r < 0 && ret >= 0)
341 int touch(const char *path) {
342 return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, MODE_INVALID);
345 #if 0 /// UNNEEDED by elogind
346 int symlink_idempotent(const char *from, const char *to) {
352 if (symlink(from, to) < 0) {
353 _cleanup_free_ char *p = NULL;
358 r = readlink_malloc(to, &p);
359 if (r == -EINVAL) /* Not a symlink? In that case return the original error we encountered: -EEXIST */
361 if (r < 0) /* Any other error? In that case propagate it as is */
364 if (!streq(p, from)) /* Not the symlink we want it to be? In that case, propagate the original -EEXIST */
371 int symlink_atomic(const char *from, const char *to) {
372 _cleanup_free_ char *t = NULL;
378 r = tempfn_random(to, NULL, &t);
382 if (symlink(from, t) < 0)
385 if (rename(t, to) < 0) {
393 int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
394 _cleanup_free_ char *t = NULL;
399 r = tempfn_random(path, NULL, &t);
403 if (mknod(t, mode, dev) < 0)
406 if (rename(t, path) < 0) {
414 int mkfifo_atomic(const char *path, mode_t mode) {
415 _cleanup_free_ char *t = NULL;
420 r = tempfn_random(path, NULL, &t);
424 if (mkfifo(t, mode) < 0)
427 if (rename(t, path) < 0) {
436 int get_files_in_directory(const char *path, char ***list) {
437 _cleanup_closedir_ DIR *d = NULL;
439 size_t bufsize = 0, n = 0;
440 _cleanup_strv_free_ char **l = NULL;
444 /* Returns all files in a directory in *list, and the number
445 * of files as return value. If list is NULL returns only the
452 FOREACH_DIRENT_ALL(de, d, return -errno) {
453 dirent_ensure_type(d, de);
455 if (!dirent_is_file(de))
459 /* one extra slot is needed for the terminating NULL */
460 if (!GREEDY_REALLOC(l, bufsize, n + 2))
463 l[n] = strdup(de->d_name);
478 static int getenv_tmp_dir(const char **ret_path) {
484 /* We use the same order of environment variables python uses in tempfile.gettempdir():
485 * https://docs.python.org/3/library/tempfile.html#tempfile.gettempdir */
486 FOREACH_STRING(n, "TMPDIR", "TEMP", "TMP") {
489 e = secure_getenv(n);
492 if (!path_is_absolute(e)) {
496 if (!path_is_normalized(e)) {
513 /* Remember first error, to make this more debuggable */
525 static int tmp_dir_internal(const char *def, const char **ret) {
532 r = getenv_tmp_dir(&e);
538 k = is_dir(def, true);
542 return r < 0 ? r : k;
548 #if 0 /// UNNEEDED by elogind
549 int var_tmp_dir(const char **ret) {
551 /* Returns the location for "larger" temporary files, that is backed by physical storage if available, and thus
552 * even might survive a boot: /var/tmp. If $TMPDIR (or related environment variables) are set, its value is
553 * returned preferably however. Note that both this function and tmp_dir() below are affected by $TMPDIR,
554 * making it a variable that overrides all temporary file storage locations. */
556 return tmp_dir_internal("/var/tmp", ret);
560 int tmp_dir(const char **ret) {
562 /* Similar to var_tmp_dir() above, but returns the location for "smaller" temporary files, which is usually
563 * backed by an in-memory file system: /tmp. */
565 return tmp_dir_internal("/tmp", ret);
568 int unlink_or_warn(const char *filename) {
569 if (unlink(filename) < 0 && errno != ENOENT)
570 /* If the file doesn't exist and the fs simply was read-only (in which
571 * case unlink() returns EROFS even if the file doesn't exist), don't
573 if (errno != EROFS || access(filename, F_OK) >= 0)
574 return log_error_errno(errno, "Failed to remove \"%s\": %m", filename);
579 #if 0 /// UNNEEDED by elogind
580 int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
581 char path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
584 /* This is like inotify_add_watch(), except that the file to watch is not referenced by a path, but by an fd */
585 xsprintf(path, "/proc/self/fd/%i", what);
587 r = inotify_add_watch(fd, path, mask);
595 static bool noop_root(const char *root) {
596 return isempty(root) || path_equal(root, "/");
599 static bool safe_transition(const struct stat *a, const struct stat *b) {
600 /* Returns true if the transition from a to b is safe, i.e. that we never transition from unprivileged to
601 * privileged files or directories. Why bother? So that unprivileged code can't symlink to privileged files
602 * making us believe we read something safe even though it isn't safe in the specific context we open it in. */
604 if (a->st_uid == 0) /* Transitioning from privileged to unprivileged is always fine */
607 return a->st_uid == b->st_uid; /* Otherwise we need to stay within the same UID */
610 int chase_symlinks(const char *path, const char *original_root, unsigned flags, char **ret) {
611 _cleanup_free_ char *buffer = NULL, *done = NULL, *root = NULL;
612 _cleanup_close_ int fd = -1;
613 unsigned max_follow = 32; /* how many symlinks to follow before giving up and returning ELOOP */
614 struct stat previous_stat;
621 /* Either the file may be missing, or we return an fd to the final object, but both make no sense */
622 if ((flags & (CHASE_NONEXISTENT|CHASE_OPEN)) == (CHASE_NONEXISTENT|CHASE_OPEN))
628 /* This is a lot like canonicalize_file_name(), but takes an additional "root" parameter, that allows following
629 * symlinks relative to a root directory, instead of the root of the host.
631 * Note that "root" primarily matters if we encounter an absolute symlink. It is also used when following
632 * relative symlinks to ensure they cannot be used to "escape" the root directory. The path parameter passed is
633 * assumed to be already prefixed by it, except if the CHASE_PREFIX_ROOT flag is set, in which case it is first
634 * prefixed accordingly.
636 * Algorithmically this operates on two path buffers: "done" are the components of the path we already
637 * processed and resolved symlinks, "." and ".." of. "todo" are the components of the path we still need to
638 * process. On each iteration, we move one component from "todo" to "done", processing it's special meaning
639 * each time. The "todo" path always starts with at least one slash, the "done" path always ends in no
640 * slash. We always keep an O_PATH fd to the component we are currently processing, thus keeping lookup races
643 * Suggested usage: whenever you want to canonicalize a path, use this function. Pass the absolute path you got
644 * as-is: fully qualified and relative to your host's root. Optionally, specify the root parameter to tell this
645 * function what to do when encountering a symlink with an absolute path as directory: prefix it by the
648 /* A root directory of "/" or "" is identical to none */
649 if (noop_root(original_root))
650 original_root = NULL;
653 r = path_make_absolute_cwd(original_root, &root);
657 if (flags & CHASE_PREFIX_ROOT) {
659 /* We don't support relative paths in combination with a root directory */
660 if (!path_is_absolute(path))
663 path = prefix_roota(root, path);
667 r = path_make_absolute_cwd(path, &buffer);
671 fd = open("/", O_CLOEXEC|O_NOFOLLOW|O_PATH);
675 if (flags & CHASE_SAFE) {
676 if (fstat(fd, &previous_stat) < 0)
682 _cleanup_free_ char *first = NULL;
683 _cleanup_close_ int child = -1;
687 /* Determine length of first component in the path */
688 n = strspn(todo, "/"); /* The slashes */
689 m = n + strcspn(todo + n, "/"); /* The entire length of the component */
691 /* Extract the first component. */
692 first = strndup(todo, m);
698 /* Empty? Then we reached the end. */
702 /* Just a single slash? Then we reached the end. */
703 if (path_equal(first, "/")) {
704 /* Preserve the trailing slash */
706 if (flags & CHASE_TRAIL_SLASH)
707 if (!strextend(&done, "/", NULL))
713 /* Just a dot? Then let's eat this up. */
714 if (path_equal(first, "/."))
717 /* Two dots? Then chop off the last bit of what we already found out. */
718 if (path_equal(first, "/..")) {
719 _cleanup_free_ char *parent = NULL;
720 _cleanup_close_ int fd_parent = -1;
722 /* If we already are at the top, then going up will not change anything. This is in-line with
723 * how the kernel handles this. */
724 if (isempty(done) || path_equal(done, "/"))
727 parent = dirname_malloc(done);
731 /* Don't allow this to leave the root dir. */
733 path_startswith(done, root) &&
734 !path_startswith(parent, root))
737 free_and_replace(done, parent);
739 fd_parent = openat(fd, "..", O_CLOEXEC|O_NOFOLLOW|O_PATH);
743 if (flags & CHASE_SAFE) {
744 if (fstat(fd_parent, &st) < 0)
747 if (!safe_transition(&previous_stat, &st))
754 fd = TAKE_FD(fd_parent);
759 /* Otherwise let's see what this is. */
760 child = openat(fd, first + n, O_CLOEXEC|O_NOFOLLOW|O_PATH);
763 if (errno == ENOENT &&
764 (flags & CHASE_NONEXISTENT) &&
765 (isempty(todo) || path_is_normalized(todo))) {
767 /* If CHASE_NONEXISTENT is set, and the path does not exist, then that's OK, return
768 * what we got so far. But don't allow this if the remaining path contains "../ or "./"
769 * or something else weird. */
771 /* If done is "/", as first also contains slash at the head, then remove this redundant slash. */
772 if (streq_ptr(done, "/"))
775 if (!strextend(&done, first, todo, NULL))
785 if (fstat(child, &st) < 0)
787 if ((flags & CHASE_SAFE) &&
788 !safe_transition(&previous_stat, &st))
793 if ((flags & CHASE_NO_AUTOFS) &&
794 fd_is_fs_type(child, AUTOFS_SUPER_MAGIC) > 0)
797 if (S_ISLNK(st.st_mode)) {
800 _cleanup_free_ char *destination = NULL;
802 /* This is a symlink, in this case read the destination. But let's make sure we don't follow
803 * symlinks without bounds. */
804 if (--max_follow <= 0)
807 r = readlinkat_malloc(fd, first + n, &destination);
810 if (isempty(destination))
813 if (path_is_absolute(destination)) {
815 /* An absolute destination. Start the loop from the beginning, but use the root
816 * directory as base. */
819 fd = open(root ?: "/", O_CLOEXEC|O_NOFOLLOW|O_PATH);
823 if (flags & CHASE_SAFE) {
824 if (fstat(fd, &st) < 0)
827 if (!safe_transition(&previous_stat, &st))
835 /* Note that we do not revalidate the root, we take it as is. */
844 /* Prefix what's left to do with what we just read, and start the loop again, but
845 * remain in the current directory. */
846 joined = strjoin(destination, todo);
848 joined = strjoin("/", destination, todo);
853 todo = buffer = joined;
858 /* If this is not a symlink, then let's just add the name we read to what we already verified. */
860 done = TAKE_PTR(first);
862 /* If done is "/", as first also contains slash at the head, then remove this redundant slash. */
863 if (streq(done, "/"))
866 if (!strextend(&done, first, NULL))
870 /* And iterate again, but go one directory further down. */
876 /* Special case, turn the empty string into "/", to indicate the root directory. */
883 *ret = TAKE_PTR(done);
885 if (flags & CHASE_OPEN) {
886 /* Return the O_PATH fd we currently are looking to the caller. It can translate it to a proper fd by
887 * opening /proc/self/fd/xyz. */
896 int chase_symlinks_and_open(
899 unsigned chase_flags,
903 _cleanup_close_ int path_fd = -1;
904 _cleanup_free_ char *p = NULL;
907 if (chase_flags & CHASE_NONEXISTENT)
910 if (noop_root(root) && !ret_path && (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE)) == 0) {
911 /* Shortcut this call if none of the special features of this call are requested */
912 r = open(path, open_flags);
919 path_fd = chase_symlinks(path, root, chase_flags|CHASE_OPEN, ret_path ? &p : NULL);
923 r = fd_reopen(path_fd, open_flags);
928 *ret_path = TAKE_PTR(p);
933 int chase_symlinks_and_opendir(
936 unsigned chase_flags,
940 char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
941 _cleanup_close_ int path_fd = -1;
942 _cleanup_free_ char *p = NULL;
947 if (chase_flags & CHASE_NONEXISTENT)
950 if (noop_root(root) && !ret_path && (chase_flags & (CHASE_NO_AUTOFS|CHASE_SAFE)) == 0) {
951 /* Shortcut this call if none of the special features of this call are requested */
960 path_fd = chase_symlinks(path, root, chase_flags|CHASE_OPEN, ret_path ? &p : NULL);
964 xsprintf(procfs_path, "/proc/self/fd/%i", path_fd);
965 d = opendir(procfs_path);
970 *ret_path = TAKE_PTR(p);
976 int access_fd(int fd, int mode) {
977 char p[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1];
980 /* Like access() but operates on an already open fd */
982 xsprintf(p, "/proc/self/fd/%i", fd);
990 int unlinkat_deallocate(int fd, const char *name, int flags) {
991 _cleanup_close_ int truncate_fd = -1;
995 /* Operates like unlinkat() but also deallocates the file contents if it is a regular file and there's no other
996 * link to it. This is useful to ensure that other processes that might have the file open for reading won't be
997 * able to keep the data pinned on disk forever. This call is particular useful whenever we execute clean-up
998 * jobs ("vacuuming"), where we want to make sure the data is really gone and the disk space released and
999 * returned to the free pool.
1001 * Deallocation is preferably done by FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE (đ) if supported, which means
1002 * the file won't change size. That's a good thing since we shouldn't needlessly trigger SIGBUS in other
1003 * programs that have mmap()ed the file. (The assumption here is that changing file contents to all zeroes
1004 * underneath those programs is the better choice than simply triggering SIGBUS in them which truncation does.)
1005 * However if hole punching is not implemented in the kernel or file system we'll fall back to normal file
1006 * truncation (đĒ), as our goal of deallocating the data space trumps our goal of being nice to readers (đ).
1008 * Note that we attempt deallocation, but failure to succeed with that is not considered fatal, as long as the
1009 * primary job â to delete the file â is accomplished. */
1011 if ((flags & AT_REMOVEDIR) == 0) {
1012 truncate_fd = openat(fd, name, O_WRONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW|O_NONBLOCK);
1013 if (truncate_fd < 0) {
1015 /* If this failed because the file doesn't exist propagate the error right-away. Also,
1016 * AT_REMOVEDIR wasn't set, and we tried to open the file for writing, which means EISDIR is
1017 * returned when this is a directory but we are not supposed to delete those, hence propagate
1018 * the error right-away too. */
1019 if (IN_SET(errno, ENOENT, EISDIR))
1022 if (errno != ELOOP) /* don't complain if this is a symlink */
1023 log_debug_errno(errno, "Failed to open file '%s' for deallocation, ignoring: %m", name);
1027 if (unlinkat(fd, name, flags) < 0)
1030 if (truncate_fd < 0) /* Don't have a file handle, can't do more âšī¸ */
1033 if (fstat(truncate_fd, &st) < 0) {
1034 log_debug_errno(errno, "Failed to stat file '%s' for deallocation, ignoring.", name);
1038 if (!S_ISREG(st.st_mode) || st.st_blocks == 0 || st.st_nlink > 0)
1041 /* If this is a regular file, it actually took up space on disk and there are no other links it's time to
1042 * punch-hole/truncate this to release the disk space. */
1044 bs = MAX(st.st_blksize, 512);
1045 l = DIV_ROUND_UP(st.st_size, bs) * bs; /* Round up to next block size */
1047 if (fallocate(truncate_fd, FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE, 0, l) >= 0)
1048 return 0; /* Successfully punched a hole! đ */
1050 /* Fall back to truncation */
1051 if (ftruncate(truncate_fd, 0) < 0) {
1052 log_debug_errno(errno, "Failed to truncate file to 0, ignoring: %m");
1059 int fsync_directory_of_file(int fd) {
1060 _cleanup_free_ char *path = NULL, *dn = NULL;
1061 _cleanup_close_ int dfd = -1;
1064 r = fd_verify_regular(fd);
1068 r = fd_get_path(fd, &path);
1070 log_debug("Failed to query /proc/self/fd/%d%s: %m",
1072 r == -EOPNOTSUPP ? ", ignoring" : "");
1074 if (r == -EOPNOTSUPP)
1075 /* If /proc is not available, we're most likely running in some
1076 * chroot environment, and syncing the directory is not very
1077 * important in that case. Let's just silently do nothing. */
1083 if (!path_is_absolute(path))
1086 dn = dirname_malloc(path);
1090 dfd = open(dn, O_RDONLY|O_CLOEXEC|O_DIRECTORY);