Commit ca33df20 authored by Nuno Carvalho's avatar Nuno Carvalho

BUG#13979418: SHOW BINLOG EVENTS MAY CRASH THE SERVER

The function mysql_show_binlog_events has a local stack variable
'LOG_INFO linfo;', which is assigned to thd->current_linfo, however
this variable goes out of scope and is destroyed before clean
thd->current_linfo.

The problem is solved by moving 'LOG_INFO linfo;' to function scope.
parent 5203d9bb
include/master-slave.inc
[connection master]
[connection slave]
SET DEBUG_SYNC= 'after_show_binlog_events SIGNAL on_show_binlog_events WAIT_FOR end';
SHOW BINLOG EVENTS;
[connection slave1]
SET DEBUG_SYNC= 'now WAIT_FOR on_show_binlog_events';
FLUSH LOGS;
SET DEBUG_SYNC= 'now SIGNAL end';
SET DEBUG_SYNC= 'RESET';
[connection slave]
SET DEBUG_SYNC= 'RESET';
include/rpl_end.inc
# BUG#13979418: SHOW BINLOG EVENTS MAY CRASH THE SERVER
#
# The function mysql_show_binlog_events has a local stack variable
# 'LOG_INFO linfo;', which is assigned to thd->current_linfo, however
# this variable goes out of scope and is destroyed before clean
# thd->current_linfo.
#
# This test case runs SHOW BINLOG EVENTS and FLUSH LOGS to make sure
# that with the fix local variable linfo is valid along all
# mysql_show_binlog_events function scope.
#
--source include/have_debug_sync.inc
--source include/master-slave.inc
--echo [connection slave]
--connection slave
SET DEBUG_SYNC= 'after_show_binlog_events SIGNAL on_show_binlog_events WAIT_FOR end';
--send SHOW BINLOG EVENTS
--connection slave1
--echo [connection slave1]
SET DEBUG_SYNC= 'now WAIT_FOR on_show_binlog_events';
FLUSH LOGS;
SET DEBUG_SYNC= 'now SIGNAL end';
SET DEBUG_SYNC= 'RESET';
--echo [connection slave]
--connection slave
--disable_result_log
--reap
--enable_result_log
SET DEBUG_SYNC= 'RESET';
--connection master
--source include/rpl_end.inc
...@@ -130,6 +130,11 @@ extern TC_LOG_DUMMY tc_log_dummy; ...@@ -130,6 +130,11 @@ extern TC_LOG_DUMMY tc_log_dummy;
class Relay_log_info; class Relay_log_info;
/*
Note that we destroy the lock mutex in the desctructor here.
This means that object instances cannot be destroyed/go out of scope,
until we have reset thd->current_linfo to NULL;
*/
typedef struct st_log_info typedef struct st_log_info
{ {
char log_file_name[FN_REFLEN]; char log_file_name[FN_REFLEN];
......
...@@ -1454,6 +1454,8 @@ bool mysql_show_binlog_events(THD* thd) ...@@ -1454,6 +1454,8 @@ bool mysql_show_binlog_events(THD* thd)
IO_CACHE log; IO_CACHE log;
File file = -1; File file = -1;
int old_max_allowed_packet= thd->variables.max_allowed_packet; int old_max_allowed_packet= thd->variables.max_allowed_packet;
LOG_INFO linfo;
DBUG_ENTER("mysql_show_binlog_events"); DBUG_ENTER("mysql_show_binlog_events");
Log_event::init_show_field_list(&field_list); Log_event::init_show_field_list(&field_list);
...@@ -1480,7 +1482,6 @@ bool mysql_show_binlog_events(THD* thd) ...@@ -1480,7 +1482,6 @@ bool mysql_show_binlog_events(THD* thd)
char search_file_name[FN_REFLEN], *name; char search_file_name[FN_REFLEN], *name;
const char *log_file_name = lex_mi->log_file_name; const char *log_file_name = lex_mi->log_file_name;
pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock(); pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock();
LOG_INFO linfo;
Log_event* ev; Log_event* ev;
unit->set_limit(thd->lex->current_select); unit->set_limit(thd->lex->current_select);
...@@ -1572,6 +1573,8 @@ bool mysql_show_binlog_events(THD* thd) ...@@ -1572,6 +1573,8 @@ bool mysql_show_binlog_events(THD* thd)
pthread_mutex_unlock(log_lock); pthread_mutex_unlock(log_lock);
} }
// Check that linfo is still on the function scope.
DEBUG_SYNC(thd, "after_show_binlog_events");
ret= FALSE; ret= FALSE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment