]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/fs-util.c
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 "stat-util.h"
27 #include "stdio-util.h"
28 #include "string-util.h"
30 #include "time-util.h"
31 #include "tmpfile-util.h"
32 #include "user-util.h"
35 int unlink_noerrno ( const char * path
) {
46 int rmdir_parents ( const char * path
, const char * stop
) {
55 /* Skip trailing slashes */
56 while ( l
> 0 && path
[ l
- 1 ] == '/' )
62 /* Skip last component */
63 while ( l
> 0 && path
[ l
- 1 ] != '/' )
66 /* Skip trailing slashes */
67 while ( l
> 0 && path
[ l
- 1 ] == '/' )
77 if ( path_startswith ( stop
, t
)) {
93 int rename_noreplace ( int olddirfd
, const char * oldpath
, int newdirfd
, const char * newpath
) {
96 /* Try the ideal approach first */
97 if ( renameat2 ( olddirfd
, oldpath
, newdirfd
, newpath
, RENAME_NOREPLACE
) >= 0 )
100 /* renameat2() exists since Linux 3.15, btrfs and FAT added support for it later. If it is not implemented,
101 * fall back to a different method. */
102 if (! IN_SET ( errno
, EINVAL
, ENOSYS
, ENOTTY
))
105 /* Let's try to use linkat()+unlinkat() as fallback. This doesn't work on directories and on some file systems
106 * that do not support hard links (such as FAT, most prominently), but for files it's pretty close to what we
107 * want — though not atomic (i.e. for a short period both the new and the old filename will exist). */
108 if ( linkat ( olddirfd
, oldpath
, newdirfd
, newpath
, 0 ) >= 0 ) {
110 if ( unlinkat ( olddirfd
, oldpath
, 0 ) < 0 ) {
111 r
= - errno
; /* Backup errno before the following unlinkat() alters it */
112 ( void ) unlinkat ( newdirfd
, newpath
, 0 );
119 if (! IN_SET ( errno
, EINVAL
, ENOSYS
, ENOTTY
, EPERM
)) /* FAT returns EPERM on link()… */
122 /* OK, neither RENAME_NOREPLACE nor linkat()+unlinkat() worked. Let's then fallback to the racy TOCTOU
123 * vulnerable accessat(F_OK) check followed by classic, replacing renameat(), we have nothing better. */
125 if ( faccessat ( newdirfd
, newpath
, F_OK
, AT_SYMLINK_NOFOLLOW
) >= 0 )
130 if ( renameat ( olddirfd
, oldpath
, newdirfd
, newpath
) < 0 )
136 int readlinkat_malloc ( int fd
, const char * p
, char ** ret
) {
137 size_t l
= FILENAME_MAX
+ 1 ;
151 n
= readlinkat ( fd
, p
, c
, l
- 1 );
158 if (( size_t ) n
< l
- 1 ) {
169 int readlink_malloc ( const char * p
, char ** ret
) {
170 return readlinkat_malloc ( AT_FDCWD
, p
, ret
);
173 int readlink_value ( const char * p
, char ** ret
) {
174 _cleanup_free_
char * link
= NULL
;
178 r
= readlink_malloc ( p
, & link
);
182 value
= basename ( link
);
186 value
= strdup ( value
);
195 int readlink_and_make_absolute ( const char * p
, char ** r
) {
196 _cleanup_free_
char * target
= NULL
;
203 j
= readlink_malloc ( p
, & target
);
207 k
= file_in_same_dir ( p
, target
);
215 int chmod_and_chown ( const char * path
, mode_t mode
, uid_t uid
, gid_t gid
) {
216 _cleanup_close_
int fd
= - 1 ;
220 fd
= open ( path
, O_PATH
| O_CLOEXEC
| O_NOFOLLOW
); /* Let's acquire an O_PATH fd, as precaution to change
221 * mode/owner on the same file */
225 return fchmod_and_chown ( fd
, mode
, uid
, gid
);
228 int fchmod_and_chown ( int fd
, mode_t mode
, uid_t uid
, gid_t gid
) {
229 bool do_chown
, do_chmod
;
232 /* Change ownership and access mode of the specified fd. Tries to do so safely, ensuring that at no
233 * point in time the access mode is above the old access mode under the old ownership or the new
234 * access mode under the new ownership. Note: this call tries hard to leave the access mode
235 * unaffected if the uid/gid is changed, i.e. it undoes implicit suid/sgid dropping the kernel does
238 * This call is happy with O_PATH fds. */
240 if ( fstat ( fd
, & st
) < 0 )
244 ( uid
!= UID_INVALID
&& st
. st_uid
!= uid
) ||
245 ( gid
!= GID_INVALID
&& st
. st_gid
!= gid
);
248 ! S_ISLNK ( st
. st_mode
) && /* chmod is not defined on symlinks */
249 (( mode
!= MODE_INVALID
&& (( st
. st_mode
^ mode
) & 07777 ) != 0 ) ||
250 do_chown
); /* If we change ownership, make sure we reset the mode afterwards, since chown()
251 * modifies the access mode too */
253 if ( mode
== MODE_INVALID
)
254 mode
= st
. st_mode
; /* If we only shall do a chown(), save original mode, since chown() might break it. */
255 else if (( mode
& S_IFMT
) != 0 && (( mode
^ st
. st_mode
) & S_IFMT
) != 0 )
256 return - EINVAL
; /* insist on the right file type if it was specified */
258 if ( do_chown
&& do_chmod
) {
259 mode_t minimal
= st
. st_mode
& mode
; /* the subset of the old and the new mask */
261 if ((( minimal
^ st
. st_mode
) & 07777 ) != 0 )
262 if ( fchmod_opath ( fd
, minimal
& 07777 ) < 0 )
267 if ( fchownat ( fd
, "" , uid
, gid
, AT_EMPTY_PATH
) < 0 )
271 if ( fchmod_opath ( fd
, mode
& 07777 ) < 0 )
274 return do_chown
|| do_chmod
;
277 int chmod_and_chown_unsafe ( const char * path
, mode_t mode
, uid_t uid
, gid_t gid
) {
278 bool do_chown
, do_chmod
;
283 /* Change ownership and access mode of the specified path, see description of fchmod_and_chown().
284 * Should only be used on trusted paths. */
286 if ( lstat ( path
, & st
) < 0 )
290 ( uid
!= UID_INVALID
&& st
. st_uid
!= uid
) ||
291 ( gid
!= GID_INVALID
&& st
. st_gid
!= gid
);
294 ! S_ISLNK ( st
. st_mode
) && /* chmod is not defined on symlinks */
295 (( mode
!= MODE_INVALID
&& (( st
. st_mode
^ mode
) & 07777 ) != 0 ) ||
296 do_chown
); /* If we change ownership, make sure we reset the mode afterwards, since chown()
297 * modifies the access mode too */
299 if ( mode
== MODE_INVALID
)
300 mode
= st
. st_mode
; /* If we only shall do a chown(), save original mode, since chown() might break it. */
301 else if (( mode
& S_IFMT
) != 0 && (( mode
^ st
. st_mode
) & S_IFMT
) != 0 )
302 return - EINVAL
; /* insist on the right file type if it was specified */
304 if ( do_chown
&& do_chmod
) {
305 mode_t minimal
= st
. st_mode
& mode
; /* the subset of the old and the new mask */
307 if ((( minimal
^ st
. st_mode
) & 07777 ) != 0 )
308 if ( chmod ( path
, minimal
& 07777 ) < 0 )
313 if ( lchown ( path
, uid
, gid
) < 0 )
317 if ( chmod ( path
, mode
& 07777 ) < 0 )
320 return do_chown
|| do_chmod
;
323 int fchmod_umask ( int fd
, mode_t m
) {
328 r
= fchmod ( fd
, m
& (~ u
)) < 0 ? - errno
: 0 ;
334 int fchmod_opath ( int fd
, mode_t m
) {
335 char procfs_path
[ STRLEN ( "/proc/self/fd/" ) + DECIMAL_STR_MAX ( int )];
337 /* This function operates also on fd that might have been opened with
338 * O_PATH. Indeed fchmodat() doesn't have the AT_EMPTY_PATH flag like
339 * fchownat() does. */
341 xsprintf ( procfs_path
, "/proc/self/fd/%i" , fd
);
342 if ( chmod ( procfs_path
, m
) < 0 ) {
346 if ( proc_mounted () == 0 )
347 return - ENOSYS
; /* if we have no /proc/, the concept is not implementable */
355 int fd_warn_permissions ( const char * path
, int fd
) {
358 if ( fstat ( fd
, & st
) < 0 )
361 /* Don't complain if we are reading something that is not a file, for example /dev/null */
362 if (! S_ISREG ( st
. st_mode
))
365 if ( st
. st_mode
& 0111 )
366 log_warning ( "Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway." , path
);
368 if ( st
. st_mode
& 0002 )
369 log_warning ( "Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway." , path
);
371 if ( getpid_cached () == 1 && ( st
. st_mode
& 0044 ) != 0044 )
372 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
);
377 int touch_file ( const char * path
, bool parents
, usec_t stamp
, uid_t uid
, gid_t gid
, mode_t mode
) {
378 char fdpath
[ STRLEN ( "/proc/self/fd/" ) + DECIMAL_STR_MAX ( int )];
379 _cleanup_close_
int fd
= - 1 ;
384 /* Note that touch_file() does not follow symlinks: if invoked on an existing symlink, then it is the symlink
385 * itself which is updated, not its target
387 * Returns the first error we encounter, but tries to apply as much as possible. */
390 ( void ) mkdir_parents ( path
, 0755 );
392 /* Initially, we try to open the node with O_PATH, so that we get a reference to the node. This is useful in
393 * case the path refers to an existing device or socket node, as we can open it successfully in all cases, and
394 * won't trigger any driver magic or so. */
395 fd
= open ( path
, O_PATH
| O_CLOEXEC
| O_NOFOLLOW
);
400 /* if the node doesn't exist yet, we create it, but with O_EXCL, so that we only create a regular file
401 * here, and nothing else */
402 fd
= open ( path
, O_WRONLY
| O_CREAT
| O_EXCL
| O_CLOEXEC
, IN_SET ( mode
, 0 , MODE_INVALID
) ? 0644 : mode
);
407 /* Let's make a path from the fd, and operate on that. With this logic, we can adjust the access mode,
408 * ownership and time of the file node in all cases, even if the fd refers to an O_PATH object — which is
409 * something fchown(), fchmod(), futimensat() don't allow. */
410 xsprintf ( fdpath
, "/proc/self/fd/%i" , fd
);
412 ret
= fchmod_and_chown ( fd
, mode
, uid
, gid
);
414 if ( stamp
!= USEC_INFINITY
) {
415 struct timespec ts
[ 2 ];
417 timespec_store (& ts
[ 0 ], stamp
);
419 r
= utimensat ( AT_FDCWD
, fdpath
, ts
, 0 );
421 r
= utimensat ( AT_FDCWD
, fdpath
, NULL
, 0 );
422 if ( r
< 0 && ret
>= 0 )
428 int touch ( const char * path
) {
429 return touch_file ( path
, false , USEC_INFINITY
, UID_INVALID
, GID_INVALID
, MODE_INVALID
);
432 int symlink_idempotent ( const char * from
, const char * to
, bool make_relative
) {
433 _cleanup_free_
char * relpath
= NULL
;
440 _cleanup_free_
char * parent
= NULL
;
442 parent
= dirname_malloc ( to
);
446 r
= path_make_relative ( parent
, from
, & relpath
);
453 if ( symlink ( from
, to
) < 0 ) {
454 _cleanup_free_
char * p
= NULL
;
459 r
= readlink_malloc ( to
, & p
);
460 if ( r
== - EINVAL
) /* Not a symlink? In that case return the original error we encountered: -EEXIST */
462 if ( r
< 0 ) /* Any other error? In that case propagate it as is */
465 if (! streq ( p
, from
)) /* Not the symlink we want it to be? In that case, propagate the original -EEXIST */
472 int symlink_atomic ( const char * from
, const char * to
) {
473 _cleanup_free_
char * t
= NULL
;
479 r
= tempfn_random ( to
, NULL
, & t
);
483 if ( symlink ( from
, t
) < 0 )
486 if ( rename ( t
, to
) < 0 ) {
494 int mknod_atomic ( const char * path
, mode_t mode
, dev_t dev
) {
495 _cleanup_free_
char * t
= NULL
;
500 r
= tempfn_random ( path
, NULL
, & t
);
504 if ( mknod ( t
, mode
, dev
) < 0 )
507 if ( rename ( t
, path
) < 0 ) {
515 int mkfifo_atomic ( const char * path
, mode_t mode
) {
516 _cleanup_free_
char * t
= NULL
;
521 r
= tempfn_random ( path
, NULL
, & t
);
525 if ( mkfifo ( t
, mode
) < 0 )
528 if ( rename ( t
, path
) < 0 ) {
536 int mkfifoat_atomic ( int dirfd
, const char * path
, mode_t mode
) {
537 _cleanup_free_
char * t
= NULL
;
542 if ( path_is_absolute ( path
))
543 return mkfifo_atomic ( path
, mode
);
545 /* We're only interested in the (random) filename. */
546 r
= tempfn_random_child ( "" , NULL
, & t
);
550 if ( mkfifoat ( dirfd
, t
, mode
) < 0 )
553 if ( renameat ( dirfd
, t
, dirfd
, path
) < 0 ) {
561 int get_files_in_directory ( const char * path
, char *** list
) {
562 _cleanup_closedir_
DIR * d
= NULL
;
564 size_t bufsize
= 0 , n
= 0 ;
565 _cleanup_strv_free_
char ** l
= NULL
;
569 /* Returns all files in a directory in *list, and the number
570 * of files as return value. If list is NULL returns only the
577 FOREACH_DIRENT_ALL ( de
, d
, return - errno
) {
578 dirent_ensure_type ( d
, de
);
580 if (! dirent_is_file ( de
))
584 /* one extra slot is needed for the terminating NULL */
585 if (! GREEDY_REALLOC ( l
, bufsize
, n
+ 2 ))
588 l
[ n
] = strdup ( de
-> d_name
);
603 static int getenv_tmp_dir ( const char ** ret_path
) {
609 /* We use the same order of environment variables python uses in tempfile.gettempdir():
610 * https://docs.python.org/3/library/tempfile.html#tempfile.gettempdir */
611 FOREACH_STRING ( n
, "TMPDIR" , "TEMP" , "TMP" ) {
614 e
= secure_getenv ( n
);
617 if (! path_is_absolute ( e
)) {
621 if (! path_is_normalized ( e
)) {
638 /* Remember first error, to make this more debuggable */
650 static int tmp_dir_internal ( const char * def
, const char ** ret
) {
657 r
= getenv_tmp_dir (& e
);
663 k
= is_dir ( def
, true );
667 return r
< 0 ? r
: k
;
673 int var_tmp_dir ( const char ** ret
) {
675 /* Returns the location for "larger" temporary files, that is backed by physical storage if available, and thus
676 * even might survive a boot: /var/tmp. If $TMPDIR (or related environment variables) are set, its value is
677 * returned preferably however. Note that both this function and tmp_dir() below are affected by $TMPDIR,
678 * making it a variable that overrides all temporary file storage locations. */
680 return tmp_dir_internal ( "/var/tmp" , ret
);
683 int tmp_dir ( const char ** ret
) {
685 /* Similar to var_tmp_dir() above, but returns the location for "smaller" temporary files, which is usually
686 * backed by an in-memory file system: /tmp. */
688 return tmp_dir_internal ( "/tmp" , ret
);
691 int unlink_or_warn ( const char * filename
) {
692 if ( unlink ( filename
) < 0 && errno
!= ENOENT
)
693 /* If the file doesn't exist and the fs simply was read-only (in which
694 * case unlink() returns EROFS even if the file doesn't exist), don't
696 if ( errno
!= EROFS
|| access ( filename
, F_OK
) >= 0 )
697 return log_error_errno ( errno
, "Failed to remove \" %s \" : %m" , filename
);
702 int inotify_add_watch_fd ( int fd
, int what
, uint32_t mask
) {
703 char path
[ STRLEN ( "/proc/self/fd/" ) + DECIMAL_STR_MAX ( int ) + 1 ];
706 /* This is like inotify_add_watch(), except that the file to watch is not referenced by a path, but by an fd */
707 xsprintf ( path
, "/proc/self/fd/%i" , what
);
709 wd
= inotify_add_watch ( fd
, path
, mask
);
716 int inotify_add_watch_and_warn ( int fd
, const char * pathname
, uint32_t mask
) {
719 wd
= inotify_add_watch ( fd
, pathname
, mask
);
722 return log_error_errno ( errno
, "Failed to add a watch for %s: inotify watch limit reached" , pathname
);
724 return log_error_errno ( errno
, "Failed to add a watch for %s: %m" , pathname
);
730 static bool unsafe_transition ( const struct stat
* a
, const struct stat
* b
) {
731 /* Returns true if the transition from a to b is safe, i.e. that we never transition from unprivileged to
732 * privileged files or directories. Why bother? So that unprivileged code can't symlink to privileged files
733 * making us believe we read something safe even though it isn't safe in the specific context we open it in. */
735 if ( a
-> st_uid
== 0 ) /* Transitioning from privileged to unprivileged is always fine */
738 return a
-> st_uid
!= b
-> st_uid
; /* Otherwise we need to stay within the same UID */
741 static int log_unsafe_transition ( int a
, int b
, const char * path
, unsigned flags
) {
742 _cleanup_free_
char * n1
= NULL
, * n2
= NULL
;
744 if (! FLAGS_SET ( flags
, CHASE_WARN
))
747 ( void ) fd_get_path ( a
, & n1
);
748 ( void ) fd_get_path ( b
, & n2
);
750 return log_warning_errno ( SYNTHETIC_ERRNO ( ENOLINK
),
751 "Detected unsafe path transition %s %s %s during canonicalization of %s." ,
752 n1
, special_glyph ( SPECIAL_GLYPH_ARROW
), n2
, path
);
755 static int log_autofs_mount_point ( int fd
, const char * path
, unsigned flags
) {
756 _cleanup_free_
char * n1
= NULL
;
758 if (! FLAGS_SET ( flags
, CHASE_WARN
))
761 ( void ) fd_get_path ( fd
, & n1
);
763 return log_warning_errno ( SYNTHETIC_ERRNO ( EREMOTE
),
764 "Detected autofs mount point %s during canonicalization of %s." ,
768 int chase_symlinks ( const char * path
, const char * original_root
, unsigned flags
, char ** ret_path
, int * ret_fd
) {
769 _cleanup_free_
char * buffer
= NULL
, * done
= NULL
, * root
= NULL
;
770 _cleanup_close_
int fd
= - 1 ;
771 unsigned max_follow
= CHASE_SYMLINKS_MAX
; /* how many symlinks to follow before giving up and returning ELOOP */
772 struct stat previous_stat
;
779 /* Either the file may be missing, or we return an fd to the final object, but both make no sense */
780 if (( flags
& CHASE_NONEXISTENT
) && ret_fd
)
783 if (( flags
& CHASE_STEP
) && ret_fd
)
789 /* This is a lot like canonicalize_file_name(), but takes an additional "root" parameter, that allows following
790 * symlinks relative to a root directory, instead of the root of the host.
792 * Note that "root" primarily matters if we encounter an absolute symlink. It is also used when following
793 * relative symlinks to ensure they cannot be used to "escape" the root directory. The path parameter passed is
794 * assumed to be already prefixed by it, except if the CHASE_PREFIX_ROOT flag is set, in which case it is first
795 * prefixed accordingly.
797 * Algorithmically this operates on two path buffers: "done" are the components of the path we already
798 * processed and resolved symlinks, "." and ".." of. "todo" are the components of the path we still need to
799 * process. On each iteration, we move one component from "todo" to "done", processing it's special meaning
800 * each time. The "todo" path always starts with at least one slash, the "done" path always ends in no
801 * slash. We always keep an O_PATH fd to the component we are currently processing, thus keeping lookup races
804 * Suggested usage: whenever you want to canonicalize a path, use this function. Pass the absolute path you got
805 * as-is: fully qualified and relative to your host's root. Optionally, specify the root parameter to tell this
806 * function what to do when encountering a symlink with an absolute path as directory: prefix it by the
809 * There are five ways to invoke this function:
811 * 1. Without CHASE_STEP or ret_fd: in this case the path is resolved and the normalized path is
812 * returned in `ret_path`. The return value is < 0 on error. If CHASE_NONEXISTENT is also set, 0
813 * is returned if the file doesn't exist, > 0 otherwise. If CHASE_NONEXISTENT is not set, >= 0 is
814 * returned if the destination was found, -ENOENT if it wasn't.
816 * 2. With ret_fd: in this case the destination is opened after chasing it as O_PATH and this file
817 * descriptor is returned as return value. This is useful to open files relative to some root
818 * directory. Note that the returned O_PATH file descriptors must be converted into a regular one (using
819 * fd_reopen() or such) before it can be used for reading/writing. ret_fd may not be combined with
822 * 3. With CHASE_STEP: in this case only a single step of the normalization is executed, i.e. only the first
823 * symlink or ".." component of the path is resolved, and the resulting path is returned. This is useful if
824 * a caller wants to trace the a path through the file system verbosely. Returns < 0 on error, > 0 if the
825 * path is fully normalized, and == 0 for each normalization step. This may be combined with
826 * CHASE_NONEXISTENT, in which case 1 is returned when a component is not found.
828 * 4. With CHASE_SAFE: in this case the path must not contain unsafe transitions, i.e. transitions from
829 * unprivileged to privileged files or directories. In such cases the return value is -ENOLINK. If
830 * CHASE_WARN is also set, a warning describing the unsafe transition is emitted.
832 * 5. With CHASE_NO_AUTOFS: in this case if an autofs mount point is encountered, path normalization
833 * is aborted and -EREMOTE is returned. If CHASE_WARN is also set, a warning showing the path of
834 * the mount point is emitted.
837 /* A root directory of "/" or "" is identical to none */
838 if ( empty_or_root ( original_root
))
839 original_root
= NULL
;
841 if (! original_root
&& ! ret_path
&& !( flags
& ( CHASE_NONEXISTENT
| CHASE_NO_AUTOFS
| CHASE_SAFE
| CHASE_STEP
)) && ret_fd
) {
842 /* Shortcut the ret_fd case if the caller isn't interested in the actual path and has no root set
843 * and doesn't care about any of the other special features we provide either. */
844 r
= open ( path
, O_PATH
| O_CLOEXEC
|(( flags
& CHASE_NOFOLLOW
) ? O_NOFOLLOW
: 0 ));
853 r
= path_make_absolute_cwd ( original_root
, & root
);
857 /* Simplify the root directory, so that it has no duplicate slashes and nothing at the
858 * end. While we won't resolve the root path we still simplify it. Note that dropping the
859 * trailing slash should not change behaviour, since when opening it we specify O_DIRECTORY
860 * anyway. Moreover at the end of this function after processing everything we'll always turn
861 * the empty string back to "/". */
862 delete_trailing_chars ( root
, "/" );
863 path_simplify ( root
, true );
865 if ( flags
& CHASE_PREFIX_ROOT
) {
866 /* We don't support relative paths in combination with a root directory */
867 if (! path_is_absolute ( path
))
870 path
= prefix_roota ( root
, path
);
874 r
= path_make_absolute_cwd ( path
, & buffer
);
878 fd
= open ( root
?: "/" , O_CLOEXEC
| O_DIRECTORY
| O_PATH
);
882 if ( flags
& CHASE_SAFE
) {
883 if ( fstat ( fd
, & previous_stat
) < 0 )
888 _cleanup_free_
char * absolute
= NULL
;
891 /* If we are operating on a root directory, let's take the root directory as it is. */
893 e
= path_startswith ( buffer
, root
);
895 return log_full_errno ( flags
& CHASE_WARN
? LOG_WARNING
: LOG_DEBUG
,
896 SYNTHETIC_ERRNO ( ECHRNG
),
897 "Specified path '%s' is outside of specified root directory '%s', refusing to resolve." ,
904 /* Make sure "todo" starts with a slash */
905 absolute
= strjoin ( "/" , e
);
909 free_and_replace ( buffer
, absolute
);
914 _cleanup_free_
char * first
= NULL
;
915 _cleanup_close_
int child
= - 1 ;
919 /* Determine length of first component in the path */
920 n
= strspn ( todo
, "/" ); /* The slashes */
923 /* If we are looking at more than a single slash then skip all but one, so that when
924 * we are done with everything we have a normalized path with only single slashes
925 * separating the path components. */
930 m
= n
+ strcspn ( todo
+ n
, "/" ); /* The entire length of the component */
932 /* Extract the first component. */
933 first
= strndup ( todo
, m
);
939 /* Empty? Then we reached the end. */
943 /* Just a single slash? Then we reached the end. */
944 if ( path_equal ( first
, "/" )) {
945 /* Preserve the trailing slash */
947 if ( flags
& CHASE_TRAIL_SLASH
)
948 if (! strextend (& done
, "/" , NULL
))
954 /* Just a dot? Then let's eat this up. */
955 if ( path_equal ( first
, "/." ))
958 /* Two dots? Then chop off the last bit of what we already found out. */
959 if ( path_equal ( first
, "/.." )) {
960 _cleanup_free_
char * parent
= NULL
;
961 _cleanup_close_
int fd_parent
= - 1 ;
963 /* If we already are at the top, then going up will not change anything. This is in-line with
964 * how the kernel handles this. */
965 if ( empty_or_root ( done
))
968 parent
= dirname_malloc ( done
);
972 /* Don't allow this to leave the root dir. */
974 path_startswith ( done
, root
) &&
975 ! path_startswith ( parent
, root
))
978 free_and_replace ( done
, parent
);
980 if ( flags
& CHASE_STEP
)
983 fd_parent
= openat ( fd
, ".." , O_CLOEXEC
| O_NOFOLLOW
| O_PATH
);
987 if ( flags
& CHASE_SAFE
) {
988 if ( fstat ( fd_parent
, & st
) < 0 )
991 if ( unsafe_transition (& previous_stat
, & st
))
992 return log_unsafe_transition ( fd
, fd_parent
, path
, flags
);
998 fd
= TAKE_FD ( fd_parent
);
1003 /* Otherwise let's see what this is. */
1004 child
= openat ( fd
, first
+ n
, O_CLOEXEC
| O_NOFOLLOW
| O_PATH
);
1007 if ( errno
== ENOENT
&&
1008 ( flags
& CHASE_NONEXISTENT
) &&
1009 ( isempty ( todo
) || path_is_normalized ( todo
))) {
1011 /* If CHASE_NONEXISTENT is set, and the path does not exist, then that's OK, return
1012 * what we got so far. But don't allow this if the remaining path contains "../ or "./"
1013 * or something else weird. */
1015 /* If done is "/", as first also contains slash at the head, then remove this redundant slash. */
1016 if ( streq_ptr ( done
, "/" ))
1019 if (! strextend (& done
, first
, todo
, NULL
))
1029 if ( fstat ( child
, & st
) < 0 )
1031 if (( flags
& CHASE_SAFE
) &&
1032 unsafe_transition (& previous_stat
, & st
))
1033 return log_unsafe_transition ( fd
, child
, path
, flags
);
1037 if (( flags
& CHASE_NO_AUTOFS
) &&
1038 fd_is_fs_type ( child
, AUTOFS_SUPER_MAGIC
) > 0 )
1039 return log_autofs_mount_point ( child
, path
, flags
);
1041 if ( S_ISLNK ( st
. st_mode
) && !(( flags
& CHASE_NOFOLLOW
) && isempty ( todo
))) {
1043 _cleanup_free_
char * destination
= NULL
;
1045 /* This is a symlink, in this case read the destination. But let's make sure we don't follow
1046 * symlinks without bounds. */
1047 if (-- max_follow
<= 0 )
1050 r
= readlinkat_malloc ( fd
, first
+ n
, & destination
);
1053 if ( isempty ( destination
))
1056 if ( path_is_absolute ( destination
)) {
1058 /* An absolute destination. Start the loop from the beginning, but use the root
1059 * directory as base. */
1062 fd
= open ( root
?: "/" , O_CLOEXEC
| O_DIRECTORY
| O_PATH
);
1066 if ( flags
& CHASE_SAFE
) {
1067 if ( fstat ( fd
, & st
) < 0 )
1070 if ( unsafe_transition (& previous_stat
, & st
))
1071 return log_unsafe_transition ( child
, fd
, path
, flags
);
1078 /* Note that we do not revalidate the root, we take it as is. */
1082 done
= strdup ( root
);
1087 /* Prefix what's left to do with what we just read, and start the loop again, but
1088 * remain in the current directory. */
1089 joined
= path_join ( destination
, todo
);
1091 joined
= path_join ( "/" , destination
, todo
);
1096 todo
= buffer
= joined
;
1098 if ( flags
& CHASE_STEP
)
1104 /* If this is not a symlink, then let's just add the name we read to what we already verified. */
1106 done
= TAKE_PTR ( first
);
1108 /* If done is "/", as first also contains slash at the head, then remove this redundant slash. */
1109 if ( streq ( done
, "/" ))
1112 if (! strextend (& done
, first
, NULL
))
1116 /* And iterate again, but go one directory further down. */
1118 fd
= TAKE_FD ( child
);
1122 /* Special case, turn the empty string into "/", to indicate the root directory. */
1129 * ret_path
= TAKE_PTR ( done
);
1132 /* Return the O_PATH fd we currently are looking to the caller. It can translate it to a
1133 * proper fd by opening /proc/self/fd/xyz. */
1136 * ret_fd
= TAKE_FD ( fd
);
1139 if ( flags
& CHASE_STEP
)
1148 c
= strjoin ( strempty ( done
), todo
);
1158 int chase_symlinks_and_open (
1161 unsigned chase_flags
,
1165 _cleanup_close_
int path_fd
= - 1 ;
1166 _cleanup_free_
char * p
= NULL
;
1169 if ( chase_flags
& CHASE_NONEXISTENT
)
1172 if ( empty_or_root ( root
) && ! ret_path
&& ( chase_flags
& ( CHASE_NO_AUTOFS
| CHASE_SAFE
)) == 0 ) {
1173 /* Shortcut this call if none of the special features of this call are requested */
1174 r
= open ( path
, open_flags
);
1181 r
= chase_symlinks ( path
, root
, chase_flags
, ret_path
? & p
: NULL
, & path_fd
);
1184 assert ( path_fd
>= 0 );
1186 r
= fd_reopen ( path_fd
, open_flags
);
1191 * ret_path
= TAKE_PTR ( p
);
1196 int chase_symlinks_and_opendir (
1199 unsigned chase_flags
,
1203 char procfs_path
[ STRLEN ( "/proc/self/fd/" ) + DECIMAL_STR_MAX ( int )];
1204 _cleanup_close_
int path_fd
= - 1 ;
1205 _cleanup_free_
char * p
= NULL
;
1211 if ( chase_flags
& CHASE_NONEXISTENT
)
1214 if ( empty_or_root ( root
) && ! ret_path
&& ( chase_flags
& ( CHASE_NO_AUTOFS
| CHASE_SAFE
)) == 0 ) {
1215 /* Shortcut this call if none of the special features of this call are requested */
1224 r
= chase_symlinks ( path
, root
, chase_flags
, ret_path
? & p
: NULL
, & path_fd
);
1227 assert ( path_fd
>= 0 );
1229 xsprintf ( procfs_path
, "/proc/self/fd/%i" , path_fd
);
1230 d
= opendir ( procfs_path
);
1235 * ret_path
= TAKE_PTR ( p
);
1241 int chase_symlinks_and_stat (
1244 unsigned chase_flags
,
1246 struct stat
* ret_stat
,
1249 _cleanup_close_
int path_fd
= - 1 ;
1250 _cleanup_free_
char * p
= NULL
;
1256 if ( chase_flags
& CHASE_NONEXISTENT
)
1259 if ( empty_or_root ( root
) && ! ret_path
&& ( chase_flags
& ( CHASE_NO_AUTOFS
| CHASE_SAFE
)) == 0 ) {
1260 /* Shortcut this call if none of the special features of this call are requested */
1261 if ( stat ( path
, ret_stat
) < 0 )
1267 r
= chase_symlinks ( path
, root
, chase_flags
, ret_path
? & p
: NULL
, & path_fd
);
1270 assert ( path_fd
>= 0 );
1272 if ( fstat ( path_fd
, ret_stat
) < 0 )
1276 * ret_path
= TAKE_PTR ( p
);
1278 * ret_fd
= TAKE_FD ( path_fd
);
1283 int access_fd ( int fd
, int mode
) {
1284 char p
[ STRLEN ( "/proc/self/fd/" ) + DECIMAL_STR_MAX ( fd
) + 1 ];
1287 /* Like access() but operates on an already open fd */
1289 xsprintf ( p
, "/proc/self/fd/%i" , fd
);
1290 r
= access ( p
, mode
);
1297 void unlink_tempfilep ( char (* p
)[]) {
1298 /* If the file is created with mkstemp(), it will (almost always)
1299 * change the suffix. Treat this as a sign that the file was
1300 * successfully created. We ignore both the rare case where the
1301 * original suffix is used and unlink failures. */
1302 if (! endswith (* p
, ".XXXXXX" ))
1303 ( void ) unlink_noerrno (* p
);
1306 int unlinkat_deallocate ( int fd
, const char * name
, int flags
) {
1307 _cleanup_close_
int truncate_fd
= - 1 ;
1311 /* Operates like unlinkat() but also deallocates the file contents if it is a regular file and there's no other
1312 * link to it. This is useful to ensure that other processes that might have the file open for reading won't be
1313 * able to keep the data pinned on disk forever. This call is particular useful whenever we execute clean-up
1314 * jobs ("vacuuming"), where we want to make sure the data is really gone and the disk space released and
1315 * returned to the free pool.
1317 * Deallocation is preferably done by FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE (👊) if supported, which means
1318 * the file won't change size. That's a good thing since we shouldn't needlessly trigger SIGBUS in other
1319 * programs that have mmap()ed the file. (The assumption here is that changing file contents to all zeroes
1320 * underneath those programs is the better choice than simply triggering SIGBUS in them which truncation does.)
1321 * However if hole punching is not implemented in the kernel or file system we'll fall back to normal file
1322 * truncation (🔪), as our goal of deallocating the data space trumps our goal of being nice to readers (💐).
1324 * Note that we attempt deallocation, but failure to succeed with that is not considered fatal, as long as the
1325 * primary job – to delete the file – is accomplished. */
1327 if (( flags
& AT_REMOVEDIR
) == 0 ) {
1328 truncate_fd
= openat ( fd
, name
, O_WRONLY
| O_CLOEXEC
| O_NOCTTY
| O_NOFOLLOW
| O_NONBLOCK
);
1329 if ( truncate_fd
< 0 ) {
1331 /* If this failed because the file doesn't exist propagate the error right-away. Also,
1332 * AT_REMOVEDIR wasn't set, and we tried to open the file for writing, which means EISDIR is
1333 * returned when this is a directory but we are not supposed to delete those, hence propagate
1334 * the error right-away too. */
1335 if ( IN_SET ( errno
, ENOENT
, EISDIR
))
1338 if ( errno
!= ELOOP
) /* don't complain if this is a symlink */
1339 log_debug_errno ( errno
, "Failed to open file '%s' for deallocation, ignoring: %m" , name
);
1343 if ( unlinkat ( fd
, name
, flags
) < 0 )
1346 if ( truncate_fd
< 0 ) /* Don't have a file handle, can't do more ☹️ */
1349 if ( fstat ( truncate_fd
, & st
) < 0 ) {
1350 log_debug_errno ( errno
, "Failed to stat file '%s' for deallocation, ignoring: %m" , name
);
1354 if (! S_ISREG ( st
. st_mode
) || st
. st_blocks
== 0 || st
. st_nlink
> 0 )
1357 /* If this is a regular file, it actually took up space on disk and there are no other links it's time to
1358 * punch-hole/truncate this to release the disk space. */
1360 bs
= MAX ( st
. st_blksize
, 512 );
1361 l
= DIV_ROUND_UP ( st
. st_size
, bs
) * bs
; /* Round up to next block size */
1363 if ( fallocate ( truncate_fd
, FALLOC_FL_PUNCH_HOLE
| FALLOC_FL_KEEP_SIZE
, 0 , l
) >= 0 )
1364 return 0 ; /* Successfully punched a hole! 😊 */
1366 /* Fall back to truncation */
1367 if ( ftruncate ( truncate_fd
, 0 ) < 0 ) {
1368 log_debug_errno ( errno
, "Failed to truncate file to 0, ignoring: %m" );
1375 int fsync_directory_of_file ( int fd
) {
1376 _cleanup_free_
char * path
= NULL
;
1377 _cleanup_close_
int dfd
= - 1 ;
1380 r
= fd_verify_regular ( fd
);
1384 r
= fd_get_path ( fd
, & path
);
1386 log_debug_errno ( r
, "Failed to query /proc/self/fd/%d%s: %m" ,
1388 r
== - EOPNOTSUPP
? ", ignoring" : "" );
1390 if ( r
== - EOPNOTSUPP
)
1391 /* If /proc is not available, we're most likely running in some
1392 * chroot environment, and syncing the directory is not very
1393 * important in that case. Let's just silently do nothing. */
1399 if (! path_is_absolute ( path
))
1402 dfd
= open_parent ( path
, O_CLOEXEC
, 0 );
1412 int fsync_full ( int fd
) {
1415 /* Sync both the file and the directory */
1417 r
= fsync ( fd
) < 0 ? - errno
: 0 ;
1418 q
= fsync_directory_of_file ( fd
);
1420 return r
< 0 ? r
: q
;
1423 int fsync_path_at ( int at_fd
, const char * path
) {
1424 _cleanup_close_
int opened_fd
= - 1 ;
1427 if ( isempty ( path
)) {
1428 if ( at_fd
== AT_FDCWD
) {
1429 opened_fd
= open ( "." , O_RDONLY
| O_DIRECTORY
| O_CLOEXEC
);
1438 opened_fd
= openat ( at_fd
, path
, O_RDONLY
| O_CLOEXEC
);
1451 int syncfs_path ( int atfd
, const char * path
) {
1452 _cleanup_close_
int fd
= - 1 ;
1456 fd
= openat ( atfd
, path
, O_CLOEXEC
| O_RDONLY
| O_NONBLOCK
);
1466 int open_parent ( const char * path
, int flags
, mode_t mode
) {
1467 _cleanup_free_
char * parent
= NULL
;
1472 if ( path_equal ( path
, "/" )) /* requesting the parent of the root dir is fishy, let's prohibit that */
1475 parent
= dirname_malloc ( path
);
1479 /* Let's insist on O_DIRECTORY since the parent of a file or directory is a directory. Except if we open an
1480 * O_TMPFILE file, because in that case we are actually create a regular file below the parent directory. */
1482 if ( FLAGS_SET ( flags
, O_PATH
))
1483 flags
|= O_DIRECTORY
;
1484 else if (! FLAGS_SET ( flags
, O_TMPFILE
))
1485 flags
|= O_DIRECTORY
| O_RDONLY
;
1487 fd
= open ( parent
, flags
, mode
);
1494 static int blockdev_is_encrypted ( const char * sysfs_path
, unsigned depth_left
) {
1495 _cleanup_free_
char * p
= NULL
, * uuids
= NULL
;
1496 _cleanup_closedir_
DIR * d
= NULL
;
1497 int r
, found_encrypted
= false ;
1501 if ( depth_left
== 0 )
1504 p
= path_join ( sysfs_path
, "dm/uuid" );
1508 r
= read_one_line_file ( p
, & uuids
);
1513 /* The DM device's uuid attribute is prefixed with "CRYPT-" if this is a dm-crypt device. */
1514 if ( startswith ( uuids
, "CRYPT-" ))
1518 /* Not a dm-crypt device itself. But maybe it is on top of one? Follow the links in the "slaves/"
1522 p
= path_join ( sysfs_path
, "slaves" );
1528 if ( errno
== ENOENT
) /* Doesn't have slaves */
1535 _cleanup_free_
char * q
= NULL
;
1539 de
= readdir_no_dot ( d
);
1544 break ; /* No more slaves */
1547 q
= path_join ( p
, de
-> d_name
);
1551 r
= blockdev_is_encrypted ( q
, depth_left
- 1 );
1554 if ( r
== 0 ) /* we found one that is not encrypted? then propagate that immediately */
1557 found_encrypted
= true ;
1560 return found_encrypted
;
1563 int path_is_encrypted ( const char * path
) {
1564 char p
[ SYS_BLOCK_PATH_MAX ( NULL
)];
1568 r
= get_block_device ( path
, & devt
);
1571 if ( r
== 0 ) /* doesn't have a block device */
1574 xsprintf_sys_block_path ( p
, NULL
, devt
);
1576 return blockdev_is_encrypted ( p
, 10 /* safety net: maximum recursion depth */ );