summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2020-04-24 08:16:22 +0200
committerGitHub <noreply@github.com>2020-04-24 08:16:22 +0200
commite2697253c8f659f66995a4e1024623369febea95 (patch)
treedb0af01f555346005ea80823776dc9b1fd0df95c
parent11f93798663009d3a83b60ce899c778d9c1f5180 (diff)
parentf8606626ed3c2582e06543550d58fe9886cdca5f (diff)
downloadsystemd-e2697253c8f659f66995a4e1024623369febea95.tar.gz
Merge pull request #15564 from poettering/tmpfiles-no-proc
util-lib: check for /proc being mounted in some really basic fs operations
-rw-r--r--src/basic/fd-util.c14
-rw-r--r--src/basic/fs-util.c11
-rw-r--r--src/basic/stat-util.c19
-rw-r--r--src/basic/stat-util.h2
-rw-r--r--src/sysusers/sysusers.c10
-rw-r--r--src/tmpfiles/tmpfiles.c7
6 files changed, 48 insertions, 15 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/basic/stat-util.c b/src/basic/stat-util.c
index 5412ccbf7d..1f3de56cf9 100644
--- a/src/basic/stat-util.c
+++ b/src/basic/stat-util.c
@@ -178,13 +178,12 @@ int fd_is_fs_type(int fd, statfs_f_type_t magic_value) {
}
int path_is_fs_type(const char *path, statfs_f_type_t magic_value) {
- _cleanup_close_ int fd = -1;
+ struct statfs s;
- fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH);
- if (fd < 0)
+ if (statfs(path, &s) < 0)
return -errno;
- return fd_is_fs_type(fd, magic_value);
+ return is_fs_type(&s, magic_value);
}
bool is_temporary_fs(const struct statfs *s) {
@@ -377,3 +376,15 @@ int device_path_parse_major_minor(const char *path, mode_t *ret_mode, dev_t *ret
return 0;
}
+
+int proc_mounted(void) {
+ int r;
+
+ /* A quick check of procfs is properly mounted */
+
+ r = path_is_fs_type("/proc/", PROC_SUPER_MAGIC);
+ if (r == -ENOENT) /* not mounted at all */
+ return false;
+
+ return r;
+}
diff --git a/src/basic/stat-util.h b/src/basic/stat-util.h
index 7824af3500..8160748312 100644
--- a/src/basic/stat-util.h
+++ b/src/basic/stat-util.h
@@ -87,3 +87,5 @@ int fd_verify_directory(int fd);
int device_path_make_major_minor(mode_t mode, dev_t devno, char **ret);
int device_path_make_canonical(mode_t mode, dev_t devno, char **ret);
int device_path_parse_major_minor(const char *path, mode_t *ret_mode, dev_t *ret_devno);
+
+int proc_mounted(void);
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index c3e5457fc1..f0359e3019 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -1443,7 +1443,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
if (name) {
r = specifier_printf(name, specifier_table, NULL, &resolved_name);
if (r < 0)
- log_error_errno(r, "[%s:%u] Failed to replace specifiers: %s", fname, line, name);
+ return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m", fname, line, name);
if (!valid_user_group_name(resolved_name, 0))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
@@ -1458,7 +1458,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
if (id) {
r = specifier_printf(id, specifier_table, NULL, &resolved_id);
if (r < 0)
- return log_error_errno(r, "[%s:%u] Failed to replace specifiers: %s",
+ return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
fname, line, name);
}
@@ -1469,7 +1469,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
if (description) {
r = specifier_printf(description, specifier_table, NULL, &resolved_description);
if (r < 0)
- return log_error_errno(r, "[%s:%u] Failed to replace specifiers: %s",
+ return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
fname, line, description);
if (!valid_gecos(resolved_description))
@@ -1485,7 +1485,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
if (home) {
r = specifier_printf(home, specifier_table, NULL, &resolved_home);
if (r < 0)
- return log_error_errno(r, "[%s:%u] Failed to replace specifiers: %s",
+ return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
fname, line, home);
if (!valid_home(resolved_home))
@@ -1501,7 +1501,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
if (shell) {
r = specifier_printf(shell, specifier_table, NULL, &resolved_shell);
if (r < 0)
- return log_error_errno(r, "[%s:%u] Failed to replace specifiers: %s",
+ return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
fname, line, shell);
if (!valid_shell(resolved_shell))
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index 6ab30cdecf..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;
@@ -2556,7 +2561,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer, bool
if (r < 0) {
if (IN_SET(r, -EINVAL, -EBADSLT))
*invalid_config = true;
- return log_error_errno(r, "[%s:%u] Failed to replace specifiers: %s", fname, line, path);
+ return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m", fname, line, path);
}
r = patch_var_run(fname, line, &i.path);