summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLuca Boccassi <luca.boccassi@gmail.com>2024-11-25 23:31:01 +0100
committerYu Watanabe <watanabe.yu+github@gmail.com>2024-11-26 14:04:24 +0100
commitc4d7a13c0665b9af2e8e0e671faa22fea95d83d3 (patch)
treea6caac44cc2560de9e22c0bccbac5177d788b245 /src
parentupdatectl: fix DBus method signature for SetFeatureEnabled (diff)
downloadsystemd-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.c12
-rw-r--r--src/cryptsetup/cryptsetup-pkcs11.h6
-rw-r--r--src/cryptsetup/cryptsetup.c23
-rw-r--r--src/shared/cryptsetup-fido2.c11
-rw-r--r--src/shared/cryptsetup-fido2.h6
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,