1From b98375f9df0b024857c03c03bc3e73e8ced8d772 Mon Sep 17 00:00:00 2001 2From: Nayuta Yanagisawa <nayuta.yanagisawa@hey.com> 3Date: Tue, 27 Sep 2022 15:22:57 +0900 4Subject: [PATCH] MDEV-29644 a potential bug of null pointer dereference in 5 spider_db_mbase::print_warnings() 6 7The function spider_db_mbase::print_warnings() can potentially result 8in a null pointer dereference. 9 10Remove the null pointer dereference by cleaning up the function. 11 12Some small changes to the original commit 13422fb63a9bbee35c50b6c7be19d199afe0bc98fa. 14 15CVE: CVE-2022-47015 16 17Upstream-Status: Backport [https://github.com/MariaDB/server/commit/b98375f9df0] 18 19Co-Authored-By: Yuchen Pei <yuchen.pei@mariadb.com> 20Signed-off-by: Mingli Yu <mingli.yu@windriver.com> 21--- 22 .../spider/bugfix/r/mdev_29644.result | 41 ++++++ 23 .../mysql-test/spider/bugfix/t/mdev_29644.cnf | 3 + 24 .../spider/bugfix/t/mdev_29644.test | 56 ++++++++ 25 storage/spider/spd_db_mysql.cc | 124 ++++++++---------- 26 storage/spider/spd_db_mysql.h | 2 +- 27 5 files changed, 154 insertions(+), 72 deletions(-) 28 create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_29644.result 29 create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_29644.cnf 30 create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_29644.test 31 32diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_29644.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_29644.result 33new file mode 100644 34index 00000000000..b52cecc5bb7 35--- /dev/null 36+++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_29644.result 37@@ -0,0 +1,41 @@ 38+# 39+# MDEV-29644 a potential bug of null pointer dereference in spider_db_mbase::print_warnings() 40+# 41+for master_1 42+for child2 43+child2_1 44+child2_2 45+child2_3 46+for child3 47+connection child2_1; 48+CREATE DATABASE auto_test_remote; 49+USE auto_test_remote; 50+CREATE TABLE tbl_a ( 51+a CHAR(5) 52+) ENGINE=InnoDB DEFAULT CHARSET=utf8; 53+SET GLOBAL sql_mode=''; 54+connection master_1; 55+CREATE DATABASE auto_test_local; 56+USE auto_test_local; 57+CREATE TABLE tbl_a ( 58+a CHAR(255) 59+) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_a", srv "s_2_1"'; 60+SET sql_mode=''; 61+INSERT INTO tbl_a VALUES ("this will be truncated"); 62+NOT FOUND /\[WARN SPIDER RESULT\].* Warning 1265 Data truncated for column 'a' at row 1.*/ in mysqld.1.1.err 63+SET GLOBAL spider_log_result_errors=4; 64+INSERT INTO tbl_a VALUES ("this will be truncated"); 65+FOUND 1 /\[WARN SPIDER RESULT\].* Warning 1265 Data truncated for column 'a' at row 1.*/ in mysqld.1.1.err 66+connection master_1; 67+SET GLOBAL spider_log_result_errors=DEFAULT; 68+SET sql_mode=DEFAULT; 69+DROP DATABASE IF EXISTS auto_test_local; 70+connection child2_1; 71+SET GLOBAL sql_mode=DEFAULT; 72+DROP DATABASE IF EXISTS auto_test_remote; 73+for master_1 74+for child2 75+child2_1 76+child2_2 77+child2_3 78+for child3 79diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_29644.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_29644.cnf 80new file mode 100644 81index 00000000000..05dfd8a0bce 82--- /dev/null 83+++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29644.cnf 84@@ -0,0 +1,3 @@ 85+!include include/default_mysqld.cnf 86+!include ../my_1_1.cnf 87+!include ../my_2_1.cnf 88diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_29644.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_29644.test 89new file mode 100644 90index 00000000000..3a8fbb251e1 91--- /dev/null 92+++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29644.test 93@@ -0,0 +1,56 @@ 94+--echo # 95+--echo # MDEV-29644 a potential bug of null pointer dereference in spider_db_mbase::print_warnings() 96+--echo # 97+ 98+# The test case below does not cause the potential null pointer dereference. 99+# It is just for checking spider_db_mbase::fetch_and_print_warnings() works. 100+ 101+--disable_query_log 102+--disable_result_log 103+--source ../../t/test_init.inc 104+--enable_result_log 105+--enable_query_log 106+ 107+--connection child2_1 108+CREATE DATABASE auto_test_remote; 109+USE auto_test_remote; 110+eval CREATE TABLE tbl_a ( 111+ a CHAR(5) 112+) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; 113+ 114+SET GLOBAL sql_mode=''; 115+ 116+--connection master_1 117+CREATE DATABASE auto_test_local; 118+USE auto_test_local; 119+eval CREATE TABLE tbl_a ( 120+ a CHAR(255) 121+) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a", srv "s_2_1"'; 122+ 123+SET sql_mode=''; 124+ 125+let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.1.err; 126+let SEARCH_PATTERN= \[WARN SPIDER RESULT\].* Warning 1265 Data truncated for column 'a' at row 1.*; 127+ 128+INSERT INTO tbl_a VALUES ("this will be truncated"); 129+--source include/search_pattern_in_file.inc # should not find 130+ 131+SET GLOBAL spider_log_result_errors=4; 132+ 133+INSERT INTO tbl_a VALUES ("this will be truncated"); 134+--source include/search_pattern_in_file.inc # should find 135+ 136+--connection master_1 137+SET GLOBAL spider_log_result_errors=DEFAULT; 138+SET sql_mode=DEFAULT; 139+DROP DATABASE IF EXISTS auto_test_local; 140+ 141+--connection child2_1 142+SET GLOBAL sql_mode=DEFAULT; 143+DROP DATABASE IF EXISTS auto_test_remote; 144+ 145+--disable_query_log 146+--disable_result_log 147+--source ../t/test_deinit.inc 148+--enable_query_log 149+--enable_result_log 150diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc 151index d377d2bd807..bc8383017f7 100644 152--- a/storage/spider/spd_db_mysql.cc 153+++ b/storage/spider/spd_db_mysql.cc 154@@ -2207,7 +2207,7 @@ int spider_db_mbase::exec_query( 155 db_conn->affected_rows, db_conn->insert_id, 156 db_conn->server_status, db_conn->warning_count); 157 if (spider_param_log_result_errors() >= 3) 158- print_warnings(l_time); 159+ fetch_and_print_warnings(l_time); 160 } else if (log_result_errors >= 4) 161 { 162 time_t cur_time = (time_t) time((time_t*) 0); 163@@ -2289,81 +2289,63 @@ bool spider_db_mbase::is_xa_nota_error( 164 DBUG_RETURN(xa_nota); 165 } 166 167-int spider_db_mbase::print_warnings( 168- struct tm *l_time 169-) { 170+int spider_db_mbase::fetch_and_print_warnings(struct tm *l_time) 171+{ 172 int error_num = 0; 173- DBUG_ENTER("spider_db_mbase::print_warnings"); 174+ DBUG_ENTER("spider_db_mbase::fetch_and_print_warnings"); 175 DBUG_PRINT("info",("spider this=%p", this)); 176- if (db_conn->status == MYSQL_STATUS_READY) 177+ 178+ if (spider_param_dry_access() || db_conn->status != MYSQL_STATUS_READY || 179+ db_conn->server_status & SERVER_MORE_RESULTS_EXISTS || 180+ !db_conn->warning_count) 181+ DBUG_RETURN(0); 182+ 183+ if (mysql_real_query(db_conn, SPIDER_SQL_SHOW_WARNINGS_STR, 184+ SPIDER_SQL_SHOW_WARNINGS_LEN)) 185+ DBUG_RETURN(0); 186+ 187+ MYSQL_RES *res= mysql_store_result(db_conn); 188+ if (!res) 189+ DBUG_RETURN(0); 190+ 191+ uint num_fields= mysql_num_fields(res); 192+ if (num_fields != 3) 193 { 194- if ( 195-#if MYSQL_VERSION_ID < 50500 196- !(db_conn->last_used_con->server_status & SERVER_MORE_RESULTS_EXISTS) && 197- db_conn->last_used_con->warning_count 198-#else 199- !(db_conn->server_status & SERVER_MORE_RESULTS_EXISTS) && 200- db_conn->warning_count 201-#endif 202- ) { 203- if ( 204- spider_param_dry_access() || 205- !mysql_real_query(db_conn, SPIDER_SQL_SHOW_WARNINGS_STR, 206- SPIDER_SQL_SHOW_WARNINGS_LEN) 207- ) { 208- MYSQL_RES *res = NULL; 209- MYSQL_ROW row = NULL; 210- uint num_fields; 211- if ( 212- spider_param_dry_access() || 213- !(res = mysql_store_result(db_conn)) || 214- !(row = mysql_fetch_row(res)) 215- ) { 216- if (mysql_errno(db_conn)) 217- { 218- if (res) 219- mysql_free_result(res); 220- DBUG_RETURN(0); 221- } 222- /* no record is ok */ 223- } 224- num_fields = mysql_num_fields(res); 225- if (num_fields != 3) 226- { 227- mysql_free_result(res); 228- DBUG_RETURN(0); 229- } 230- if (l_time) 231- { 232- while (row) 233- { 234- fprintf(stderr, "%04d%02d%02d %02d:%02d:%02d [WARN SPIDER RESULT] " 235- "from [%s] %ld to %ld: %s %s %s\n", 236+ mysql_free_result(res); 237+ DBUG_RETURN(0); 238+ } 239+ 240+ MYSQL_ROW row= mysql_fetch_row(res); 241+ if (l_time) 242+ { 243+ while (row) 244+ { 245+ fprintf(stderr, 246+ "%04d%02d%02d %02d:%02d:%02d [WARN SPIDER RESULT] from [%s] %ld " 247+ "to %ld: %s %s %s\n", 248 l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday, 249- l_time->tm_hour, l_time->tm_min, l_time->tm_sec, 250- conn->tgt_host, (ulong) db_conn->thread_id, 251- (ulong) current_thd->thread_id, row[0], row[1], row[2]); 252- row = mysql_fetch_row(res); 253- } 254- } else { 255- while (row) 256- { 257- DBUG_PRINT("info",("spider row[0]=%s", row[0])); 258- DBUG_PRINT("info",("spider row[1]=%s", row[1])); 259- DBUG_PRINT("info",("spider row[2]=%s", row[2])); 260- longlong res_num = 261- (longlong) my_strtoll10(row[1], (char**) NULL, &error_num); 262- DBUG_PRINT("info",("spider res_num=%lld", res_num)); 263- my_printf_error((int) res_num, row[2], MYF(0)); 264- error_num = (int) res_num; 265- row = mysql_fetch_row(res); 266- } 267- } 268- if (res) 269- mysql_free_result(res); 270- } 271+ l_time->tm_hour, l_time->tm_min, l_time->tm_sec, conn->tgt_host, 272+ (ulong) db_conn->thread_id, (ulong) current_thd->thread_id, row[0], 273+ row[1], row[2]); 274+ row= mysql_fetch_row(res); 275+ } 276+ } else { 277+ while (row) 278+ { 279+ DBUG_PRINT("info",("spider row[0]=%s", row[0])); 280+ DBUG_PRINT("info",("spider row[1]=%s", row[1])); 281+ DBUG_PRINT("info",("spider row[2]=%s", row[2])); 282+ longlong res_num = 283+ (longlong) my_strtoll10(row[1], (char**) NULL, &error_num); 284+ DBUG_PRINT("info",("spider res_num=%lld", res_num)); 285+ my_printf_error((int) res_num, row[2], MYF(0)); 286+ error_num = (int) res_num; 287+ row = mysql_fetch_row(res); 288 } 289 } 290+ 291+ mysql_free_result(res); 292+ 293 DBUG_RETURN(error_num); 294 } 295 296@@ -14668,7 +14650,7 @@ int spider_mbase_handler::show_table_status( 297 DBUG_RETURN(error_num); 298 } 299 } 300- if ((error_num = ((spider_db_mbase *) conn->db_conn)->print_warnings(NULL))) 301+ if ((error_num = ((spider_db_mbase *) conn->db_conn)->fetch_and_print_warnings(NULL))) 302 { 303 DBUG_RETURN(error_num); 304 } 305diff --git a/storage/spider/spd_db_mysql.h b/storage/spider/spd_db_mysql.h 306index e90461ea278..a2012352f21 100644 307--- a/storage/spider/spd_db_mysql.h 308+++ b/storage/spider/spd_db_mysql.h 309@@ -442,7 +442,7 @@ class spider_db_mbase: public spider_db_conn 310 bool is_xa_nota_error( 311 int error_num 312 ); 313- int print_warnings( 314+ int fetch_and_print_warnings( 315 struct tm *l_time 316 ); 317 spider_db_result *store_result( 318-- 3192.25.1 320 321