]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
nspawn: escape paths in overlay mount options
authorRichard Maw <richard.maw@codethink.co.uk>
Fri, 19 Jun 2015 15:24:37 +0000 (15:24 +0000)
committerRichard Maw <richard.maw@codethink.co.uk>
Fri, 7 Aug 2015 15:50:43 +0000 (15:50 +0000)
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

index b65b13426ff20bcc7f91af40881623ac9b872231..59e013d5c5157e2b62447c4e4ca49ba4358e6b35 100644 (file)
@@ -1235,6 +1235,21 @@ static int mount_tmpfs(const char *dest, CustomMount *m) {
         return 0;
 }
 
+static char *joined_and_escaped_lower_dirs(char * const *lower) {
+        _cleanup_strv_free_ char **sv = NULL;
+
+        sv = strv_copy(lower);
+        if (!sv)
+                return NULL;
+
+        strv_reverse(sv);
+
+        if (!strv_shell_escape(sv, ",:"))
+                return NULL;
+
+        return strv_join(sv, ":");
+}
+
 static int mount_overlay(const char *dest, CustomMount *m) {
         _cleanup_free_ char *lower = NULL;
         const char *where, *options;
@@ -1251,19 +1266,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 = shell_escape(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 = shell_escape(m->source, ",:");
+                if (!escaped_source)
+                        return log_oom();
+                escaped_work_dir = shell_escape(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)