Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitcd694f6

Browse files
committed
Change pgcrypto to use the new ResourceOwner mechanism.
This is a nice example of how extensions can now use ResourceOwners totrack extension-specific resource kindsReviewed-by: Peter Eisentraut, Andres FreundDiscussion:https://www.postgresql.org/message-id/d746cead-a1ef-7efe-fb47-933311e876a3%40iki.fi
1 parent954e435 commitcd694f6

File tree

1 file changed

+78
-103
lines changed

1 file changed

+78
-103
lines changed

‎contrib/pgcrypto/openssl.c

Lines changed: 78 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -50,64 +50,48 @@
5050
*/
5151

5252
/*
53-
* To make sure we don't leak OpenSSL handles on abort, we keep OSSLDigest
54-
* objects in a linked list, allocated in TopMemoryContext. We use the
55-
* ResourceOwner mechanism to free them on abort.
53+
* To make sure we don't leak OpenSSL handles, we use the ResourceOwner
54+
* mechanism to free them on abort.
5655
*/
5756
typedefstructOSSLDigest
5857
{
5958
constEVP_MD*algo;
6059
EVP_MD_CTX*ctx;
6160

6261
ResourceOwnerowner;
63-
structOSSLDigest*next;
64-
structOSSLDigest*prev;
6562
}OSSLDigest;
6663

67-
staticOSSLDigest*open_digests=NULL;
68-
staticbooldigest_resowner_callback_registered= false;
64+
/* ResourceOwner callbacks to hold OpenSSL digest handles */
65+
staticvoidResOwnerReleaseOSSLDigest(Datumres);
6966

70-
staticvoid
71-
free_openssl_digest(OSSLDigest*digest)
67+
staticconstResourceOwnerDescossldigest_resowner_desc=
7268
{
73-
EVP_MD_CTX_destroy(digest->ctx);
74-
if (digest->prev)
75-
digest->prev->next=digest->next;
76-
else
77-
open_digests=digest->next;
78-
if (digest->next)
79-
digest->next->prev=digest->prev;
80-
pfree(digest);
69+
.name="pgcrypto OpenSSL digest handle",
70+
.release_phase=RESOURCE_RELEASE_BEFORE_LOCKS,
71+
.release_priority=RELEASE_PRIO_FIRST,
72+
.ReleaseResource=ResOwnerReleaseOSSLDigest,
73+
.DebugPrint=NULL,/* default message is fine */
74+
};
75+
76+
/* Convenience wrappers over ResourceOwnerRemember/Forget */
77+
staticinlinevoid
78+
ResourceOwnerRememberOSSLDigest(ResourceOwnerowner,OSSLDigest*digest)
79+
{
80+
ResourceOwnerRemember(owner,PointerGetDatum(digest),&ossldigest_resowner_desc);
81+
}
82+
staticinlinevoid
83+
ResourceOwnerForgetOSSLDigest(ResourceOwnerowner,OSSLDigest*digest)
84+
{
85+
ResourceOwnerForget(owner,PointerGetDatum(digest),&ossldigest_resowner_desc);
8186
}
8287

83-
/*
84-
* Close any open OpenSSL handles on abort.
85-
*/
8688
staticvoid
87-
digest_free_callback(ResourceReleasePhasephase,
88-
boolisCommit,
89-
boolisTopLevel,
90-
void*arg)
89+
free_openssl_digest(OSSLDigest*digest)
9190
{
92-
OSSLDigest*curr;
93-
OSSLDigest*next;
94-
95-
if (phase!=RESOURCE_RELEASE_AFTER_LOCKS)
96-
return;
97-
98-
next=open_digests;
99-
while (next)
100-
{
101-
curr=next;
102-
next=curr->next;
103-
104-
if (curr->owner==CurrentResourceOwner)
105-
{
106-
if (isCommit)
107-
elog(WARNING,"pgcrypto digest reference leak: digest %p still referenced",curr);
108-
free_openssl_digest(curr);
109-
}
110-
}
91+
EVP_MD_CTX_destroy(digest->ctx);
92+
if (digest->owner!=NULL)
93+
ResourceOwnerForgetOSSLDigest(digest->owner,digest);
94+
pfree(digest);
11195
}
11296

11397
staticunsigned
@@ -188,16 +172,12 @@ px_find_digest(const char *name, PX_MD **res)
188172
OpenSSL_add_all_algorithms();
189173
}
190174

191-
if (!digest_resowner_callback_registered)
192-
{
193-
RegisterResourceReleaseCallback(digest_free_callback,NULL);
194-
digest_resowner_callback_registered= true;
195-
}
196-
197175
md=EVP_get_digestbyname(name);
198176
if (md==NULL)
199177
returnPXE_NO_HASH;
200178

179+
ResourceOwnerEnlarge(CurrentResourceOwner);
180+
201181
/*
202182
* Create an OSSLDigest object, an OpenSSL MD object, and a PX_MD object.
203183
* The order is crucial, to make sure we don't leak anything on
@@ -221,9 +201,7 @@ px_find_digest(const char *name, PX_MD **res)
221201
digest->algo=md;
222202
digest->ctx=ctx;
223203
digest->owner=CurrentResourceOwner;
224-
digest->next=open_digests;
225-
digest->prev=NULL;
226-
open_digests=digest;
204+
ResourceOwnerRememberOSSLDigest(digest->owner,digest);
227205

228206
/* The PX_MD object is allocated in the current memory context. */
229207
h=palloc(sizeof(*h));
@@ -239,6 +217,17 @@ px_find_digest(const char *name, PX_MD **res)
239217
return0;
240218
}
241219

