]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
cryptsetup: convert pkcs11/fido2 to iovec for key handling
authorLuca Boccassi <luca.boccassi@gmail.com>
Mon, 25 Nov 2024 22:31:01 +0000 (22:31 +0000)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 26 Nov 2024 13:04:24 +0000 (22:04 +0900)
key-data might be NULL. Fixes crash:

0  0x0000559c62120530 in attach_luks_or_plain_or_bitlk (cd=0x559c6b192830, name=0x7ffd57981dc4 "root", token_type=TOKEN_FIDO2, key_file=0x0, key_data=0x0, passwords=0x0, flags=524296, until=0)
    at ../src/cryptsetup/cryptsetup.c:2234
        pass_volume_key = false
        r = 1469577760
        __func__ = '\000' <repeats 29 times>
1  0x0000559c6212279c in run (argc=6, argv=0x7ffd5797fe98) at ../src/cryptsetup/cryptsetup.c:2597
        discovered_key_data = {iov_base = 0x0, iov_len = 0}
        key_data = 0x0
        token_type = TOKEN_FIDO2
        destroy_key_file = 0x0
        flags = 524296
        until = 0
        passphrase_type = PASSPHRASE_NONE
        volume = 0x7ffd57981dc4 "root"
        source = 0x7ffd57981dc9 "/dev/disk/by-uuid/8372fb39-9ba4-461a-a618-07dcaae66280"
        status = CRYPT_INACTIVE
        tries = 0
        key_file = 0x0
        config = 0x7ffd57981e05 "luks,discard,fido2-device=auto,x-initrd.attach"
        use_cached_passphrase = true
        try_discover_key = true
        discovered_key_fn = 0x7ffd5797fa70 "root.key"
        passwords = 0x0
        cd = 0x559c6b192830
        verb = 0x7ffd57981dbd "attach"
        r = 0
        __func__ = "\000\000\000"
2  0x0000559c621231e6 in main (argc=6, argv=0x7ffd5797fe98) at ../src/cryptsetup/cryptsetup.c:2674
        r = 32553
        __func__ = "\000\000\000\000"

Follow-up for 53b6c99018f918a5d2c9000ac5fe3a2440115ea7

src/cryptsetup/cryptsetup-pkcs11.c
src/cryptsetup/cryptsetup-pkcs11.h
src/cryptsetup/cryptsetup.c
src/shared/cryptsetup-fido2.c
src/shared/cryptsetup-fido2.h

index 3443b8f5853bd23d8eba0cad39bdf7b471940615..c7ecca865ead6f6e4d7605566d1cd0443cbab8b3 100644 (file)
@@ -16,6 +16,7 @@
 #include "fileio.h"
 #include "format-util.h"
 #include "hexdecoct.h"
+#include "iovec-util.h"
 #include "macro.h"
 #include "memory-util.h"
 #include "parse-util.h"
