Navigation Menu

Skip to content

Commit

Permalink
MDEV-16478: mysql_real_connect() from libmariadbd.so always crash
Browse files Browse the repository at this point in the history
Returned accidentally removed undefinition of MYSQL_SERVER in net_serv.cc inside embedded server
(embedded server uses real_net_read/write only as a client)

Prevented attempt to clean up embedded server if it was not initialized
  • Loading branch information
sanja-byelkin committed Jun 25, 2018
1 parent 88aaf59 commit 46fc864
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 4 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Expand Up @@ -398,6 +398,7 @@ IF(NOT WITHOUT_SERVER)
IF(WITH_EMBEDDED_SERVER)
ADD_SUBDIRECTORY(libmysqld)
ADD_SUBDIRECTORY(libmysqld/examples)
ADD_SUBDIRECTORY(unittest/embedded)
ENDIF(WITH_EMBEDDED_SERVER)

IF(WITH_WSREP)
Expand Down
17 changes: 13 additions & 4 deletions libmysqld/lib_sql.cc
Expand Up @@ -55,6 +55,9 @@ extern "C" void unireg_clear(int exit_code)
DBUG_VOID_RETURN;
}


static my_bool mysql_embedded_init= 0;

/*
Wrapper error handler for embedded server to call client/server error
handler based on whether thread is in client/server context
Expand Down Expand Up @@ -518,6 +521,8 @@ int init_embedded_server(int argc, char **argv, char **groups)
const char *fake_groups[] = { "server", "embedded", 0 };
my_bool acl_error;

DBUG_ASSERT(mysql_embedded_init == 0);

if (my_thread_init())
return 1;

Expand Down Expand Up @@ -637,15 +642,19 @@ int init_embedded_server(int argc, char **argv, char **groups)
}

execute_ddl_log_recovery();
mysql_embedded_init= 1;
return 0;
}

void end_embedded_server()
{
my_free(copy_arguments_ptr);
copy_arguments_ptr=0;
clean_up(0);
clean_up_mutexes();
if (mysql_embedded_init)
{
my_free(copy_arguments_ptr);
copy_arguments_ptr=0;
clean_up(0);
clean_up_mutexes();
}
}


Expand Down
6 changes: 6 additions & 0 deletions sql/net_serv.cc
Expand Up @@ -47,6 +47,12 @@
#include "probes_mysql.h"
#include "proxy_protocol.h"

#ifdef EMBEDDED_LIBRARY
#undef MYSQL_SERVER
#undef MYSQL_CLIENT
#define MYSQL_CLIENT
#endif /*EMBEDDED_LIBRARY */

/*
to reduce the number of ifdef's in the code
*/
Expand Down
20 changes: 20 additions & 0 deletions unittest/embedded/CMakeLists.txt
@@ -0,0 +1,20 @@

INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/libmysqld/include
${PCRE_INCLUDES}
${CMAKE_SOURCE_DIR}/sql
${MY_READLINE_INCLUDE_DIR}
)


ADD_DEFINITIONS(-DEMBEDDED_LIBRARY -UMYSQL_CLIENT)


MYSQL_ADD_EXECUTABLE(test-connect-t test-connect.cc
COMPONENT Test)
TARGET_LINK_LIBRARIES(test-connect-t mysqlserver )
MY_ADD_TEST(test-connect)

IF(UNIX)
SET_TARGET_PROPERTIES(test-connect-t PROPERTIES ENABLE_EXPORTS TRUE)
ENDIF()
78 changes: 78 additions & 0 deletions unittest/embedded/test-connect.cc
@@ -0,0 +1,78 @@
#include <mysql.h>
#include <stdio.h>
#include <stdlib.h>

int get_evar(char **hostname, char **port, char** username, char ** password)
{

if (!((*hostname)= getenv("MYSQL_TEST_HOST")))
(*hostname)= (char *)"127.0.0.1";

if (!((*port)= getenv("MASTER_MYPORT")))
{
if (!((*port)= getenv("MYSQL_TEST_PORT")))
return 1;
}

if (!((*username)= getenv("MYSQL_TEST_USER")))
(*username)= (char *)"root";

if (!((*password)= getenv("MYSQL_TEST_PASSWD")))
(*password)= (char *)"";

return 0;
}

int main(int argc, char *argv[])
{
MYSQL *mysql;
char *host;
char *user;
char *passwd;
char *porta;
unsigned int port;

if (get_evar(&host, &porta, &user, &passwd))
{
printf("set environment variable MASTER_MYPORT\n");
return 1;
}

port = atoi(porta);

mysql_thread_init();

if (mysql_server_init(-1, NULL, NULL) != 0) {
printf("mysql_library_init failed");
return 1;
}


mysql = mysql_init(NULL);

if (!mysql) {
printf("mysql_init failed");
return 1;
}

if (mysql_options(mysql, MYSQL_OPT_USE_REMOTE_CONNECTION, NULL) != 0) {
printf("mysql_options MYSQL_OPT_USE_REMOTE_CONNECTION failed: %s\n", mysql_error(mysql));
return 1;
}

if (mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "utf8mb4") != 0) {
printf("mysql_options MYSQL_SET_CHARSET_NAME utf8mb4 failed: %s\n", mysql_error(mysql));
return 1;
}

if (!mysql_real_connect(mysql, host, user, passwd, NULL, port, NULL, CLIENT_FOUND_ROWS | CLIENT_MULTI_RESULTS | CLIENT_REMEMBER_OPTIONS)) {
printf("mysql_real_connect failed: %s\n", mysql_error(mysql));
return 1;
}
mysql_close(mysql);
mysql_thread_end();
mysql_library_end();

return 0;

}

0 comments on commit 46fc864

Please sign in to comment.