]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tpm2-util: copy serialized result in tpm2_serialize()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 8 Aug 2025 02:27:21 +0000 (11:27 +0900)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 3 Sep 2025 10:10:48 +0000 (12:10 +0200)
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)

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

index 94c80247768fb2d717456bda2ddaa27ac34fed85..f92d313377b330e6e8c915f17ae52d9a3b7f7773 100644 (file)
@@ -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");
         }
index 82a96a94f344fc2ff06b0b42b5833c3df669e75f..15dd98f0aba00fee4528ef5b0721bfb4cb0cd119 100644 (file)
@@ -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);
index 097f25ebaa7a81a2c3578b5cd27e6ccf7b5de7a6..9861647400d84cf0aa3b6c78ac94e1d14585c4e5 100644 (file)
@@ -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);