@@ -31,8 +32,7 @@ int decrypt_pkcs11_key(
                 const char *key_file,         /* We either expect key_file and associated parameters to be set (for file keys) … */
                 size_t key_file_size,
                 uint64_t key_file_offset,
-                const void *key_data,         /* … or key_data and key_data_size (for literal keys) */
-                size_t key_data_size,
+                const struct iovec *key_data, /* … or literal keys via key_data */
                 usec_t until,
                 AskPasswordFlags askpw_flags,
                 void **ret_decrypted_key,
@@ -47,15 +47,15 @@ int decrypt_pkcs11_key(
 
         assert(friendly_name);
         assert(pkcs11_uri);
-        assert(key_file || key_data);
+        assert(key_file || iovec_is_set(key_data));
         assert(ret_decrypted_key);
         assert(ret_decrypted_key_size);
 
         /* The functions called here log about all errors, except for EAGAIN which means "token not found right now" */
 
-        if (key_data) {
-                data.encrypted_key = (void*) key_data;
-                data.encrypted_key_size = key_data_size;
+        if (iovec_is_set(key_data)) {
+                data.encrypted_key = (void*) key_data->iov_base;
+                data.encrypted_key_size = key_data->iov_len;
 
                 data.free_encrypted_key = false;
         } else {
index 22e6992582c06ec7356638a8ee2ba1259683aaa7..83a2b54be32ef0879272a2ba09f929dba41b2756 100644 (file)
@@ -16,8 +16,7 @@ int decrypt_pkcs11_key(
                 const char *key_file,
                 size_t key_file_size,
                 uint64_t key_file_offset,
-                const void *key_data,
-                size_t key_data_size,
+                const struct iovec *key_data,
                 usec_t until,
                 AskPasswordFlags askpw_flags,
                 void **ret_decrypted_key,
@@ -39,8 +38,7 @@ static inline int decrypt_pkcs11_key(
                 const char *key_file,
                 size_t key_file_size,
                 uint64_t key_file_offset,
-                const void *key_data,
-                size_t key_data_size,
+                const struct iovec *key_data,
                 usec_t until,
                 AskPasswordFlags askpw_flags,
                 void **ret_decrypted_key,
index a415c3e6d756446dabd3072155d26e09e9f42582..ee93fd3dca0c58d7eeba39916e04c6d2d7406045 100644 (file)
@@ -1471,8 +1471,7 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
                 struct crypt_device *cd,
                 const char *name,
                 const char *key_file,
-                const void *key_data,
-                size_t key_data_size,
+                const struct iovec *key_data,
                 usec_t until,
                 uint32_t flags,
                 bool pass_volume_key) {
@@ -1489,7 +1488,7 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
         assert(name);
         assert(arg_fido2_device || arg_fido2_device_auto);
 
-        if (arg_fido2_cid && !key_file && !key_data)
+        if (arg_fido2_cid && !key_file && !iovec_is_set(key_data))
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                         "FIDO2 mode with manual parameters selected, but no keyfile specified, refusing.");
 
@@ -1513,7 +1512,7 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
                                                 arg_fido2_rp_id,
                                                 arg_fido2_cid, arg_fido2_cid_size,
                                                 key_file, arg_keyfile_size, arg_keyfile_offset,
-                                                key_data, key_data_size,
+                                                key_data,
                                                 until,
                                                 arg_fido2_manual_flags,
                                                 "cryptsetup.fido2-pin",
@@ -1623,8 +1622,7 @@ static int attach_luks_or_plain_or_bitlk_by_pkcs11(
                 struct crypt_device *cd,
                 const char *name,
                 const char *key_file,
-                const void *key_data,
-                size_t key_data_size,
+                const struct iovec *key_data,
                 usec_t until,
                 uint32_t flags,
                 bool pass_volume_key) {
@@ -1635,6 +1633,7 @@ static int attach_luks_or_plain_or_bitlk_by_pkcs11(
         _cleanup_(erase_and_freep) void *decrypted_key = NULL;
         _cleanup_(sd_event_unrefp) sd_event *event = NULL;
         _cleanup_free_ void *discovered_key = NULL;
+        struct iovec discovered_key_data = {};
         int keyslot = arg_key_slot, r;
         const char *uri = NULL;
         bool use_libcryptsetup_plugin = use_token_plugins();
@@ -1653,13 +1652,13 @@ static int attach_luks_or_plain_or_bitlk_by_pkcs11(
                                 return r;
 
                         uri = discovered_uri;
-                        key_data = discovered_key;
-                        key_data_size = discovered_key_size;
+                        discovered_key_data = IOVEC_MAKE(discovered_key, discovered_key_size);
+                        key_data = &discovered_key_data;
                 }
         } else {
                 uri = arg_pkcs11_uri;
 
-                if (!key_file && !key_data)
+                if (!key_file && !iovec_is_set(key_data))
                         return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "PKCS#11 mode selected but no key file specified, refusing.");
         }
 
@@ -1682,7 +1681,7 @@ static int attach_luks_or_plain_or_bitlk_by_pkcs11(
                                         friendly,
                                         uri,
                                         key_file, arg_keyfile_size, arg_keyfile_offset,
-                                        key_data, key_data_size,
+                                        key_data,
                                         until,
                                         arg_ask_password_flags,
                                         &decrypted_key, &decrypted_key_size);
@@ -2231,9 +2230,9 @@ static int attach_luks_or_plain_or_bitlk(
         if (token_type == TOKEN_TPM2)
                 return attach_luks_or_plain_or_bitlk_by_tpm2(cd, name, key_file, key_data, until, flags, pass_volume_key);
         if (token_type == TOKEN_FIDO2)
-                return attach_luks_or_plain_or_bitlk_by_fido2(cd, name, key_file, key_data->iov_base, key_data->iov_len, until, flags, pass_volume_key);
+                return attach_luks_or_plain_or_bitlk_by_fido2(cd, name, key_file, key_data, until, flags, pass_volume_key);
         if (token_type == TOKEN_PKCS11)
-                return attach_luks_or_plain_or_bitlk_by_pkcs11(cd, name, key_file, key_data->iov_base, key_data->iov_len, until, flags, pass_volume_key);
+                return attach_luks_or_plain_or_bitlk_by_pkcs11(cd, name, key_file, key_data, until, flags, pass_volume_key);
         if (key_data)
                 return attach_luks_or_plain_or_bitlk_by_key_data(cd, name, key_data, flags, pass_volume_key);
         if (key_file)
index 9ac728594ad8b19510a17e994e1424df3cd3410b..1e1ef6dec02caf95bfaffbdb116e02d189662165 100644 (file)
@@ -24,8 +24,7 @@ int acquire_fido2_key(
                 const char *key_file,
                 size_t key_file_size,
                 uint64_t key_file_offset,
-                const void *key_data,
-                size_t key_data_size,
+                const struct iovec *key_data,
                 usec_t until,
                 Fido2EnrollFlags required,
                 const char *askpw_credential,
@@ -45,10 +44,10 @@ int acquire_fido2_key(
                                         "Local verification is required to unlock this volume, but the 'headless' parameter was set.");
 
         assert(cid);
-        assert(key_file || key_data);
+        assert(key_file || iovec_is_set(key_data));
 
-        if (key_data)
-                salt = IOVEC_MAKE(key_data, key_data_size);
+        if (iovec_is_set(key_data))
+                salt = *key_data;
         else {
                 if (key_file_size > 0)
                         log_debug("Ignoring 'keyfile-size=' option for a FIDO2 salt file.");
@@ -252,7 +251,7 @@ int acquire_fido2_key_auto(
                                 /* key_file= */ NULL, /* salt is read from LUKS header instead of key_file */
                                 /* key_file_size= */ 0,
                                 /* key_file_offset= */ 0,
-                                salt, salt_size,
+                                &IOVEC_MAKE(salt, salt_size),
                                 until,
                                 required,
                                 "cryptsetup.fido2-pin",
index bd255668065a26e5b9715ca113d3d928f367e8a9..86ac30c76640d1155729ce2fa08618ed7ee77ce5 100644 (file)
@@ -20,8 +20,7 @@ int acquire_fido2_key(
                 const char *key_file,
                 size_t key_file_size,
                 uint64_t key_file_offset,
-                const void *key_data,
-                size_t key_data_size,
+                const struct iovec *key_data,
                 usec_t until,
                 Fido2EnrollFlags required,
                 const char *askpw_credential,
@@ -52,8 +51,7 @@ static inline int acquire_fido2_key(
                 const char *key_file,
                 size_t key_file_size,
                 uint64_t key_file_offset,
-                const void *key_data,
-                size_t key_data_size,
+                const struct iovec *key_data,
                 usec_t until,
                 Fido2EnrollFlags required,
                 const char *askpw_credential,