From f8606626ed3c2582e06543550d58fe9886cdca5f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 23 Apr 2020 14:52:10 +0200 Subject: [PATCH] tmpfiles: if we get ENOENT when opening /proc/self/fd/, check if /proc is mounted let's return ENOSYS in that case, to make things a bit less confusng. Previously we'd just propagate ENOENT, which people might mistake as applying to the object being modified rather than /proc/ just not being there. Let's return ENOSYS instead, i.e. an error clearly indicating that some kernel API is not available. This hopefully should put people on a better track. Note that we only do the procfs check in the error path, which hopefully means it's the less likely path. We probably can add similar bits to more suitable codepaths dealing with /proc/self/fd, but for now, let's pick to the ones noticed in #14745. Fixes: #14745 --- src/basic/fd-util.c | 14 +++++++++++--- src/basic/fs-util.c | 11 +++++++++-- src/tmpfiles/tmpfiles.c | 5 +++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c index a3dced441a..e2bee51147 100644 --- a/src/basic/fd-util.c +++ b/src/basic/fd-util.c @@ -21,9 +21,10 @@ #include "path-util.h" #include "process-util.h" #include "socket-util.h" +#include "stat-util.h" #include "stdio-util.h" -#include "util.h" #include "tmpfile-util.h" +#include "util.h" /* The maximum number of iterations in the loop to close descriptors in the fallback case * when /proc/self/fd/ is inaccessible. */ @@ -939,8 +940,15 @@ int fd_reopen(int fd, int flags) { xsprintf(procfs_path, "/proc/self/fd/%i", fd); new_fd = open(procfs_path, flags); - if (new_fd < 0) - return -errno; + if (new_fd < 0) { + if (errno != ENOENT) + return -errno; + + if (proc_mounted() == 0) + return -ENOSYS; /* if we have no /proc/, the concept is not implementable */ + + return -ENOENT; + } return new_fd; } diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index ef3b5a5184..e16bfef3c3 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -337,8 +337,15 @@ int fchmod_opath(int fd, mode_t m) { * fchownat() does. */ xsprintf(procfs_path, "/proc/self/fd/%i", fd); - if (chmod(procfs_path, m) < 0) - return -errno; + if (chmod(procfs_path, m) < 0) { + if (errno != ENOENT) + return -errno; + + if (proc_mounted() == 0) + return -ENOSYS; /* if we have no /proc/, the concept is not implementable */ + + return -ENOENT; + } return 0; } diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 6f0dc2426e..ff1dff13da 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -1078,6 +1078,11 @@ static int fd_set_acls(Item *item, int fd, const char *path, const struct stat * if (r > 0) return -r; /* already warned */ + + /* The above procfs paths don't work if /proc is not mounted. */ + if (r == -ENOENT && proc_mounted() == 0) + r = -ENOSYS; + if (r == -EOPNOTSUPP) { log_debug_errno(r, "ACLs not supported by file system at %s", path); return 0;