]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #10010 from msekletar/cryptsetup-generator-keydev-followups
authorLennart Poettering <lennart@poettering.net>
Wed, 31 Oct 2018 17:26:25 +0000 (18:26 +0100)
committerGitHub <noreply@github.com>
Wed, 31 Oct 2018 17:26:25 +0000 (18:26 +0100)
cryptsetup-generator: keydev support - followups

src/cryptsetup/cryptsetup-generator.c

index c3a4509030f509c5e56d60acb50ed493e79a8d97..45231bf5271922423a08cfebf57e19ffde357c64 100644 (file)
@@ -6,11 +6,13 @@
 #include "alloc-util.h"
 #include "def.h"
 #include "dropin.h"
+#include "escape.h"
 #include "fd-util.h"
 #include "fileio.h"
 #include "fstab-util.h"
 #include "generator.h"
 #include "hashmap.h"
+#include "id128-util.h"
 #include "log.h"
 #include "mkdir.h"
 #include "parse-util.h"
@@ -40,7 +42,7 @@ static char *arg_default_options = NULL;
 static char *arg_default_keyfile = NULL;
 
 static int generate_keydev_mount(const char *name, const char *keydev, char **unit, char **mount) {
-        _cleanup_free_ char *u = NULL, *what = NULL, *where = NULL;
+        _cleanup_free_ char *u = NULL, *what = NULL, *where = NULL, *name_escaped = NULL;
         _cleanup_fclose_ FILE *f = NULL;
         int r;
 
@@ -54,16 +56,20 @@ static int generate_keydev_mount(const char *name, const char *keydev, char **un
                 return r;
 
         r = mkdir("/run/systemd/cryptsetup", 0700);
-        if (r < 0)
-                return r;
+        if (r < 0 && errno != EEXIST)
+                return -errno;
 
-        where = strjoin("/run/systemd/cryptsetup/keydev-", name);
+        name_escaped = cescape(name);
+        if (!name_escaped)
+                return -ENOMEM;
+
+        where = strjoin("/run/systemd/cryptsetup/keydev-", name_escaped);
         if (!where)
                 return -ENOMEM;
 
         r = mkdir(where, 0700);
-        if (r < 0)
-                return r;
+        if (r < 0 && errno != EEXIST)
+                return -errno;
 
         r = unit_name_from_path(where, ".mount", &u);
         if (r < 0)
@@ -392,36 +398,52 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
                         return log_oom();
 
         } else if (streq(key, "luks.key")) {
+                size_t n;
+                _cleanup_free_ char *keyfile = NULL, *keydev = NULL;
+                char *c;
+                const char *keyspec;
 
                 if (proc_cmdline_value_missing(key, value))
                         return 0;
 
-                r = sscanf(value, "%m[0-9a-fA-F-]=%ms", &uuid, &uuid_value);
-                if (r == 2) {
-                        char *c;
-                        _cleanup_free_ char *keyfile = NULL, *keydev = NULL;
+                n = strspn(value, LETTERS DIGITS "-");
+                if (value[n] != '=') {
+                        if (free_and_strdup(&arg_default_keyfile, value) < 0)
+                                 return log_oom();
+                        return 0;
+                }
 
-                        d = get_crypto_device(uuid);
-                        if (!d)
-                                return log_oom();
+                uuid = strndup(value, n);
+                if (!uuid)
+                        return log_oom();
+
+                if (!id128_is_valid(uuid)) {
+                        log_warning("Failed to parse luks.key= kernel command line switch. UUID is invalid, ignoring.");
+                        return 0;
+                }
 
-                        c = strrchr(uuid_value, ':');
-                        if (!c)
-                                /* No keydev specified */
-                                return free_and_replace(d->keyfile, uuid_value);
+                d = get_crypto_device(uuid);
+                if (!d)
+                        return log_oom();
 
-                        *c = '\0';
-                        keyfile = strdup(uuid_value);
-                        keydev = strdup(++c);
+                keyspec = value + n + 1;
+                c = strrchr(keyspec, ':');
+                if (c) {
+                         *c = '\0';
+                        keyfile = strdup(keyspec);
+                        keydev = strdup(c + 1);
 
                         if (!keyfile || !keydev)
                                 return log_oom();
+                } else {
+                        /* No keydev specified */
+                        keyfile = strdup(keyspec);
+                        if (!keyfile)
+                                return log_oom();
+                }
 
-                        free_and_replace(d->keyfile, keyfile);
-                        free_and_replace(d->keydev, keydev);
-                } else if (free_and_strdup(&arg_default_keyfile, value) < 0)
-                        return log_oom();
-
+                free_and_replace(d->keyfile, keyfile);
+                free_and_replace(d->keydev, keydev);
         } else if (streq(key, "luks.name")) {
 
                 if (proc_cmdline_value_missing(key, value))