Don't skip calling the cleanup hook in EVP_PKEY_CTX when the copy hook fails This was only reachable from malloc failure. Way back in https://boringssl-review.googlesource.com/c/boringssl/+/13830 we imported a change from BoringSSL to stop calling cleanup when EVP_PKEY_CTX_dup failed. This supposedly fixed a crash (I didn't check if it did at the time) but instead caused different malloc failures to leak memory. Now that all our cleanup functions are just a call to C++ Delete, and we use C++ scopers for all the fields, the EVP_PKEY_CTX state is in a consistent enough state to delete all the time anyway. While I'm here, I've fixed the cleanup functions to all be more consistent. Some of them reset ctx->data and some of them didn't. It doesn't matter if we do because the object will be destroyed immediately afterwards, so I standardized on the shorter pattern. To review this, check that a failure in the copy hook never leaves the EVP_PKEY_CTX in a state where the cleanup hook will not safely clean this up. Note that bssl::Delete, like C++ delete, gracefully handles nullptr. Change-Id: I874b953efbef179f1387c0a2b2e0320e6c3ff2e6 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/93627 Commit-Queue: David Benjamin <davidben@google.com> Reviewed-by: Rudolf Polzer <rpolzer@google.com> Auto-Submit: David Benjamin <davidben@google.com>
diff --git a/crypto/evp/evp_ctx.cc b/crypto/evp/evp_ctx.cc index adac362..ffb9b6f 100644 --- a/crypto/evp/evp_ctx.cc +++ b/crypto/evp/evp_ctx.cc
@@ -144,7 +144,6 @@ ret->pkey = UpRef(impl->pkey); ret->peerkey = UpRef(impl->peerkey); if (impl->pmeth->copy(ret.get(), impl) <= 0) { - ret->pmeth = nullptr; // Don't call |pmeth->cleanup|. OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP); return nullptr; }
diff --git a/crypto/evp/p_dh.cc b/crypto/evp/p_dh.cc index 26c4770..eaf7fad 100644 --- a/crypto/evp/p_dh.cc +++ b/crypto/evp/p_dh.cc
@@ -189,9 +189,7 @@ } static void pkey_dh_cleanup(EvpPkeyCtx *ctx) { - DH_PKEY_CTX *dctx = reinterpret_cast<DH_PKEY_CTX *>(ctx->data); - Delete(dctx); - ctx->data = nullptr; + Delete(reinterpret_cast<DH_PKEY_CTX *>(ctx->data)); } static int pkey_dh_keygen(EvpPkeyCtx *ctx, EvpPkey *pkey) {
diff --git a/crypto/evp/p_ec.cc b/crypto/evp/p_ec.cc index cf58518..ac9a489 100644 --- a/crypto/evp/p_ec.cc +++ b/crypto/evp/p_ec.cc
@@ -365,12 +365,7 @@ } static void pkey_ec_cleanup(EvpPkeyCtx *ctx) { - EC_PKEY_CTX *dctx = reinterpret_cast<EC_PKEY_CTX *>(ctx->data); - if (!dctx) { - return; - } - - Delete(dctx); + Delete(reinterpret_cast<EC_PKEY_CTX *>(ctx->data)); } static int pkey_ec_sign(EvpPkeyCtx *ctx, uint8_t *sig, size_t *siglen,
diff --git a/crypto/evp/p_hkdf.cc b/crypto/evp/p_hkdf.cc index f1a8a35..14cb76c 100644 --- a/crypto/evp/p_hkdf.cc +++ b/crypto/evp/p_hkdf.cc
@@ -63,9 +63,7 @@ } static void pkey_hkdf_cleanup(EvpPkeyCtx *ctx) { - HKDF_PKEY_CTX *hctx = reinterpret_cast<HKDF_PKEY_CTX *>(ctx->data); - Delete(hctx); - ctx->data = nullptr; + Delete(reinterpret_cast<HKDF_PKEY_CTX *>(ctx->data)); } static int pkey_hkdf_derive(EvpPkeyCtx *ctx, uint8_t *out, size_t *out_len) {