From 2af02e61657aa513aa7b6df7fd1a04b13f853cef Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 14 Aug 2023 12:54:40 +0200 Subject: [PATCH 1/2] tree-wide: Always include before related linux headers Otherwise, we get redefinition errors if is included later on by another header. --- src/libsystemd-network/sd-dhcp6-client.c | 5 +++-- src/network/networkd-dhcp-server.c | 5 +++-- src/network/networkd-manager.c | 3 ++- src/network/networkd-state-file.c | 3 ++- src/resolve/resolved-link.c | 3 ++- src/udev/net/link-config.c | 3 ++- 6 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 6d62ba380b..9a4f3ab1bf 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -5,8 +5,9 @@ #include #include -#include -#include +#include +#include /* Must be included after */ +#include /* Must be included after */ #include "sd-dhcp6-client.h" diff --git a/src/network/networkd-dhcp-server.c b/src/network/networkd-dhcp-server.c index 8221fd92db..fedc2e4f04 100644 --- a/src/network/networkd-dhcp-server.c +++ b/src/network/networkd-dhcp-server.c @@ -1,8 +1,9 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include -#include -#include +#include +#include /* Must be included after */ +#include /* Must be included after */ #include "sd-dhcp-server.h" diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index ab5460db27..51434a1abd 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -3,7 +3,8 @@ #include #include #include -#include +#include +#include /* Must be included after */ #include #include #include diff --git a/src/network/networkd-state-file.c b/src/network/networkd-state-file.c index 85c9d21082..e27984d2de 100644 --- a/src/network/networkd-state-file.c +++ b/src/network/networkd-state-file.c @@ -1,7 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include -#include +#include +#include /* Must be included after */ #include "alloc-util.h" #include "dns-domain.h" diff --git a/src/resolve/resolved-link.c b/src/resolve/resolved-link.c index dd5daddce4..a60aabb395 100644 --- a/src/resolve/resolved-link.c +++ b/src/resolve/resolved-link.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include +#include +#include /* Must be included after */ #include #include "sd-network.h" diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index ff8fb24f66..e7b28d33f0 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include +#include +#include /* Must be included after */ #include #include From 4419735822d72744dad1c76a57463561b332897a Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 14 Aug 2023 21:57:59 +0200 Subject: [PATCH 2/2] fd-util: Use /proc/pid/fd instead of /proc/self/fd Currently, we mount via file descriptors using /proc/self/fd. This works, but it means that in /proc/mounts and various other files, the source of the mount will be listed as /proc/self/fd/xxx. For other software that parses these files, /proc/self/fd/xxx doesn't mean anything, or worse, it means the completely wrong thing, as it will refer to one of their own file descriptors instead. Let's improve the situation by using /proc/pid/fd instead. This allows processes parsing /proc/mounts to do the right thing more often than not. One scenario where even this doesn't work if when containers are involved, as with the pid namespace unshared, even /proc/pid/fd will mean the wrong thing, but it's no worse than /proc/self/fd which will always means the wrong thing. This also doesn't work if we mount via file descriptor and then exit, as the pid will be gone, but it does work as long as the process that did the mount is alive, which makes it useful for systemd-dissect --with for example if the program we run in the image wants to parse /proc/mounts. --- src/basic/fd-util.h | 11 ++++++++--- src/test/test-fd-util.c | 15 ++++++++++----- 2 files changed, 18 insertions(+), 8 deletions(-) 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) {