Am 14.04.2016 um 19:53 schrieb Rainer Jung:
Am 14.04.2016 um 17:02 schrieb Poggenpohl, Daniel:
Hello everyone,

thanks to this mailing list I have identified and solved many problems
in my builds regarding my current setup for a Moodle installation.
- Removed unnecessary switches from Apache build
- Placement of switches inside commands
- new switches for selective runtime search path changing (even if I
don't use them yet...)
- found new (to me) tools for checking info about binaries and libraries
- Facts about the order of checking in runtime linking paths (-R,
crle, LD_LIBRARY_PATH)

So thanks for this so far, you've been very helpful.

Yet two problems remain, which may or may be the same problem.
- I have to set LD_LIBRARY_PATH to my own OpenSSL. Only then does
PHPInfo tell me that the correct OpenSSL is in use.
- Using the system OpenLDAP, I can't connect using LDAPS. Using my own
OpenLDAP 2.4.44, I can use LDAPS on the prompt and I can process a php
file containing commands to connect via LDAPS. I just can't request
the same file via the browser (PHP then reports that it can't bind to
the LDAP server. I also can't login via LDAP to Moodle, but get a an
error that the secured connection can't be established. (I will send
the exact error message if I recompile again to test).

Checking in with ldd, all runtime search paths are set. I checked the
paths for
OpenSSL: openssl, libssl, libcrypto
OpenLDAP: ldapsearch, libldap, liblber
Apache: httpd, the apr and apr-util libraries, mod_ssl
PHP: php, libphp5.so (in Apache)

The only things that's looked strange are:
- PHP uses Postgres libraries, which in turn depend on libssl and
libcrypto. When I ldd, I have dependencies to both
/my/own/openssl/install/lib and to /usr/lib (libssl and libcrypto).
But I think that's okay....?
- PHP uses libcurl, it finds it in /usr/local/lib . This in turn
depends on libssl and libcrypto and when I ldd libcurl, it finds them
in /usr/lib. Again, I don't know? How deep do I have to go here?

My configure commands for each of the four tools:
# OpenSSL
OPENSSLDIR=/moodle/openssl/1.0.2g \
; \
export CFLAGS="-I$OPENSSLDIR/include" \
CFLAG= \
CPPFLAGS= \
LDFLAGS= \
; \
./Configure shared --openssldir=$OPENSSLDIR enable-ssl2 solaris-x86-gcc \
-I$OPENSSLDIR/include -L$OPENSSLDIR/lib -R$OPENSSLDIR/lib \
openssl-102g-configure.out

# OpenLDAP
OPENLDAPDIR=/moodle/openldap/2.4.44 \
OPENSSLDIR=/moodle/openssl/1.0.2g \
; \
export CPPFLAGS="-I$OPENSSLDIR/include" \
CFLAGS= \
LDFLAGS="-L$OPENSSLDIR/lib -R$OPENSSLDIR/lib" \
; \
./configure --prefix=$OPENLDAPDIR --disable-slapd --with-cyrus-sasl
--with-tls=openssl \
openldap-2444-configure.out 2>&1

# Apache
APACHEDIR=/moodle/apache2/2.4.18 \
OPENSSLDIR=/moodle/openssl/1.0.2g \
; \
export PKG_CONFIG_PATH=$OPENSSLDIR/lib/pkgconfig \
CFLAGS= \
CPPFLAGS="-I$OPENSSLDIR/include" \
LDFLAGS="-L$OPENSSLDIR/lib -R$OPENSSLDIR/lib" \
; \
./configure --prefix=$APACHEDIR \
--enable-rewrite --enable-deflate \
--enable-ssl --with-ssl=$OPENSSLDIR \
--disable-version \
--with-included-apr \
--with-mpm=prefork \
apache-2418-configure.out 2>&1

# PHP
APACHEDIR=/moodle/apache2/2.4.18 \
POSTGRESDIR= /usr/postgres/9.3-pgdg \
PHPDIR=/moodle/php/5.6.20 \
OPENSSLDIR=/moodle/openssl/1.0.2g \
; \
export PKG_CONFIG_PATH=$OPENSSLDIR/lib/pkgconfig \
CFLAGS="-std=gnu99" \
CPPFLAGS="-I$OPENLDAPDIR/include -I$OPENSSLDIR/include" \
LDFLAGS="-L$OPENLDAPDIR/lib -L$OPENSSLDIR/lib -R$OPENLDAPDIR/lib
-R$OPENSSLDIR/lib" \
; \
./configure --prefix=$PHPDIR --with-config-file-path=$PHPDIR \
--enable-mbstring --enable-soap --enable-zip --enable-opcache \
--without-sqlite3 --without-pdo-sqlite \
--with-pgsql=$POSTGRESDIR --with-pdo-pgsql=$POSTGRESDIR \
--with-apxs2=$APACHEDIR/bin/apxs \
--with-gd --with-curl --with-xmlrpc --with-zlib --with-mcrypt \
--with-ldap=$OPENLDAPDIR \
--with-openssl=$OPENSSLDIR --with-jpeg-dir=$PHPDIR/jpeg \
--with-iconv=/usr/local \
php-5620-configure.out 2>&1

I also have output for the different stages of the build if that would
help.

I don't have a complete answer, only some hints. The problem with PHP
is, that is uses lots of libraries. Once you start updating some of the
more complex ones, it can happen, that a non-updated lib uses the same
other lib as a dependency that your updated lib also uses. OpenSSL is a
common example for such a dependency. Than you run into trouble, because
it starts to become harder to decide, which version of that dependency
lib (OpenSSL in your case) is actually used when.

Here symbol resolution comes into play. Say OpenSSl is linked into all
places it is needed as a shared object (dynamic linking, .so file), not
statically. Say you use PHp as mod_php, not via FPM. You start httpd,
which loads some modules and PHp as pone of the modules loads
extensions. Assume we have the following load order:

- httpd
   - apr libs
   - ...
   - mod_php
     - php curl extension
       - libcurl
         - OpenSSL-old
     - php ldap extension
       - libldap
         - OpenSSL-new
   - ...
   - mod_ssl
     - OpenSSL-new
   - ...

Now assume the PHP ldap extension starts to use OpenSSL symbols, e.g.
function calls. Since those are not statically compiled into the PHP
ldap.so file, it needs to look them up in the running process. By
default it starts looking inside httpd (not found), then the libs loaded
directly by httpd (not found), then through all of the shared objects in
the order they were loaded. In the above scenario it will find the
symbols in OpenSSL-old, since it was the first version loaded. Not what
you expect, because you compiled ldap.so against a new OpenLDAP which
was meant to use the new OpenSSL.

As a result depending on the load order and the compatibility of the old
and new OpenSSL versions you either get the old version being used in
everything, or the new version, or a crash.

That might explain your LD_LIBRARY_PATH observation, because then all of
the loaded parts will load the new OpenSSL (if they need OpenSSL, and
the SONAME hasn't changed betweeen the old and new version; the SONAME
for OpenSSL hasn't changed between 1.0.0 and 1.0.2 inclusive).

What you can try to change if you don't like this:

- if you only replace few parts by your own builds, you can try to link
OpenSSL statically into the parts you compile. That is not a great
solution, but it might be the simplest you get for your problem.
Depending on the build procedures, sometimes it can be enough to rename
the installed libssl.so and libcrypto.so files during building the
components that want to use them. If the build process is clean, they
should then automatically link in the .a (static) ones instead.

I should add: if you try the static linking attempt, you might also want to add -Bsymbolic to the linking (gcc -Wl,-Bsymbolic).

- Since (I think) you are on Solaris, you can link with "-Bdirect" as a
linker flag, e.g. -Wl,-Bdirect for gcc. This changes the search path for
symbols searched by the created shared object to first search the
dependencies that were loaded for this object before starting to search
at the beginning of the tree. That way each modules/lib should use its
version of OpenSSL. But I can't guarantee, that there are no clashes. We
can't e sure, that those versions running in parallel do not influence
each other in any way."-Bdirect" doesn't exist in Linux. There was a
discussion about adding it a few years ago, but it wasn't agreed upon.

Whether Bsymbolic and/ori Bdirect was correctly applied can again be seen with "elfdump -d" (I think). It should show SYMBOLIC resp. DIRECT somewhere.

I expect you LDAP problem is similar. Typically httpd or the apr-util
library loaded by httpd already has a dependency on libldap. httpd
indirectly, apr-util directly. So starting httpd, the system ldap libs
are loaded early. Later comes your PHP ldap extension which loads the
newer ldap you compiled yourself. But when it actually tries to use it,
the symbol resolution first hits the old ldap. Unfortunately there I
found no way how ldap.so in PHP could be asked about which version of
library it uses. Since you compiled OpenLDAp yourself, you could add a
debug output line to the impl of the ldap commect and check whether the
line appears on commandline use (expected) but not during browser use,
which would show that the other version is being used.

Again: as long as the SONAME of the system ldap and you self-compiled
ldap shows they are compatible, you can try to add the path to your
newer OpenLDAP to LD_LIBRARY_PATH to try forcing every component to use it.

I hope this was understandable.

Regards,

Rainer

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@httpd.apache.org
For additional commands, e-mail: users-h...@httpd.apache.org

Reply via email to