From: Lennart Poettering Date: Tue, 10 Sep 2024 13:40:12 +0000 (+0200) Subject: cryptsetup: use the new crypt_token_set_external_path() API if available X-Git-Tag: v257-rc1~495 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d794c10d9695547834f60e282edc46be0f7f70ca;p=thirdparty%2Fsystemd.git cryptsetup: use the new crypt_token_set_external_path() API if available Let's make use of libcryptsetup's new crypt_token_set_external_path() API in place of the interposition stuff we have been doing before. Let's kill it entirely, given that this was a developer feature only anyway (and guarded by an appropriate ifdef). Fixes: #30098 --- diff --git a/meson.build b/meson.build index 80e0047281b..6d96996acbd 100644 --- a/meson.build +++ b/meson.build @@ -1288,7 +1288,8 @@ foreach ident : ['crypt_set_metadata_size', 'crypt_reencrypt_run', 'crypt_set_data_offset', 'crypt_set_keyring_to_link', - 'crypt_resume_by_volume_key'] + 'crypt_resume_by_volume_key', + 'crypt_token_set_external_path'] have_ident = have and cc.has_function( ident, prefix : '#include ', diff --git a/src/shared/cryptsetup-util.c b/src/shared/cryptsetup-util.c index 026738b74c2..46f91934537 100644 --- a/src/shared/cryptsetup-util.c +++ b/src/shared/cryptsetup-util.c @@ -49,6 +49,9 @@ DLSYM_PROTOTYPE(crypt_token_json_set) = NULL; #if HAVE_CRYPT_TOKEN_MAX DLSYM_PROTOTYPE(crypt_token_max) = NULL; #endif +#if HAVE_CRYPT_TOKEN_SET_EXTERNAL_PATH +DLSYM_PROTOTYPE(crypt_token_set_external_path) = NULL; +#endif DLSYM_PROTOTYPE(crypt_token_status) = NULL; DLSYM_PROTOTYPE(crypt_volume_key_get) = NULL; #if HAVE_CRYPT_REENCRYPT_INIT_BY_PASSPHRASE @@ -66,41 +69,6 @@ DLSYM_PROTOTYPE(crypt_set_data_offset) = NULL; DLSYM_PROTOTYPE(crypt_header_restore) = NULL; DLSYM_PROTOTYPE(crypt_volume_key_keyring) = NULL; -/* Unfortunately libcryptsetup provides neither an environment variable to redirect where to look for token - * modules, nor does it have an API to change the token lookup path at runtime. The maintainers suggest using - * ELF interposition instead (see https://gitlab.com/cryptsetup/cryptsetup/-/issues/846). Hence let's do - * that: let's interpose libcryptsetup's crypt_token_external_path() function with our own, that *does* - * honour an environment variable where to look for tokens. This is tremendously useful for debugging - * libcryptsetup tokens: set the environment variable to your build dir and you can easily test token modules - * without jumping through various hoops. */ - -/* Do this only on new enough compilers that actually support the "symver" attribute. Given this is a debug - * feature, let's simply not bother on older compilers */ -#if BUILD_MODE_DEVELOPER && defined(__has_attribute) && __has_attribute(symver) -const char* my_crypt_token_external_path(void); /* prototype for our own implementation */ - -/* We use the "symver" attribute to mark this implementation as the default implementation, and drop the - * SD_SHARED namespace we by default attach to our symbols via a version script. */ -__attribute__((symver("crypt_token_external_path@@"))) -_public_ const char *my_crypt_token_external_path(void) { - const char *e; - - e = secure_getenv("SYSTEMD_CRYPTSETUP_TOKEN_PATH"); - if (e) - return e; - - /* Now chain invoke the original implementation. */ - if (cryptsetup_dl) { - typeof(crypt_token_external_path) *func; - func = (typeof(crypt_token_external_path)*) dlsym(cryptsetup_dl, "crypt_token_external_path"); - if (func) - return func(); - } - - return NULL; -} -#endif - static void cryptsetup_log_glue(int level, const char *msg, void *usrptr) { switch (level) { @@ -295,6 +263,9 @@ int dlopen_cryptsetup(void) { DLSYM_ARG(crypt_token_json_set), #if HAVE_CRYPT_TOKEN_MAX DLSYM_ARG(crypt_token_max), +#endif +#if HAVE_CRYPT_TOKEN_SET_EXTERNAL_PATH + DLSYM_ARG(crypt_token_set_external_path), #endif DLSYM_ARG(crypt_token_status), DLSYM_ARG(crypt_volume_key_get), @@ -321,6 +292,18 @@ int dlopen_cryptsetup(void) { * other code loaded into this process also changes the global log functions of libcryptsetup, who * knows? And if so, we still want our own objects to log via our own infra, at the very least.) */ cryptsetup_enable_logging(NULL); + + const char *e = secure_getenv("SYSTEMD_CRYPTSETUP_TOKEN_PATH"); + if (e) { +#if HAVE_CRYPT_TOKEN_SET_EXTERNAL_PATH + r = sym_crypt_token_set_external_path(e); + if (r < 0) + log_debug_errno(r, "Failed to set the libcryptsetup external token path to '%s', ignoring: %m", e); +#else + log_debug("libcryptsetup version does not support setting the external token path, not setting it to '%s'.", e); +#endif + } + return 1; #else return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "cryptsetup support is not compiled in."); diff --git a/src/shared/cryptsetup-util.h b/src/shared/cryptsetup-util.h index 86ac022f303..ea3baf9675b 100644 --- a/src/shared/cryptsetup-util.h +++ b/src/shared/cryptsetup-util.h @@ -68,6 +68,9 @@ static inline int crypt_token_max(_unused_ const char *type) { } #define sym_crypt_token_max(type) crypt_token_max(type) #endif +#if HAVE_CRYPT_TOKEN_SET_EXTERNAL_PATH +extern DLSYM_PROTOTYPE(crypt_token_set_external_path); +#endif extern DLSYM_PROTOTYPE(crypt_token_status); extern DLSYM_PROTOTYPE(crypt_volume_key_get); #if HAVE_CRYPT_REENCRYPT_INIT_BY_PASSPHRASE