From: Lennart Poettering Date: Wed, 17 Sep 2025 08:37:31 +0000 (+0200) Subject: core: if we cannot decode a TPM credential skip over it for ImportCredential= X-Git-Tag: v258.1~60 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5a5326bda9d1a0ac057ceea9eb91d0ff4283351b;p=thirdparty%2Fsystemd.git core: if we cannot decode a TPM credential skip over it for ImportCredential= let's skip over credentials we cannot decode when they are found with ImportCredential=. When installing an OS on some disk and using that disk on a different machine than assumed we'll otherwise end up with a broken boot, because the credentials cannot be decoded when starting systemd-firstboot. Let's handle this somewhat gracefully. This leaves handling for LoadCredential=/SetCredential= as it is (i.e. failure to decrypt results in service failure), because it is a lot more explicit and focussed as opposed to ImportCredentials= which looks everywhere, uses globs and so on and is hence very vague and unfocussed. Fixes: #34740 (cherry picked from commit 4be269563db777bb30f2609b3d4f5180fe9e2d2a) --- diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 0afde99ee6f..c0c147045e2 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -3915,6 +3915,13 @@ StandardInputData=V2XigLJyZSBubyBzdHJhbmdlcnMgdG8gbG92ZQpZb3Uga25vdyB0aGUgcnVsZX LoadCredential= and LoadCredentialEncrypted= take priority over credentials found by ImportCredential=. + Note that if decryption or authentication of a credential picked up as result of + ImportCredential= fails it will be skipped gracefully (a warning is generated, but + the credential will not be made available to the invoked service). This is different for those + configured via + SetCredentialEncrypted=/LoadCredentialEncrypted=, where failed + decryption/authentication will result in service failure. + diff --git a/src/core/exec-credential.c b/src/core/exec-credential.c index 5e2bc8edd97..ae5a32fb2c9 100644 --- a/src/core/exec-credential.c +++ b/src/core/exec-credential.c @@ -468,7 +468,8 @@ static int maybe_decrypt_and_write_credential( struct load_cred_args *args, const char *id, const char *data, - size_t size) { + size_t size, + bool graceful) { _cleanup_(iovec_done_erase) struct iovec plaintext = {}; size_t add; @@ -522,8 +523,14 @@ static int maybe_decrypt_and_write_credential( default: assert_not_reached(); } - if (r < 0) + if (r < 0) { + if (graceful) { + log_warning_errno(r, "Unable to decrypt credential '%s', skipping.", id); + return 0; + } + return r; + } data = plaintext.iov_base; size = plaintext.iov_len; @@ -612,7 +619,7 @@ static int load_credential_glob( if (r < 0) return log_debug_errno(r, "Failed to read credential '%s': %m", *p); - r = maybe_decrypt_and_write_credential(args, fn, data, size); + r = maybe_decrypt_and_write_credential(args, fn, data, size, /* graceful= */ true); if (r < 0) return r; } @@ -737,7 +744,7 @@ static int load_credential( if (r < 0) return log_debug_errno(r, "Failed to read credential '%s': %m", path); - return maybe_decrypt_and_write_credential(args, id, data, size); + return maybe_decrypt_and_write_credential(args, id, data, size, /* graceful= */ true); } static int load_cred_recurse_dir_cb( @@ -874,10 +881,11 @@ static int acquire_credentials( args.encrypted = false; - r = load_credential_glob(&args, - ic, - search_path, - READ_FULL_FILE_SECURE|READ_FULL_FILE_FAIL_WHEN_LARGER); + r = load_credential_glob( + &args, + ic, + search_path, + READ_FULL_FILE_SECURE|READ_FULL_FILE_FAIL_WHEN_LARGER); if (r < 0) return r; @@ -889,10 +897,11 @@ static int acquire_credentials( args.encrypted = true; - r = load_credential_glob(&args, - ic, - search_path, - READ_FULL_FILE_SECURE|READ_FULL_FILE_FAIL_WHEN_LARGER|READ_FULL_FILE_UNBASE64); + r = load_credential_glob( + &args, + ic, + search_path, + READ_FULL_FILE_SECURE|READ_FULL_FILE_FAIL_WHEN_LARGER|READ_FULL_FILE_UNBASE64); if (r < 0) return r; } @@ -910,7 +919,7 @@ static int acquire_credentials( if (errno != ENOENT) return log_debug_errno(errno, "Failed to test if credential %s exists: %m", sc->id); - r = maybe_decrypt_and_write_credential(&args, sc->id, sc->data, sc->size); + r = maybe_decrypt_and_write_credential(&args, sc->id, sc->data, sc->size, /* graceful= */ false); if (r < 0) return r; }