|
|
44a72b9 |
From 2c655092f8cd7c20c4146254cb549ff9ba795fda Mon Sep 17 00:00:00 2001
|
|
|
44a72b9 |
From: NeilBrown <neil@brown.name>
|
|
|
44a72b9 |
Date: Mon, 4 Sep 2017 23:35:07 +1000
|
|
|
44a72b9 |
Subject: [PATCH] tmpfiles: silently ignore any path that passes through autofs
|
|
|
44a72b9 |
(#6506)
|
|
|
44a72b9 |
|
|
|
44a72b9 |
If a path passes though an autofs filesystem, then accessing
|
|
|
44a72b9 |
the path might trigger and automount. As systemd-tmpfiles is run before
|
|
|
44a72b9 |
the network is up, and as automounts are often used for networked
|
|
|
44a72b9 |
filesystems, this can cause a deadlock.
|
|
|
44a72b9 |
|
|
|
44a72b9 |
So chase_symlinks is enhance to accept a new flag which tells it
|
|
|
44a72b9 |
to check for autofs, and return -EREMOTE if autofs is found.
|
|
|
44a72b9 |
|
|
|
44a72b9 |
tmpfiles is changed to check just before acting on a path so that it
|
|
|
44a72b9 |
can avoid autofs even if a symlink was created earlier by tmpfiles
|
|
|
44a72b9 |
that would send this path through an autofs.
|
|
|
44a72b9 |
|
|
|
44a72b9 |
This fixes a deadlock that happens when /home is listed in /etc/fstab as
|
|
|
44a72b9 |
x-systemd.automount for an NFS directory.
|
|
|
44a72b9 |
|
|
|
44a72b9 |
(cherry picked from commit 655f2da0790d0f8670f7a4c7da1833786ce0137e)
|
|
|
44a72b9 |
---
|
|
|
44a72b9 |
src/basic/fs-util.c | 4 ++++
|
|
|
44a72b9 |
src/basic/fs-util.h | 1 +
|
|
|
44a72b9 |
src/tmpfiles/tmpfiles.c | 3 +++
|
|
|
44a72b9 |
3 files changed, 8 insertions(+)
|
|
|
44a72b9 |
|
|
|
44a72b9 |
diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c
|
|
|
44a72b9 |
index 8fe19ee4e4..5b3bd0c45d 100644
|
|
|
44a72b9 |
--- a/src/basic/fs-util.c
|
|
|
44a72b9 |
+++ b/src/basic/fs-util.c
|
|
|
44a72b9 |
@@ -23,6 +23,7 @@
|
|
|
44a72b9 |
#include <stdlib.h>
|
|
|
44a72b9 |
#include <string.h>
|
|
|
44a72b9 |
#include <sys/stat.h>
|
|
|
44a72b9 |
+#include <linux/magic.h>
|
|
|
44a72b9 |
#include <time.h>
|
|
|
44a72b9 |
#include <unistd.h>
|
|
|
44a72b9 |
|
|
|
44a72b9 |
@@ -721,6 +722,9 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
|
|
|
44a72b9 |
|
|
|
44a72b9 |
if (fstat(child, &st) < 0)
|
|
|
44a72b9 |
return -errno;
|
|
|
44a72b9 |
+ if ((flags & CHASE_NO_AUTOFS) &&
|
|
|
44a72b9 |
+ fd_check_fstype(child, AUTOFS_SUPER_MAGIC) > 0)
|
|
|
44a72b9 |
+ return -EREMOTE;
|
|
|
44a72b9 |
|
|
|
44a72b9 |
if (S_ISLNK(st.st_mode)) {
|
|
|
44a72b9 |
char *joined;
|
|
|
44a72b9 |
diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h
|
|
|
44a72b9 |
index 094acf1799..d3342d5cda 100644
|
|
|
44a72b9 |
--- a/src/basic/fs-util.h
|
|
|
44a72b9 |
+++ b/src/basic/fs-util.h
|
|
|
44a72b9 |
@@ -81,6 +81,7 @@ int inotify_add_watch_fd(int fd, int what, uint32_t mask);
|
|
|
44a72b9 |
enum {
|
|
|
44a72b9 |
CHASE_PREFIX_ROOT = 1, /* If set, the specified path will be prefixed by the specified root before beginning the iteration */
|
|
|
44a72b9 |
CHASE_NONEXISTENT = 2, /* If set, it's OK if the path doesn't actually exist. */
|
|
|
44a72b9 |
+ CHASE_NO_AUTOFS = 4, /* If set, return -EREMOTE if autofs mount point found */
|
|
|
44a72b9 |
};
|
|
|
44a72b9 |
|
|
|
44a72b9 |
int chase_symlinks(const char *path_with_prefix, const char *root, unsigned flags, char **ret);
|
|
|
44a72b9 |
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
|
|
|
44a72b9 |
index 0ee606fc30..be52398f5f 100644
|
|
|
44a72b9 |
--- a/src/tmpfiles/tmpfiles.c
|
|
|
44a72b9 |
+++ b/src/tmpfiles/tmpfiles.c
|
|
|
44a72b9 |
@@ -1655,6 +1655,9 @@ static int process_item(Item *i) {
|
|
|
44a72b9 |
}
|
|
|
44a72b9 |
}
|
|
|
44a72b9 |
|
|
|
44a72b9 |
+ if (chase_symlinks(i->path, NULL, CHASE_NO_AUTOFS, NULL) == -EREMOTE)
|
|
|
44a72b9 |
+ return t;
|
|
|
44a72b9 |
+
|
|
|
44a72b9 |
r = arg_create ? create_item(i) : 0;
|
|
|
44a72b9 |
q = arg_remove ? remove_item(i) : 0;
|
|
|
44a72b9 |
p = arg_clean ? clean_item(i) : 0;
|