]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/cryptsetup/cryptsetup-generator.c
generators: be more careful when writing unit settings that support specifier expansion
[thirdparty/systemd.git] / src / cryptsetup / cryptsetup-generator.c
index 3f7222a8aac5e71e37a23ec3ffe023b6e5a1c3ab..e2dc96bdb7e8499ed872684c15b7b5589c1a3c29 100644 (file)
@@ -32,6 +32,7 @@
 #include "parse-util.h"
 #include "path-util.h"
 #include "proc-cmdline.h"
+#include "specifier.h"
 #include "string-util.h"
 #include "strv.h"
 #include "unit-name.h"
@@ -60,7 +61,7 @@ static int create_disk(
                 const char *options) {
 
         _cleanup_free_ char *p = NULL, *n = NULL, *d = NULL, *u = NULL, *e = NULL,
-                *filtered = NULL;
+                *filtered = NULL, *u_escaped = NULL, *password_escaped = NULL, *filtered_escaped = NULL, *name_escaped = NULL;
         _cleanup_fclose_ FILE *f = NULL;
         const char *dmname;
         bool noauto, nofail, tmp, swap, netdev;
@@ -80,6 +81,10 @@ static int create_disk(
                 return -EINVAL;
         }
 
+        name_escaped = specifier_escape(name);
+        if (!name_escaped)
+                return log_oom();
+
         e = unit_name_escape(name);
         if (!e)
                 return log_oom();
@@ -96,10 +101,18 @@ static int create_disk(
         if (!u)
                 return log_oom();
 
+        u_escaped = specifier_escape(u);
+        if (!u_escaped)
+                return log_oom();
+
         r = unit_name_from_path(u, ".device", &d);
         if (r < 0)
                 return log_error_errno(r, "Failed to generate unit name: %m");
 
+        password_escaped = specifier_escape(password);
+        if (!password_escaped)
+                return log_oom();
+
         f = fopen(p, "wxe");
         if (!f)
                 return log_error_errno(errno, "Failed to create unit file %s: %m", p);
@@ -142,7 +155,7 @@ static int create_disk(
 
                                         fprintf(f, "After=%1$s\nRequires=%1$s\n", dd);
                                 } else
-                                        fprintf(f, "RequiresMountsFor=%s\n", password);
+                                        fprintf(f, "RequiresMountsFor=%s\n", password_escaped);
                         }
                 }
         }
@@ -160,12 +173,17 @@ static int create_disk(
         } else
                 fprintf(f,
                         "RequiresMountsFor=%s\n",
-                        u);
+                        u_escaped);
+
 
         r = generator_write_timeouts(arg_dest, device, name, options, &filtered);
         if (r < 0)
                 return r;
 
+        filtered_escaped = specifier_escape(filtered);
+        if (!filtered_escaped)
+                return log_oom();
+
         fprintf(f,
                 "\n[Service]\n"
                 "Type=oneshot\n"
@@ -174,18 +192,18 @@ static int create_disk(
                 "KeyringMode=shared\n" /* make sure we can share cached keys among instances */
                 "ExecStart=" SYSTEMD_CRYPTSETUP_PATH " attach '%s' '%s' '%s' '%s'\n"
                 "ExecStop=" SYSTEMD_CRYPTSETUP_PATH " detach '%s'\n",
-                name, u, strempty(password), strempty(filtered),
-                name);
+                name_escaped, u_escaped, strempty(password_escaped), strempty(filtered_escaped),
+                name_escaped);
 
         if (tmp)
                 fprintf(f,
                         "ExecStartPost=/sbin/mke2fs '/dev/mapper/%s'\n",
-                        name);
+                        name_escaped);
 
         if (swap)
                 fprintf(f,
                         "ExecStartPost=/sbin/mkswap '/dev/mapper/%s'\n",
-                        name);
+                        name_escaped);
 
         r = fflush_and_check(f);
         if (r < 0)
@@ -219,18 +237,12 @@ static int create_disk(
         return 0;
 }
 
-static void free_arg_disks(void) {
-        crypto_device *d;
-
-        while ((d = hashmap_steal_first(arg_disks))) {
-                free(d->uuid);
-                free(d->keyfile);
-                free(d->name);
-                free(d->options);
-                free(d);
-        }
-
-        hashmap_free(arg_disks);
+static void crypt_device_free(crypto_device *d) {
+        free(d->uuid);
+        free(d->keyfile);
+        free(d->name);
+        free(d->options);
+        free(d);
 }
 
 static crypto_device *get_crypto_device(const char *uuid) {
@@ -492,7 +504,7 @@ int main(int argc, char *argv[]) {
         r = 0;
 
 finish:
-        free_arg_disks();
+        hashmap_free_with_destructor(arg_disks, crypt_device_free);
         free(arg_default_options);
         free(arg_default_keyfile);