Bug #11892 ODBC Connector/libmysql cause corruption of the MySQL charset data.
Submitted: 12 Jul 2005 21:52 Modified: 2 Feb 2006 19:29
Reporter: Landon Fuller
Status: Closed
Category:Connector/ODBC Severity:S2 (Serious)
Version:5.0.7-beta-log OS:FreeBSD (FreeBSD 5.4)
Assigned to: Target Version:

[12 Jul 2005 21:52] Landon Fuller
Description:
This bug is a followup on bug #6536. As I am not the originator of #6536, I am unable to
change the bug's state from "No Feedback" to "Open".

Short version:
MyODBC calls my_end(), which deallocates the memory used to store charset data. The
charset data is corrupted, leading to library failure and program crashes.

Long version:
SQLFreeConnect() causes libiodbc to deallocate the associated database
environment handle, at which point my_SQLFreeEnv() calls myodbc_end().

myodbc_end() calls libmysql's my_end(), and in turn, my_end() deallocates the
"once" memory pool with my_once_free().

A backtrace may make this more clear:
#0  my_once_free () at my_once.c:111
#1  0x281e4aad in my_end (infoflag=0) at my_init.c:143
#2  0x281afe87 in myodbc_end () at dll.c:118
#3  0x281b3327 in my_SQLFreeEnv (henv=0x2817da30) at handle.c:109
#4  0x281b3e50 in SQLFreeHandle (HandleType=1, Handle=0x2817db0c) at
handle.c:487
#5  0x28084f92 in _iodbcdm_driverunload (hdbc=0x804c000) at connect.c:640
#6  0x2808b1c9 in SQLFreeConnect_Internal (hdbc=0x804c000) at hdbc.c:277
#7  0x2808b28b in SQLFreeConnect (hdbc=0x804c000) at hdbc.c:297
#8  0x080486c4 in main ()

The crash is ultimately due to corruption of the charset data stored in the
"once" memory pool. The pool's memory is freed by my_end() and eventually
reallocated for other uses by malloc. However, the charset data is never
re-initialized, and pointers to the old memory pool remain. This quickly results
in the corruption of MySQL's charset data structures, and the crashes and
failures outlined in this bug.

How to repeat:
#include <stdio.h>
#include <iodbcinst.h>

int main(void) {
        SQLRETURN ret;
        SQLHDBC env;
        SQLHDBC dbh;
        int i;

        SQLAllocEnv(&env);

        for (i = 0; i < 50; i++) {
                SQLAllocConnect(env, &dbh);
                ret = SQLConnect(dbh, "mysql", SQL_NTS, "root", SQL_NTS, "",
SQL_NTS);
                if (ret != SQL_SUCCESS) {
                        printf("SQLConnect() failed!\n");
                        exit(1);
                }
                SQLDisconnect(dbh);
                SQLFreeConnect(dbh);
        }
        exit (0);
}

Suggested fix:
The solution for MySQL is to ensure that my_init() also re-initializes the
charset data if necessary.

I'm not sure of the best solution for MyODBC. I'm inclined to say that my_end()
should not be called; the memory that will be leaked is only allocated on
libmysql initialization, and will not grow. If MyODBC continues to call
my_end(), the cumulative overhead of repeatedly re-initializing the charset data
is significant.
[14 Jul 2005 9:34] Vasily Kishkin
Test case for Windows

Attachment: test.c (text/plain), 637 bytes.

[15 Jul 2005 7:23] Jorge del Conde
Thanks for your bug report.  I was able to reproduce this bug in FC4 using the supplied
test-case.
[16 Aug 2005 17:25] M T
Has a fix been released for this? I have the same problem with FC4.
Prefer fix that does not require me to recomplie the ODBC.
[8 Sep 2005 0:02] [ name withheld ]
I would love to see a fix for this as well.  I am migrating a ColdFusion application from
MS SQL Server and am running into this bug also.
[26 Oct 2005 6:17] Peter Harvey
Please try the just released c/odbc v3.51.12 and report if success or failure. Assigning
to sergey in the event that it is still a problem so it can be fixed.
[26 Oct 2005 23:18] Landon Fuller
This is not fixed in c/odbc v3.51.12.

