From 8036e4d0b9ef0990597196155fe6fc6329a6a881 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 29 Nov 2016 16:49:30 +0100 Subject: [PATCH] fs-util: add flags parameter to chase_symlinks() 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 | 34 ++++++++++++++-------------------- src/basic/fs-util.h | 7 +++++-- src/basic/mount-util.c | 32 -------------------------------- src/basic/path-util.c | 2 +- 4 files changed, 20 insertions(+), 55 deletions(-) diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index b97edb552..e47b050b0 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -236,7 +236,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); @@ -603,7 +603,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 */ @@ -616,8 +616,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 @@ -634,16 +635,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; @@ -797,13 +801,3 @@ int chase_symlinks(const char *path, const char *_root, char **ret) { return 0; } #endif // 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); -} diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h index d58b14801..b5883b6c5 100644 --- a/src/basic/fs-util.h +++ b/src/basic/fs-util.h @@ -91,5 +91,8 @@ union inotify_event_buffer { int inotify_add_watch_fd(int fd, int what, uint32_t mask); #endif // 0 -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); diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c index 61190e40a..d757abad9 100644 --- a/src/basic/mount-util.c +++ b/src/basic/mount-util.c @@ -691,35 +691,3 @@ int umount_verbose(const char *what) { return 0; } #endif // 0 - -const char *mount_propagation_flags_to_string(unsigned long flags) { - - switch (flags & (MS_SHARED|MS_SLAVE|MS_PRIVATE)) { - - case MS_SHARED: - return "shared"; - - case MS_SLAVE: - return "slave"; - - case MS_PRIVATE: - return "private"; - } - - return NULL; -} - -unsigned long mount_propagation_flags_from_string(const char *name) { - - if (isempty(name)) - return 0; - - if (streq(name, "shared")) - return MS_SHARED; - if (streq(name, "slave")) - return MS_SLAVE; - if (streq(name, "private")) - return MS_PRIVATE; - - return 0; -} diff --git a/src/basic/path-util.c b/src/basic/path-util.c index 9dd073338..84f327d7d 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -254,7 +254,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; -- 2.30.2