Bug #21930 libmysqlclient defines BN_bin2bn which belongs to OpenSSL! Breaks other apps!
Submitted: 30 Aug 2006 21:11 Modified: 20 Sep 2006 7:43
Reporter: Christian Hammers (Silver Quality Contributor) (OCA) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S2 (Serious)
Version:5.0.24 OS:Linux (Debian GNU/Linux Sid)
Assigned to: Magnus Blåudd
Tags: yassl

[30 Aug 2006 21:11] Christian Hammers
Description:
Hello

As reported by Peter Cernak to http://bugs.debian.org/385348 the latest versions of libmysqlclient.so.15 break programs that link also against OpenSSL's libcrypto.so as MySQL exports the symbol BN_bin2bn which it probably should better not:

$ objdump -T /usr/lib/libmysqlclient.so.15.0.0  |grep -i BN_bin2bn
00000000000862f0 g    DF .text  0000000000000092  libmysqlclient_15 BN_bin2bn

$ objdump -T /usr/lib/libcrypto.so.0.9.8 | grep -i BN_bin2bn
0000000000085210 g    DF .text  000000000000013a  OPENSSL_0.9.8 BN_bin2bn

$ grep -ris BN_bin2bn /usr/include/
/usr/include/openssl/bn.h:BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret);

So the symbol clearly belongs to OpenSSL. Hm interestingly it seems even to be
borrowed from there as the function is defined in ./extra/yassl/include/openssl/ssl.h

bye,

-christian-

How to repeat:
$ cat test.cc
#include <openssl/ssl.h>

BIGNUM *bn = 0;
const unsigned char src[] = {0x42, 0x42, 0x42, 0x42};
const int nel = sizeof(src);

int main (void)
{
        printf ("creating bn from array of size %i\n", nel);
        bn = BN_bin2bn (src, nel, 0);
        unsigned int u = BN_get_word (bn);
        printf ("u is %x\n", u);
        return 0;
}

$ g++ -W -Wall -o test -lstdc++ -lssl test.cc
$ ./test
creating bn from array of size 4
u is 42424242

$ g++ -W -Wall -o test -lstdc++ -lssl -lmysqlclient test.cc
$ ./test
creating bn from array of size 4
u is 0

Suggested fix:
*** IMPORTANT ***
Please, whatever you do to fix this, do *not* break the ABI of libmysqlclient.so again, ok? :) 

Apart from that, consider that people who linked apps against mysql and openssl
might actually tested their programs with your version in effect so that their apps break if they now get openssl's which seems to give different results.
I don't know how likely that is as I'm not sure what the function does :)
[31 Aug 2006 11:50] Domas Mituzas
indeed, same symbols are exported by both MySQL client and OpenSSL, tested against current BK tree builds for 5.0 and 5.1:

flute:~/Tests/bnlink midom$ nm /usr/local/mysql-5.0/lib/mysql/libmysqlclient.dylib  | grep BN
         U _BN_bin2bn
00046da8 T _BN_bin2bn

flute:~/Tests/bnlink midom$ nm /usr/local/mysql-5.1/lib/mysql/libmysqlclient.dylib  | grep BN
         U _BN_bin2bn
00047bcc T _BN_bin2bn

flute:~/Tests/bnlink midom$ nm /usr/lib/libssl.dylib  | grep BN
         U _BN_bin2bn
         U _BN_bn2bin
         U _BN_clear_free
         U _BN_dup
         U _BN_num_bits
         U _BN_bin2bn
         U _BN_bn2bin
         U _BN_num_bits
         U _BN_dup
[31 Aug 2006 12:07] Domas Mituzas
flute:~ midom$ nm -g /usr/lib/libssl.dylib /usr/lib/libcrypto.dylib /usr/local/mysql/lib/mysql/libmysqlclient.dylib | awk '$2=="T" {print $3}'  | sort | uniq -c | awk '$1>1'
   2 _BN_bin2bn
   2 _CRYPTO_add_lock
   2 _CRYPTO_lock
   2 _RAND_bytes
   2 _SSL_peek
   2 _SSLv23_server_method
   2 _SSLv3_client_method
   2 _SSLv3_method
   2 _SSLv3_server_method
   2 _TLSv1_client_method
   2 _TLSv1_server_method
[31 Aug 2006 12:26] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/11158

ChangeSet@1.2261, 2006-08-31 14:26:12+02:00, msvensson@shellback.(none) +1 -0
  Bug #21930 libmysqlclient defines BN_bin2bn which belongs to OpenSSL! Breaks other apps!
   - Correct bug in perl script that faild to add rename macros for some functions.
[31 Aug 2006 12:37] Magnus Blåudd
Setting showstopper and raising priority. We want this in 5.0.25
[31 Aug 2006 13:17] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/11160

ChangeSet@1.2262, 2006-08-31 15:16:44+02:00, msvensson@shellback.(none) +1 -0
  Bug#21930 libmysqlclient defines BN_bin2bn which belongs to OpenSSL! Breaks other apps!
   - Don't add the signatures for CRYPTO_* when compiling yaSSL for MySQL
[2 Sep 2006 9:26] Timothy Smith
Pushed to 5.0 (will be in 5.0.25)

TODO: Merge to 5.1
[7 Sep 2006 0:00] Jon Stephens
Documented the fix in the 5.0.25 changelog, set bug status to NDI pending merge to 5.1 tree.
[13 Sep 2006 8:55] Timothy Smith
Pushed to 5.1.12
[13 Sep 2006 12:46] Valerii Kravchuk
Bug #19289 was marked as a duplicate if this one.
[14 Sep 2006 13:50] Paul Dubois
Noted in 5.1.12 changelog.
[20 Sep 2006 7:17] Christian Hammers
After applying your patch against 5.0.24a, there are two symbols left that seems to be exported by both the mysql and the openssl libraries. Please check if they are in the forthcoming 5.0.25, too!

bye,

-christian-