Partial valgrind output from running the reproduction case:
==60783== Invalid read of size 4
==60783==    at 0x3C2A374F: get_charset_number (in /usr/local/lib/mysql/libmysql
client.so.15)
==60783==    by 0x3C2A3A5F: get_charset_by_csname (in /usr/local/lib/mysql/libmy
sqlclient.so.15)
==60783==    by 0x3C2B3C68: mysql_real_connect (in /usr/local/lib/mysql/libmysql
client.so.15)
==60783==    by 0x3C26E761: SQLConnect (in /usr/local/lib/libmyodbc3.so)
==60783==  Address 0x3C19FE64 is 3872 bytes inside a block of size 4088 free'd
==60783==    at 0x3C03467F: free (in /usr/local/lib/valgrind/vgpreload_memcheck. so)
==60783==    by 0x3C2A2BA8: my_once_free (in /usr/local/lib/mysql/libmysqlclient .so.15)
==60783==    by 0x3C29CA2C: my_end (in /usr/local/lib/mysql/libmysqlclient.so.15 )
==60783==    by 0x3C271542: myodbc_end (in /usr/local/lib/libmyodbc3.so)
[10 Nov 2005 17:51] Howard Finer
I also have this problem, and would like to see a fix.  If we open and close a connection
to the database multiple times, we also fail in the MyODBC library.  From the postings I
have read, it is the same issue.
#0  0xb7218943 in my_strcasecmp_8bit () from /usr/lib/libmyodbc3-3.51.11.so
(gdb) bt
#0  0xb7218943 in my_strcasecmp_8bit () from /usr/lib/libmyodbc3-3.51.11.so
#1  0xb7211e16 in get_charset_number () from /usr/lib/libmyodbc3-3.51.11.so
#2  0xb72120b9 in get_charset_by_csname () from /usr/lib/libmyodbc3-3.51.11.so
#3  0xb7226f7d in mysql_real_connect () from /usr/lib/libmyodbc3-3.51.11.so
#4  0xb71f72b0 in SQLConnect () from /usr/lib/libmyodbc3-3.51.11.so
....
[11 Nov 2005 13:34] [ name withheld ]
We are having this same problem on fedora core 2 and fedora core 4.
MyODBC keeps crashing. Can we please see a bug fix for this.
[24 Nov 2005 13:10] Seb James
I wrote a Gentoo ebuild to implement the fix suggested by Landon: to remove the call to
my_end() in dll.c in the myodbc source. You can see the patch and fix here:
http://forums.gentoo.org/viewtopic-t-405586.html
[1 Dec 2005 21:44] 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/internals/32932
[14 Jan 2006 2:14] M T
is an rpm with this fix integrated available for download anywhere... 
is there an estimated time on when the rpm will be availble?
we are getting about 50 crashes a day on the website becuase of this bug.
[24 Jan 2006 20:47] Peter Harvey
This will be included in the next release of C/ODBC v3.51.
[26 Jan 2006 17:25] Sergey Vlasenko
Fix is available in 5.0.19
[27 Jan 2006 11:21] M T
I don't understand 'Fix is available in 5.0.19' Does this mean an rpm is now available
somewhere within the mysql site for ODBC v3.51 for redhat for download? if yes.. where...
thanks...
[2 Feb 2006 19:29] Mike Hillyer
Documented in 5.0.19 changelog:

<listitem>
        <para>
          When MyODBC or any other client called
<function>my_init()</function>/<function>my_end()</function>
          several times, it caused corruption of charset data stored in
          <literal>once_mem_pool</literal>. (Bug #11892)
        </para>
      </listitem>
[13 Apr 2006 21:33] Mark Smith
When is a new release of MyODBC coming that includes the fix for this bug?

Because the MyODBC shared libraries are statically linked with the MySQL client library,
this bug is still affecting everyone who uses ODBC.
[18 Apr 2006 18:37] Christophe de Vienne
I have a very similar problem with mysql 4.1.14 on a gentoo box : using ODBC with multiple
threads opening/closing connections was leading in certain cases to a segfault in
my_strcasecmp_8bit.

Applying the path (http://lists.mysql.com/internals/32932) solve the problem.

Could this patch be applied on the 4.1 branch ?
[25 Aug 2006 20:56] Thomas Gagne
Why is this closed?  The last comments suggested that since myodbc is statically linked
with the earlier (buggy) libraries, the problem won't be fixed until a new release of
myodbc is available?
[29 Aug 2006 19:54] Bogdan Degtyariov
> I don't understand 'Fix is available in 5.0.19' Does this mean an 
> rpm is now available somewhere within the mysql site for ODBC v3.51 
> for redhat for download? if yes.. where... thanks...

This means that MyODBC 3.51.14 which is going to be released in a week will use mysql
client library newer than 5.0.19 (to be more precise it will be linked against 5.0.24). As
it was the bug in the client library, new MyODBC should not corrupt the charset data.
[13 Oct 2006 16:50] Mark Smith
Is there a new estimate for when MyODBC 3.51.14 will be available?  This bug us still
causing our application to crash when it is used with MyODBC/MySQL.