Merge branch 'v2.x' into v2.1.2-cluster

pull/3305/head
René Cannaò 5 years ago committed by GitHub
commit ebbd9845bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -8,6 +8,12 @@ endif
### NOTES:
### to compile without jemalloc, set environment variable NOJEMALLOC=1
### to compile with gcov code coverage, set environment variable WITHGCOV=1
### to compile with ASAN, set environment variables NOJEMALLOC=1, WITHASAN=1:
### * To perform a full ProxySQL build with ASAN then execute:
###
### ```
### make build_deps_debug -j$(nproc) && make debug -j$(nproc) && make build_tap_test_debug -j$(nproc)
### ```
O0=-O0
O2=-O2
@ -133,6 +139,10 @@ build_lib_testall: build_deps_debug
build_tap_test: build_src
cd test/tap && OPTZ="${O0} -ggdb -DDEBUG" CC=${CC} CXX=${CXX} ${MAKE}
.PHONY: build_tap_test_debug
build_tap_test_debug: build_src
cd test/tap && OPTZ="${O0} -ggdb -DDEBUG" CC=${CC} CXX=${CXX} ${MAKE} debug
.PHONY: build_src_debug
build_src_debug: build_deps build_lib_debug
cd src && OPTZ="${O0} -ggdb -DDEBUG" CC=${CC} CXX=${CXX} ${MAKE}

4
deps/Makefile vendored

@ -165,6 +165,7 @@ jemalloc/jemalloc/lib/libjemalloc.a:
jemalloc: jemalloc/jemalloc/lib/libjemalloc.a
WITHASAN := $(shell echo $(WITHASAN))
mariadb-client-library/mariadb_client/libmariadb/libmariadbclient.a: libssl/openssl/libssl.a
cd mariadb-client-library && rm -rf mariadb-connector-c-3.1.9-src
@ -189,6 +190,9 @@ mariadb-client-library/mariadb_client/libmariadb/libmariadbclient.a: libssl/open
cd mariadb-client-library/mariadb_client && patch -p0 < ../client_deprecate_eof.patch
cd mariadb-client-library/mariadb_client && patch -p0 < ../cr_new_stmt_metadata_removal.patch
cd mariadb-client-library/mariadb_client && patch -p0 < ../ps_buffer_stmt_read_all_rows.patch
ifeq ($(WITHASAN),1)
cd mariadb-client-library/mariadb_client && patch -p0 < ../mariadb_asan.patch
endif
cd mariadb-client-library/mariadb_client && CC=${CC} CXX=${CXX} ${MAKE} mariadbclient
# cd mariadb-client-library/mariadb_client/include && make my_config.h

@ -7,12 +7,6 @@ ARCH=$PROXYSQL_BUILD_ARCH
echo "==> $ARCH architecture detected for package"
# Dirty patch to ensure OS deps are installed:
apt-get update
apt-get -y install gnutls-dev || true
apt-get -y install libgnutls28-dev || true
apt-get -y install libtool || true
# Delete package if exists
rm -f "/opt/proxysql/binaries/proxysql_${CURVER}-${PKG_RELEASE}_$ARCH.deb" || true
# Cleanup relic directories from a previously failed build

@ -7,18 +7,6 @@ env
ARCH=$PROXYSQL_BUILD_ARCH
echo "==> $ARCH architecture detected for package"
echo "==> Dirty patching to ensure OS deps are installed"
if [[ -f "/usr/bin/python" ]] || [[ -h "/usr/bin/python" ]];
then
echo "==> Installing dependancies for RHEL compliant version 7"
yum -y install gnutls-devel libtool || true
else
echo "==> Installing dependancies for RHEL compliant version 8"
yum -y install python2 gnutls-devel libtool || true
ln -s /usr/bin/python2.7 /usr/bin/python || true
fi
echo "==> Cleaning"
# Delete package if exists
rm -f /opt/proxysql/binaries/proxysql-${CURVER}-1-${PKG_RELEASE}.$ARCH.rpm || true

@ -522,9 +522,12 @@ class MySQL_Threads_Handler
int auditlog_filesize;
// SSL related, proxy to server
char * ssl_p2s_ca;
char * ssl_p2s_capath;
char * ssl_p2s_cert;
char * ssl_p2s_key;
char * ssl_p2s_cipher;
char * ssl_p2s_crl;
char * ssl_p2s_crlpath;
int query_cache_size_MB;
int min_num_servers_lantency_awareness;
int aurora_max_lag_ms_only_read_from_replicas;

