Commit dfab097832 for openssl.org
commit dfab09783211350a2223422e5ea01657c331bd68
Author: Nikola Pajkovsky <nikolap@openssl.org>
Date: Wed Nov 11 15:58:32 2026 +0100
crypto/evp/pmeth_lib.c: clear genctx after keymgmt cleanup
evp_pkey_ctx_free_old_ops() releases the previous operation state
before ctx->operation is switched to a new operation family. Every
branch clears the pointers it freed except the key generation branch,
which left ctx->op.keymgmt.genctx pointing at memory already released
by evp_keymgmt_gen_cleanup().
genctx is the first member of the op union and therefore shares
storage with op.sig.signature, op.kex.exchange, op.ciph.cipher,
and op.encap.kem. After EVP_PKEY_keygen_init()
or EVP_PKEY_paramgen_init() succeeded and a subsequent init of another
family failed, a later evp_pkey_ctx_free_old_ops() call dispatched
on the new operation and passed the stale generation pointer
to EVP_SIGNATURE_free(), EVP_KEYEXCH_free(), EVP_ASYM_CIPHER_free(),
or EVP_KEM_free(). The asymmetric cipher and KEM paths fault inside
their failing init, since their err: labels call
evp_pkey_ctx_free_old_ops() a second time; the signature and derive
paths fault later in EVP_PKEY_CTX_free().
Clear genctx alongside the other branches so that repeated cleanup
becomes a no-op. This does not change any key or keymgmt reference
count: genctx is an opaque provider allocation owned exclusively
by the EVP_PKEY_CTX, evp_keymgmt_gen_cleanup() only invokes
the provider gen_cleanup callback, and the reference int_ctx_new()
holds on ctx->keymgmt is still released exactly once
by EVP_PKEY_CTX_free(). EVP_PKEY_CTX_dup() rejects generation
operations, so the pointer can never acquire a second owner,
and gen_init() always assigns a fresh genctx after freeing the old
operations.
Resolves: https://github.com/openssl/openssl/issues/33507
Fixes: 629247557336 "EVP: Add new domparams and key generation functionality"
Signed-off-by: Nikola Pajkovsky <nikolap@openssl.org>
Reviewed-by: Eugene Syromiatnikov <esyr@openssl.org>
Reviewed-by: Andrew Dinh <andrewd@openssl.org>
Merge-date: Sat Nov 14 03:09:05 2026
Merged-from: https://github.com/openssl/openssl/pull/33667
diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
index 963e0615c2..3ffe51d822 100644
--- a/crypto/evp/pmeth_lib.c
+++ b/crypto/evp/pmeth_lib.c
@@ -230,6 +230,7 @@ void evp_pkey_ctx_free_old_ops(EVP_PKEY_CTX *ctx)
} else if (EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
if (ctx->op.keymgmt.genctx != NULL && ctx->keymgmt != NULL)
evp_keymgmt_gen_cleanup(ctx->keymgmt, ctx->op.keymgmt.genctx);
+ ctx->op.keymgmt.genctx = NULL;
}
}