From 55fe56fa42679e698036fcbf77fe4761feb56723 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Thu, 22 Feb 2024 09:03:51 +0100 Subject: [PATCH] Fix for CONC-505: Don't allow to specify unsupported client flags (like CLIENT_DEPRECATE_EOF) as client flag in mysql_real_connect api function. --- include/errmsg.h | 3 ++- include/mariadb_com.h | 6 ++++++ libmariadb/ma_errmsg.c | 4 ++-- libmariadb/mariadb_lib.c | 8 ++++++++ unittest/libmariadb/connection.c | 26 ++++++++++++++++++++++++++ 5 files changed, 44 insertions(+), 3 deletions(-) diff --git a/include/errmsg.h b/include/errmsg.h index 0d8ddcaf..0e6d24e0 100644 --- a/include/errmsg.h +++ b/include/errmsg.h @@ -114,7 +114,8 @@ extern const char *mariadb_client_errors[]; /* Error messages */ #define CR_BINLOG_ERROR 5021 #define CR_BINLOG_INVALID_FILE 5022 #define CR_BINLOG_SEMI_SYNC_ERROR 5023 -#define CR_STMT_NO_RESULT 5024 +#define CR_INVALID_CLIENT_FLAG 5024 +#define CR_STMT_NO_RESULT 5025 /* Always last, if you add new error codes please update the value for CR_MARIADB_LAST_ERROR */ diff --git a/include/mariadb_com.h b/include/mariadb_com.h index 44111000..f904f98d 100644 --- a/include/mariadb_com.h +++ b/include/mariadb_com.h @@ -213,6 +213,12 @@ enum enum_server_command CLIENT_PLUGIN_AUTH |\ CLIENT_SESSION_TRACKING |\ CLIENT_CONNECT_ATTRS) +#define CLIENT_ALLOWED_FLAGS ((CLIENT_SUPPORTED_FLAGS |\ + CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA |\ + CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS |\ + CLIENT_ZSTD_COMPRESSION |\ + CLIENT_PS_MULTI_RESULTS |\ + CLIENT_REMEMBER_OPTIONS) & ~CLIENT_MYSQL) #define CLIENT_CAPABILITIES (CLIENT_MYSQL | \ CLIENT_LONG_FLAG |\ CLIENT_TRANSACTIONS |\ diff --git a/libmariadb/ma_errmsg.c b/libmariadb/ma_errmsg.c index 1fcc6d4a..775244d3 100644 --- a/libmariadb/ma_errmsg.c +++ b/libmariadb/ma_errmsg.c @@ -118,8 +118,8 @@ const char *mariadb_client_errors[] = /* 5021 */ "Binary log error (File: %.*s start_pos=%ld): %s.", /* 5022 */ "File '%s' is not a binary log file", /* 5023 */ "Semi sync request error: %s", - /* 5024 */ "Statement has no result set", - "" + /* 5024 */ "Invalid client flags (%lu) specified. Supported flags: %lu", + /* 5025 */ "Statement has no result set", }; const char ** NEAR my_errmsg[MAXMAPS]={0,0,0,0}; diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c index e2c2d0a7..1db7cf34 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -1444,6 +1444,14 @@ mysql_real_connect(MYSQL *mysql, const char *host, const char *user, char *connection_handler= (mysql->options.extension) ? mysql->options.extension->connection_handler : 0; + if ((client_flag & CLIENT_ALLOWED_FLAGS) != client_flag) + { + my_set_error(mysql, CR_INVALID_CLIENT_FLAG, SQLSTATE_UNKNOWN, + ER(CR_INVALID_CLIENT_FLAG), + client_flag, CLIENT_ALLOWED_FLAGS); + return NULL; + } + if (!mysql->methods) mysql->methods= &MARIADB_DEFAULT_METHODS; diff --git a/unittest/libmariadb/connection.c b/unittest/libmariadb/connection.c index 49f3abec..bd4e0e0a 100644 --- a/unittest/libmariadb/connection.c +++ b/unittest/libmariadb/connection.c @@ -2351,8 +2351,34 @@ static int test_x509(MYSQL *my __attribute__((unused))) return OK; } +static int test_conc505(MYSQL *my __attribute__((unused))) +{ + MYSQL *mysql= mysql_init(NULL); + +#define CLIENT_DEPRECATE_EOF (1ULL << 24) + + if (my_test_connect(mysql, hostname, username, password, schema, port, socketname, CLIENT_DEPRECATE_EOF)) + { + diag("Error expected: Invalid client flag"); + mysql_close(mysql); + return FAIL; + } + diag("Error (expected): %s", mysql_error(mysql)); + FAIL_IF(mysql_errno(mysql) != CR_INVALID_CLIENT_FLAG, "Wrong error number"); + if (!my_test_connect(mysql, hostname, username, password, schema, port, socketname, CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS)) + { + diag("Error: %s", mysql_error(mysql)); + mysql_close(mysql); + return FAIL; + } + + mysql_close(mysql); + return OK; +} + struct my_tests_st my_tests[] = { {"test_x509", test_x509, TEST_CONNECTION_NONE, 0, NULL, NULL}, + {"test_conc505", test_conc505, TEST_CONNECTION_NONE, 0, NULL, NULL}, {"test_conc632", test_conc632, TEST_CONNECTION_NONE, 0, NULL, NULL}, {"test_status_callback", test_status_callback, TEST_CONNECTION_NONE, 0, NULL, NULL}, {"test_conc365", test_conc365, TEST_CONNECTION_NONE, 0, NULL, NULL},