From: Yu Watanabe Date: Fri, 8 Aug 2025 02:27:21 +0000 (+0900) Subject: tpm2-util: copy serialized result in tpm2_serialize() X-Git-Tag: v257.9~47 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6c8c2a8abfcef0b360b6e7b25a99d81a55d07261;p=thirdparty%2Fsystemd.git tpm2-util: copy serialized result in tpm2_serialize() For safety, though typically Esys_Free() is just a simple wrapper of free(), but let's do unconditionally. See the comment in the code. While at it, this makes it store the result into struct iovec. (cherry picked from commit 48d06b99e6a048d5adc90851cceef89621b8b517) --- diff --git a/src/pcrlock/pcrlock.c b/src/pcrlock/pcrlock.c index 94c80247768..f92d313377b 100644 --- a/src/pcrlock/pcrlock.c +++ b/src/pcrlock/pcrlock.c @@ -4783,13 +4783,13 @@ static int make_policy(bool force, RecoveryPinMode recovery_pin_mode) { } if (!iovec_is_set(&nv_blob)) { - r = tpm2_serialize(tc, nv_handle, &nv_blob.iov_base, &nv_blob.iov_len); + r = tpm2_serialize(tc, nv_handle, &nv_blob); if (r < 0) return log_error_errno(r, "Failed to serialize NV index TR: %m"); } if (!iovec_is_set(&srk_blob)) { - r = tpm2_serialize(tc, srk_handle, &srk_blob.iov_base, &srk_blob.iov_len); + r = tpm2_serialize(tc, srk_handle, &srk_blob); if (r < 0) return log_error_errno(r, "Failed to serialize SRK index TR: %m"); } diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 82a96a94f34..15dd98f0aba 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -4728,15 +4728,13 @@ int tpm2_calculate_serialize( int tpm2_serialize( Tpm2Context *c, const Tpm2Handle *handle, - void **ret_serialized, - size_t *ret_serialized_size) { + struct iovec *ret) { TSS2_RC rc; assert(c); assert(handle); - assert(ret_serialized); - assert(ret_serialized_size); + assert(ret); _cleanup_(Esys_Freep) unsigned char *serialized = NULL; size_t size = 0; @@ -4745,9 +4743,15 @@ int tpm2_serialize( return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to serialize: %s", sym_Tss2_RC_Decode(rc)); - *ret_serialized = TAKE_PTR(serialized); - *ret_serialized_size = size; + /* Make a copy since we don't want the caller to understand that ESYS allocated the pointer. + * It would make tracking what deallocator to use for the result in which context a PITA. */ + struct iovec v; + v.iov_base = memdup(serialized, size); + if (!v.iov_base) + return log_oom_debug(); + v.iov_len = size; + *ret = v; return 0; } @@ -5614,25 +5618,9 @@ int tpm2_seal(Tpm2Context *c, log_debug("Completed TPM2 key sealing in %s.", FORMAT_TIMESPAN(now(CLOCK_MONOTONIC) - start, 1)); if (ret_srk) { - _cleanup_(iovec_done) struct iovec srk = {}; - _cleanup_(Esys_Freep) void *tmp = NULL; - size_t tmp_size; - - r = tpm2_serialize(c, primary_handle, &tmp, &tmp_size); + r = tpm2_serialize(c, primary_handle, ret_srk); if (r < 0) return r; - - /* - * make a copy since we don't want the caller to understand that - * ESYS allocated the pointer. It would make tracking what deallocator - * to use for srk in which context a PITA. - */ - srk.iov_base = memdup(tmp, tmp_size); - if (!srk.iov_base) - return log_oom_debug(); - srk.iov_len = tmp_size; - - *ret_srk = TAKE_STRUCT(srk); } *ret_secret = TAKE_STRUCT(secret); diff --git a/src/shared/tpm2-util.h b/src/shared/tpm2-util.h index 097f25ebaa7..9861647400d 100644 --- a/src/shared/tpm2-util.h +++ b/src/shared/tpm2-util.h @@ -309,7 +309,7 @@ int tpm2_undefine_policy_nv_index(Tpm2Context *c, const Tpm2Handle *session, TPM int tpm2_seal_data(Tpm2Context *c, const struct iovec *data, const Tpm2Handle *primary_handle, const Tpm2Handle *encryption_session, const TPM2B_DIGEST *policy, struct iovec *ret_public, struct iovec *ret_private); int tpm2_unseal_data(Tpm2Context *c, const struct iovec *public, const struct iovec *private, const Tpm2Handle *primary_handle, const Tpm2Handle *policy_session, const Tpm2Handle *encryption_session, struct iovec *ret_data); -int tpm2_serialize(Tpm2Context *c, const Tpm2Handle *handle, void **ret_serialized, size_t *ret_serialized_size); +int tpm2_serialize(Tpm2Context *c, const Tpm2Handle *handle, struct iovec *ret); int tpm2_deserialize(Tpm2Context *c, const struct iovec *serialized, Tpm2Handle **ret_handle); int tpm2_load_public_key_file(const char *path, TPM2B_PUBLIC *ret);