Fix error paths for pcrextend_pcr_now and pkcs7_extract_signers (#43357)
- 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). - 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.
This commit is contained in:
@@ -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,
|
||||
|
||||
+12
-5
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user