Uploaded image for project: 'MariaDB Connector/C'
  1. MariaDB Connector/C
  2. CONC-276

Crash after reconnecting to server using TLS

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed (View Workflow)
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 3.0.2
    • Fix Version/s: 3.0.3
    • Labels:
      None
    • Environment:
      Tested on Windows client with Linux server configured for TLS

      Description

      Hi

      I'm seeing a crash within the MariaDB connector client when connecting to a server via TLS after a server reconnect (eg, internet, restart, etc).

      After doing some digging, it appears that the mysql pointer within the security context is not set to the new structure after a disconnect and reconnect, thus when doing a read or write the connector then tries to access freed memory. The crashes tend to happen deep inside ma_schannel_read_decrypt or ma_schannel_write_encrypt but can be traced back to ma_tls_read/write, (schannel.c, Ln 394 + Ln 408) where the sctx->mysql pointer refers to the pre-reconnect structure.

      Adding a hack to set sctx->mysql to ctls->pvio->mysql (or amending the following line to pvio = ctls->pvio) works however this is obviously not the correct location to update that pointer.

      #include <stdio.h>
      #include <stdlib.h>
      #include <time.h>
       
      #ifdef LINUX
      #include <unistd.h>
      #endif
      #ifdef WINDOWS
      #include <windows.h>
      #endif
       
      void mySleep(int sleepMs)
      {
      #ifdef LINUX
          usleep(sleepMs * 1000);   // usleep takes sleep time in us (1 millionth of a second)
      #endif
      #ifdef WINDOWS
          Sleep(sleepMs);
      #endif
      }
       
      #include "mysql.h"
       
      const char* host = "127.0.0.1";
      const char* user = "root";
      const char* pass = "";
       
      int main(int argc, char** arvg) {
        MYSQL *mysql = new MYSQL;
        mysql_init(mysql);
        my_bool yes = 1;
        mysql_options(mysql, MYSQL_OPT_RECONNECT, &yes);
        //mysql_options(mysql, MYSQL_OPT_COMPRESS, NULL);
        mysql_ssl_set(mysql, 0, 0, 0, 0, 0);
       
        if (!mysql_real_connect(mysql, host, user, pass, "mysql", 3306, NULL, CLIENT_SSL)) {
          printf("Can't connect\n");
          return 0;
        }
       
        while (mysql_ping(mysql) == 0) {
          printf("Connected, please stop server. Sleeping\n");
          mySleep(5000); 
        }
       
        while (mysql_ping(mysql) != 0) {
          printf("Server gone, please start it\n");
          mySleep(5000);
        }
       
        printf("Recovered, exiting");
       
        mysql_close(mysql);
      }

        Attachments

          Activity

            People

            Assignee:
            georg Georg Richter
            Reporter:
            scott_t Scott Thomas
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved: