libpq: Don't overwrite existing OpenSSL thread callbacks
authorPeter Eisentraut <[email protected]>
Fri, 10 Apr 2015 00:45:34 +0000 (20:45 -0400)
committerPeter Eisentraut <[email protected]>
Fri, 10 Apr 2015 00:45:34 +0000 (20:45 -0400)
If someone else already set the callbacks, don't overwrite them with
ours.  When unsetting the callbacks, only unset them if they point to
ours.

Author: Jan UrbaƄski <[email protected]>

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

index 1b9f3a4a7b0a7ad065c62bfcd1a85ba3c3b91df1..fee154904a61e4f9068b2f18a92482d4f774f05d 100644 (file)
@@ -806,9 +806,12 @@ pgtls_init(PGconn *conn)
 
                if (ssl_open_connections++ == 0)
                {
-                       /* These are only required for threaded libcrypto applications */
-                       CRYPTO_set_id_callback(pq_threadidcallback);
-                       CRYPTO_set_locking_callback(pq_lockingcallback);
+                       /* These are only required for threaded libcrypto applications, but
+                        * make sure we don't stomp on them if they're already set. */
+                       if (CRYPTO_get_id_callback() == NULL)
+                               CRYPTO_set_id_callback(pq_threadidcallback);
+                       if (CRYPTO_get_locking_callback() == NULL)
+                               CRYPTO_set_locking_callback(pq_lockingcallback);
                }
        }
 #endif   /* ENABLE_THREAD_SAFETY */
@@ -885,9 +888,12 @@ destroy_ssl_system(void)
 
        if (pq_init_crypto_lib && ssl_open_connections == 0)
        {
-               /* No connections left, unregister libcrypto callbacks */
-               CRYPTO_set_locking_callback(NULL);
-               CRYPTO_set_id_callback(NULL);
+               /* No connections left, unregister libcrypto callbacks, if no one
+                * registered different ones in the meantime. */
+               if (CRYPTO_get_locking_callback() == pq_lockingcallback)
+                       CRYPTO_set_locking_callback(NULL);
+               if (CRYPTO_get_id_callback() == pq_threadidcallback)
+                       CRYPTO_set_id_callback(NULL);
 
                /*
                 * We don't free the lock array or the SSL_context. If we get another