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: v258-rc3~52^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F38520%2Fhead;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. --- diff --git a/src/pcrlock/pcrlock.c b/src/pcrlock/pcrlock.c index 457cec139f6..8ab089e6098 100644 --- a/src/pcrlock/pcrlock.c +++ b/src/pcrlock/pcrlock.c @@ -4794,13 +4794,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 6abebb5d5d5..57e7a91f933 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -4579,15 +4579,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; @@ -4596,9 +4594,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; } @@ -5466,25 +5470,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 f938b3981a3..3205ac446fa 100644 --- a/src/shared/tpm2-util.h +++ b/src/shared/tpm2-util.h @@ -301,7 +301,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);