]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tpm2-util: copy serialized result in tpm2_serialize() 38520/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 8 Aug 2025 02:27:21 +0000 (11:27 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 11 Aug 2025 21:11:34 +0000 (06:11 +0900)
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.

src/pcrlock/pcrlock.c
src/shared/tpm2-util.c
src/shared/tpm2-util.h

index 457cec139f60d08da3a52fc2886eb880861dd5c1..8ab089e609832af2153d9c81ab51c779d708a54a 100644 (file)
@@ -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");
         }
index 6abebb5d5d58e65a3e5a51c702a46b64a9c89bf1..57e7a91f93345cc928269ba99fcbb68102735296 100644 (file)
@@ -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);
index f938b3981a3e0edbdf1434befb6b38cbd331fb3c..3205ac446fa39d7aca04352633ed6803b2870aa3 100644 (file)
@@ -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);