ID:               40926
 Updated by:       hholz...@php.net
 Reported By:      seanius at debian dot org
-Status:           Analyzed
+Status:           Closed
 Bug Type:         PostgreSQL related
 Operating System: Debian GNU/Linux
 PHP Version:      5.2CVS-2008-05-15
 Assigned To:      hholzgra


Previous Comments:
------------------------------------------------------------------------

[2008-12-04 04:17:33] miracee at miracee dot de

PostgreSQL fixed this bug.

http://archives.postgresql.org/pgsql-committers/2008-12/msg00037.php

Fix will be available in PostgreSQL version 8.4+

------------------------------------------------------------------------

[2008-12-01 20:33:57] hholz...@php.net

This is being worked on on the PG side, see "libpq callback
unregistration" on 
http://wiki.postgresql.org/wiki/CommitFest_2008-11#Clients

------------------------------------------------------------------------

[2008-10-28 22:27:52] j...@php.net

yohgaki seems to have left us so de-assigning. 

------------------------------------------------------------------------

[2008-03-01 14:17:22] jbq at caraldi dot com

Another workaround is to recompile PostgreSQL's libpq without OpenSSL
support (ie the --with-openssl configure switch).  After all, OpenSSL is
rarely needed in a typical LAPP installation.

------------------------------------------------------------------------

[2007-11-12 14:45:13] sam at zoy dot org

Hello, I did read the sources and studied them, and I can confirm
that it is a matter of callback jumping to an invalid address.

libpq's init_ssl_system() installs callbacks by calling
CRYPTO_set_id_callback() and CRYPTO_set_locking_callback(). This
function is called each time initialize_SSL() is called (for instance
through the PHP pg_connect() function) and does not keep a reference
counter, so libpq's destroy_SSL() has no way to know that it should
call a destroy_ssl_system() function, and there is no such function
anyway. So the callbacks are never removed.

But then, upon cleanup, PHP calls zend_shutdown() which properly
unloads pgsql.so and therefore the unused libpq.

Finally, the zend_shutdown procedure calls zm_shutdown_curl()
which in turn calls curl_global_cleanup() which leads to an
ERR_free_strings() call and eventually a CRYPTO_lock() call.
CRYPTO_lock() checks whether there are any callbacks to call,
finds one (the one installed by libpg), calls it, and crashes
because libpq was unloaded and hence the callback is no longer
in mapped memory.

There are a few ways to fix the problem, all of which are highly
unsatisfying or irrealist:

 - always ensure that pgsql.so is loaded before (and therefore
unloaded after) any other SSL-using library.

 - fix libpq so that it keeps a reference count when
initialize_SSL() is called, updates it when destroy_SSL() is
called, and remove SSL callbacks when the reference count
reaches zero.

 - fix libpq so that it removes the SSL callbacks when unloaded
(done in the library's .fini section)

 - hack PHP's module_destructor() so that it does not unload
a module if its name was pgsql.so (or maybe there is already
a mechanism for that).

None of these proposals is really safe because there might be other
conflicts due to libssl not being context-aware.

There is also the possibility to fix libssl by making it reentrant
or context-aware (just kidding, lol). In all cases, libssl can be
copiously blamed.

------------------------------------------------------------------------

The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
    http://bugs.php.net/40926

-- 
Edit this bug report at http://bugs.php.net/?id=40926&edit=1

Reply via email to