From: Mike Yuan Date: Sat, 5 Apr 2025 20:35:01 +0000 (+0200) Subject: build-path: port to open_and_check_executable(), do not return resolved path X-Git-Tag: v258-rc1~902^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=28b6bfd3704916479fc59d0a150c0c22d2297fec;p=thirdparty%2Fsystemd.git build-path: port to open_and_check_executable(), do not return resolved path Follow-up for b58c240312a5cc0f9f9eab3018d6459e44d085e0 We need to be extremely careful with using the path associated with fd, since it contains the resolved path if a symlink was opened. In particular, it's really not desirable to return the resolved executable path in pin_callout_binary(), which would end up as argv[0] in udev_event_spawn(), potentially changing the behavior of spawned process. --- diff --git a/src/basic/build-path.c b/src/basic/build-path.c index ba49273cd39..95de7d3ca34 100644 --- a/src/basic/build-path.c +++ b/src/basic/build-path.c @@ -246,34 +246,8 @@ int invoke_callout_binary(const char *path, char *const argv[]) { return -errno; } -static int open_executable(const char *path, char **ret_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; - - if (ret_path) { - r = fd_get_path(fd, ret_path); - if (r < 0) - return r; - } - - return TAKE_FD(fd); -} - int pin_callout_binary(const char *path, char **ret_path) { - int r; + int r, fd; assert(path); @@ -288,15 +262,25 @@ int pin_callout_binary(const char *path, char **ret_path) { return -EISDIR; const char *e; - if (find_environment_binary(fn, &e) >= 0) - return open_executable(e, ret_path); + if (find_environment_binary(fn, &e) >= 0) { + /* The environment variable counts. We'd fail if the executable is not available/invalid. */ + r = open_and_check_executable(e, /* root = */ NULL, ret_path, &fd); + if (r < 0) + return r; + + return fd; + } _cleanup_free_ char *np = NULL; if (find_build_dir_binary(fn, &np) >= 0) { - r = open_executable(np, ret_path); + r = open_and_check_executable(np, /* root = */ NULL, ret_path, &fd); if (r >= 0) - return r; + return fd; } - return open_executable(path, ret_path); + r = open_and_check_executable(path, /* root = */ NULL, ret_path, &fd); + if (r < 0) + return r; + + return fd; }