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

Commit4e81628

Browse files
committed
Properly unregister OpenSSL callbacks when libpq is done with
it's connection. This is required for applications that unloadthe libpq library (such as PHP) in which case we'd otherwisehave pointers to these functions when they no longer exist.This needs a bit more testing before we can consider a backpatch,so not doing that yet.In passing, remove unused functions in backend/libpq.Bruce Momjian and Magnus Hagander, per report and analysisby Russell Smith.
1 parentc37951e commit4e81628

File tree

2 files changed

+125
-72
lines changed

2 files changed

+125
-72
lines changed

‎src/backend/libpq/be-secure.c

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.86 2008/11/20 09:29:36 mha Exp $
14+
* $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.87 2008/12/03 20:04:26 mha Exp $
1515
*
1616
* Since the server static private key ($DataDir/server.key)
1717
* will normally be stored unencrypted so that the database
@@ -88,7 +88,6 @@ static DH *tmp_dh_cb(SSL *s, int is_export, int keylength);
8888
staticintverify_cb(int,X509_STORE_CTX*);
8989
staticvoidinfo_cb(constSSL*ssl,inttype,intargs);
9090
staticvoidinitialize_SSL(void);
91-
staticvoiddestroy_SSL(void);
9291
staticintopen_server_SSL(Port*);
9392
staticvoidclose_SSL(Port*);
9493
staticconstchar*SSLerrmessage(void);
@@ -192,17 +191,6 @@ secure_initialize(void)
192191
return0;
193192
}
194193

195-
/*
196-
*Destroy global context
197-
*/
198-
void
199-
secure_destroy(void)
200-
{
201-
#ifdefUSE_SSL
202-
destroy_SSL();
203-
#endif
204-
}
205-
206194
/*
207195
* Indicate if we have loaded the root CA store to verify certificates
208196
*/
@@ -843,19 +831,6 @@ initialize_SSL(void)
843831
}
844832
}
845833

846-
/*
847-
*Destroy global SSL context.
848-
*/
849-
staticvoid
850-
destroy_SSL(void)
851-
{
852-
if (SSL_context)
853-
{
854-
SSL_CTX_free(SSL_context);
855-
SSL_context=NULL;
856-
}
857-
}
858-
859834
/*
860835
*Attempt to negotiate SSL connection.
861836
*/

‎src/interfaces/libpq/fe-secure.c

Lines changed: 124 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.110 2008/12/02 10:39:30 mha Exp $
14+
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.111 2008/12/03 20:04:26 mha Exp $
1515
*
1616
* NOTES
1717
*
@@ -44,6 +44,7 @@
4444
#endif
4545
#include<arpa/inet.h>
4646
#endif
47+
4748
#include<sys/stat.h>
4849

4950
#ifdefENABLE_THREAD_SAFETY
@@ -89,20 +90,32 @@ static bool verify_peer_name_matches_certificate(PGconn *);
8990
staticintverify_cb(intok,X509_STORE_CTX*ctx);
9091
staticintclient_cert_cb(SSL*,X509**,EVP_PKEY**);
9192
staticintinit_ssl_system(PGconn*conn);
93+
staticvoiddestroy_ssl_system(void);
9294
staticintinitialize_SSL(PGconn*);
93-
staticvoiddestroy_SSL(void);
95+
staticvoiddestroySSL(void);
9496
staticPostgresPollingStatusTypeopen_client_SSL(PGconn*);
9597
staticvoidclose_SSL(PGconn*);
9698
staticchar*SSLerrmessage(void);
9799
staticvoidSSLerrfree(char*buf);
98-
#endif
99100

100-
#ifdefUSE_SSL
101101
staticboolpq_initssllib= true;
102-
103102
staticSSL_CTX*SSL_context=NULL;
103+
104+
#ifdefENABLE_THREAD_SAFETY
105+
staticintssl_open_connections=0;
106+
107+
#ifndefWIN32
108+
staticpthread_mutex_tssl_config_mutex=PTHREAD_MUTEX_INITIALIZER;
109+
#else
110+
staticpthread_mutex_tssl_config_mutex=NULL;
111+
staticlongwin32_ssl_create_mutex=0;
104112
#endif
105113

