]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fs-util: add flags parameter to chase_symlinks()
authorLennart Poettering <lennart@poettering.net>
Tue, 29 Nov 2016 15:49:30 +0000 (16:49 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 30 Nov 2016 23:25:51 +0000 (00:25 +0100)
Let's remove chase_symlinks_prefix() and instead introduce a flags parameter to
chase_symlinks(), with a flag CHASE_PREFIX_ROOT that exposes the behaviour of
chase_symlinks_prefix().

src/basic/fs-util.c
src/basic/fs-util.h
src/basic/mount-util.c
src/basic/path-util.c
src/core/namespace.c
src/delta/delta.c
src/journal/journalctl.c
src/nspawn/nspawn-mount.c
src/nspawn/nspawn.c
src/systemctl/systemctl.c
src/test/test-fs-util.c

index c20faf67b02658c1c1c2b7103ba548fc65c88313..0a3e983631b09082260f056e16544dc7de2cfb18 100644 (file)
@@ -235,7 +235,7 @@ int readlink_and_canonicalize(const char *p, const char *root, char **ret) {
         if (r < 0)
                 return r;
 
-        r = chase_symlinks(t, root, &s);
+        r = chase_symlinks(t, root, 0, &s);
         if (r < 0)
                 /* If we can't follow up, then let's return the original string, slightly cleaned up. */
                 *ret = path_kill_slashes(t);
@@ -598,7 +598,7 @@ int inotify_add_watch_fd(int fd, int what, uint32_t mask) {
         return r;
 }
 
-int chase_symlinks(const char *path, const char *_root, char **ret) {
+int chase_symlinks(const char *path, const char *original_root, unsigned flags, char **ret) {
         _cleanup_free_ char *buffer = NULL, *done = NULL, *root = NULL;
         _cleanup_close_ int fd = -1;
         unsigned max_follow = 32; /* how many symlinks to follow before giving up and returning ELOOP */
@@ -611,8 +611,9 @@ int chase_symlinks(const char *path, const char *_root, char **ret) {
          * symlinks relative to a root directory, instead of the root of the host.
          *
          * Note that "root" primarily matters if we encounter an absolute symlink. It is also used when following
-         * relative symlinks to ensure they cannot be used to "escape" the root directory. The path parameter passed
-         * shall *not* be prefixed by it.
+         * relative symlinks to ensure they cannot be used to "escape" the root directory. The path parameter passed is
+         * assumed to be already prefixed by it, except if the CHASE_PREFIX_ROOT flag is set, in which case it is first
+         * prefixed accordingly.
          *
          * Algorithmically this operates on two path buffers: "done" are the components of the path we already
          * processed and resolved symlinks, "." and ".." of. "todo" are the components of the path we still need to
@@ -629,16 +630,19 @@ int chase_symlinks(const char *path, const char *_root, char **ret) {
          * Note: there's also chase_symlinks_prefix() (see below), which as first step prefixes the passed path by the
          * passed root. */
 
-        r = path_make_absolute_cwd(path, &buffer);
-        if (r < 0)
-                return r;
-
-        if (_root) {
-                r = path_make_absolute_cwd(_root, &root);
+        if (original_root) {
+                r = path_make_absolute_cwd(original_root, &root);
                 if (r < 0)
                         return r;
+
+                if (flags & CHASE_PREFIX_ROOT)
+                        path = prefix_roota(root, path);
         }
 
+        r = path_make_absolute_cwd(path, &buffer);
+        if (r < 0)
+                return r;
+
         fd = open("/", O_CLOEXEC|O_NOFOLLOW|O_PATH);
         if (fd < 0)
                 return -errno;
@@ -791,13 +795,3 @@ int chase_symlinks(const char *path, const char *_root, char **ret) {
 
         return 0;
 }
-
-int chase_symlinks_prefix(const char *path, const char *root, char **ret) {
-        const char *t;
-
-        /* Same as chase_symlinks(), but prefixes 'path' by 'root' first. */
-
-        t = prefix_roota(root, path);
-
-        return chase_symlinks(t, root, ret);
-}
index 2d039e3b98b90eb03067d616eafdad725292a9f6..ee3d6bf7afb92cc9b85148db3de55f2365044f9a 100644 (file)
@@ -78,5 +78,8 @@ union inotify_event_buffer {
 
 int inotify_add_watch_fd(int fd, int what, uint32_t mask);
 
-int chase_symlinks(const char *path_with_prefix, const char *root, char **ret);
-int chase_symlinks_prefix(const char *path_without_prefix, const char *root, char **ret);
+enum {
+        CHASE_PREFIX_ROOT = 1,   /* If set, the specified path will be prefixed by the specified root before beginning the iteration */
+};
+
+int chase_symlinks(const char *path_with_prefix, const char *root, unsigned flags, char **ret);
index 4a72d4700a5a7903c94092c94469c500169b874f..352c3505fb34e2045f88be4f43b5642fe8f718b0 100644 (file)
@@ -221,7 +221,7 @@ int path_is_mount_point(const char *t, const char *root, int flags) {
          * /bin -> /usr/bin/ and /usr is a mount point, then the parent that we
          * look at needs to be /usr, not /. */
         if (flags & AT_SYMLINK_FOLLOW) {
-                r = chase_symlinks(t, root, &canonical);
+                r = chase_symlinks(t, root, 0, &canonical);
                 if (r < 0)
                         return r;
 
index 475a73d292aedf817b747b9cefd2914f3299767e..9a51e0d8bc783bf4147378b74a83bbede40ed542 100644 (file)
@@ -252,7 +252,7 @@ char **path_strv_resolve(char **l, const char *root) {
                 } else
                         t = *s;
 
-                r = chase_symlinks(t, root, &u);
+                r = chase_symlinks(t, root, 0, &u);
                 if (r == -ENOENT) {
                         if (root) {
                                 u = orig;
index 9954b9e97d5df12657f6ed9d6e76bf97e2637755..aca47a4d2fb7f065c5e859f2052a4fd98962dba0 100644 (file)
@@ -665,7 +665,7 @@ static int chase_all_symlinks(const char *root_directory, BindMount *m, unsigned
                 _cleanup_free_ char *chased = NULL;
                 int k;
 
-                k = chase_symlinks(bind_mount_path(f), root_directory, &chased);
+                k = chase_symlinks(bind_mount_path(f), root_directory, 0, &chased);
                 if (k < 0) {
                         /* Get only real errors */
                         if (r >= 0 && (k != -ENOENT || !f->ignore))
index 70ff79330428ad7669249fe364640373ee814299..107b105fde8f99288df129c737124e6607f3dd45 100644 (file)
@@ -89,11 +89,11 @@ static int equivalent(const char *a, const char *b) {
         _cleanup_free_ char *x = NULL, *y = NULL;
         int r;
 
-        r = chase_symlinks(a, NULL, &x);
+        r = chase_symlinks(a, NULL, 0, &x);
         if (r < 0)
                 return r;
 
-        r = chase_symlinks(b, NULL, &y);
+        r = chase_symlinks(b, NULL, 0, &y);
         if (r < 0)
                 return r;
 
@@ -361,7 +361,7 @@ static int should_skip_prefix(const char* p) {
         int r;
         _cleanup_free_ char *target = NULL;
 
-        r = chase_symlinks(p, NULL, &target);
+        r = chase_symlinks(p, NULL, 0, &target);
         if (r < 0)
                 return r;
 
index d0d4524c9f277f2a1b429488b295b14a134d272e..10d3ff3b45ca8a17ca10b3a2eb8bcd792924df46 100644 (file)
@@ -941,7 +941,7 @@ static int add_matches(sd_journal *j, char **args) {
                         _cleanup_free_ char *p = NULL, *t = NULL, *t2 = NULL, *interpreter = NULL;
                         struct stat st;
 
-                        r = chase_symlinks(*i, NULL, &p);
+                        r = chase_symlinks(*i, NULL, 0, &p);
                         if (r < 0)
                                 return log_error_errno(r, "Couldn't canonicalize path: %m");
 
index 914e43da98b9b646a9c3029d8d2bc3fa8cd680db..de9e40d55f9f3eda8880c2ab8477469f98a7645f 100644 (file)
@@ -512,7 +512,7 @@ static int mount_bind(const char *dest, CustomMount *m) {
         if (stat(m->source, &source_st) < 0)
                 return log_error_errno(errno, "Failed to stat %s: %m", m->source);
 
-        r = chase_symlinks_prefix(m->destination, dest, &where);
+        r = chase_symlinks(m->destination, dest, CHASE_PREFIX_ROOT, &where);
         if (r < 0)
                 return log_error_errno(r, "Failed to resolve %s: %m", m->destination);
 
@@ -572,7 +572,7 @@ static int mount_tmpfs(
         assert(dest);
         assert(m);
 
-        r = chase_symlinks_prefix(m->destination, dest, &where);
+        r = chase_symlinks(m->destination, dest, CHASE_PREFIX_ROOT, &where);
         if (r < 0)
                 return log_error_errno(r, "Failed to resolve %s: %m", m->destination);
 
@@ -612,7 +612,7 @@ static int mount_overlay(const char *dest, CustomMount *m) {
         assert(dest);
         assert(m);
 
-        r = chase_symlinks_prefix(m->destination, dest, &where);
+        r = chase_symlinks(m->destination, dest, CHASE_PREFIX_ROOT, &where);
         if (r < 0)
                 return log_error_errno(r, "Failed to resolve %s: %m", m->destination);
 
index 624c4f6a40d433604c89c41c1df37c5d222df0af..1a625e142e26560a89a16aea55c43feba78a7f02 100644 (file)
@@ -2675,7 +2675,7 @@ static int chase_symlinks_and_update(char **p) {
         if (!*p)
                 return 0;
 
-        r = chase_symlinks(*p, NULL, &chased);
+        r = chase_symlinks(*p, NULL, 0, &chased);
         if (r < 0)
                 return log_error_errno(r, "Failed to resolve path %s: %m", *p);
 
index c3cb8ef1088f464a20434ea04bcc33747778a92a..67516cf5fb8bb542109768fb1149b5a9ff92a90f 100644 (file)
@@ -2487,7 +2487,7 @@ static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **un
                 if (!path)
                         return log_oom();
 
-                r = chase_symlinks(path, arg_root, &lpath);
+                r = chase_symlinks(path, arg_root, 0, &lpath);
                 if (r == -ENOENT)
                         continue;
                 if (r == -ENOMEM)
index 792ad46847fbf57503bee7b912a46aaac3ba8114..fac3a1d089b117bf3b553de36cf0d2f13987bfac 100644 (file)
@@ -62,18 +62,18 @@ static void test_chase_symlinks(void) {
 
         /* Paths that use symlinks underneath the "root" */
 
-        r = chase_symlinks(p, NULL, &result);
+        r = chase_symlinks(p, NULL, 0, &result);
         assert_se(r >= 0);
         assert_se(path_equal(result, "/usr"));
 
         result = mfree(result);
-        r = chase_symlinks(p, temp, &result);
+        r = chase_symlinks(p, temp, 0, &result);
         assert_se(r == -ENOENT);
 
         q = strjoina(temp, "/usr");
         assert_se(mkdir(q, 0700) >= 0);
 
-        r = chase_symlinks(p, temp, &result);
+        r = chase_symlinks(p, temp, 0, &result);
         assert_se(r >= 0);
         assert_se(path_equal(result, q));
 
@@ -81,12 +81,12 @@ static void test_chase_symlinks(void) {
         assert_se(symlink("/", p) >= 0);
 
         result = mfree(result);
-        r = chase_symlinks(p, NULL, &result);
+        r = chase_symlinks(p, NULL, 0, &result);
         assert_se(r >= 0);
         assert_se(path_equal(result, "/"));
 
         result = mfree(result);
-        r = chase_symlinks(p, temp, &result);
+        r = chase_symlinks(p, temp, 0, &result);
         assert_se(r >= 0);
         assert_se(path_equal(result, temp));
 
@@ -96,21 +96,21 @@ static void test_chase_symlinks(void) {
         assert_se(symlink("../../..", p) >= 0);
 
         result = mfree(result);
-        r = chase_symlinks(p, temp, &result);
+        r = chase_symlinks(p, temp, 0, &result);
         assert_se(r == 0 && path_equal(result, temp));
 
         p = strjoina(temp, "/6dotsusr");
         assert_se(symlink("../../../usr", p) >= 0);
 
         result = mfree(result);
-        r = chase_symlinks(p, temp, &result);
+        r = chase_symlinks(p, temp, 0, &result);
         assert_se(r == 0 && path_equal(result, q));
 
         p = strjoina(temp, "/top/8dotsusr");
         assert_se(symlink("../../../../usr", p) >= 0);
 
         result = mfree(result);
-        r = chase_symlinks(p, temp, &result);
+        r = chase_symlinks(p, temp, 0, &result);
         assert_se(r == 0 && path_equal(result, q));
 
         /* Paths that contain repeated slashes */
@@ -119,28 +119,28 @@ static void test_chase_symlinks(void) {
         assert_se(symlink("///usr///", p) >= 0);
 
         result = mfree(result);
-        r = chase_symlinks(p, NULL, &result);
+        r = chase_symlinks(p, NULL, 0, &result);
         assert_se(r >= 0);
         assert_se(path_equal(result, "/usr"));
 
         result = mfree(result);
-        r = chase_symlinks(p, temp, &result);
+        r = chase_symlinks(p, temp, 0, &result);
         assert_se(r >= 0);
         assert_se(path_equal(result, q));
 
         /* Paths using . */
 
         result = mfree(result);
-        r = chase_symlinks("/etc/./.././", NULL, &result);
+        r = chase_symlinks("/etc/./.././", NULL, 0, &result);
         assert_se(r >= 0);
         assert_se(path_equal(result, "/"));
 
         result = mfree(result);
-        r = chase_symlinks("/etc/./.././", "/etc", &result);
+        r = chase_symlinks("/etc/./.././", "/etc", 0, &result);
         assert_se(r == 0 && path_equal(result, "/etc"));
 
         result = mfree(result);
-        r = chase_symlinks("/etc/machine-id/foo", NULL, &result);
+        r = chase_symlinks("/etc/machine-id/foo", NULL, 0, &result);
         assert_se(r == -ENOTDIR);
 
         /* Path that loops back to self */
@@ -148,7 +148,7 @@ static void test_chase_symlinks(void) {
         result = mfree(result);
         p = strjoina(temp, "/recursive-symlink");
         assert_se(symlink("recursive-symlink", p) >= 0);
-        r = chase_symlinks(p, NULL, &result);
+        r = chase_symlinks(p, NULL, 0, &result);
         assert_se(r == -ELOOP);
 
         assert_se(rm_rf(temp, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0);