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;
     }
 }