114+
#endif/* ENABLE_THREAD_SAFETY */
115+
116+
#endif/* SSL */
117+
118+
106119
/*
107120
* Macros to handle disabling and then restoring the state of SIGPIPE handling.
108121
* Note that DISABLE_SIGPIPE() must appear at the start of a block.
@@ -186,7 +199,7 @@ void
186199
pqsecure_destroy(void)
187200
{
188201
#ifdefUSE_SSL
189-
destroy_SSL();
202+
destroySSL();
190203
#endif
191204
}
192205

@@ -734,6 +747,9 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
734747
}
735748

736749
#ifdefENABLE_THREAD_SAFETY
750+
/*
751+
*Callback functions for OpenSSL internal locking
752+
*/
737753

738754
staticunsigned long
739755
pq_threadidcallback(void)
@@ -765,54 +781,74 @@ pq_lockingcallback(int mode, int n, const char *file, int line)
765781
#endif/* ENABLE_THREAD_SAFETY */
766782

767783
/*
768-
* Also see similar code in fe-connect.c, default_threadlock()
784+
* Initialize SSL system. In threadsafe mode, this includes setting
785+
* up OpenSSL callback functions to do thread locking.
786+
*
787+
* If the caller has told us (through PQinitSSL) that he's taking care
788+
* of SSL, we expect that callbacks are already set, and won't try to
789+
* override it.
790+
*
791+
* The conn parameter is only used to be able to pass back an error
792+
* message - no connection local setup is made.
769793
*/
770794
staticint
771795
init_ssl_system(PGconn*conn)
772796
{
773797
#ifdefENABLE_THREAD_SAFETY
774-
#ifndefWIN32
775-
staticpthread_mutex_tinit_mutex=PTHREAD_MUTEX_INITIALIZER;
776-
#else
777-
staticpthread_mutex_tinit_mutex=NULL;
778-
staticlongmutex_initlock=0;
779-
780-
if (init_mutex==NULL)
798+
#ifdefWIN32
799+
/* Also see similar code in fe-connect.c, default_threadlock() */
800+
if (ssl_config_mutex==NULL)
781801
{
782-
while (InterlockedExchange(&mutex_initlock,1)==1)
802+
while (InterlockedExchange(&win32_ssl_create_mutex,1)==1)
783803
/* loop, another thread own the lock */ ;
784-
if (init_mutex==NULL)
804+
if (ssl_config_mutex==NULL)
785805
{
786-
if (pthread_mutex_init(&init_mutex,NULL))
806+
if (pthread_mutex_init(&ssl_config_mutex,NULL))
787807
return-1;
788808
}
789-
InterlockedExchange(&mutex_initlock,0);
809+
InterlockedExchange(&win32_ssl_create_mutex,0);
790810
}
791811
#endif
792-
if (pthread_mutex_lock(&init_mutex))
812+
if (pthread_mutex_lock(&ssl_config_mutex))
793813
return-1;
794814

795-
if (pq_initssllib&&pq_lockarray==NULL)
815+
if (pq_initssllib)
796816
{
797-
inti;
798-
799-
CRYPTO_set_id_callback(pq_threadidcallback);
800-
801-
pq_lockarray=malloc(sizeof(pthread_mutex_t)*CRYPTO_num_locks());
802-
if (!pq_lockarray)
803-
{
804-
pthread_mutex_unlock(&init_mutex);
805-
return-1;
806-
}
807-
for (i=0;i<CRYPTO_num_locks();i++)
817+
/*
818+
* If necessary, set up an array to hold locks for OpenSSL. OpenSSL will
819+
* tell us how big to make this array.
820+
*/
821+
if (pq_lockarray==NULL)
808822
{
809-
if (pthread_mutex_init(&pq_lockarray[i],NULL))
823+
inti;
824+
825+
pq_lockarray=malloc(sizeof(pthread_mutex_t)*CRYPTO_num_locks());
826+
if (!pq_lockarray)
827+
{
828+
pthread_mutex_unlock(&ssl_config_mutex);
810829
return-1;
830+
}
831+
for (i=0;i<CRYPTO_num_locks();i++)
832+
{
833+
if (pthread_mutex_init(&pq_lockarray[i],NULL))
834+
{
835+
free(pq_lockarray);
836+
pq_lockarray=NULL;
837+
pthread_mutex_unlock(&ssl_config_mutex);
838+
return-1;
839+
}
840+
}
811841
}
812842

813-
CRYPTO_set_locking_callback(pq_lockingcallback);
843+
if (ssl_open_connections++==0)
844+
{
845+
/* These are only required for threaded SSL applications */
846+
CRYPTO_set_id_callback(pq_threadidcallback);
847+
CRYPTO_set_locking_callback(pq_lockingcallback);
848+
}
814849
}
815-
#endif
850+
#endif/* ENABLE_THREAD_SAFETY */
851+
816852
if (!SSL_context)
817853
{
818854
if (pq_initssllib)
@@ -833,19 +869,67 @@ init_ssl_system(PGconn *conn)
833869
err);
834870
SSLerrfree(err);
835871
#ifdefENABLE_THREAD_SAFETY
836-
pthread_mutex_unlock(&init_mutex);
872+
pthread_mutex_unlock(&ssl_config_mutex);
837873
#endif
838874
return-1;
839875
}
840876
}
877+
841878
#ifdefENABLE_THREAD_SAFETY
842-
pthread_mutex_unlock(&init_mutex);
879+
pthread_mutex_unlock(&ssl_config_mutex);
843880
#endif
844881
return0;
845882
}
846883

