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