summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-03-22 19:54:24 +0100
committerLennart Poettering <lennart@poettering.net>2018-03-22 19:54:24 +0100
commit62570f6f03fd6defb0d053e3650457553e42085a (patch)
tree3505b0fbb64a1d78e0c4dc5cbe30806e42608220 /src
parent1147eef0b6a5937526247ff81ca1e5e45205ed16 (diff)
downloadsystemd-62570f6f03fd6defb0d053e3650457553e42085a.tar.gz
fs-util: add new CHASE_TRAIL_SLASH flag for chase_symlinks()
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
Diffstat (limited to 'src')
-rw-r--r--src/basic/fs-util.c6
-rw-r--r--src/basic/fs-util.h1
-rw-r--r--src/basic/mount-util.c2
-rw-r--r--src/core/dbus-manager.c2
-rw-r--r--src/core/namespace.c2
-rw-r--r--src/delta/delta.c4
-rw-r--r--src/journal/journalctl.c2
-rw-r--r--src/machine/machine-dbus.c2
-rw-r--r--src/shared/dissect-image.c2
-rw-r--r--src/shared/machine-image.c10
10 files changed, 18 insertions, 15 deletions
diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c
index c65ba4bfe5..fc8f87da5f 100644
--- a/src/basic/fs-util.c
+++ b/src/basic/fs-util.c
@@ -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;
}
diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h
index 82d7e765b3..5298a41f0e 100644
--- a/src/basic/fs-util.h
+++ b/src/basic/fs-util.h
@@ -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);
diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c
index 8151b3a4e4..9672a7cf96 100644
--- a/src/basic/mount-util.c
+++ b/src/basic/mount-util.c
@@ -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;
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index 90e7f86389..9136dcf17c 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -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);
diff --git a/src/core/namespace.c b/src/core/namespace.c
index 0e9c7b8fb4..a11c8e0147 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -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;
diff --git a/src/delta/delta.c b/src/delta/delta.c
index 49d9f0bb03..dc064b4c07 100644
--- a/src/delta/delta.c
+++ b/src/delta/delta.c
@@ -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;
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index e8eb9ac161..fa2127c2b6 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -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");
diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c
index 9c435d6715..37e16bbe79 100644
--- a/src/machine/machine-dbus.c
+++ b/src/machine/machine-dbus.c
@@ -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");
diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c
index faeaddc66e..7af59422b2 100644
--- a/src/shared/dissect-image.c
+++ b/src/shared/dissect-image.c
@@ -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;
diff --git a/src/shared/machine-image.c b/src/shared/machine-image.c
index 66eefb3036..12528ed015 100644
--- a/src/shared/machine-image.c
+++ b/src/shared/machine-image.c
@@ -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) {