@ -806,9 +806,12 @@ __thread int mysql_thread___query_cache_size_MB;
/* variables used for SSL , from proxy to server (p2s) */
__thread char * mysql_thread___ssl_p2s_ca;
__thread char * mysql_thread___ssl_p2s_capath;
__thread char * mysql_thread___ssl_p2s_cert;
__thread char * mysql_thread___ssl_p2s_key;
__thread char * mysql_thread___ssl_p2s_cipher;
__thread char * mysql_thread___ssl_p2s_crl;
__thread char * mysql_thread___ssl_p2s_crlpath;
/* variables used by events log */
__thread char * mysql_thread___eventslog_filename;
@ -958,9 +961,12 @@ extern __thread int mysql_thread___query_cache_size_MB;
/* variables used for SSL , from proxy to server (p2s) */
extern __thread char * mysql_thread___ssl_p2s_ca;
extern __thread char * mysql_thread___ssl_p2s_capath;
extern __thread char * mysql_thread___ssl_p2s_cert;
extern __thread char * mysql_thread___ssl_p2s_key;
extern __thread char * mysql_thread___ssl_p2s_cipher;
extern __thread char * mysql_thread___ssl_p2s_crl;
extern __thread char * mysql_thread___ssl_p2s_crlpath;
/* variables used by events log */
extern __thread char * mysql_thread___eventslog_filename;

@ -67,6 +67,15 @@ ODIR= obj
#CXX=g++
#CC=clang
WITHASANVAR := $(shell echo $(WITHASAN))
ifeq ($(WITHASANVAR),1)
WASAN=-fsanitize=address
# Force the disable of JEMALLOC, since ASAN isn't compatible.
export NOJEMALLOC = 1
else
WASAN=
endif
#CFLAGS=$(IDIRS) $(OPTZ) $(DEBUG) -Wall #-lcrypto
#CXXFLAGS=-std=c++11 $(CFLAGS) $(LDIRS) $(LIBS)
NOJEMALLOC := $(shell echo $(NOJEMALLOC))
@ -100,7 +109,7 @@ ifeq ($(UNAME_S),Darwin)
endif
MYCFLAGS=$(IDIRS) $(OPTZ) $(DEBUG) -Wall -DGITVERSION=\"$(GIT_VERSION)\" $(NOJEM) $(WGCOV)
MYCFLAGS=$(IDIRS) $(OPTZ) $(DEBUG) -Wall -DGITVERSION=\"$(GIT_VERSION)\" $(NOJEM) $(WGCOV) $(WASAN)
MYCXXFLAGS=-std=c++11 $(MYCFLAGS) $(PSQLCH)
default: libproxysql.a

@ -1084,7 +1084,14 @@ bool MySQL_Monitor_State_Data::create_new_connection() {
mysql=mysql_init(NULL);
assert(mysql);
if (use_ssl) {
mysql_ssl_set(mysql, mysql_thread___ssl_p2s_key, mysql_thread___ssl_p2s_cert, mysql_thread___ssl_p2s_ca, NULL, mysql_thread___ssl_p2s_cipher);
mysql_ssl_set(mysql,
mysql_thread___ssl_p2s_key,
mysql_thread___ssl_p2s_cert,
mysql_thread___ssl_p2s_ca,
mysql_thread___ssl_p2s_capath,
mysql_thread___ssl_p2s_cipher);
mysql_options(mysql, MYSQL_OPT_SSL_CRL, mysql_thread___ssl_p2s_crl);
mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH, mysql_thread___ssl_p2s_crlpath);
}
unsigned int timeout=mysql_thread___monitor_connect_timeout/1000;
if (timeout==0) timeout=1;

@ -1537,6 +1537,15 @@ bool MySQL_Protocol::process_pkt_handshake_response(unsigned char *pkt, unsigned
//Copy4B(&hdr,pkt);
pkt += sizeof(mysql_hdr);
// NOTE: 'mysqlsh' sends a 'COM_INIT_DB' as soon as the connection is openned
// before ProxySQL has sent 'Server Greeting' messsage. Because this packet is
// unexpected, we simple return 'false' and exit.
if (hdr.pkt_id == 0 && *pkt == 2) {
ret = false;
proxy_debug(PROXY_DEBUG_MYSQL_AUTH, 5, "Session=%p , DS=%p , user='%s' . Client is disconnecting\n", (*myds), (*myds)->sess, user);
goto __exit_process_pkt_handshake_response;
}
if ((*myds)->myconn->userinfo->username) {
(*myds)->switching_auth_stage=2;
if (len==5) {
@ -2259,6 +2268,9 @@ stmt_execute_metadata_t * MySQL_Protocol::get_binds_from_pkt(void *ptr, unsigned
continue;
} else if (is_nulls[i]==true) {
// the parameter is NULL, no need to read any data from the packet
// NOTE: We nullify buffers here to reflect that memory wasn't
// initalized. See #3546.
binds[i].buffer = NULL;
continue;
}

@ -3909,6 +3909,9 @@ void MySQL_Session::handler_rc0_PROCESSING_STMT_EXECUTE(MySQL_Data_Stream *myds)
(buffer_type == MYSQL_TYPE_DATETIME)
) {
free(CurrentQuery.stmt_meta->binds[i].buffer);
// NOTE: This memory should be zeroed during initialization,
// but we also nullify it here for extra safety. See #3546.
CurrentQuery.stmt_meta->binds[i].buffer = NULL;
}
}
}

