]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tmpfiles: silently ignore any path that passes through autofs (#6506)
authorNeilBrown <neil@brown.name>
Mon, 4 Sep 2017 13:35:07 +0000 (23:35 +1000)
committerLennart Poettering <lennart@poettering.net>
Mon, 4 Sep 2017 13:35:07 +0000 (15:35 +0200)
If a path passes though an autofs filesystem, then accessing
the path might trigger and automount.  As systemd-tmpfiles is run before
the network is up, and as automounts are often used for networked
filesystems, this can cause a deadlock.

So chase_symlinks is enhance to accept a new flag which tells it
to check for autofs, and return -EREMOTE if autofs is found.

tmpfiles is changed to check just before acting on a path so that it
can avoid autofs even if a symlink was created earlier by tmpfiles
that would send this path through an autofs.

This fixes a deadlock that happens when /home is listed in /etc/fstab as
x-systemd.automount for an NFS directory.

src/basic/fs-util.c
src/basic/fs-util.h
src/tmpfiles/tmpfiles.c

index 5e1163c6a74aa341dc5171306aa170db8e9e0b7e..fdedeffb9aaabf09dc0583b3b18cae3b6e922713 100644 (file)
@@ -23,6 +23,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
+#include <linux/magic.h>
 #include <time.h>
 #include <unistd.h>
 
@@ -721,6 +722,9 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
 
                 if (fstat(child, &st) < 0)
                         return -errno;
+                if ((flags & CHASE_NO_AUTOFS) &&
+                    fd_check_fstype(child, AUTOFS_SUPER_MAGIC) > 0)
+                        return -EREMOTE;
 
                 if (S_ISLNK(st.st_mode)) {
                         char *joined;
index 094acf179963ec1da3449fb7d5117fee67198e3e..d3342d5cdaadff288c4911c2e214a15ca96d395a 100644 (file)
@@ -81,6 +81,7 @@ int inotify_add_watch_fd(int fd, int what, uint32_t mask);
 enum {
         CHASE_PREFIX_ROOT = 1,   /* If set, the specified path will be prefixed by the specified root before beginning the iteration */
         CHASE_NONEXISTENT = 2,   /* If set, it's OK if the path doesn't actually exist. */
+        CHASE_NO_AUTOFS = 4,     /* If set, return -EREMOTE if autofs mount point found */
 };
 
 int chase_symlinks(const char *path_with_prefix, const char *root, unsigned flags, char **ret);
index 8f960cc0edb8ed7e113fed49a226a1fea041d75f..875a886bf3de9cbe92ca2bf060c09c3e4674e87b 100644 (file)
@@ -1664,6 +1664,9 @@ static int process_item(Item *i) {
                 }
         }
 
+        if (chase_symlinks(i->path, NULL, CHASE_NO_AUTOFS, NULL) == -EREMOTE)
+                return t;
+
         r = arg_create ? create_item(i) : 0;
         q = arg_remove ? remove_item(i) : 0;
         p = arg_clean ? clean_item(i) : 0;