Commit 8d7af8f0 authored by unknown's avatar unknown

BUG#30752 rpl_dual_pos_advance valgrind (jump depends on uninitialized LOG_INFO)

Problem: one thread could read uninitialized memory from (the stack of) another
thread.
Fix: swapped order of initializing the memory and making it available to the
other thread.
Fix: put lock around the statement that makes the memory available to the other
thread.
Fix: all fields of the struct are now initialized in the constructor, to avoid
future problems.


sql/sql_class.h:
  Initialize all members in constructor for more safe future code.
sql/sql_repl.cc:
  Swap order so that linfo is first initialized, then assigned, instead of the
  other way around.
  Put a lock around the assignment. We use LOCK_thread_count since log_in_use
  uses it: log_in_use may be running concurrently, called from
  MYSQL_LOG::purge_logs.
parent 56fe8fc4
...@@ -159,7 +159,13 @@ typedef struct st_log_info ...@@ -159,7 +159,13 @@ typedef struct st_log_info
my_off_t pos; my_off_t pos;
bool fatal; // if the purge happens to give us a negative offset bool fatal; // if the purge happens to give us a negative offset
pthread_mutex_t lock; pthread_mutex_t lock;
st_log_info():fatal(0) { pthread_mutex_init(&lock, MY_MUTEX_INIT_FAST);} st_log_info()
: index_file_offset(0), index_file_start_offset(0),
pos(0), fatal(0)
{
log_file_name[0] = '\0';
pthread_mutex_init(&lock, MY_MUTEX_INIT_FAST);
}
~st_log_info() { pthread_mutex_destroy(&lock);} ~st_log_info() { pthread_mutex_destroy(&lock);}
} LOG_INFO; } LOG_INFO;
......
...@@ -364,7 +364,6 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, ...@@ -364,7 +364,6 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos,
name=0; // Find first log name=0; // Find first log
linfo.index_file_offset = 0; linfo.index_file_offset = 0;
thd->current_linfo = &linfo;
if (mysql_bin_log.find_log_pos(&linfo, name, 1)) if (mysql_bin_log.find_log_pos(&linfo, name, 1))
{ {
...@@ -373,6 +372,10 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, ...@@ -373,6 +372,10 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos,
goto err; goto err;
} }
pthread_mutex_lock(&LOCK_thread_count);
thd->current_linfo = &linfo;
pthread_mutex_unlock(&LOCK_thread_count);
if ((file=open_binlog(&log, log_file_name, &errmsg)) < 0) if ((file=open_binlog(&log, log_file_name, &errmsg)) < 0)
{ {
my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG; my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
...@@ -1338,7 +1341,6 @@ bool mysql_show_binlog_events(THD* thd) ...@@ -1338,7 +1341,6 @@ bool mysql_show_binlog_events(THD* thd)
name=0; // Find first log name=0; // Find first log
linfo.index_file_offset = 0; linfo.index_file_offset = 0;
thd->current_linfo = &linfo;
if (mysql_bin_log.find_log_pos(&linfo, name, 1)) if (mysql_bin_log.find_log_pos(&linfo, name, 1))
{ {
...@@ -1346,6 +1348,10 @@ bool mysql_show_binlog_events(THD* thd) ...@@ -1346,6 +1348,10 @@ bool mysql_show_binlog_events(THD* thd)
goto err; goto err;
} }
pthread_mutex_lock(&LOCK_thread_count);
thd->current_linfo = &linfo;
pthread_mutex_unlock(&LOCK_thread_count);
if ((file=open_binlog(&log, linfo.log_file_name, &errmsg)) < 0) if ((file=open_binlog(&log, linfo.log_file_name, &errmsg)) < 0)
goto err; goto err;
......
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