From a257de2688d6ed88ec29fe7e8a5cc867c3a790f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20L=C3=BCke?= Date: Tue, 11 Aug 2026 00:10:06 +0900 Subject: [PATCH 1/2] pkcs7: Correct error handling for pkcs7_extract_signers The lack of error handling for sym_i2d_X509_NAME/sym_i2d_ASN1_INTEGER means that we get a NULL iovec that will cause an assertion failure later. The use of regular free for OpenSSL is probably okay but since the allocator can differ, one should use OPENSSL_free. Add error handling and do an explicit copy instead of ownership transfer between possibly different allocators. --- src/shared/pkcs7-util.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/shared/pkcs7-util.c b/src/shared/pkcs7-util.c index 4d22d90421..36a46cf9ab 100644 --- a/src/shared/pkcs7-util.c +++ b/src/shared/pkcs7-util.c @@ -2,6 +2,7 @@ #include "alloc-util.h" #include "crypto-util.h" +#include "iovec-util.h" #include "pkcs7-util.h" #include "log.h" @@ -72,13 +73,19 @@ int pkcs7_extract_signers( return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to get signer information."); _cleanup_(signer_done) Signer signer = {}; + _cleanup_(OPENSSL_freep) void *issuer = NULL, *serial = NULL; - _cleanup_free_ unsigned char *p = NULL; - int len = sym_i2d_X509_NAME(si->issuer_and_serial->issuer, &p); - signer.issuer = IOVEC_MAKE(TAKE_PTR(p), len); + int len = sym_i2d_X509_NAME(si->issuer_and_serial->issuer, (unsigned char**) &issuer); + if (len < 0) + return log_openssl_errors(LOG_DEBUG, "Failed to convert issuer name to DER format"); + if (!iovec_memdup(&IOVEC_MAKE(issuer, len), &signer.issuer)) + return log_oom_debug(); - len = sym_i2d_ASN1_INTEGER(si->issuer_and_serial->serial, &p); - signer.serial = IOVEC_MAKE(TAKE_PTR(p), len); + len = sym_i2d_ASN1_INTEGER(si->issuer_and_serial->serial, (unsigned char**) &serial); + if (len < 0) + return log_openssl_errors(LOG_DEBUG, "Failed to convert serial number to DER format"); + if (!iovec_memdup(&IOVEC_MAKE(serial, len), &signer.serial)) + return log_oom_debug(); signers[n_signers++] = TAKE_STRUCT(signer); } From 76a6dc6dc01831b7d641c3b21a1ca2f8eec29e5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20L=C3=BCke?= Date: Tue, 11 Aug 2026 01:18:29 +0900 Subject: [PATCH 2/2] pcrextend: Fix use-after-free/double-free error in pcrextend_pcr_now With SignInitrdPCRs=disabled in mkosi the TPM/PCR services are broken which triggers the error path in the varlink call which means that we get parameters set in the response. The wrong ownership assumption when looking at the reply with _cleanup_ set caused a memory corruption that surfaced in systemd-sysext with an ABRT. This is a common mistake done with the API, fix it by not setting _cleanup_(sd_json_variant_unrefp). --- src/shared/pcrextend-util.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/shared/pcrextend-util.c b/src/shared/pcrextend-util.c index 158699a73d..afa1b88cf5 100644 --- a/src/shared/pcrextend-util.c +++ b/src/shared/pcrextend-util.c @@ -58,7 +58,8 @@ int pcrextend_pcr_now(unsigned pcr, const char *word, const struct iovec *secret if (iovec_is_set(secret)) sd_json_variant_sensitive(parameters); - _cleanup_(sd_json_variant_unrefp) sd_json_variant *reply = NULL; + /* Both the reply and the error id are borrowed from the connection, don't unref/free them. */ + sd_json_variant *reply = NULL; const char *error_id = NULL; r = sd_varlink_call(vl, "io.systemd.PCRExtend.Extend", parameters, &reply, &error_id); if (r < 0) @@ -91,7 +92,8 @@ int pcrextend_nvpcr_now(const char *nvpcr, const char *word, const char *event) if (r < 0) return r; - _cleanup_(sd_json_variant_unrefp) sd_json_variant *reply = NULL; + /* Both the reply and the error id are borrowed from the connection, don't unref/free them. */ + sd_json_variant *reply = NULL; const char *error_id = NULL; r = sd_varlink_callbo( vl,