Skip to content

Commit

Permalink
MDEV-29644 a potential bug of null pointer dereference in spider_db_m…
Browse files Browse the repository at this point in the history
…base::print_warnings()

The function spider_db_mbase::print_warnings() can potentially result
in a null pointer dereference.

Remove the null pointer dereference by cleaning up the function.
  • Loading branch information
nayuta-yanagisawa committed Sep 28, 2022
1 parent 2b89598 commit be0a46b
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 56 deletions.
44 changes: 44 additions & 0 deletions storage/spider/mysql-test/spider/bugfix/r/mdev_29644.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#
# MDEV-29644 a potential bug of null pointer dereference in spider_db_mbase::print_warnings()
#
for master_1
for child2
child2_1
child2_2
child2_3
for child3
connection child2_1;
CREATE DATABASE auto_test_remote;
USE auto_test_remote;
CREATE TABLE tbl_a (
a CHAR(5)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
set @orig_sql_mode=@@global.sql_mode;
SET GLOBAL sql_mode='';
connection master_1;
CREATE DATABASE auto_test_local;
USE auto_test_local;
CREATE TABLE tbl_a (
a CHAR(255)
) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_a", srv "s_2_1"';
SET @orig_sql_mode=@@global.sql_mode;
SET GLOBAL sql_mode='';
INSERT INTO tbl_a VALUES ("this will be truncated");
NOT FOUND /\[WARN SPIDER RESULT\].* Warning 1265 Data truncated for column 'a' at row 1.*/ in mysqld.1.1.err
SET @orig_log_result_errors=@@global.spider_log_result_errors;
SET GLOBAL spider_log_result_errors=4;
INSERT INTO tbl_a VALUES ("this will be truncated");
FOUND 1 /\[WARN SPIDER RESULT\].* Warning 1265 Data truncated for column 'a' at row 1.*/ in mysqld.1.1.err
connection master_1;
SET GLOBAL spider_log_result_errors=@orig_log_result_errors;
SET GLOBAL sql_mode=@orig_sql_mode;
DROP DATABASE IF EXISTS auto_test_local;
connection child2_1;
SET GLOBAL sql_mode=@orig_sql_mode;
DROP DATABASE IF EXISTS auto_test_remote;
for master_1
for child2
child2_1
child2_2
child2_3
for child3
3 changes: 3 additions & 0 deletions storage/spider/mysql-test/spider/bugfix/t/mdev_29644.cnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
!include include/default_mysqld.cnf
!include ../my_1_1.cnf
!include ../my_2_1.cnf
58 changes: 58 additions & 0 deletions storage/spider/mysql-test/spider/bugfix/t/mdev_29644.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
--echo #
--echo # MDEV-29644 a potential bug of null pointer dereference in spider_db_mbase::print_warnings()
--echo #

# The test case below does not cause the potential null pointer dereference.
# It is just for checking spider_db_mbase::fetch_and_print_warnings() works.

--disable_query_log
--disable_result_log
--source ../../t/test_init.inc
--enable_result_log
--enable_query_log

--connection child2_1
CREATE DATABASE auto_test_remote;
USE auto_test_remote;
eval CREATE TABLE tbl_a (
a CHAR(5)
) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
set @orig_sql_mode=@@global.sql_mode;
SET GLOBAL sql_mode='';

--connection master_1
CREATE DATABASE auto_test_local;
USE auto_test_local;
eval CREATE TABLE tbl_a (
a CHAR(255)
) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a", srv "s_2_1"';

SET @orig_sql_mode=@@global.sql_mode;
SET GLOBAL sql_mode='';

let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.1.err;
let SEARCH_PATTERN= \[WARN SPIDER RESULT\].* Warning 1265 Data truncated for column 'a' at row 1.*;

INSERT INTO tbl_a VALUES ("this will be truncated");
--source include/search_pattern_in_file.inc # should not find

SET @orig_log_result_errors=@@global.spider_log_result_errors;
SET GLOBAL spider_log_result_errors=4;

INSERT INTO tbl_a VALUES ("this will be truncated");
--source include/search_pattern_in_file.inc # should find

--connection master_1
SET GLOBAL spider_log_result_errors=@orig_log_result_errors;
SET GLOBAL sql_mode=@orig_sql_mode;
DROP DATABASE IF EXISTS auto_test_local;

--connection child2_1
SET GLOBAL sql_mode=@orig_sql_mode;
DROP DATABASE IF EXISTS auto_test_remote;

--disable_query_log
--disable_result_log
--source ../t/test_deinit.inc
--enable_query_log
--enable_result_log
88 changes: 35 additions & 53 deletions storage/spider/spd_db_mysql.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2090,7 +2090,7 @@ int spider_db_mbase::exec_query(
db_conn->affected_rows, db_conn->insert_id,
db_conn->server_status, db_conn->warning_count);
if (spider_param_log_result_errors() >= 3)
print_warnings(l_time);
fetch_and_print_warnings(l_time);
} else if (log_result_errors >= 4)
{
time_t cur_time = (time_t) time((time_t*) 0);
Expand Down Expand Up @@ -2172,61 +2172,43 @@ bool spider_db_mbase::is_xa_nota_error(
DBUG_RETURN(xa_nota);
}

void spider_db_mbase::print_warnings(
struct tm *l_time
) {
DBUG_ENTER("spider_db_mbase::print_warnings");
DBUG_PRINT("info",("spider this=%p", this));
if (db_conn->status == MYSQL_STATUS_READY)
void spider_db_mbase::fetch_and_print_warnings(struct tm *l_time)
{
DBUG_ENTER("spider_db_mbase::fetch_and_print_warnings");

if (spider_param_dry_access() || db_conn->status != MYSQL_STATUS_READY ||
db_conn->server_status & SERVER_MORE_RESULTS_EXISTS)
DBUG_VOID_RETURN;

if (mysql_real_query(db_conn, SPIDER_SQL_SHOW_WARNINGS_STR,
SPIDER_SQL_SHOW_WARNINGS_LEN))
DBUG_VOID_RETURN;

MYSQL_RES *res= mysql_store_result(db_conn);
if (!res)
DBUG_VOID_RETURN;

uint num_fields= mysql_num_fields(res);
if (num_fields != 3)
{
#if MYSQL_VERSION_ID < 50500
if (!(db_conn->last_used_con->server_status & SERVER_MORE_RESULTS_EXISTS))
#else
if (!(db_conn->server_status & SERVER_MORE_RESULTS_EXISTS))
#endif
{
if (
spider_param_dry_access() ||
!mysql_real_query(db_conn, SPIDER_SQL_SHOW_WARNINGS_STR,
SPIDER_SQL_SHOW_WARNINGS_LEN)
) {
MYSQL_RES *res = NULL;
MYSQL_ROW row = NULL;
uint num_fields;
if (
spider_param_dry_access() ||
!(res = mysql_store_result(db_conn)) ||
!(row = mysql_fetch_row(res))
) {
if (mysql_errno(db_conn))
{
if (res)
mysql_free_result(res);
DBUG_VOID_RETURN;
}
/* no record is ok */
}
num_fields = mysql_num_fields(res);
if (num_fields != 3)
{
mysql_free_result(res);
DBUG_VOID_RETURN;
}
while (row)
{
fprintf(stderr, "%04d%02d%02d %02d:%02d:%02d [WARN SPIDER RESULT] "
"from [%s] %ld to %ld: %s %s %s\n",
mysql_free_result(res);
DBUG_VOID_RETURN;
}

MYSQL_ROW row= mysql_fetch_row(res);
while (row)
{
fprintf(stderr,
"%04d%02d%02d %02d:%02d:%02d [WARN SPIDER RESULT] from [%s] %ld "
"to %ld: %s %s %s\n",
l_time->tm_year + 1900, l_time->tm_mon + 1, l_time->tm_mday,
l_time->tm_hour, l_time->tm_min, l_time->tm_sec,
conn->tgt_host, (ulong) db_conn->thread_id,
(ulong) current_thd->thread_id, row[0], row[1], row[2]);
row = mysql_fetch_row(res);
}
if (res)
mysql_free_result(res);
}
}
l_time->tm_hour, l_time->tm_min, l_time->tm_sec, conn->tgt_host,
(ulong) db_conn->thread_id, (ulong) current_thd->thread_id, row[0],
row[1], row[2]);
row= mysql_fetch_row(res);
}
mysql_free_result(res);

DBUG_VOID_RETURN;
}

Expand Down
4 changes: 1 addition & 3 deletions storage/spider/spd_db_mysql.h
Original file line number Diff line number Diff line change
Expand Up @@ -392,9 +392,7 @@ class spider_db_mbase: public spider_db_conn
bool is_xa_nota_error(
int error_num
);
void print_warnings(
struct tm *l_time
);
void fetch_and_print_warnings(struct tm *l_time);
spider_db_result *store_result(
spider_db_result_buffer **spider_res_buf,
st_spider_db_request_key *request_key,
Expand Down

0 comments on commit be0a46b

Please sign in to comment.