From 2287565d4697053311fde60bcd8ae74c964a3b31 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 20 Feb 2024 12:47:10 +0100 Subject: [PATCH] pid1: port executor binary pinning to new build path logic --- src/basic/build-path.c | 29 +++++++++++++++++++++++++++++ src/basic/build-path.h | 2 ++ src/core/manager.c | 36 +++++++----------------------------- 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/basic/build-path.c b/src/basic/build-path.c index 0c43afaefdf..8ddef7b2dd5 100644 --- a/src/basic/build-path.c +++ b/src/basic/build-path.c @@ -6,6 +6,7 @@ #include "build-path.h" #include "errno-list.h" +#include "errno-util.h" #include "macro.h" #include "path-util.h" #include "process-util.h" @@ -236,3 +237,31 @@ int invoke_callout_binary(const char *path, char *const argv[]) { execv(path, argv); return -errno; } + +int pin_callout_binary(const char *path) { + int r; + + assert(path); + + /* Similar to invoke_callout_binary(), but pins (i.e. O_PATH opens) the binary instead of executing it. */ + + _cleanup_free_ char *fn = NULL; + r = path_extract_filename(path, &fn); + if (r < 0) + return r; + if (r == O_DIRECTORY) /* Uh? */ + return -EISDIR; + + const char *e; + if (find_environment_binary(fn, &e) >= 0) + return RET_NERRNO(open(e, O_CLOEXEC|O_PATH)); + + _cleanup_free_ char *np = NULL; + if (find_build_dir_binary(fn, &np) >= 0) { + r = RET_NERRNO(open(np, O_CLOEXEC|O_PATH)); + if (r >= 0) + return r; + } + + return RET_NERRNO(open(path, O_CLOEXEC|O_PATH)); +} diff --git a/src/basic/build-path.h b/src/basic/build-path.h index bf42783f1b0..6c38a4a3bb5 100644 --- a/src/basic/build-path.h +++ b/src/basic/build-path.h @@ -4,3 +4,5 @@ int get_build_exec_dir(char **ret); int invoke_callout_binary(const char *path, char *const argv[]); + +int pin_callout_binary(const char *path); diff --git a/src/core/manager.c b/src/core/manager.c index e8c747d96d9..7a7669f315f 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -25,6 +25,7 @@ #include "alloc-util.h" #include "audit-fd.h" #include "boot-timestamps.h" +#include "build-path.h" #include "bus-common-errors.h" #include "bus-error.h" #include "bus-kernel.h" @@ -1024,42 +1025,19 @@ int manager_new(RuntimeScope runtime_scope, ManagerTestRunFlags test_run_flags, if (r < 0 && r != -EEXIST) return r; + } - m->executor_fd = open(SYSTEMD_EXECUTOR_BINARY_PATH, O_CLOEXEC|O_PATH); - if (m->executor_fd < 0) - return log_emergency_errno(errno, - "Failed to open executor binary '%s': %m", - SYSTEMD_EXECUTOR_BINARY_PATH); - } else if (!FLAGS_SET(test_run_flags, MANAGER_TEST_DONT_OPEN_EXECUTOR)) { - _cleanup_free_ char *self_exe = NULL, *executor_path = NULL; - _cleanup_close_ int self_dir_fd = -EBADF; - int level = LOG_DEBUG; - - /* Prefer sd-executor from the same directory as the test, e.g.: when running unit tests from the - * build directory. Fallback to working directory and then the installation path. */ - r = readlink_and_make_absolute("/proc/self/exe", &self_exe); - if (r < 0) - return r; - - self_dir_fd = open_parent(self_exe, O_CLOEXEC|O_PATH|O_DIRECTORY, 0); - if (self_dir_fd < 0) - return self_dir_fd; - - m->executor_fd = RET_NERRNO(openat(self_dir_fd, "systemd-executor", O_CLOEXEC|O_PATH)); - if (m->executor_fd == -ENOENT) - m->executor_fd = RET_NERRNO(openat(AT_FDCWD, "systemd-executor", O_CLOEXEC|O_PATH)); - if (m->executor_fd == -ENOENT) { - m->executor_fd = RET_NERRNO(open(SYSTEMD_EXECUTOR_BINARY_PATH, O_CLOEXEC|O_PATH)); - level = LOG_WARNING; /* Tests should normally use local builds */ - } + if (!FLAGS_SET(test_run_flags, MANAGER_TEST_DONT_OPEN_EXECUTOR)) { + m->executor_fd = pin_callout_binary(SYSTEMD_EXECUTOR_BINARY_PATH); if (m->executor_fd < 0) - return m->executor_fd; + return log_debug_errno(m->executor_fd, "Failed to pin executor binary: %m"); + _cleanup_free_ char *executor_path = NULL; r = fd_get_path(m->executor_fd, &executor_path); if (r < 0) return r; - log_full(level, "Using systemd-executor binary from '%s'.", executor_path); + log_debug("Using systemd-executor binary from '%s'.", executor_path); } /* Note that we do not set up the notify fd here. We do that after deserialization, -- 2.47.3