]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
build-path: port to open_and_check_executable(), do not return resolved path
authorMike Yuan <me@yhndnzj.com>
Sat, 5 Apr 2025 20:35:01 +0000 (22:35 +0200)
committerMike Yuan <me@yhndnzj.com>
Sun, 6 Apr 2025 00:39:05 +0000 (02:39 +0200)
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.

src/basic/build-path.c

index ba49273cd396d3da3d38090356a0b0b353e7287e..95de7d3ca34721168ca720a8436d3ee820b8db71 100644 (file)
@@ -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;
 }