]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
chase: make the result absolute when a symlink is absolute
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 16 Apr 2023 20:19:07 +0000 (05:19 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 18 Apr 2023 18:28:34 +0000 (03:28 +0900)
As the path may be outside of the specified dir_fd.

src/basic/chase.c
src/test/test-chase.c

index a6a37978e8f57d727c5e51aaf1e434314096be1e..2b8befc7f7b22c5af1bea3c6bfdacfb0b53688d7 100644 (file)
@@ -374,6 +374,11 @@ int chaseat(int dir_fd, const char *path, ChaseFlags flags, char **ret_path, int
                                     unsafe_transition(&st_child, &st))
                                         return log_unsafe_transition(child, fd, path, flags);
 
+                                /* When CHASE_AT_RESOLVE_IN_ROOT is not set, now the chased path may be
+                                 * outside of the specified dir_fd. Let's make the result absolute. */
+                                if (!FLAGS_SET(flags, CHASE_AT_RESOLVE_IN_ROOT))
+                                        need_absolute = true;
+
                                 r = free_and_strdup(&done, need_absolute ? "/" : NULL);
                                 if (r < 0)
                                         return r;
index 52ea21a54c67646dc8ae3adb3c65dbaf9d2d0f37..c5fc08ca25a0e961c239b689cc6f2d8e2bb9f704 100644 (file)
@@ -457,7 +457,16 @@ TEST(chaseat) {
 
         fd = safe_close(fd);
 
-        /* If the file descriptor does not point to the root directory, the result will be relative. */
+        /* If the file descriptor does not point to the root directory, the result will be relative
+         * unless the result is outside of the specified file descriptor. */
+
+        assert_se(chaseat(tfd, "abc", 0, &result, NULL) >= 0);
+        assert_se(streq(result, "/usr"));
+        result = mfree(result);
+
+        assert_se(chaseat(tfd, "/abc", 0, &result, NULL) >= 0);
+        assert_se(streq(result, "/usr"));
+        result = mfree(result);
 
         assert_se(chaseat(tfd, "abc", CHASE_AT_RESOLVE_IN_ROOT, NULL, NULL) == -ENOENT);
         assert_se(chaseat(tfd, "/abc", CHASE_AT_RESOLVE_IN_ROOT, NULL, NULL) == -ENOENT);