847884
/*
848-
*Initialize global SSL context.
885+
*This function is needed because if the libpq library is unloaded
886+
*from the application, the callback functions will no longer exist when
887+
*SSL used by other parts of the system. For this reason,
888+
*we unregister the SSL callback functions when the last libpq
889+
*connection is closed.
890+
*
891+
*Callbacks are only set when we're compiled in threadsafe mode, so
892+
*we only need to remove them in this case.
893+
*/
894+
staticvoid
895+
destroy_ssl_system(void)
896+
{
897+
#ifdefENABLE_THREAD_SAFETY
898+
/* Mutex is created in initialize_ssl_system() */
899+
if (pthread_mutex_lock(&ssl_config_mutex))
900+
return;
901+
902+
if (pq_initssllib)
903+
{
904+
if (ssl_open_connections>0)
905+
--ssl_open_connections;
906+
907+
if (ssl_open_connections==0)
908+
{
909+
/* No connections left, unregister all callbacks */
910+
CRYPTO_set_locking_callback(NULL);
911+
CRYPTO_set_id_callback(NULL);
912+
913+
/*
914+
* We don't free the lock array. If we get another connection
915+
* from the same caller, we will just re-use it with the existing
916+
* mutexes.
917+
*
918+
* This means we leak a little memory on repeated load/unload
919+
* of the library.
920+
*/
921+
free(pqlockarray);
922+
pqlockarray=NULL;
923+
}
924+
}
925+
926+
pthread_mutex_unlock(&ssl_config_mutex);
927+
#endif
928+
return;
929+
}
930+
931+
/*
932+
*Initialize SSL context.
849933
*/
850934
staticint
851935
initialize_SSL(PGconn*conn)
@@ -932,17 +1016,10 @@ initialize_SSL(PGconn *conn)
9321016
return0;
9331017
}
9341018

935-
/*
936-
*Destroy global SSL context.
937-
*/
9381019
staticvoid
939-
destroy_SSL(void)
1020+
destroySSL(void)
9401021
{
941-
if (SSL_context)
942-
{
943-
SSL_CTX_free(SSL_context);
944-
SSL_context=NULL;
945-
}
1022+
destroy_ssl_system();
9461023
}
9471024

9481025
/*
@@ -1061,6 +1138,7 @@ close_SSL(PGconn *conn)
10611138
SSL_shutdown(conn->ssl);
10621139
SSL_free(conn->ssl);
10631140
conn->ssl=NULL;
1141+
pqsecure_destroy();
10641142
/* We have to assume we got EPIPE */
10651143
REMEMBER_EPIPE(true);
10661144
RESTORE_SIGPIPE();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp