[systemd-devel] [PATCH 7/9] nspawn: escape paths in overlay mount options
Richard Maw
richard.maw at codethink.co.uk
Thu May 28 05:02:13 PDT 2015
Overlayfs uses , as an option separator and : as a list separator. These
characters are both valid in file paths, so overlayfs allows file paths
which contain these characters to backslash escape these values.
---
src/nspawn/nspawn.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 56 insertions(+), 7 deletions(-)
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index c40d50f..f7580f9 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -1237,6 +1237,42 @@ static int mount_tmpfs(const char *dest, CustomMount *m) {
return 0;
}
+static char *escaped_overlay_path(const char *path) {
+ _cleanup_free_ char *colon_escaped = NULL;
+ char *comma_escaped = NULL;
+
+ colon_escaped = strreplace(path, ":", "\\:");
+ if (!colon_escaped)
+ return NULL;
+
+ comma_escaped = strreplace(colon_escaped, ",", "\\,");
+
+ return comma_escaped;
+}
+
+static char *joined_and_escaped_lower_dirs(char * const *lower) {
+ _cleanup_free_ char *s = NULL;
+ char *ret = NULL;
+ char * const *path;
+ bool first = true;
+
+ STRV_FOREACH_BACKWARDS(path, lower) {
+ _cleanup_free_ char *escaped_path = NULL;
+ escaped_path = escaped_overlay_path(*path);
+ if (first) {
+ if (!strextend(&s, escaped_path, NULL))
+ return NULL;
+ first = false;
+ } else
+ if (!strextend(&s, ":", escaped_path, NULL))
+ return NULL;
+ }
+
+ ret = s;
+ s = NULL;
+ return ret;
+}
+
static int mount_overlay(const char *dest, CustomMount *m) {
_cleanup_free_ char *lower = NULL;
const char *where, *options;
@@ -1253,19 +1289,32 @@ static int mount_overlay(const char *dest, CustomMount *m) {
(void) mkdir_p_label(m->source, 0755);
- strv_reverse(m->lower);
- lower = strv_join(m->lower, ":");
- strv_reverse(m->lower);
+ lower = joined_and_escaped_lower_dirs(m->lower);
if (!lower)
return log_oom();
- if (m->read_only)
- options = strjoina("lowerdir=", m->source, ":", lower);
- else {
+ if (m->read_only) {
+ _cleanup_free_ char *escaped_source = NULL;
+
+ escaped_source = escaped_overlay_path(m->source);
+ if (!escaped_source)
+ return log_oom();
+
+ options = strjoina("lowerdir=", escaped_source, ":", lower);
+ } else {
+ _cleanup_free_ char *escaped_source = NULL, *escaped_work_dir = NULL;
+
assert(m->work_dir);
(void) mkdir_label(m->work_dir, 0700);
- options = strjoina("lowerdir=", lower, ",upperdir=", m->source, ",workdir=", m->work_dir);
+ escaped_source = escaped_overlay_path(m->source);
+ if (!escaped_source)
+ return log_oom();
+ escaped_work_dir = escaped_overlay_path(m->work_dir);
+ if (!escaped_work_dir)
+ return log_oom();
+
+ options = strjoina("lowerdir=", lower, ",upperdir=", escaped_source, ",workdir=", escaped_work_dir);
}
if (mount("overlay", where, "overlay", m->read_only ? MS_RDONLY : 0, options) < 0)
--
1.9.1
More information about the systemd-devel
mailing list