220+
/* ResourceOwner callbacks for OSSLDigest */
221+
222+
staticvoid
223+
ResOwnerReleaseOSSLDigest(Datumres)
224+
{
225+
OSSLDigest*digest= (OSSLDigest*)DatumGetPointer(res);
226+
227+
digest->owner=NULL;
228+
free_openssl_digest(digest);
229+
}
230+
242231
/*
243232
* Ciphers
244233
*
@@ -266,9 +255,8 @@ struct ossl_cipher
266255
* OSSLCipher contains the state for using a cipher. A separate OSSLCipher
267256
* object is allocated in each px_find_cipher() call.
268257
*
269-
* To make sure we don't leak OpenSSL handles on abort, we keep OSSLCipher
270-
* objects in a linked list, allocated in TopMemoryContext. We use the
271-
* ResourceOwner mechanism to free them on abort.
258+
* To make sure we don't leak OpenSSL handles, we use the ResourceOwner
259+
* mechanism to free them on abort.
272260
*/
273261
typedefstructOSSLCipher
274262
{
@@ -281,54 +269,39 @@ typedef struct OSSLCipher
281269
conststructossl_cipher*ciph;
282270

283271
ResourceOwnerowner;
284-
structOSSLCipher*next;
285-
structOSSLCipher*prev;
286272
}OSSLCipher;
287273

288-
staticOSSLCipher*open_ciphers=NULL;
289-
staticboolcipher_resowner_callback_registered= false;
274+
/* ResourceOwner callbacks to hold OpenSSL cipher state */
275+
staticvoidResOwnerReleaseOSSLCipher(Datumres);
290276

291-
staticvoid
292-
free_openssl_cipher(OSSLCipher*od)
277+
staticconstResourceOwnerDescosslcipher_resowner_desc=
293278
{
294-
EVP_CIPHER_CTX_free(od->evp_ctx);
295-
if (od->prev)
296-
od->prev->next=od->next;
297-
else
298-
open_ciphers=od->next;
299-
if (od->next)
300-
od->next->prev=od->prev;
301-
pfree(od);
279+
.name="pgcrypto OpenSSL cipher handle",
280+
.release_phase=RESOURCE_RELEASE_BEFORE_LOCKS,
281+
.release_priority=RELEASE_PRIO_FIRST,
282+
.ReleaseResource=ResOwnerReleaseOSSLCipher,
283+
.DebugPrint=NULL,/* default message is fine */
284+
};
285+
286+
/* Convenience wrappers over ResourceOwnerRemember/Forget */
287+
staticinlinevoid
288+
ResourceOwnerRememberOSSLCipher(ResourceOwnerowner,OSSLCipher*od)
289+
{
290+
ResourceOwnerRemember(owner,PointerGetDatum(od),&osslcipher_resowner_desc);
291+
}
292+
staticinlinevoid
293+
ResourceOwnerForgetOSSLCipher(ResourceOwnerowner,OSSLCipher*od)
294+
{
295+
ResourceOwnerForget(owner,PointerGetDatum(od),&osslcipher_resowner_desc);
302296
}
303297

304-
/*
305-
* Close any open OpenSSL cipher handles on abort.
306-
*/
307298
staticvoid
308-
cipher_free_callback(ResourceReleasePhasephase,
309-
boolisCommit,
310-
boolisTopLevel,
311-
void*arg)
299+
free_openssl_cipher(OSSLCipher*od)
312300
{
313-
OSSLCipher*curr;
314-
OSSLCipher*next;
315-
316-
if (phase!=RESOURCE_RELEASE_AFTER_LOCKS)
317-
return;
318-
319-
next=open_ciphers;
320-
while (next)
321-
{
322-
curr=next;
323-
next=curr->next;
324-
325-
if (curr->owner==CurrentResourceOwner)
326-
{
327-
if (isCommit)
328-
elog(WARNING,"pgcrypto cipher reference leak: cipher %p still referenced",curr);
329-
free_openssl_cipher(curr);
330-
}
331-
}
301+
EVP_CIPHER_CTX_free(od->evp_ctx);
302+
if (od->owner!=NULL)
303+
ResourceOwnerForgetOSSLCipher(od->owner,od);
304+
pfree(od);
332305
}
333306

334307
/* Common routines for all algorithms */
@@ -782,11 +755,7 @@ px_find_cipher(const char *name, PX_Cipher **res)
782755
if (i->name==NULL)
783756
returnPXE_NO_CIPHER;
784757

785-
if (!cipher_resowner_callback_registered)
786-
{
787-
RegisterResourceReleaseCallback(cipher_free_callback,NULL);
788-
cipher_resowner_callback_registered= true;
789-
}
758+
ResourceOwnerEnlarge(CurrentResourceOwner);
790759

791760
/*
792761
* Create an OSSLCipher object, an EVP_CIPHER_CTX object and a PX_Cipher.
@@ -806,9 +775,7 @@ px_find_cipher(const char *name, PX_Cipher **res)
806775

807776
od->evp_ctx=ctx;
808777
od->owner=CurrentResourceOwner;
809-
od->next=open_ciphers;
810-
od->prev=NULL;
811-
open_ciphers=od;
778+
ResourceOwnerRememberOSSLCipher(od->owner,od);
812779

813780
if (i->ciph->cipher_func)
814781
od->evp_ciph=i->ciph->cipher_func();
@@ -827,3 +794,11 @@ px_find_cipher(const char *name, PX_Cipher **res)
827794
*res=c;
828795
return0;
829796
}
797+
798+
/* ResourceOwner callbacks for OSSLCipher */
799+
800+
staticvoid
801+
ResOwnerReleaseOSSLCipher(Datumres)
802+
{
803+
free_openssl_cipher((OSSLCipher*)DatumGetPointer(res));
804+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp