Details
-
Bug
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Fixed
-
3.0.2
-
None
-
None
-
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);
|
}
|