Bug #26582 Crash in multi-thread apps due to signal(2) in libmysqlclient/taocrypt
Submitted: 22 Feb 2007 23:41 Modified: 16 Apr 2007 15:31
Reporter: Christian Hammers (Silver Quality Contributor) (OCA) Email Updates:
Status: No Feedback Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version:5.0.32 OS:Linux (Debian GNU/Linux)
Assigned to: CPU Architecture:Any
Tags: Contribution, qc

[22 Feb 2007 23:41] Christian Hammers
Description:
I'm forwarding a bug reported by Mariano Santamarina <msantamarina@gmail.com> 
on http://bugs.debian.org/412024. I've not yet tested the patch nor verified 
the problem. -chrstian-
---------------------------------------------------

Using libmysqlclient in multi-threaded enviroments like java can result in:
#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
#  SIGILL (0x4) at pc=0x00000000, pid=10933, tid=2877021104
#
# Java VM: Java HotSpot(TM) Client VM (Blackdown-1.4.2-03 mixed mode)
# An error report file with more information is saved as 
hs_err_pid10933.log
#
# If you would like to submit a bug report, please visit:
#   http://www.blackdown.org/cgi-bin/jdk
#

After two days finding the bug. i discovered that in the taocrypt 
library included in libmysql are calls to signal(...).

In the signal(2) Manual Page. Section NOTES says: "The effects of this 
call in a multi-threaded process are unspecified..." (indeed is true)

My modest solution is to relace signal(...) with pthread_sigmask(...) 
and sigaction(...)

Attached is the patch

Thanks.
PD: Sorry form my poor english.

How to repeat:
-

Suggested fix:

diff -Nrau mysql-dfsg-5.0-5.0.32.orig/extra/yassl/taocrypt/src/integer.cpp mysql-dfsg-5.0-5.0.32/extra/yassl/taocrypt/src/integer.cpp
--- mysql-dfsg-5.0-5.0.32.orig/extra/yassl/taocrypt/src/integer.cpp	2006-12-20 08:13:59.000000000 -0300
+++ mysql-dfsg-5.0-5.0.32/extra/yassl/taocrypt/src/integer.cpp	2007-02-22 15:21:04.000000000 -0300
@@ -1050,11 +1050,21 @@
     }
     return true;
 #else
-    typedef void (*SigHandler)(int);
+    struct sigaction sigact,sigoldact;
+    memset(&sigact,0,sizeof(sigact));
+    sigact.sa_handler=SigIllHandler;
+    sigemptyset(&sigact.sa_mask);
+    if(0!=sigaction(SIGILL,&sigact,&sigoldact)) return false;
+
+    sigset_t newmask,oldmask;
+    sigemptyset(&newmask);
+    sigaddset(&newmask,SIGILL);
 
-    SigHandler oldHandler = signal(SIGILL, SigIllHandler);
-    if (oldHandler == SIG_ERR)
+    if(0!=pthread_sigmask(SIG_UNBLOCK,&newmask,&oldmask))
+    {
+        sigaction(SIGILL,&sigoldact,NULL);
         return false;
+    }
 
     bool result = true;
     if (setjmp(s_env))
@@ -1062,7 +1072,11 @@
     else
         __asm __volatile ("xorpd %xmm0, %xmm0");
 
-    signal(SIGILL, oldHandler);
+    if(sigismember(&oldmask,SIGILL))
+    {
+        pthread_sigmask(SIG_BLOCK,&newmask,NULL);
+    }
+    sigaction(SIGILL,&sigoldact,NULL);
     return result;
 #endif
 }
diff -Nrau mysql-dfsg-5.0-5.0.32.orig/extra/yassl/taocrypt/src/misc.cpp mysql-dfsg-5.0-5.0.32/extra/yassl/taocrypt/src/misc.cpp
--- mysql-dfsg-5.0-5.0.32.orig/extra/yassl/taocrypt/src/misc.cpp	2006-12-20 08:14:34.000000000 -0300
+++ mysql-dfsg-5.0-5.0.32/extra/yassl/taocrypt/src/misc.cpp	2007-02-22 15:20:57.000000000 -0300
@@ -199,11 +199,22 @@
     }
     return true;
 #else
-    typedef void (*SigHandler)(int);
 
-    SigHandler oldHandler = signal(SIGILL, SigIllHandler);
-    if (oldHandler == SIG_ERR)
+    struct sigaction sigact,sigoldact;
+    memset(&sigact,0,sizeof(sigact));
+    sigact.sa_handler=SigIllHandler;
+    sigemptyset(&sigact.sa_mask);
+    if(0!=sigaction(SIGILL,&sigact,&sigoldact)) return false;
+
+    sigset_t newmask,oldmask;
+    sigemptyset(&newmask);
+    sigaddset(&newmask,SIGILL);
+
+    if(0!=pthread_sigmask(SIG_UNBLOCK,&newmask,&oldmask))
+    {
+        sigaction(SIGILL,&sigoldact,NULL);
         return false;
+    }
 
     bool result = true;
     if (setjmp(s_env))
@@ -218,7 +229,11 @@
             : "%eax", "%ecx", "%edx" 
         );
 
-    signal(SIGILL, oldHandler);
+    if(sigismember(&oldmask,SIGILL))
+    {
+        pthread_sigmask(SIG_BLOCK,&newmask,NULL);
+    }
+    sigaction(SIGILL,&sigoldact,NULL);
     return result;
 #endif
 }
[23 Feb 2007 14:14] MySQL Verification Team
Thank you for the bug report. Could you please inform if the user has
used a thread-safe client in his application?. Thanks in advance.
[4 Mar 2007 21:12] Christian Hammers
Test case

Attachment: libmysqlclienttest.tar.bz2 (application/x-bzip, text), 29.14 KiB.

[4 Mar 2007 21:15] Christian Hammers
Hello

I've just added a test case that the original submitter sent me.
I will ask him about the thread safe client question (missed that comment from you) but you can probably easily figure it out yourself as the .c and .java files for the test case are included.

Feel free to contact the submitter via 412024@bugs.debian.org if you need further information.

bye,

-christian-
[14 Mar 2007 0:58] Christian Hammers
Hello Miguel

Regarding your question about the thread safety of the client, Mariano Santamarina <msantamarina@gmail.com> wrote:

    Yes, it's thread-safe.
    I'm using mysqlclient_r
    one thread is calling mysql_query and mysql_store_result
    and the other thread is calling mysql_free_result.
    The threads are synchronized in the java side.

bye,

-christian-
[16 Mar 2007 15:31] Valeriy Kravchuk
Please, try to repeat with a newer version, 5.0.37, and inform about the results.
[16 Apr 2007 23:00] Bugs System
No feedback was provided for this bug for over a month, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".