Description:
If in multithreaded program two or more threads are calling function get_driver_instance()->connect(host, user, password) then sometimes this call produces SEGV signal.
How to repeat:
Here is a code which sometimes produces a bug:
#include <cppconn/driver.h>
#include <mysql_connection.h>
#include <csignal>
#include <cstdio>
#include <cstring>
#include <execinfo.h>
#include <thread>
constexpr const char* host = "localhost";
constexpr const char* user = "sim";
constexpr const char* password = "sim";
constexpr unsigned TRY_PER_THREAD = 3;
constexpr unsigned THREADS = 5;
void handler(int sig) {
void *array[30];
size_t size;
// Get void*'s for all entries on the stack
size = backtrace(array, 30);
// Print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, STDERR_FILENO);
exit(15);
}
void break_mysqlcppconn() {
sql::Connection *conns[TRY_PER_THREAD];
for (;;) {
// Create connections
for (int i = 0; i < TRY_PER_THREAD; ++i)
conns[i] = get_driver_instance()->connect(host, user, password);
// Delete connections
for (int i = 0; i < TRY_PER_THREAD; ++i)
delete conns[i];
}
}
int main() {
// Signal control (set handler as SEGV signal handler)
struct sigaction sa;
memset (&sa, 0, sizeof(sa));
sa.sa_handler = &handler;
sigaction(SIGSEGV, &sa, nullptr);
// Try to break MySQL Connector C++
std::thread t[THREADS - 1];
for (int i = 0; i < THREADS - 1; ++i)
t[i] = std::thread(break_mysqlcppconn);
break_mysqlcppconn(); // I also become an attacker
return 0;
}
1. Compile it: g++ x.cc -O2 -o x -lmysqlcppconn -std=c++11
2. Try runinng it several times (I used several times command: for((RET=0; RET!=15;)); do ./x; RET=$?; done) until you will get something like that:
Error: signal 11:
./x[0x401128]
/lib/x86_64-linux-gnu/libc.so.6(+0x36d40)[0x7fcc0b0ead40]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(+0x749e4)[0x7fcc0b7039e4]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS_+0xe1)[0x7fcc0b703cc1]
/usr/lib/libmysqlcppconn.so.7(_ZNSt8_Rb_treeIN3sql9SQLStringESt4pairIKS1_N5boost10shared_ptrINS0_5mysql12MySQL_DriverEEEESt10_Select1stIS9_ESt4lessIS1_ESaIS9_EE10_M_insert_EPSt18_Rb_tree_node_baseSH_RKS9_+0xbd)[0x7fcc0ba268c7]
/usr/lib/libmysqlcppconn.so.7(_ZNSt8_Rb_treeIN3sql9SQLStringESt4pairIKS1_N5boost10shared_ptrINS0_5mysql12MySQL_DriverEEEESt10_Select1stIS9_ESt4lessIS1_ESaIS9_EE17_M_insert_unique_ESt23_Rb_tree_const_iteratorIS9_ERKS9_+0x66)[0x7fcc0ba26196]
/usr/lib/libmysqlcppconn.so.7(_ZNSt3mapIN3sql9SQLStringEN5boost10shared_ptrINS0_5mysql12MySQL_DriverEEESt4lessIS1_ESaISt4pairIKS1_S6_EEE6insertESt17_Rb_tree_iteratorISB_ERKSB_+0x3e)[0x7fcc0ba25dd6]
/usr/lib/libmysqlcppconn.so.7(_ZNSt3mapIN3sql9SQLStringEN5boost10shared_ptrINS0_5mysql12MySQL_DriverEEESt4lessIS1_ESaISt4pairIKS1_S6_EEEixERSA_+0x108)[0x7fcc0ba258d6]
/usr/lib/libmysqlcppconn.so.7(_ZN3sql5mysql27get_driver_instance_by_nameEPKc+0x101)[0x7fcc0ba24e51]
/usr/lib/libmysqlcppconn.so.7(_ZN3sql5mysql19get_driver_instanceEv+0x10)[0x7fcc0ba24d4e]
/usr/lib/libmysqlcppconn.so.7(get_driver_instance+0x9)[0x7fcc0ba24d3c]
./x[0x401185]
/usr/lib/x86_64-linux-gnu/libstdc++.so.6(+0xb1a40)[0x7fcc0b740a40]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x8182)[0x7fcc0a243182]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x6d)[0x7fcc0b1ae47d]