@ -539,9 +539,12 @@ static char * mysql_thread_variables_names[]= {
(char *)"session_debug",
#endif /* DEBUG */
(char *)"ssl_p2s_ca",
(char *)"ssl_p2s_capath",
(char *)"ssl_p2s_cert",
(char *)"ssl_p2s_key",
(char *)"ssl_p2s_cipher",
(char *)"ssl_p2s_crl",
(char *)"ssl_p2s_crlpath",
(char *)"stacksize",
(char *)"threads",
(char *)"init_connect",
@ -1151,9 +1154,12 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() {
variables.servers_stats=true;
variables.default_reconnect=true;
variables.ssl_p2s_ca=NULL;
variables.ssl_p2s_capath=NULL;
variables.ssl_p2s_cert=NULL;
variables.ssl_p2s_key=NULL;
variables.ssl_p2s_cipher=NULL;
variables.ssl_p2s_crl=NULL;
variables.ssl_p2s_crlpath=NULL;
variables.keep_multiplexing_variables=strdup((char *)"tx_isolation,version");
#ifdef DEBUG
variables.session_debug=true;
@ -1276,6 +1282,13 @@ char * MySQL_Threads_Handler::get_variable_string(char *name) {
return strdup(variables.ssl_p2s_cert);
}
}
if (!strcmp(name,"ssl_p2s_capath")) {
if (variables.ssl_p2s_capath==NULL || strlen(variables.ssl_p2s_capath)==0) {
return NULL;
} else {
return strdup(variables.ssl_p2s_capath);
}
}
if (!strcmp(name,"ssl_p2s_key")) {
if (variables.ssl_p2s_key==NULL || strlen(variables.ssl_p2s_key)==0) {
return NULL;
@ -1290,6 +1303,20 @@ char * MySQL_Threads_Handler::get_variable_string(char *name) {
return strdup(variables.ssl_p2s_cipher);
}
}
if (!strcmp(name,"ssl_p2s_crl")) {
if (variables.ssl_p2s_crl==NULL || strlen(variables.ssl_p2s_crl)==0) {
return NULL;
} else {
return strdup(variables.ssl_p2s_crl);
}
}
if (!strcmp(name,"ssl_p2s_crlpath")) {
if (variables.ssl_p2s_crlpath==NULL || strlen(variables.ssl_p2s_crlpath)==0) {
return NULL;
} else {
return strdup(variables.ssl_p2s_crlpath);
}
}
}
if (!strcmp(name,"firewall_whitelist_errormsg")) {
if (variables.firewall_whitelist_errormsg==NULL || strlen(variables.firewall_whitelist_errormsg)==0) {
@ -1500,6 +1527,13 @@ char * MySQL_Threads_Handler::get_variable(char *name) { // this is the public f
return strdup(variables.ssl_p2s_ca);
}
}
if (!strcasecmp(name,"ssl_p2s_capath")) {
if (variables.ssl_p2s_capath==NULL || strlen(variables.ssl_p2s_capath)==0) {
return NULL;
} else {
return strdup(variables.ssl_p2s_capath);
}
}
if (!strcasecmp(name,"ssl_p2s_cert")) {
if (variables.ssl_p2s_cert==NULL || strlen(variables.ssl_p2s_cert)==0) {
return NULL;
@ -1521,6 +1555,20 @@ char * MySQL_Threads_Handler::get_variable(char *name) { // this is the public f
return strdup(variables.ssl_p2s_cipher);
}
}
if (!strcasecmp(name,"ssl_p2s_crl")) {
if (variables.ssl_p2s_crl==NULL || strlen(variables.ssl_p2s_crl)==0) {
return NULL;
} else {
return strdup(variables.ssl_p2s_crl);
}
}
if (!strcasecmp(name,"ssl_p2s_crlpath")) {
if (variables.ssl_p2s_crlpath==NULL || strlen(variables.ssl_p2s_crlpath)==0) {
return NULL;
} else {
return strdup(variables.ssl_p2s_crlpath);
}
}
}
// monitor variables
if (!strncasecmp(name,"monitor_",8)) {
@ -1821,6 +1869,15 @@ bool MySQL_Threads_Handler::set_variable(char *name, const char *value) { // thi
}
return true;
}
if (!strcasecmp(name,"ssl_p2s_capath")) {
if (variables.ssl_p2s_capath) free(variables.ssl_p2s_capath);
variables.ssl_p2s_capath=NULL;
if (vallen) {
if (strcmp(value,"(null)"))
variables.ssl_p2s_capath=strdup(value);
}
return true;
}
if (!strcasecmp(name,"ssl_p2s_cert")) {
if (variables.ssl_p2s_cert) free(variables.ssl_p2s_cert);
variables.ssl_p2s_cert=NULL;
@ -1848,6 +1905,24 @@ bool MySQL_Threads_Handler::set_variable(char *name, const char *value) { // thi
}
return true;
}
if (!strcasecmp(name,"ssl_p2s_crl")) {
if (variables.ssl_p2s_crl) free(variables.ssl_p2s_crl);
variables.ssl_p2s_crl=NULL;
if (vallen) {
if (strcmp(value,"(null)"))
variables.ssl_p2s_crl=strdup(value);
}
return true;
}
if (!strcasecmp(name,"ssl_p2s_crlpath")) {
if (variables.ssl_p2s_crlpath) free(variables.ssl_p2s_crlpath);
variables.ssl_p2s_crlpath=NULL;
if (vallen) {
if (strcmp(value,"(null)"))
variables.ssl_p2s_crlpath=strdup(value);
}
return true;
}
if (!strcasecmp(name,"auditlog_filename")) {
if (value[strlen(value) - 1] == '/') {
@ -2317,9 +2392,12 @@ MySQL_Threads_Handler::~MySQL_Threads_Handler() {
if (variables.eventslog_filename) free(variables.eventslog_filename);
if (variables.auditlog_filename) free(variables.auditlog_filename);
if (variables.ssl_p2s_ca) free(variables.ssl_p2s_ca);
if (variables.ssl_p2s_capath) free(variables.ssl_p2s_capath);
if (variables.ssl_p2s_cert) free(variables.ssl_p2s_cert);
if (variables.ssl_p2s_key) free(variables.ssl_p2s_key);
if (variables.ssl_p2s_cipher) free(variables.ssl_p2s_cipher);
if (variables.ssl_p2s_crl) free(variables.ssl_p2s_crl);
if (variables.ssl_p2s_crlpath) free(variables.ssl_p2s_crlpath);
for (int i=0; i<SQL_NAME_LAST; i++) {
if (variables.default_variables[i]) {
free(variables.default_variables[i]);
@ -2452,9 +2530,12 @@ MySQL_Thread::~MySQL_Thread() {
if (mysql_thread___eventslog_filename) { free(mysql_thread___eventslog_filename); mysql_thread___eventslog_filename=NULL; }
if (mysql_thread___auditlog_filename) { free(mysql_thread___auditlog_filename); mysql_thread___auditlog_filename=NULL; }
if (mysql_thread___ssl_p2s_ca) { free(mysql_thread___ssl_p2s_ca); mysql_thread___ssl_p2s_ca=NULL; }
if (mysql_thread___ssl_p2s_capath) { free(mysql_thread___ssl_p2s_capath); mysql_thread___ssl_p2s_capath=NULL; }
if (mysql_thread___ssl_p2s_cert) { free(mysql_thread___ssl_p2s_cert); mysql_thread___ssl_p2s_cert=NULL; }
if (mysql_thread___ssl_p2s_key) { free(mysql_thread___ssl_p2s_key); mysql_thread___ssl_p2s_key=NULL; }
if (mysql_thread___ssl_p2s_cipher) { free(mysql_thread___ssl_p2s_cipher); mysql_thread___ssl_p2s_cipher=NULL; }
if (mysql_thread___ssl_p2s_crl) { free(mysql_thread___ssl_p2s_crl); mysql_thread___ssl_p2s_crl=NULL; }
if (mysql_thread___ssl_p2s_crlpath) { free(mysql_thread___ssl_p2s_crlpath); mysql_thread___ssl_p2s_crlpath=NULL; }
if (match_regexes) {
@ -3556,12 +3637,18 @@ void MySQL_Thread::refresh_variables() {
// SSL proxy to server
if (mysql_thread___ssl_p2s_ca) free(mysql_thread___ssl_p2s_ca);
mysql_thread___ssl_p2s_ca=GloMTH->get_variable_string((char *)"ssl_p2s_ca");
if (mysql_thread___ssl_p2s_capath) free(mysql_thread___ssl_p2s_capath);
mysql_thread___ssl_p2s_capath=GloMTH->get_variable_string((char *)"ssl_p2s_ca");
if (mysql_thread___ssl_p2s_cert) free(mysql_thread___ssl_p2s_cert);
mysql_thread___ssl_p2s_cert=GloMTH->get_variable_string((char *)"ssl_p2s_cert");
if (mysql_thread___ssl_p2s_key) free(mysql_thread___ssl_p2s_key);
mysql_thread___ssl_p2s_key=GloMTH->get_variable_string((char *)"ssl_p2s_key");
if (mysql_thread___ssl_p2s_cipher) free(mysql_thread___ssl_p2s_cipher);
mysql_thread___ssl_p2s_cipher=GloMTH->get_variable_string((char *)"ssl_p2s_cipher");
if (mysql_thread___ssl_p2s_crl) free(mysql_thread___ssl_p2s_crl);
mysql_thread___ssl_p2s_crl=GloMTH->get_variable_string((char *)"ssl_p2s_crl");
if (mysql_thread___ssl_p2s_crlpath) free(mysql_thread___ssl_p2s_crlpath);
mysql_thread___ssl_p2s_crlpath=GloMTH->get_variable_string((char *)"ssl_p2s_crlpath");
mysql_thread___monitor_wait_timeout=(bool)GloMTH->get_variable_int((char *)"monitor_wait_timeout");
mysql_thread___monitor_writer_is_also_reader=(bool)GloMTH->get_variable_int((char *)"monitor_writer_is_also_reader");
@ -3709,9 +3796,12 @@ MySQL_Thread::MySQL_Thread() {
// SSL proxy to server
mysql_thread___ssl_p2s_ca=NULL;
mysql_thread___ssl_p2s_capath=NULL;
mysql_thread___ssl_p2s_cert=NULL;
mysql_thread___ssl_p2s_key=NULL;
mysql_thread___ssl_p2s_cipher=NULL;
mysql_thread___ssl_p2s_crl=NULL;
mysql_thread___ssl_p2s_crlpath=NULL;
last_maintenance_time=0;
maintenance_loop=true;

@ -3313,7 +3313,7 @@ bool ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign
SQLite3_result * ProxySQL_Admin::generate_show_fields_from(const char *tablename, char **err) {
char *tn=NULL; // tablename
// note that tablename is passed with a trailing '
tn=(char *)malloc(strlen(tablename));
tn=(char *)malloc(strlen(tablename) + 1);
unsigned int i=0, j=0;
while (i<strlen(tablename)) {
if (tablename[i]!='\\' && tablename[i]!='`' && tablename[i]!='\'') {

@ -659,7 +659,14 @@ void MySQL_Connection::connect_start() {
mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD, "mysql_bug_102266", "Avoid MySQL bug https://bugs.mysql.com/bug.php?id=102266 , https://github.com/sysown/proxysql/issues/3276");
}
if (parent->use_ssl) {
mysql_ssl_set(mysql, mysql_thread___ssl_p2s_key, mysql_thread___ssl_p2s_cert, mysql_thread___ssl_p2s_ca, NULL, mysql_thread___ssl_p2s_cipher);
mysql_ssl_set(mysql,
mysql_thread___ssl_p2s_key,
mysql_thread___ssl_p2s_cert,
mysql_thread___ssl_p2s_ca,
mysql_thread___ssl_p2s_capath,
mysql_thread___ssl_p2s_cipher);
mysql_options(mysql, MYSQL_OPT_SSL_CRL, mysql_thread___ssl_p2s_crl);
mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH, mysql_thread___ssl_p2s_crlpath);
}
unsigned int timeout= 1;
const char *csname = NULL;
@ -1012,7 +1019,7 @@ handler_again:
}
if (!ret_mysql) {
// always increase the counter
proxy_error("Failed to mysql_real_connect() on %s:%d , FD (Conn:%d , MyDS:%d) , %d: %s.\n", parent->address, parent->port, mysql->net.fd , myds->fd, mysql_errno(mysql), mysql_error(mysql));
proxy_error("Failed to mysql_real_connect() on %u:%s:%d , FD (Conn:%d , MyDS:%d) , %d: %s.\n", parent->myhgc->hid, parent->address, parent->port, mysql->net.fd , myds->fd, mysql_errno(mysql), mysql_error(mysql));
NEXT_IMMEDIATE(ASYNC_CONNECT_FAILED);
} else {
NEXT_IMMEDIATE(ASYNC_CONNECT_SUCCESSFUL);
@ -2292,7 +2299,11 @@ bool MySQL_Connection::IsKeepMultiplexEnabledVariables(char *query_digest_text)
}
while (query_digest_text_filter_select && (match = strcasestr(query_digest_text_filter_select,"@@"))) {
*match = '\0';
strcat(query_digest_text_filter_select, match+strlen("@@"));
if (strlen(query_digest_text_filter_select) == 0) {
memcpy(query_digest_text_filter_select, match, strlen("@@"));
} else {
strcat(query_digest_text_filter_select, match+strlen("@@"));
}
}
std::vector<char*>query_digest_text_filter_select_v;

@ -100,12 +100,25 @@ else
WGCOV=
endif
MYCXXFLAGS=-std=c++11 $(IDIRS) $(OPTZ) $(DEBUG) $(PSQLCH) -DGITVERSION=\"$(GIT_VERSION)\" $(WGCOV)
WITHASANVAR := $(shell echo $(WITHASAN))
ifeq ($(WITHASANVAR),1)
WASAN= -fsanitize=address
# Force the disable of JEMALLOC, since ASAN isn't compatible.
export NOJEMALLOC = 1
else
WASAN=
endif
MYCXXFLAGS=-std=c++11 $(IDIRS) $(OPTZ) $(DEBUG) $(PSQLCH) -DGITVERSION=\"$(GIT_VERSION)\" $(WGCOV) $(WASAN)
ifeq ($(WITHGCOVVAR),1)
LDFLAGS+= -lgcov --coverage
endif
ifeq ($(WITHASANVAR),1)
LDFLAGS+= -fsanitize=address
endif
NOJEMALLOC := $(shell echo $(NOJEMALLOC))
ifeq ($(NOJEMALLOC),1)
MYLIBS=-Wl,--export-dynamic -Wl,-Bstatic -lconfig -lproxysql -ldaemon -lconfig++ -lre2 -lpcrecpp -lpcre -lmariadbclient -lhttpserver -lmicrohttpd -linjection -lcurl -lssl -lcrypto -lev -luuid -Wl,-Bdynamic -lgnutls -lpthread -lm -lz -lrt -lprometheus-cpp-pull -lprometheus-cpp-core $(EXTRALINK)

@ -1146,6 +1146,7 @@ void ProxySQL_Main_join_all_threads() {
if (GloMyMon && MyMon_thread) {
cpu_timer t;
MyMon_thread->join();
delete MyMon_thread;
MyMon_thread = NULL;
#ifdef DEBUG
std::cerr << "GloMyMon joined in ";
@ -1742,7 +1743,7 @@ int main(int argc, const char * argv[]) {
SHA1(fb, statbuf.st_size, temp);
binary_sha1 = (char *)malloc(SHA_DIGEST_LENGTH*2+1);
memset(binary_sha1, 0, SHA_DIGEST_LENGTH*2+1);
char buf[SHA_DIGEST_LENGTH*2];
char buf[SHA_DIGEST_LENGTH*2 + 1];
for (int i=0; i < SHA_DIGEST_LENGTH; i++) {
sprintf((char*)&(buf[i*2]), "%02x", temp[i]);
}

@ -85,13 +85,20 @@ clean:
WITHGCOVVAR := $(shell echo $(WITHGCOV))
ifeq ($(WITHGCOVVAR),1)
WGCOV=-DWITHGCOV --coverage
WGCOV=-DWITHGCOV --coverage -lgcov
else
WGCOV=
endif
WITHASANVAR := $(shell echo $(WITHASAN))
ifeq ($(WITHASANVAR),1)
WASAN=-fsanitize=address
else
WASAN=
endif
OPT=-O2 $(WGCOV) -Wl,--no-as-needed
debug: OPT=-O0 -DDEBUG $(WGCOV) -ggdb -Wl,--no-as-needed
debug: OPT=-O0 -DDEBUG -ggdb -Wl,--no-as-needed $(WGCOV) $(WASAN)
debug: tests
tests: $(patsubst %.cpp,%,$(wildcard *-t.cpp)) setparser_test
@ -113,6 +120,9 @@ aurora: aurora.cpp $(TAP_LIBDIR)/libtap.a
test_tokenizer-t: test_tokenizer-t.cpp $(TAP_LIBDIR)/libtap.a
g++ test_tokenizer-t.cpp $(INCLUDEDIRS) $(LDIRS) $(OPT) -std=c++11 $(MYLIBS) -lproxysql -ltap -Wl,--no-as-needed -ldl -lpthread -o test_tokenizer-t -DGITVERSION=\"$(GIT_VERSION)\"
sqlite3-t: sqlite3-t.cpp $(TAP_LIBDIR)/libtap.a
g++ sqlite3-t.cpp $(INCLUDEDIRS) $(LDIRS) $(OPT) -std=c++11 -lproxysql $(MYLIBS) -ltap -Wl,--no-as-needed -ldl -lpthread -o sqlite3-t -DGITVERSION=\"$(GIT_VERSION)\"
test_gtid_forwarding-t: test_gtid_forwarding-t.cpp $(TAP_LIBDIR)/libtap.a
g++ test_gtid_forwarding-t.cpp $(INCLUDEDIRS) $(LDIRS) $(OPT) -std=c++11 $(MYLIBS) -ltap -Wl,--no-as-needed -ldl -lpthread -o test_gtid_forwarding-t -DGITVERSION=\"$(GIT_VERSION)\"
@ -126,4 +136,4 @@ test_set_collation-t: test_set_collation-t.cpp $(TAP_LIBDIR)/libtap.a
g++ test_set_collation-t.cpp $(INCLUDEDIRS) $(LDIRS) $(OPT) -std=c++11 $(MYLIBS) -ltap -Wl,--no-as-needed -ldl -lpthread -o test_set_collation-t -DGITVERSION=\"$(GIT_VERSION)\"
setparser_test: setparser_test.cpp $(TAP_LIBDIR)/libtap.a $(RE2_PATH)/util/test.cc $(LDIR)/set_parser.cpp $(LIBPROXYSQLAR)
g++ -DDEBUG setparser_test.cpp $(RE2_PATH)/util/test.cc ../../../src/obj/proxysql_global.o $(INCLUDEDIRS) $(LDIRS) $(OPT) -std=c++11 $(MYLIBS) -ltap -ldl -lpthread -o setparser_test -DGITVERSION=\"$(GIT_VERSION)\"
g++ -DDEBUG setparser_test.cpp $(RE2_PATH)/util/test.cc ../../../src/obj/proxysql_global.o $(INCLUDEDIRS) $(LDIRS) $(OPT) -std=c++11 -lproxysql $(MYLIBS) -ltap -ldl -lpthread $(WASAN) -o setparser_test -DGITVERSION=\"$(GIT_VERSION)\"

@ -0,0 +1,257 @@
/**
* @file reg_test_3546-stmt_empty_params-t.cpp
* @brief This test is a regression test for exercising the code path that lead
* to issue #3546. It's not meant to test a specific feature, but to server as
* a regression test that should flag the issue under a memory analyzer.
* @details Memory corruption related to #3546 was double-free provoqued when a
* prepared statement with param of types ['MYSQL_TYPE_DATE'|'MYSQL_TYPE_TIMESTAMP'|'MYSQL_TYPE_DATETIME'|'MYSQL_TYPE_TIME'],
* was prepared and a later prepared with 'NULL' parameters. Because the memory
* for the buffered was not zeroed neither at initialization or during the later
* `free` a corruption takes place during the second execution.
*/
#include <iostream>
#include <chrono>
#include <ctime>
#include <cstring>
#include <unistd.h>
#include <time.h>
#include <vector>
#include <string>
#include <stdio.h>
#include <mysql.h>
#include <mysql/mysqld_error.h>
#include "proxysql_utils.h"
#include "tap.h"
#include "command_line.h"
#include "utils.h"
#include "errno.h"
/**
* @brief String size of the columns created for the testing table.
*/
const int STRING_SIZE=32;
/**
* @brief Number of iterations to perform.
*/
const uint32_t ITERATIONS = 100;
/**
* @brief Id for the current writer hostgroup.
*/
const uint32_t WRITER_HOSTGROUP_ID = 0;
int prepare_stmt(
MYSQL* proxysql_mysql, MYSQL_STMT* stmt, MYSQL_TIME* ts, my_bool* is_null
) {
int res = EXIT_SUCCESS;
std::string query {
"SELECT /*+ ;hostgroup=0 */ id,c1,c2 FROM test.reg_test_3546 WHERE date IN (?)"
};
if (mysql_stmt_prepare(stmt, query.c_str(), strlen(query.c_str()))) {
diag("mysql_stmt_prepare at line %d failed: %s", __LINE__ , mysql_error(proxysql_mysql));
mysql_close(proxysql_mysql);
res = EXIT_FAILURE;
goto exit;
}
MYSQL_BIND bind_params;
memset(&bind_params, 0, sizeof(MYSQL_BIND));
bind_params.buffer_type= MYSQL_TYPE_DATE;
bind_params.buffer= ts;
bind_params.is_null= is_null;
bind_params.length= 0;
if (mysql_stmt_bind_param(stmt, &bind_params)) {
diag(
"mysql_stmt_bind_result at line %d failed: %s", __LINE__ ,
mysql_stmt_error(stmt)
);
res = EXIT_FAILURE;
goto exit;
}
exit:
return res;
}
int main(int argc, char** argv) {
CommandLine cl;
plan(ITERATIONS);
if (cl.getEnv()) {
diag("Failed to get the required environmental variables.");
return -1;
}
MYSQL_STMT* stmt_param = nullptr;
MYSQL* proxysql_mysql = mysql_init(NULL);
MYSQL* proxysql_admin = mysql_init(NULL);
if (!mysql_real_connect(proxysql_mysql, cl.host, cl.username, cl.password, NULL, cl.port, NULL, 0)) {
fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_mysql));
return -1;
}
if (!mysql_real_connect(proxysql_admin, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, 0)) {
fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin));
return -1;
}
stmt_param = mysql_stmt_init(proxysql_mysql);
if (!stmt_param) {
diag("mysql_stmt_init(), out of memory");
goto exit;
}
// Insert the row to be queried with the prepared statement.
// *************************************************************************
MYSQL_QUERY(proxysql_mysql, "CREATE DATABASE IF NOT EXISTS test");
MYSQL_QUERY(proxysql_mysql, "DROP TABLE IF EXISTS test.reg_test_3546");
MYSQL_QUERY(
proxysql_mysql,
"CREATE TABLE IF NOT EXISTS test.reg_test_3546"
" (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, `c1` BIGINT, `c2` varchar(32), `date` DATE)"
);
MYSQL_QUERY(proxysql_mysql, "INSERT INTO test.reg_test_3546(c1, c2, date) VALUES (100, 'abcde', '2009-01-01')");
mysql_close(proxysql_mysql);
// *************************************************************************
// Initialize the connection again
proxysql_mysql = mysql_init(NULL);
if (!mysql_real_connect(proxysql_mysql, cl.host, cl.username, cl.password, NULL, cl.port, NULL, 0)) {
fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_mysql));
return -1;
}
{
// Set the number of maximum connections for servers in the writer hostgroup
std::string t_update_mysql_servers {
"UPDATE mysql_servers SET max_connections=1 WHERE hostgroup_id=%d"
};
std::string update_mysql_queries {};
string_format(t_update_mysql_servers, update_mysql_queries, WRITER_HOSTGROUP_ID);
MYSQL_QUERY(proxysql_admin, update_mysql_queries.c_str());
MYSQL_QUERY(proxysql_admin, "LOAD MYSQL SERVERS TO RUNTIME");
MYSQL_TIME ts;
char data_param[STRING_SIZE] = {};
my_bool is_null = 0;
if (prepare_stmt(proxysql_mysql, stmt_param, &ts, &is_null)) {
diag("'prepare_stmt' at line %d failed", __LINE__);
goto exit;
}
// Prepare parameters
ts.year = 2009;
ts.month = 1;
ts.day = 1;
for (uint32_t i = 0; i < ITERATIONS; i++) {
if (i % 2) {
is_null = 0;
} else {
is_null = 1;
}
if (mysql_stmt_execute(stmt_param)) {
diag(
"'mysql_stmt_execute' at line %d failed: %s", __LINE__ ,
mysql_stmt_error(stmt_param)
);
goto exit;
}
MYSQL_BIND bind[3];
memset(bind, 0, sizeof(bind));
int data_id = 0;
int64_t data_c1 = 0;
char data_c2[STRING_SIZE] { 0 };
char is_null[3] { 0 };
long unsigned int length[3] { 0 };
char error[3] { 0 };
bind[0].buffer_type = MYSQL_TYPE_LONG;
bind[0].buffer = (char *)&data_id;
bind[0].buffer_length = sizeof(int);
bind[0].is_null = &is_null[0];
bind[0].length = &length[0];
bind[1].buffer_type = MYSQL_TYPE_LONGLONG;
bind[1].buffer = (char *)&data_c1;
bind[1].buffer_length = sizeof(int64_t);
bind[1].is_null = &is_null[1];
bind[1].length = &length[1];
bind[2].buffer_type = MYSQL_TYPE_STRING;
bind[2].buffer = (char *)&data_c2;
bind[2].buffer_length = STRING_SIZE;
bind[2].is_null = &is_null[2];
bind[2].length = &length[2];
bind[2].error = &error[2];
if (mysql_stmt_bind_result(stmt_param, bind)) {
diag(
"mysql_stmt_bind_result at line %d failed: %s", __LINE__,
mysql_stmt_error(stmt_param)
);
goto exit;
}
int fetch_result = mysql_stmt_fetch(stmt_param);
if (fetch_result == 1) {
diag(
"mysql_stmt_fetch at line %d failed: %s", __LINE__,
mysql_stmt_error(stmt_param)
);
goto exit;
}
if (i % 2) {
bool data_match_expected =
(data_id == static_cast<int64_t>(1)) &&
(data_c1 == static_cast<int64_t>(100)) &&
(strcmp(data_c2, "abcde") == 0);
ok(
data_match_expected,
"Prepared statement SELECT result *SHOULD* match expected -"
" Exp=(id:1, c1:100, c2:'abcde'), Act=(id:%d, c1:%ld, c2:'%s')",
data_id,
data_c1,
data_c2
);
} else {
bool data_match_expected =
(data_id == static_cast<int64_t>(0)) &&
(data_c1 == static_cast<int64_t>(0)) &&
(strcmp(data_c2, "") == 0);
ok(
data_match_expected,
"Prepared statement SELECT result *SHOULD* match expected -"
" Exp=(id:0, c1:0, c2:''), Act=(id:%d, c1:%ld, c2:'%s')",
data_id,
data_c1,
data_c2
);
}
}
}
exit:
if (stmt_param) { mysql_stmt_close(stmt_param); }
mysql_close(proxysql_mysql);
mysql_close(proxysql_admin);
return exit_status();
}

@ -59,7 +59,8 @@ int main(int argc, char** argv) {
// Test that firewall initialized and blocks all queries
if (mysql_query(mysql, "select @@version")) {
ok(mysql_num_rows(result) == 0, "Any query should be blocked");
int myerrno = mysql_errno(mysql);
ok(myerrno == 1148, "Any query should be blocked");
}
// enable 'Select 1' query

Loading…
Cancel
Save