diff options
author | Luca Boccassi <luca.boccassi@gmail.com> | 2024-11-25 23:31:01 +0100 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2024-11-26 14:04:24 +0100 |
commit | c4d7a13c0665b9af2e8e0e671faa22fea95d83d3 (patch) | |
tree | a6caac44cc2560de9e22c0bccbac5177d788b245 /src | |
parent | updatectl: fix DBus method signature for SetFeatureEnabled (diff) | |
download | systemd-c4d7a13c0665b9af2e8e0e671faa22fea95d83d3.tar.xz systemd-c4d7a13c0665b9af2e8e0e671faa22fea95d83d3.zip |
cryptsetup: convert pkcs11/fido2 to iovec for key handling
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
Diffstat (limited to 'src')
-rw-r--r-- | src/cryptsetup/cryptsetup-pkcs11.c | 12 | ||||
-rw-r--r-- | src/cryptsetup/cryptsetup-pkcs11.h | 6 | ||||
-rw-r--r-- | src/cryptsetup/cryptsetup.c | 23 | ||||
-rw-r--r-- | src/shared/cryptsetup-fido2.c | 11 | ||||
-rw-r--r-- | src/shared/cryptsetup-fido2.h | 6 |
5 files changed, 26 insertions, 32 deletions
diff --git a/src/cryptsetup/cryptsetup-pkcs11.c b/src/cryptsetup/cryptsetup-pkcs11.c index 3443b8f585..c7ecca865e 100644 --- a/src/cryptsetup/cryptsetup-pkcs11.c +++ b/src/cryptsetup/cryptsetup-pkcs11.c @@ -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 { diff --git a/src/cryptsetup/cryptsetup-pkcs11.h b/src/cryptsetup/cryptsetup-pkcs11.h index 22e6992582..83a2b54be3 100644 --- a/src/cryptsetup/cryptsetup-pkcs11.h +++ b/src/cryptsetup/cryptsetup-pkcs11.h @@ -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, diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index a415c3e6d7..ee93fd3dca 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -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) diff --git a/src/shared/cryptsetup-fido2.c b/src/shared/cryptsetup-fido2.c index 9ac728594a..1e1ef6dec0 100644 --- a/src/shared/cryptsetup-fido2.c +++ b/src/shared/cryptsetup-fido2.c @@ -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", diff --git a/src/shared/cryptsetup-fido2.h b/src/shared/cryptsetup-fido2.h index bd25566806..86ac30c766 100644 --- a/src/shared/cryptsetup-fido2.h +++ b/src/shared/cryptsetup-fido2.h @@ -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, |