summaryrefslogtreecommitdiffstats
path: root/src/test
diff options
context:
space:
mode:
authorDaan De Meyer <daan.j.demeyer@gmail.com>2023-01-06 13:49:09 +0100
committerDaan De Meyer <daan.j.demeyer@gmail.com>2023-02-07 16:36:54 +0100
commitc677e13c35ff2d475199bcc9432892396485b6b8 (patch)
tree0b51f16336f4ea95400a1e2647c062f1d740d190 /src/test
parentMerge pull request #26324 from yuwata/argv-util-update-short-name (diff)
downloadsystemd-c677e13c35ff2d475199bcc9432892396485b6b8.tar.xz
systemd-c677e13c35ff2d475199bcc9432892396485b6b8.zip
chase-symlinks: chase_symlinks_at() AT_FDCWD fixes
- Whether we should return an absolute path or not is irrelevant to whether CHASE_AT_RESOLVE_IN_ROOT is set. We should only return an absolute path if we are provided one and the directory file descriptor is AT_FDCWD - When the directory file descriptor is AT_FDCWD, we should always resolve symlinks against "/". Currently, if the directory file descriptor is AT_FDCWD and CHASE_AT_RESOLVE_IN_ROOT is set, we resolve symlinks against the current working directory which is almost always not going to be what the caller wants. - Currently, if we provide an absolute path with a positive directory file descriptor without CHASE_AT_RESOLVE_IN_ROOT SET, we interpret the path relative to "/" instead of the given directory file descriptor. Let's make sure that when we're given a positive directory file descriptor, we always resolve the given path relative to it.
Diffstat (limited to 'src/test')
-rw-r--r--src/test/test-fs-util.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c
index 668a44733b..3fc5f88d26 100644
--- a/src/test/test-fs-util.c
+++ b/src/test/test-fs-util.c
@@ -430,6 +430,42 @@ TEST(chase_symlinks) {
assert_se(rm_rf(temp, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);
}
+TEST(chase_symlinks_at) {
+ _cleanup_(rm_rf_physical_and_freep) char *t = NULL;
+ _cleanup_close_ int tfd = -EBADF, fd = -EBADF;
+ _cleanup_free_ char *result = NULL;
+ const char *p;
+
+ assert_se((tfd = mkdtemp_open(NULL, 0, &t)) >= 0);
+
+ /* Test that AT_FDCWD with CHASE_AT_RESOLVE_IN_ROOT resolves against / and not the current working
+ * directory. */
+
+ assert_se(symlinkat("/usr", tfd, "abc") >= 0);
+
+ p = strjoina(t, "/abc");
+ assert_se(chase_symlinks_at(AT_FDCWD, p, CHASE_AT_RESOLVE_IN_ROOT, &result, NULL) >= 0);
+ assert_se(streq(result, "/usr"));
+ result = mfree(result);
+
+ /* Test that absolute path or not are the same when resolving relative to a directory file
+ * descriptor and that we always get a relative path back. */
+
+ assert_se(fd = openat(tfd, "def", O_CREAT|O_CLOEXEC, 0700) >= 0);
+ fd = safe_close(fd);
+ assert_se(symlinkat("/def", tfd, "qed") >= 0);
+ assert_se(chase_symlinks_at(tfd, "qed", CHASE_AT_RESOLVE_IN_ROOT, &result, NULL) >= 0);
+ assert_se(streq(result, "def"));
+ result = mfree(result);
+ assert_se(chase_symlinks_at(tfd, "/qed", CHASE_AT_RESOLVE_IN_ROOT, &result, NULL) >= 0);
+ assert_se(streq(result, "def"));
+ result = mfree(result);
+
+ /* Valid directory file descriptor without CHASE_AT_RESOLVE_IN_ROOT should resolve symlinks against
+ * host's root. */
+ assert_se(chase_symlinks_at(tfd, "/qed", 0, &result, NULL) == -ENOENT);
+}
+
TEST(unlink_noerrno) {
char *name;
int fd;