v3-0003-Move-pgcrypto-to-use-in-core-resowner-facility-fo.patch
text/x-diff
Filename: v3-0003-Move-pgcrypto-to-use-in-core-resowner-facility-fo.patch
Type: text/x-diff
Part: 2
Patch
Format: format-patch
Series: patch v3-0003
Subject: Move pgcrypto to use in-core resowner facility for EVP
| File | + | − |
|---|---|---|
| contrib/pgcrypto/openssl.c | 10 | 77 |
From 5138e31e3dd1a85e4c91811cddbad1650efbf147 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Thu, 5 Nov 2020 15:34:55 +0900
Subject: [PATCH v3 3/3] Move pgcrypto to use in-core resowner facility for EVP
This simplifies some code in pgcrypto as it does not need anymore to
rely on its own internal logic for the EVP registration and automatic
cleanup.
---
contrib/pgcrypto/openssl.c | 87 +++++---------------------------------
1 file changed, 10 insertions(+), 77 deletions(-)
diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c
index 5ebe213406..d8e1269a40 100644
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -38,6 +38,7 @@
#include "px.h"
#include "utils/memutils.h"
#include "utils/resowner.h"
+#include "utils/resowner_private.h"
/*
* Max lengths we might want to handle.
@@ -49,67 +50,12 @@
* Hashes
*/
-/*
- * To make sure we don't leak OpenSSL handles on abort, we keep OSSLDigest
- * objects in a linked list, allocated in TopMemoryContext. We use the
- * ResourceOwner mechanism to free them on abort.
- */
typedef struct OSSLDigest
{
const EVP_MD *algo;
EVP_MD_CTX *ctx;
-
- ResourceOwner owner;
- struct OSSLDigest *next;
- struct OSSLDigest *prev;
} OSSLDigest;
-static OSSLDigest *open_digests = NULL;
-static bool digest_resowner_callback_registered = false;
-
-static void
-free_openssl_digest(OSSLDigest *digest)
-{
- EVP_MD_CTX_destroy(digest->ctx);
- if (digest->prev)
- digest->prev->next = digest->next;
- else
- open_digests = digest->next;
- if (digest->next)
- digest->next->prev = digest->prev;
- pfree(digest);
-}
-
-/*
- * Close any open OpenSSL handles on abort.
- */
-static void
-digest_free_callback(ResourceReleasePhase phase,
- bool isCommit,
- bool isTopLevel,
- void *arg)
-{
- OSSLDigest *curr;
- OSSLDigest *next;
-
- if (phase != RESOURCE_RELEASE_AFTER_LOCKS)
- return;
-
- next = open_digests;
- while (next)
- {
- curr = next;
- next = curr->next;
-
- if (curr->owner == CurrentResourceOwner)
- {
- if (isCommit)
- elog(WARNING, "pgcrypto digest reference leak: digest %p still referenced", curr);
- free_openssl_digest(curr);
- }
- }
-}
-
static unsigned
digest_result_size(PX_MD *h)
{
@@ -155,7 +101,10 @@ digest_free(PX_MD *h)
{
OSSLDigest *digest = (OSSLDigest *) h->p.ptr;
- free_openssl_digest(digest);
+ EVP_MD_CTX_destroy(digest->ctx);
+ ResourceOwnerForgetEVP(CurrentResourceOwner,
+ PointerGetDatum(digest->ctx));
+ pfree(digest);
pfree(h);
}
@@ -177,42 +126,26 @@ px_find_digest(const char *name, PX_MD **res)
OpenSSL_add_all_algorithms();
}
- if (!digest_resowner_callback_registered)
- {
- RegisterResourceReleaseCallback(digest_free_callback, NULL);
- digest_resowner_callback_registered = true;
- }
-
md = EVP_get_digestbyname(name);
if (md == NULL)
return PXE_NO_HASH;
- /*
- * Create an OSSLDigest object, an OpenSSL MD object, and a PX_MD object.
- * The order is crucial, to make sure we don't leak anything on
- * out-of-memory or other error.
- */
- digest = MemoryContextAlloc(TopMemoryContext, sizeof(*digest));
-
ctx = EVP_MD_CTX_create();
if (!ctx)
- {
- pfree(digest);
return -1;
- }
+
if (EVP_DigestInit_ex(ctx, md, NULL) == 0)
{
EVP_MD_CTX_destroy(ctx);
- pfree(digest);
return -1;
}
+ ResourceOwnerEnlargeEVP(CurrentResourceOwner);
+ ResourceOwnerRememberEVP(CurrentResourceOwner, PointerGetDatum(ctx));
+
+ digest = palloc(sizeof(*digest));
digest->algo = md;
digest->ctx = ctx;
- digest->owner = CurrentResourceOwner;
- digest->next = open_digests;
- digest->prev = NULL;
- open_digests = digest;
/* The PX_MD object is allocated in the current memory context. */
h = palloc(sizeof(*h));
--
2.29.1