From 2c31eda469603554b844f1880d44451a5f9e3499 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 3 Apr 2025 23:38:40 +0900 Subject: [PATCH] build-path: check if found path is executable binary Otherwise, the path may point to a non-executable, e.g. a directory. --- src/basic/build-path.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/basic/build-path.c b/src/basic/build-path.c index 4a94fcb717..bc0dfc7f9b 100644 --- a/src/basic/build-path.c +++ b/src/basic/build-path.c @@ -7,6 +7,7 @@ #include "build-path.h" #include "errno-list.h" #include "errno-util.h" +#include "fd-util.h" #include "macro.h" #include "path-util.h" #include "process-util.h" @@ -245,6 +246,26 @@ int invoke_callout_binary(const char *path, char *const argv[]) { return -errno; } +static int open_executable(const char *path) { + int r; + + assert(path); + + _cleanup_close_ int fd = RET_NERRNO(open(path, O_CLOEXEC|O_PATH)); + if (fd < 0) + return fd; + + r = fd_verify_regular(fd); + if (r < 0) + return r; + + r = access_fd(fd, X_OK); + if (r < 0) + return r; + + return TAKE_FD(fd); +} + int pin_callout_binary(const char *path) { int r; @@ -261,14 +282,14 @@ int pin_callout_binary(const char *path) { const char *e; if (find_environment_binary(fn, &e) >= 0) - return RET_NERRNO(open(e, O_CLOEXEC|O_PATH)); + return open_executable(e); _cleanup_free_ char *np = NULL; if (find_build_dir_binary(fn, &np) >= 0) { - r = RET_NERRNO(open(np, O_CLOEXEC|O_PATH)); + r = open_executable(np); if (r >= 0) return r; } - return RET_NERRNO(open(path, O_CLOEXEC|O_PATH)); + return open_executable(path); }