]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fs-util: add new CHASE_TRAIL_SLASH flag for chase_symlinks()
authorLennart Poettering <lennart@poettering.net>
Thu, 22 Mar 2018 18:54:24 +0000 (19:54 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 22 Mar 2018 18:54:24 +0000 (19:54 +0100)
This rearranges chase_symlinks() a bit: if no special flags are
specified it will now revert to behaviour before
b12d25a8d631af00b200e7aa9dbba6ba4a4a59ff. However, if the new
CHASE_TRAIL_SLASH flag is specified it will follow the behaviour
introduced by that commit.

I wasn't sure which one to make the beaviour that requires specification
of a flag to enable. I opted to make the "append trailing slash"
behaviour the one to enable by a flag, following the thinking that the
function should primarily be used to generate a normalized path, and I
am pretty sure a path without trailing slash is the more "normalized"
one, as the trailing slash is not really a part of it, but merely a
"decorator" that tells various system calls to generate ENOTDIR if the
path doesn't refer to a path.

Or to say this differently: if the slash was part of normalization then
we really should add it in all cases when the final path is a directory,
not just when the user originally specified it.

Fixes: #8544
Replaces: #8545

src/basic/fs-util.c
src/basic/fs-util.h
src/basic/mount-util.c
src/core/dbus-manager.c
src/core/namespace.c
src/delta/delta.c
src/journal/journalctl.c
src/machine/machine-dbus.c
src/shared/dissect-image.c
src/shared/machine-image.c

index c65ba4bfe57f23118084d5f94e74d6fb28e70ea4..fc8f87da5fa366db97df6bee05cb7470e2d7dfe9 100644 (file)
@@ -685,8 +685,10 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
                 /* Just a single slash? Then we reached the end. */
                 if (path_equal(first, "/")) {
                         /* Preserve the trailing slash */
-                        if (!strextend(&done, "/", NULL))
-                                return -ENOMEM;
+
+                        if (flags & CHASE_TRAIL_SLASH)
+                                if (!strextend(&done, "/", NULL))
+                                        return -ENOMEM;
 
                         break;
                 }
index 82d7e765b3e1d68aa533b34ecd48abc3f23c3833..5298a41f0efd9de5ef135d0d4ba24b0dd9a7fe6e 100644 (file)
@@ -86,6 +86,7 @@ enum {
         CHASE_NO_AUTOFS   = 1U << 2,   /* If set, return -EREMOTE if autofs mount point found */
         CHASE_SAFE        = 1U << 3,   /* If set, return EPERM if we ever traverse from unprivileged to privileged files or directories */
         CHASE_OPEN        = 1U << 4,   /* If set, return an O_PATH object to the final component */
+        CHASE_TRAIL_SLASH = 1U << 5,   /* If set, any trailing slash will be preserved */
 };
 
 int chase_symlinks(const char *path_with_prefix, const char *root, unsigned flags, char **ret);
index 8151b3a4e4f7305babe535895d56d31590d4935c..9672a7cf96f636b4999d4ca0142247e8c59456da 100644 (file)
@@ -296,7 +296,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, 0, &canonical);
+                r = chase_symlinks(t, root, CHASE_TRAIL_SLASH, &canonical);
                 if (r < 0)
                         return r;
 
index 90e7f863895d7473f598e73d18a5a8fcb32fc818..9136dcf17c7c207f535284215cd3e782ef336cfc 100644 (file)
@@ -1583,7 +1583,7 @@ static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_er
                 if (!path_is_absolute(init))
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path to init binary '%s' not absolute.", init);
 
-                r = chase_symlinks(init, root, CHASE_PREFIX_ROOT, &chased);
+                r = chase_symlinks(init, root, CHASE_PREFIX_ROOT|CHASE_TRAIL_SLASH, &chased);
                 if (r < 0)
                         return sd_bus_error_set_errnof(error, r, "Could not resolve init executable %s: %m", init);
 
