diff --git a/src/basic/fd-util.h b/src/basic/fd-util.h index 6aecb91fab..4a02d92078 100644 --- a/src/basic/fd-util.h +++ b/src/basic/fd-util.h @@ -8,6 +8,8 @@ #include #include "macro.h" +#include "format-util.h" +#include "process-util.h" #include "stdio-util.h" /* maximum length of fdname */ @@ -112,14 +114,17 @@ static inline int dir_fd_is_root_or_cwd(int dir_fd) { return dir_fd == AT_FDCWD ? true : path_is_root_at(dir_fd, NULL); } -/* The maximum length a buffer for a /proc/self/fd/ path needs */ +/* The maximum length a buffer for a /proc//fd/ path needs. We intentionally don't use /proc/self/fd + * as these paths might be read by other programs (for example when mounting file descriptors the source path + * ends up in /proc/mounts and related files) for which /proc/self/fd will be interpreted differently than + * /proc//fd. */ #define PROC_FD_PATH_MAX \ - (STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)) + (STRLEN("/proc//fd/") + DECIMAL_STR_MAX(pid_t) + DECIMAL_STR_MAX(int)) static inline char *format_proc_fd_path(char buf[static PROC_FD_PATH_MAX], int fd) { assert(buf); assert(fd >= 0); - assert_se(snprintf_ok(buf, PROC_FD_PATH_MAX, "/proc/self/fd/%i", fd)); + assert_se(snprintf_ok(buf, PROC_FD_PATH_MAX, "/proc/" PID_FMT "/fd/%i", getpid_cached(), fd)); return buf; } diff --git a/src/test/test-fd-util.c b/src/test/test-fd-util.c index 20d412f5c6..1674758e6b 100644 --- a/src/test/test-fd-util.c +++ b/src/test/test-fd-util.c @@ -382,11 +382,16 @@ TEST(close_all_fds) { } TEST(format_proc_fd_path) { - assert_se(streq_ptr(FORMAT_PROC_FD_PATH(0), "/proc/self/fd/0")); - assert_se(streq_ptr(FORMAT_PROC_FD_PATH(1), "/proc/self/fd/1")); - assert_se(streq_ptr(FORMAT_PROC_FD_PATH(2), "/proc/self/fd/2")); - assert_se(streq_ptr(FORMAT_PROC_FD_PATH(3), "/proc/self/fd/3")); - assert_se(streq_ptr(FORMAT_PROC_FD_PATH(2147483647), "/proc/self/fd/2147483647")); + _cleanup_free_ char *expected = NULL; + + for (int i = 0; i < 4; i++) { + assert_se(asprintf(&expected, "/proc/" PID_FMT "/fd/%i", getpid_cached(), i) >= 0); + assert_se(streq_ptr(FORMAT_PROC_FD_PATH(i), expected)); + expected = mfree(expected); + } + + assert_se(asprintf(&expected, "/proc/" PID_FMT "/fd/2147483647", getpid_cached()) >= 0); + assert_se(streq_ptr(FORMAT_PROC_FD_PATH(2147483647), expected)); } TEST(fd_reopen) {