Bug #12353 mysql ssl connection using mysql_real_connect and mysql_close cause memory leak
Submitted: 3 Aug 2005 18:03 Modified: 5 Aug 2005 2:18
Reporter: jimmy ta Email Updates:
Status: Can't repeat Impact on me:
None 
Category:MySQL Server Severity:S1 (Critical)
Version:4.1.13 source OS:Windows (windows XP and unix)
Assigned to: CPU Architecture:Any

[3 Aug 2005 18:03] jimmy ta
Description:
Calling mysql_real_connect and mysql_close to establish a SSL connection results in about 60 kb of leaked memory per connection.  I also saw the same problem on Solaris.

How to repeat:

Here's sample code to reproduce the problem on windows.

requires:
1) mysqlclient.lib - compiled with ssl
2) ssleay32.lib - openssl lib version 9.7 or 9.8 (got this from http://www.slproweb.com/products/Win32OpenSSL.html )
3) libeay32.lib - openssl lib version 9.7 or 9.8 (got this from http://www.slproweb.com/products/Win32OpenSSL.html )
4) sslcerts
5) ssl enabled MySQL server

------------------------------SAMPLE CODE------------------------------------------
#include <windows.h>
#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include <mysql.h>
#include <mysql_embed.h>
#include <errmsg.h>
#include <my_getopt.h>

#include <m_ctype.h>
#include <stdarg.h>
#include <my_dir.h>

int main(int argc, char **argv)
{

  char host[64]="1.2.3.4";

  char user[64]="testssl";
  char passwd[64]="testssl";
  char database[NAME_LEN+1]="testssl";
  int port = 3306;
  char flag[10],init_stmt[256],*dsn_ptr;
  char szTRACE[FILENAME_MAX+1]= "";
  char socket[256]= "";
  char sslca[FILENAME_MAX+1]="c:\\certs\\cacert.pem";
  char sslcert[FILENAME_MAX+1]="c:\\certs\\cert.pem";
  char sslkey[FILENAME_MAX+1]="c:\\certs\\key.pem";
  static struct st_VioSSLConnectorFd * fd_static=NULL;
  MYSQL mysql;
  ulong client_flag;
  int i=0;
  printf("START TEST\n");

  while(1)
  {
    mysql_init(&mysql);

    client_flag=0; 

    mysql_ssl_set(&mysql,
                  sslkey,
                  sslcert,
                  sslca,
                  NULL,
                  NULL);

    if (!mysql_real_connect(&mysql, host, user, passwd,
			    database, port, NULL,
			    client_flag))
    {
      fprintf(stderr, "Failed to connect to database: Error: %s\n",
            mysql_error(&mysql));
      return -1;
    }

    mysql_close(&mysql);
    printf("NUMBER OF CONNECTIONS MADE : %d\r",++i);
  }
  printf("END TEST\n");

  return(0);
}

------------------------------END SAMPLE CODE---------------------------------------

Suggested fix:
The problem seems to be:
1)  the call to create a new_VioSSLConnectorFd() (line 1995|client.c) and the mysql_ssl_free() on the mysql->connector_fd (line 1494|client.c) fail to deallocate all the memory.
2)  the vio_ssl_delete(Vio * vio) (line 81|viossl.c) should call vio_ssl_close(), instead of vio_close()
[5 Aug 2005 2:18] MySQL Verification Team
I tested your test case against Purify for Windows. There is a potentila
memory leak and the memory leak of 4 bytes in the function putenv
is for the use of VC++ 6.0 compiler, you can avoid that compiling
the server and client with VS 2003. 

I just modified your test code removing the while(1) and the
user, password, database values.

c:\mysql\bin>mysql --ssl-ca=cacert.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1 to server version: 4.1.13-nt

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> SHOW VARIABLES LIKE 'have_openssl';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| have_openssl  | YES   |
+---------------+-------+
1 row in set (0.06 sec)

mysql>

START TEST
END TESTF CONNECTIONS MADE : 1
Press any key to continue...

[I] Starting Purify'd ssltest.exe at 04/08/2005 23:09:26
        Instrumented executable: C:\Arquivos de programas\Rational\PurifyPlus\cache\ssltest$Purify_C_mysql_bin.exe
        Working directory:       C:\mysql\bin
        Command line arguments:  <none>
        Process ID:              0x3fc
        Thread ID: 0xb5c
[I] Starting main
[E] ABR: Array bounds read in my_xml_parse {1 occurrence}
        Reading 4 bytes from 0x025c45dd (1 byte at 0x025c45e0 illegal)
        Address 0x025c45dd is 17797 bytes into a 17800 byte block at 0x025c0058
        Address 0x025c45dd points to a malloc'd block in heap 0x003e0000
        Thread ID: 0xb5c
        Error location
            my_xml_parse   [xml.obj]
            my_parse_charset_xml [ssltest.exe]
            get_collation_number [ssltest.exe]
            get_collation_number [ssltest.exe]
            get_charset_by_csname [ssltest.exe]
            mysql_real_connect [ssltest.exe]
            main           [ssltest.cpp:48]
            mainCRTStartup [printf.obj]
        Allocation location
            my_malloc      [my_malloc.obj]
            get_collation_number [ssltest.exe]
            get_collation_number [ssltest.exe]
            get_charset_by_csname [ssltest.exe]
            mysql_real_connect [ssltest.exe]
            main           [ssltest.cpp:48]
            mainCRTStartup [printf.obj]
[I] Summary of all memory leaks... {32 bytes, 2 blocks}
[I] MPK: Potential memory leak of 28 bytes from 1 block allocated in LdrLoadDll [NTDLL.dll]
        Distribution of potentially leaked blocks
                28 bytes from 1 block of 28 bytes (0x0015adc8) 
        Allocation location
            HeapAlloc      [KERNEL32.dll]
            LdrLoadDll     [NTDLL.dll]
            LoadLibraryExA [kernel32.dll]
            mysql_server_init [ssltest.exe]
            mysql_init     [ssltest.exe]
            main           [ssltest.cpp:35]
            mainCRTStartup [printf.obj]
[W] MLK: Memory leak of 4 bytes from 1 block allocated in putenv [ssltest.exe]
        Distribution of leaked blocks
                 4 bytes from 1 block of 4 bytes (0x003e6670) 
        Allocation location
            _putenv_lk     [putenv.obj]
            putenv         [putenv.obj]
            setEnvString   [ssltest.exe]
            my_init        [ssltest.exe]
            mysql_server_init [ssltest.exe]
            mysql_init     [ssltest.exe]
            main           [ssltest.cpp:35]
            mainCRTStartup [printf.obj]
[I] Exiting with code 0 (0x00000000)
        Process time: 406 milliseconds
[I] Program terminated at 04/08/2005 23:10:20
[5 Aug 2005 23:48] jimmy ta
I am compiling with gcc 3.4.1 on solaris and I notice the same problem.  Can you suggest a version of gcc I can use on solaris.