index 0e9c7b8fb4cfd63d57fb481a5dd3f6a853d349ff..a11c8e01471d2aaba391da3f23b657e4cfd9b36c 100644 (file)
@@ -824,7 +824,7 @@ static int mount_entry_chase(
          * chase the symlinks on our own first. This is called for the destination path, as well as the source path (if
          * that applies). The result is stored in "location". */
 
-        r = chase_symlinks(path, root_directory, chase_nonexistent ? CHASE_NONEXISTENT : 0, &chased);
+        r = chase_symlinks(path, root_directory, CHASE_TRAIL_SLASH | (chase_nonexistent ? CHASE_NONEXISTENT : 0), &chased);
         if (r == -ENOENT && m->ignore) {
                 log_debug_errno(r, "Path %s does not exist, ignoring.", path);
                 return 0;
index 49d9f0bb032e6139fcdbf2c85e0a2324d1aeca00..dc064b4c07e324489762d23084bcfb52d276fbb0 100644 (file)
@@ -90,11 +90,11 @@ static int equivalent(const char *a, const char *b) {
         _cleanup_free_ char *x = NULL, *y = NULL;
         int r;
 
-        r = chase_symlinks(a, NULL, 0, &x);
+        r = chase_symlinks(a, NULL, CHASE_TRAIL_SLASH, &x);
         if (r < 0)
                 return r;
 
-        r = chase_symlinks(b, NULL, 0, &y);
+        r = chase_symlinks(b, NULL, CHASE_TRAIL_SLASH, &y);
         if (r < 0)
                 return r;
 
index e8eb9ac1611098367e90a65a00971fcbbaa43f08..fa2127c2b6cc6609d1eeba5ca2422cc8fc11d4c3 100644 (file)
@@ -1070,7 +1070,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, 0, &p);
+                        r = chase_symlinks(*i, NULL, CHASE_TRAIL_SLASH, &p);
                         if (r < 0)
                                 return log_error_errno(r, "Couldn't canonicalize path: %m");
 
index 9c435d6715a74c9fcb618417344a6a3710db6375..37e16bbe7956b3184e470bb6d4863abc668e53a4 100644 (file)
@@ -907,7 +907,7 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu
         if (laccess(p, F_OK) < 0)
                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Container does not allow propagation of mount points.");
 
-        r = chase_symlinks(src, NULL, 0, &chased_src);
+        r = chase_symlinks(src, NULL, CHASE_TRAIL_SLASH, &chased_src);
         if (r < 0)
                 return sd_bus_error_set_errnof(error, r, "Failed to resolve source path: %m");
 
index faeaddc66ebf5dd3e422cb5a6c53bbb23ace782a..7af59422b27eeccde01df11a2a6129b24a5a5d73 100644 (file)
@@ -1288,7 +1288,7 @@ int dissected_image_acquire_metadata(DissectedImage *m) {
                         NULSTR_FOREACH(p, paths[k]) {
                                 _cleanup_free_ char *q = NULL;
 
-                                r = chase_symlinks(p, t, CHASE_PREFIX_ROOT, &q);
+                                r = chase_symlinks(p, t, CHASE_PREFIX_ROOT|CHASE_TRAIL_SLASH, &q);
                                 if (r < 0)
                                         continue;
 
index 66eefb3036628ecb02f7168f597e50ccfbe19e89..12528ed0154277b90dae4e58263460fa652bdd8d 100644 (file)
@@ -938,7 +938,7 @@ int image_read_metadata(Image *i) {
                 _cleanup_free_ char *hostname = NULL;
                 _cleanup_free_ char *path = NULL;
 
-                r = chase_symlinks("/etc/hostname", i->path, CHASE_PREFIX_ROOT, &path);
+                r = chase_symlinks("/etc/hostname", i->path, CHASE_PREFIX_ROOT|CHASE_TRAIL_SLASH, &path);
                 if (r < 0 && r != -ENOENT)
                         log_debug_errno(r, "Failed to chase /etc/hostname in image %s: %m", i->name);
                 else if (r >= 0) {
@@ -949,7 +949,7 @@ int image_read_metadata(Image *i) {
 
                 path = mfree(path);
 
-                r = chase_symlinks("/etc/machine-id", i->path, CHASE_PREFIX_ROOT, &path);
+                r = chase_symlinks("/etc/machine-id", i->path, CHASE_PREFIX_ROOT|CHASE_TRAIL_SLASH, &path);
                 if (r < 0 && r != -ENOENT)
                         log_debug_errno(r, "Failed to chase /etc/machine-id in image %s: %m", i->name);
                 else if (r >= 0) {
@@ -967,7 +967,7 @@ int image_read_metadata(Image *i) {
 
                 path = mfree(path);
 
-                r = chase_symlinks("/etc/machine-info", i->path, CHASE_PREFIX_ROOT, &path);
+                r = chase_symlinks("/etc/machine-info", i->path, CHASE_PREFIX_ROOT|CHASE_TRAIL_SLASH, &path);
                 if (r < 0 && r != -ENOENT)
                         log_debug_errno(r, "Failed to chase /etc/machine-info in image %s: %m", i->name);
                 else if (r >= 0) {
@@ -978,9 +978,9 @@ int image_read_metadata(Image *i) {
 
                 path = mfree(path);
 
-                r = chase_symlinks("/etc/os-release", i->path, CHASE_PREFIX_ROOT, &path);
+                r = chase_symlinks("/etc/os-release", i->path, CHASE_PREFIX_ROOT|CHASE_TRAIL_SLASH, &path);
                 if (r == -ENOENT)
-                        r = chase_symlinks("/usr/lib/os-release", i->path, CHASE_PREFIX_ROOT, &path);
+                        r = chase_symlinks("/usr/lib/os-release", i->path, CHASE_PREFIX_ROOT|CHASE_TRAIL_SLASH, &path);
                 if (r < 0 && r != -ENOENT)
                         log_debug_errno(r, "Failed to chase os-release in image: %m");
                 else if (r >= 0) {