$ objdump -T /usr/lib/libcrypto.so.0.9.8  |awk '{ print $7 }' |sort |uniq> sym.crypto
$ objdump -T /usr/lib/libmysqlclient.so.15.0.0 |awk '{ print $7 }' |sort |uniq> sym.mysql 
$ join sym.crypto sym.mysql 
__bss_start
CRYPTO_add_lock          <-------------
CRYPTO_lock              <-------------
__cxa_finalize
_edata
_end
_fini
_init
[20 Sep 2006 7:18] Christian Hammers
I set the status to open again.
[20 Sep 2006 7:39] Magnus Blåudd
Thanks! Will double check those two. I remember we looked at those symbols and disabled them but something must have been missed. :(
[20 Sep 2006 7:43] Magnus Blåudd
Double checked that we in 5.0.25 have this additional patch that removes those two functions from libmysql.

--- 1.14/extra/yassl/taocrypt/src/misc.cpp	2006-08-31 15:16:50 +02:00
+++ 1.15/extra/yassl/taocrypt/src/misc.cpp	2006-08-31 15:16:50 +02:00
@@ -29,7 +29,7 @@
 #include "runtime.hpp"
 #include "misc.hpp"
 
-
+#if !defined(YASSL_MYSQL_COMPATIBLE)
 extern "C" {
 
     // for libcurl configure test, these are the signatures they use
@@ -37,6 +37,7 @@
     char CRYPTO_lock() { return 0;}
     char CRYPTO_add_lock() { return 0;}
 }  // extern "C"
+#endif
 
 #ifdef YASSL_PURE_C
[11 Oct 2006 18:58] Andrew Hanna
I have just downloaded 5.0.26 (OSX 10.4 x86), and am trying to recompile PHP 5.1.6.  However, I am not using OpenSSL directly in PHP but rather cURL (which itself has OpenSSL support).  When I run make, I get multiple definition errors on _CRYPTO_add_lock and _CRYPTO_lock:

/usr/bin/ld: multiple definitions of symbol _CRYPTO_add_lock
/usr/lib/gcc/i686-apple-darwin8/4.0.1/../../../libcrypto.dylib(cryptlib.o) definition of _CRYPTO_add_lock
/usr/local/mysql//lib/libmysqlclient.a(libtaocrypt_la-misc.o) definition of _CRYPTO_add_lock in section (__TEXT,__text)
/usr/bin/ld: multiple definitions of symbol _CRYPTO_lock
/usr/lib/gcc/i686-apple-darwin8/4.0.1/../../../libcrypto.dylib(cryptlib.o) definition of _CRYPTO_lock
/usr/local/mysql//lib/libmysqlclient.a(libtaocrypt_la-misc.o) definition of _CRYPTO_lock in section (__TEXT,__text)

I am also getting these:

/usr/bin/ld: warning multiple definitions of symbol _regcomp
/usr/local/apache2//bin/httpd definition of _regcomp
/usr/lib/gcc/i686-apple-darwin8/4.0.1/../../../libpthread.dylib(regcomp.So) definition of _regcomp
/usr/bin/ld: warning multiple definitions of symbol _regexec
/usr/local/apache2//bin/httpd definition of _regexec
/usr/lib/gcc/i686-apple-darwin8/4.0.1/../../../libpthread.dylib(regexec.So) definition of _regexec
/usr/bin/ld: warning multiple definitions of symbol _regfree
/usr/local/apache2//bin/httpd definition of _regfree
/usr/lib/gcc/i686-apple-darwin8/4.0.1/../../../libpthread.dylib(regfree.So) definition of _regfree

And I never got those before, since I successfully compiled PHP 5.1.6 before upgrading MySQL to 5.0.26.  Not sure if those will go away once the crypto ones go away, but that seems to be an Apache/PHP build bug anyway.

Am I doing something wrong?  The previous post seems to question whether or not these two symbols are in fact being defined by the mysql client library, and it seems that they are defined in the Mac OSX build of 5.0.26.

Running that other command someone posted:

nm -g /usr/lib/libssl.dylib /usr/lib/libcrypto.dylib /usr/local/mysql/lib/libmysqlclient.a | awk '$2=="T" {print $3}'  | sort | uniq -c | awk '$1>1'

   2 _CRYPTO_add_lock
   2 _CRYPTO_lock

I didn't have a .dylib file in my ./mysql/lib folder, so I used the one I found in the path above instead.

Requesting that this bug be reopened.
[14 Oct 2006 15:00] Marcus Bointon
I've seen the same problem too, compiling on Intel OS X.
I tried a few other combinations: openssl and curl works ok, openssl and mysql works ok, mysql and curl (without explicitly specifying ssl, and even with --disable-ssl) breaks. Is it therefore not MySQL's fault but that curl has the same problem that was fixed in MySQL 5.0.25? If so, should this be reported as a PHP bug?
[16 Oct 2006 9:39] Magnus Blåudd
Unfortunately the patch to remove CRYPTO_* functions with the use of  #ifndef(YASSL_MYSQL_COMPATIBLE) didn't work as YASSL_MYSQL_COMPATIBLE was not defined in that file. That mean libmysqlclient as of version 5.0.26 will define CRYPTO_add_lock and CRYPTO_lock
[16 Oct 2006 9:41] Magnus Blåudd
The most annoying thing is that the CRYPTO_* are two empty functions. They have been removed from the imported yaSSL source in MySQL and moved to another file in the yaSSL CVS repository which will not be compiled into libmysqlclient.
[7 Jan 2007 17:55] Nickolas Daskalou
I'm getting that same Segmentation fault (cored dumped) error by the PHP CLI when I try to CLOSE an SSL/HTTPS connection.

My current installation details are:

PHP 5.2
MySQL 5.0.27-0
Apache 1.3.37
Hosted on a CentOS 3.8 installation (which includes cPanel)

This can be reproduced using the following PHP code:

<?php
$fp = fopen("https://webmail.optusnet.com.au/", "r");
fclose($fp);
echo "done!";
?>

The expected result is:

done!

Instead I get this:

Segmentation fault (cored dumped)
[13 Jan 2007 23:50] mono clast
Just curious - why is this marked Closed? The bug still exists in 5.0.27:

nm -g /usr/lib/libssl.dylib /usr/lib/libcrypto.dylib /usr/local/mysql/lib/libmysqlclient.a | awk '$2=="T" {print $3}'  | sort | uniq -c | awk '$1>1'
nm: no name list
nm: no name list
nm: no name list
nm: no name list
nm: no name list
nm: no name list
nm: no name list
nm: no name list
nm: no name list
   2 _CRYPTO_add_lock
   2 _CRYPTO_lock

What is the work-around to make this work in 5.0.27?
[15 Jan 2007 14:25] Magnus Blåudd
1. A workaround is to use a mysqlclient library(libmysqlclient) compiled without yaSSL. There was some rpm's available for download on our site. Please check my previous answers(might be another bug number).

2. Another is to apply the patch
--- 1.14/extra/yassl/taocrypt/src/misc.cpp	2006-08-31 15:16:50 +02:00
+++ 1.15/extra/yassl/taocrypt/src/misc.cpp	2006-08-31 15:16:50 +02:00
@@ -29,7 +29,7 @@
 #include "runtime.hpp"
 #include "misc.hpp"
 
-
+#if !defined(YASSL_MYSQL_COMPATIBLE)
 extern "C" {
 
     // for libcurl configure test, these are the signatures they use
@@ -37,6 +37,7 @@
     char CRYPTO_lock() { return 0;}
     char CRYPTO_add_lock() { return 0;}
 }  // extern "C"
+#endif
 
 #ifdef YASSL_PURE_C

And recompile.

3. Use 5.0.33 of MySQL release as of January 9
[15 Jan 2007 14:27] Magnus Blåudd
Link to libmysqlclient.so is attached to bug#19810.
[16 Jan 2007 6:29] mono clast
Thank you Magnus.  

Unfortunately, I'm using this on Mac OS X, so an RPM won't do.  I suppose a Darwin x86 version of the problem library would do the trick though...

I downloaded the source for 5.0.33, compiled and installed it, but apparently there's some additional stuff that needs to be there for it to work the same way as the pre-packaged  Mac OS X binary install (for instance there's a "support-files" directory in 5.0.27 with a bunch of files in it that isn't there in the source 5.0.33 build). And I am not experienced enough to reverse-engineer everything in the Mac OS X packages to see eactly how it all works.

This is preventing me from installing proftpd on a Mac Intel machine, because we want to use a mySQL database for proftpd authentication.

: (
[19 Jan 2007 19:36] mono clast
Since 5.0.33 is available only as source, I installed 5.0.33 over my previous mySQL 5.0.27 installation.  Installation appears to have gone well. mySQL Administrator shows that I am indeed now running MySQL 5.0.33-standard.

Yet, if I do: 

# strings /usr/local/mysql/lib/libmysqlclient.a | grep CRYPTO

It outputs:

_CRYPTO_add_lock
_CRYPTO_lock

Could it be possible that this is in fact *not* fixed in 5.0.33? 

Also if I try to compile proftpd with mySQL  support, I get:

/usr/bin/ld: multiple definitions of symbol _CRYPTO_add_lock
/usr/lib/gcc/i686-apple-darwin8/4.0.1/../../../libcrypto.dylib(cryptlib.o) definition of _CRYPTO_add_lock
/usr/local/mysql/lib//libmysqlclient.a(libtaocrypt_la-misc.o) definition of _CRYPTO_add_lock in section (__TEXT,__text)
/usr/bin/ld: multiple definitions of symbol _CRYPTO_lock
/usr/lib/gcc/i686-apple-darwin8/4.0.1/../../../libcrypto.dylib(cryptlib.o) definition of _CRYPTO_lock
/usr/local/mysql/lib//libmysqlclient.a(libtaocrypt_la-misc.o) definition of _CRYPTO_lock in section (__TEXT,__text)
collect2: ld returned 1 exit status
make: *** [proftpd] Error 1

Any ideas?
[22 Jan 2007 11:12] Magnus Blåudd
Hard to tell. Are you sure that the newly built libmysqlclient ended up in /usr/local/mysql/lib/?

First build locally and do a strings/nm on the libmysqlclient library in libmysql/ to verify it's ok. Then install and watch the output to see where it installed.
[24 Jan 2007 5:59] mono clast
Can someone please explain how to apply this patch over the downloadable mysql-5.0.33 source base?  I tried a couple different patch commands, without success. It seems like the first couple lines have paths that don't match my source base, but I am unsure of how to modify it to match:

--- 1.14/extra/yassl/taocrypt/src/misc.cpp	2006-08-31 15:16:50 +02:00
+++ 1.15/extra/yassl/taocrypt/src/misc.cpp	2006-08-31 15:16:50 +02:00
@@ -29,7 +29,7 @@
 #include "runtime.hpp"
 #include "misc.hpp"
 
-
+#if !defined(YASSL_MYSQL_COMPATIBLE)
 extern "C" {
 
     // for libcurl configure test, these are the signatures they use
@@ -37,6 +37,7 @@
     char CRYPTO_lock() { return 0;}
     char CRYPTO_add_lock() { return 0;}
 }  // extern "C"
+#endif
 
 #ifdef YASSL_PURE_C
[24 Jan 2007 10:01] Magnus Blåudd
5.0.33 shouldn't have those two functions in the code - thus you can't apply the patch. Open extra/yassl/taoucrypt/src/misc.cpp and have a look.

The implementation of those two functions have been moved to extra/yassl/taocrypt/src/crypto.cpp which is a file we don't build when compiling yaSSL for MySQL