From 8fe8f3aabad344b2a237f4ec022516fd835031c4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 23 Sep 2020 18:16:34 +0200 Subject: [PATCH 1/3] basic: update fd_get_path() to use proc_mounted() helper We use it pretty much everywhere else, hence use it here too. This also changes the error generated from EOPNOTSUPP to ENOSYS, to match the other cases where we do such a check. One user checked for EOPNOTSUPP which is updated to check for ENOSYS instead. --- src/basic/fd-util.c | 8 +++----- src/basic/fs-util.c | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c index 14b12b2706..56700bc057 100644 --- a/src/basic/fd-util.c +++ b/src/basic/fd-util.c @@ -385,11 +385,9 @@ int fd_get_path(int fd, char **ret) { /* ENOENT can mean two things: that the fd does not exist or that /proc is not mounted. Let's make * things debuggable and distinguish the two. */ - if (access("/proc/self/fd/", F_OK) < 0) - /* /proc is not available or not set up properly, we're most likely in some chroot - * environment. */ - return errno == ENOENT ? -EOPNOTSUPP : -errno; - + if (proc_mounted() == 0) + return -ENOSYS; /* /proc is not available or not set up properly, we're most likely in some chroot + * environment. */ return -EBADF; /* The directory exists, hence it's the fd that doesn't. */ } diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index 7f8b8b22b3..477848f2a0 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -1441,9 +1441,9 @@ int fsync_directory_of_file(int fd) { if (r < 0) { log_debug_errno(r, "Failed to query /proc/self/fd/%d%s: %m", fd, - r == -EOPNOTSUPP ? ", ignoring" : ""); + r == -ENOSYS ? ", ignoring" : ""); - if (r == -EOPNOTSUPP) + if (r == -ENOSYS) /* If /proc is not available, we're most likely running in some * chroot environment, and syncing the directory is not very * important in that case. Let's just silently do nothing. */ From 48d837cd92c4b3452adace8db59383273bc5a65d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 23 Sep 2020 18:18:03 +0200 Subject: [PATCH 2/3] fs-util: use strna() on returned strings of fd_get_path() if we don't check its return value Let's make sure to use strna() on the strings returned by fd_get_path() where we knowingly ignore any failures. We got this right in most cases, but two were missing. --- src/basic/fs-util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index 477848f2a0..fb74501105 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -765,7 +765,7 @@ static int log_unsafe_transition(int a, int b, const char *path, unsigned flags) return log_warning_errno(SYNTHETIC_ERRNO(ENOLINK), "Detected unsafe path transition %s %s %s during canonicalization of %s.", - n1, special_glyph(SPECIAL_GLYPH_ARROW), n2, path); + strna(n1), special_glyph(SPECIAL_GLYPH_ARROW), strna(n2), path); } static int log_autofs_mount_point(int fd, const char *path, unsigned flags) { @@ -778,7 +778,7 @@ static int log_autofs_mount_point(int fd, const char *path, unsigned flags) { return log_warning_errno(SYNTHETIC_ERRNO(EREMOTE), "Detected autofs mount point %s during canonicalization of %s.", - n1, path); + strna(n1), path); } int chase_symlinks(const char *path, const char *original_root, unsigned flags, char **ret_path, int *ret_fd) { From 4265a66a5e84137d1f874c413b2961f363c8f358 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 23 Sep 2020 18:19:21 +0200 Subject: [PATCH 3/3] fs-util: check for /proc mounted in access_fd() It's a very basic function very similar to other cases where we go via /proc/self/fd/, hence do the explicit proc_mounted() check here too. --- src/basic/fs-util.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index fb74501105..13e7b1b163 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -1298,16 +1298,25 @@ int chase_symlinks_and_stat( int access_fd(int fd, int mode) { char p[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1]; - int r; /* Like access() but operates on an already open fd */ xsprintf(p, "/proc/self/fd/%i", fd); - r = access(p, mode); - if (r < 0) - return -errno; + if (access(p, mode) < 0) { + if (errno != ENOENT) + return -errno; - return r; + /* ENOENT can mean two things: that the fd does not exist or that /proc is not mounted. Let's + * make things debuggable and distinguish the two. */ + + if (proc_mounted() == 0) + return -ENOSYS; /* /proc is not available or not set up properly, we're most likely in some chroot + * environment. */ + + return -EBADF; /* The directory exists, hence it's the fd that doesn't. */ + } + + return 0; } void unlink_tempfilep(char (*p)[]) {