cryptsetup: load libcryptsetup via dlopen in setup binaries
Convert systemd-cryptsetup, systemd-cryptenroll, systemd-veritysetup
and systemd-integritysetup to go through the existing dlopen wrapper
for libcryptsetup instead of linking the library directly. Each binary
calls dlopen_cryptsetup() at the start of its run() and uses the sym_*
variants for every libcryptsetup entry point.
Extend cryptsetup-util.{h,c} to cover the libcryptsetup symbols that
these binaries use and that the wrapper was missing:
crypt_activate_by_token_pin, crypt_deactivate, crypt_init_data_device,
crypt_keyslot_status, crypt_set_keyring_to_link (conditional on
HAVE_CRYPT_SET_KEYRING_TO_LINK), crypt_status and
crypt_token_external_path.
With no direct callers of crypt_free() left, drop the non-sym
crypt_freep cleanup variant and rename sym_crypt_freep back to
crypt_freep via DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME, matching the
naming convention used by other dlopen wrappers (acl_freep,
xkb_context_unrefp, ...). Update the remaining users in src/shared,
src/repart, src/home and src/growfs to the new name.
The four affected meson targets switch from libcryptsetup to
libcryptsetup_cflags so they no longer record a DT_NEEDED entry for
libcryptsetup.so.12.
This commit is contained in:
committed by
Daan De Meyer
parent
4114bf7e70
commit
43dab5ea87
@@ -54,7 +54,7 @@ int load_volume_key_fido2(
|
||||
if (passphrase_size < 0)
|
||||
return log_oom();
|
||||
|
||||
r = crypt_volume_key_get(
|
||||
r = sym_crypt_volume_key_get(
|
||||
cd,
|
||||
CRYPT_ANY_SLOT,
|
||||
ret_vk,
|
||||
@@ -95,9 +95,9 @@ int enroll_fido2(
|
||||
assert_se(iovec_is_set(volume_key));
|
||||
assert_se(device);
|
||||
|
||||
assert_se(node = crypt_get_device_name(cd));
|
||||
assert_se(node = sym_crypt_get_device_name(cd));
|
||||
|
||||
un = strempty(crypt_get_uuid(cd));
|
||||
un = strempty(sym_crypt_get_uuid(cd));
|
||||
|
||||
if (salt_file)
|
||||
r = fido2_read_salt_file(
|
||||
@@ -140,7 +140,7 @@ int enroll_fido2(
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set minimal PBKDF: %m");
|
||||
|
||||
keyslot = crypt_keyslot_add_by_volume_key(
|
||||
keyslot = sym_crypt_keyslot_add_by_volume_key(
|
||||
cd,
|
||||
CRYPT_ANY_SLOT,
|
||||
volume_key->iov_base,
|
||||
|
||||
@@ -26,11 +26,11 @@ int list_enrolled(struct crypt_device *cd) {
|
||||
assert(cd);
|
||||
|
||||
/* First step, find out all currently used slots */
|
||||
assert_se((slot_max = crypt_keyslot_max(CRYPT_LUKS2)) > 0);
|
||||
assert_se((slot_max = sym_crypt_keyslot_max(CRYPT_LUKS2)) > 0);
|
||||
for (int slot = 0; slot < slot_max; slot++) {
|
||||
crypt_keyslot_info status;
|
||||
|
||||
status = crypt_keyslot_status(cd, slot);
|
||||
status = sym_crypt_keyslot_status(cd, slot);
|
||||
if (!IN_SET(status, CRYPT_SLOT_ACTIVE, CRYPT_SLOT_ACTIVE_LAST))
|
||||
continue;
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ int load_volume_key_password(
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to acquire password from environment: %m");
|
||||
if (r > 0) {
|
||||
r = crypt_volume_key_get(
|
||||
r = sym_crypt_volume_key_get(
|
||||
cd,
|
||||
CRYPT_ANY_SLOT,
|
||||
ret_vk,
|
||||
@@ -81,7 +81,7 @@ int load_volume_key_password(
|
||||
|
||||
r = -EPERM;
|
||||
STRV_FOREACH(p, passwords) {
|
||||
r = crypt_volume_key_get(
|
||||
r = sym_crypt_volume_key_get(
|
||||
cd,
|
||||
CRYPT_ANY_SLOT,
|
||||
ret_vk,
|
||||
@@ -114,7 +114,7 @@ int enroll_password(
|
||||
assert(cd);
|
||||
assert(iovec_is_set(volume_key));
|
||||
|
||||
assert_se(node = crypt_get_device_name(cd));
|
||||
assert_se(node = sym_crypt_get_device_name(cd));
|
||||
|
||||
r = getenv_steal_erase("NEWPASSWORD", &new_password);
|
||||
if (r < 0)
|
||||
@@ -123,7 +123,7 @@ int enroll_password(
|
||||
_cleanup_free_ char *disk_path = NULL, *id = NULL;
|
||||
unsigned i = 5;
|
||||
|
||||
assert_se(node = crypt_get_device_name(cd));
|
||||
assert_se(node = sym_crypt_get_device_name(cd));
|
||||
|
||||
(void) suggest_passwords();
|
||||
|
||||
@@ -196,7 +196,7 @@ int enroll_password(
|
||||
else if (r == 0)
|
||||
log_warning("Specified password does not pass quality checks (%s), proceeding anyway.", error);
|
||||
|
||||
keyslot = crypt_keyslot_add_by_volume_key(
|
||||
keyslot = sym_crypt_keyslot_add_by_volume_key(
|
||||
cd,
|
||||
CRYPT_ANY_SLOT,
|
||||
volume_key->iov_base,
|
||||
|
||||
@@ -53,7 +53,7 @@ int enroll_pkcs11(struct crypt_device *cd, const struct iovec *volume_key,const
|
||||
assert_se(iovec_is_set(volume_key));
|
||||
assert_se(uri);
|
||||
|
||||
assert_se(node = crypt_get_device_name(cd));
|
||||
assert_se(node = sym_crypt_get_device_name(cd));
|
||||
|
||||
r = pkcs11_acquire_public_key(
|
||||
uri,
|
||||
@@ -80,7 +80,7 @@ int enroll_pkcs11(struct crypt_device *cd, const struct iovec *volume_key,const
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set minimal PBKDF: %m");
|
||||
|
||||
int keyslot = crypt_keyslot_add_by_volume_key(
|
||||
int keyslot = sym_crypt_keyslot_add_by_volume_key(
|
||||
cd,
|
||||
CRYPT_ANY_SLOT,
|
||||
volume_key->iov_base,
|
||||
|
||||
@@ -24,7 +24,7 @@ int enroll_recovery(
|
||||
assert_se(cd);
|
||||
assert_se(iovec_is_set(volume_key));
|
||||
|
||||
assert_se(node = crypt_get_device_name(cd));
|
||||
assert_se(node = sym_crypt_get_device_name(cd));
|
||||
|
||||
r = make_recovery_key(&password);
|
||||
if (r < 0)
|
||||
@@ -34,7 +34,7 @@ int enroll_recovery(
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set minimal PBKDF: %m");
|
||||
|
||||
keyslot = crypt_keyslot_add_by_volume_key(
|
||||
keyslot = sym_crypt_keyslot_add_by_volume_key(
|
||||
cd,
|
||||
CRYPT_ANY_SLOT,
|
||||
volume_key->iov_base,
|
||||
@@ -93,7 +93,7 @@ int enroll_recovery(
|
||||
return keyslot;
|
||||
|
||||
rollback:
|
||||
q = crypt_keyslot_destroy(cd, keyslot);
|
||||
q = sym_crypt_keyslot_destroy(cd, keyslot);
|
||||
if (q < 0)
|
||||
log_debug_errno(q, "Unable to remove key slot we just added again, can't rollback, sorry: %m");
|
||||
|
||||
|
||||
@@ -272,7 +272,7 @@ int load_volume_key_tpm2(
|
||||
if (passphrase_size < 0)
|
||||
return log_oom();
|
||||
|
||||
r = crypt_volume_key_get(
|
||||
r = sym_crypt_volume_key_get(
|
||||
cd,
|
||||
CRYPT_ANY_SLOT,
|
||||
ret_vk,
|
||||
@@ -329,7 +329,7 @@ int enroll_tpm2(struct crypt_device *cd,
|
||||
assert(TPM2_PCR_MASK_VALID(pubkey_pcr_mask));
|
||||
assert(ret_slot_to_wipe);
|
||||
|
||||
assert_se(node = crypt_get_device_name(cd));
|
||||
assert_se(node = sym_crypt_get_device_name(cd));
|
||||
|
||||
if (use_pin) {
|
||||
r = get_pin(&pin_str, &flags);
|
||||
@@ -579,7 +579,7 @@ int enroll_tpm2(struct crypt_device *cd,
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set minimal PBKDF: %m");
|
||||
|
||||
keyslot = crypt_keyslot_add_by_volume_key(
|
||||
keyslot = sym_crypt_keyslot_add_by_volume_key(
|
||||
cd,
|
||||
CRYPT_ANY_SLOT,
|
||||
volume_key->iov_base,
|
||||
|
||||
@@ -15,7 +15,7 @@ static int find_all_slots(struct crypt_device *cd, Set *wipe_slots, Set *keep_sl
|
||||
|
||||
assert(cd);
|
||||
assert(wipe_slots);
|
||||
assert_se((slot_max = crypt_keyslot_max(CRYPT_LUKS2)) > 0);
|
||||
assert_se((slot_max = sym_crypt_keyslot_max(CRYPT_LUKS2)) > 0);
|
||||
|
||||
/* Finds all currently assigned slots, and adds them to 'wipe_slots', except if listed already in 'keep_slots' */
|
||||
|
||||
@@ -27,7 +27,7 @@ static int find_all_slots(struct crypt_device *cd, Set *wipe_slots, Set *keep_sl
|
||||
set_contains(wipe_slots, INT_TO_PTR(slot)))
|
||||
continue;
|
||||
|
||||
status = crypt_keyslot_status(cd, slot);
|
||||
status = sym_crypt_keyslot_status(cd, slot);
|
||||
if (!IN_SET(status, CRYPT_SLOT_ACTIVE, CRYPT_SLOT_ACTIVE_LAST))
|
||||
continue;
|
||||
|
||||
@@ -44,12 +44,12 @@ static int find_empty_passphrase_slots(struct crypt_device *cd, Set *wipe_slots,
|
||||
|
||||
assert(cd);
|
||||
assert(wipe_slots);
|
||||
assert_se((slot_max = crypt_keyslot_max(CRYPT_LUKS2)) > 0);
|
||||
assert_se((slot_max = sym_crypt_keyslot_max(CRYPT_LUKS2)) > 0);
|
||||
|
||||
/* Finds all slots with an empty passphrase assigned (i.e. "") and adds them to 'wipe_slots', except
|
||||
* if listed already in 'keep_slots' */
|
||||
|
||||
r = crypt_get_volume_key_size(cd);
|
||||
r = sym_crypt_get_volume_key_size(cd);
|
||||
if (r <= 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to determine LUKS volume key size");
|
||||
vks = (size_t) r;
|
||||
@@ -63,7 +63,7 @@ static int find_empty_passphrase_slots(struct crypt_device *cd, Set *wipe_slots,
|
||||
set_contains(wipe_slots, INT_TO_PTR(slot)))
|
||||
continue;
|
||||
|
||||
status = crypt_keyslot_status(cd, slot);
|
||||
status = sym_crypt_keyslot_status(cd, slot);
|
||||
if (!IN_SET(status, CRYPT_SLOT_ACTIVE, CRYPT_SLOT_ACTIVE_LAST))
|
||||
continue;
|
||||
|
||||
@@ -71,7 +71,7 @@ static int find_empty_passphrase_slots(struct crypt_device *cd, Set *wipe_slots,
|
||||
if (!vk)
|
||||
return log_oom();
|
||||
|
||||
r = crypt_volume_key_get(cd, slot, vk, &vks, "", 0);
|
||||
r = sym_crypt_volume_key_get(cd, slot, vk, &vks, "", 0);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to acquire volume key from slot %i with empty password, ignoring: %m", slot);
|
||||
continue;
|
||||
@@ -164,7 +164,7 @@ static int find_slots_by_mask(
|
||||
if ((by_mask & (1U << ENROLL_PASSWORD)) != 0) {
|
||||
int slot_max;
|
||||
|
||||
assert_se((slot_max = crypt_keyslot_max(CRYPT_LUKS2)) > 0);
|
||||
assert_se((slot_max = sym_crypt_keyslot_max(CRYPT_LUKS2)) > 0);
|
||||
|
||||
for (int slot = 0; slot < slot_max; slot++) {
|
||||
crypt_keyslot_info status;
|
||||
@@ -177,7 +177,7 @@ static int find_slots_by_mask(
|
||||
if (set_contains(listed_slots, INT_TO_PTR(slot))) /* This has a token, hence is not a password. */
|
||||
continue;
|
||||
|
||||
status = crypt_keyslot_status(cd, slot);
|
||||
status = sym_crypt_keyslot_status(cd, slot);
|
||||
if (!IN_SET(status, CRYPT_SLOT_ACTIVE, CRYPT_SLOT_ACTIVE_LAST)) /* Not actually assigned? */
|
||||
continue;
|
||||
|
||||
@@ -273,7 +273,7 @@ static bool slots_remain(struct crypt_device *cd, Set *wipe_slots, Set *keep_slo
|
||||
int slot_max;
|
||||
|
||||
assert(cd);
|
||||
assert_se((slot_max = crypt_keyslot_max(CRYPT_LUKS2)) > 0);
|
||||
assert_se((slot_max = sym_crypt_keyslot_max(CRYPT_LUKS2)) > 0);
|
||||
|
||||
/* Checks if any slots remaining in the LUKS2 header if we remove all slots listed in 'wipe_slots'
|
||||
* (keeping those listed in 'keep_slots') */
|
||||
@@ -281,7 +281,7 @@ static bool slots_remain(struct crypt_device *cd, Set *wipe_slots, Set *keep_slo
|
||||
for (int slot = 0; slot < slot_max; slot++) {
|
||||
crypt_keyslot_info status;
|
||||
|
||||
status = crypt_keyslot_status(cd, slot);
|
||||
status = sym_crypt_keyslot_status(cd, slot);
|
||||
if (!IN_SET(status, CRYPT_SLOT_ACTIVE, CRYPT_SLOT_ACTIVE_LAST))
|
||||
continue;
|
||||
|
||||
@@ -338,7 +338,7 @@ int wipe_slots(struct crypt_device *cd,
|
||||
if (set_put(keep_slots, INT_TO_PTR(except_slot)) < 0)
|
||||
return log_oom();
|
||||
|
||||
assert_se((slot_max = crypt_keyslot_max(CRYPT_LUKS2)) > 0);
|
||||
assert_se((slot_max = sym_crypt_keyslot_max(CRYPT_LUKS2)) > 0);
|
||||
|
||||
/* Maintain another set of the slots we intend to wipe */
|
||||
for (size_t i = 0; i < n_explicit_slots; i++) {
|
||||
@@ -425,7 +425,7 @@ int wipe_slots(struct crypt_device *cd,
|
||||
* first.) */
|
||||
ret = 0;
|
||||
for (size_t i = n_ordered_slots; i > 0; i--) {
|
||||
r = crypt_keyslot_destroy(cd, ordered_slots[i - 1]);
|
||||
r = sym_crypt_keyslot_destroy(cd, ordered_slots[i - 1]);
|
||||
if (r < 0) {
|
||||
if (r == -ENOENT)
|
||||
log_warning_errno(r, "Failed to wipe non-existent slot %i, continuing.", ordered_slots[i - 1]);
|
||||
@@ -438,7 +438,7 @@ int wipe_slots(struct crypt_device *cd,
|
||||
}
|
||||
|
||||
for (size_t i = n_ordered_tokens; i > 0; i--) {
|
||||
r = crypt_token_json_set(cd, ordered_tokens[i - 1], NULL);
|
||||
r = sym_crypt_token_json_set(cd, ordered_tokens[i - 1], NULL);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to wipe token %i, continuing: %m", ordered_tokens[i - 1]);
|
||||
if (ret == 0)
|
||||
|
||||
@@ -649,7 +649,7 @@ static int check_for_homed(struct crypt_device *cd) {
|
||||
/* Politely refuse operating on homed volumes. The enrolled tokens for the user record and the LUKS2
|
||||
* volume should not get out of sync. */
|
||||
|
||||
for (int token = 0; token < crypt_token_max(CRYPT_LUKS2); token++) {
|
||||
for (int token = 0; token < sym_crypt_token_max(CRYPT_LUKS2); token++) {
|
||||
r = cryptsetup_get_token_as_json(cd, token, "systemd-homed", NULL);
|
||||
if (IN_SET(r, -ENOENT, -EINVAL, -EMEDIUMTYPE))
|
||||
continue;
|
||||
@@ -688,7 +688,7 @@ static int load_volume_key_keyfile(
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Reading keyfile %s failed: %m", arg_unlock_keyfile);
|
||||
|
||||
r = crypt_volume_key_get(
|
||||
r = sym_crypt_volume_key_get(
|
||||
cd,
|
||||
CRYPT_ANY_SLOT,
|
||||
ret_vk,
|
||||
@@ -710,13 +710,13 @@ static int prepare_luks(
|
||||
|
||||
assert(ret_cd);
|
||||
|
||||
r = crypt_init(&cd, arg_node);
|
||||
r = sym_crypt_init(&cd, arg_node);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to allocate libcryptsetup context: %m");
|
||||
|
||||
cryptsetup_enable_logging(cd);
|
||||
|
||||
r = crypt_load(cd, CRYPT_LUKS2, NULL);
|
||||
r = sym_crypt_load(cd, CRYPT_LUKS2, NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to load LUKS2 superblock of %s: %m", arg_node);
|
||||
|
||||
@@ -729,7 +729,7 @@ static int prepare_luks(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = crypt_get_volume_key_size(cd);
|
||||
r = sym_crypt_get_volume_key_size(cd);
|
||||
if (r <= 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to determine LUKS volume key size");
|
||||
|
||||
@@ -783,11 +783,13 @@ static int run(int argc, char *argv[]) {
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
r = dlopen_cryptsetup(LOG_ERR);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* A delicious drop of snake oil */
|
||||
(void) safe_mlockall(MCL_CURRENT|MCL_FUTURE|MCL_ONFAULT);
|
||||
|
||||
cryptsetup_enable_logging(NULL);
|
||||
|
||||
if (arg_enroll_type < 0)
|
||||
r = prepare_luks(&cd, /* ret_volume_key= */ NULL); /* No need to unlock device if we don't need the volume key because we don't need to enroll anything */
|
||||
else
|
||||
|
||||
@@ -21,7 +21,7 @@ executables += [
|
||||
'public' : true,
|
||||
'sources' : systemd_cryptenroll_sources,
|
||||
'dependencies' : [
|
||||
libcryptsetup,
|
||||
libcryptsetup_cflags,
|
||||
libdl,
|
||||
libfido2_cflags,
|
||||
libopenssl,
|
||||
|
||||
Reference in New Issue
Block a user