Skip to content

Commit 4eb898b

Browse files
committed
MDEV-10563 Crash during shutdown in Master_info_index::any_slave_sql_running
In well defined C code, the "this" pointer is never NULL. Currently, we were potentially dereferencing a NULL pointer (master_info_index). GCC v6 removes any "if (!this)" conditions as it assumes this is always a non-null pointer. In order to prevent undefined behaviour, check the pointer before dereferencing and remove the check within member functions.
1 parent 4da2b83 commit 4eb898b

5 files changed

Lines changed: 26 additions & 19 deletions

File tree

‎sql/item_func.cc‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3942,7 +3942,7 @@ longlong Item_master_pos_wait::val_int()
39423942
longlong timeout = (arg_count>=3) ? args[2]->val_int() : 0 ;
39433943
String connection_name_buff;
39443944
LEX_STRING connection_name;
3945-
Master_info *mi;
3945+
Master_info *mi= NULL;
39463946
if (arg_count >= 4)
39473947
{
39483948
String *con;
@@ -3962,8 +3962,9 @@ longlong Item_master_pos_wait::val_int()
39623962
connection_name= thd->variables.default_master_connection;
39633963

39643964
mysql_mutex_lock(&LOCK_active_mi);
3965-
mi= master_info_index->get_master_info(&connection_name,
3966-
Sql_condition::WARN_LEVEL_WARN);
3965+
if (master_info_index) // master_info_index is set to NULL on shutdown.
3966+
mi= master_info_index->get_master_info(&connection_name,
3967+
Sql_condition::WARN_LEVEL_WARN);
39673968
mysql_mutex_unlock(&LOCK_active_mi);
39683969
if (!mi)
39693970
goto err;

‎sql/mysqld.cc‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7307,7 +7307,10 @@ static int show_slaves_running(THD *thd, SHOW_VAR *var, char *buff)
73077307
var->value= buff;
73087308
mysql_mutex_lock(&LOCK_active_mi);
73097309

7310-
*((longlong *)buff)= master_info_index->any_slave_sql_running();
7310+
if (master_info_index)
7311+
*((longlong *)buff)= master_info_index->any_slave_sql_running();
7312+
else
7313+
*((longlong *)buff)= 0;
73117314

73127315
mysql_mutex_unlock(&LOCK_active_mi);
73137316
return 0;

‎sql/rpl_mi.cc‎

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,8 +1095,6 @@ Master_info_index::get_master_info(LEX_STRING *connection_name,
10951095
connection_name->str));
10961096

10971097
mysql_mutex_assert_owner(&LOCK_active_mi);
1098-
if (!this) // master_info_index is set to NULL on server shutdown
1099-
DBUG_RETURN(NULL);
11001098

11011099
/* Make name lower case for comparison */
11021100
res= strmake(buff, connection_name->str, connection_name->length);
@@ -1250,8 +1248,6 @@ bool Master_info_index::give_error_if_slave_running()
12501248
{
12511249
DBUG_ENTER("give_error_if_slave_running");
12521250
mysql_mutex_assert_owner(&LOCK_active_mi);
1253-
if (!this) // master_info_index is set to NULL on server shutdown
1254-
DBUG_RETURN(TRUE);
12551251

12561252
for (uint i= 0; i< master_info_hash.records; ++i)
12571253
{
@@ -1282,8 +1278,7 @@ uint Master_info_index::any_slave_sql_running()
12821278
{
12831279
uint count= 0;
12841280
DBUG_ENTER("any_slave_sql_running");
1285-
if (!this) // master_info_index is set to NULL on server shutdown
1286-
DBUG_RETURN(count);
1281+
mysql_mutex_assert_owner(&LOCK_active_mi);
12871282

12881283
for (uint i= 0; i< master_info_hash.records; ++i)
12891284
{

‎sql/slave.cc‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,7 @@ int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock)
649649
mysql_mutex_unlock(log_lock);
650650
}
651651
if (opt_slave_parallel_threads > 0 &&
652+
master_info_index &&// master_info_index is set to NULL on server shutdown
652653
!master_info_index->any_slave_sql_running())
653654
rpl_parallel_inactivate_pool(&global_rpl_thread_pool);
654655
if (thread_mask & (SLAVE_IO|SLAVE_FORCE_ALL))

‎sql/sys_vars.cc‎

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1538,7 +1538,8 @@ Sys_var_gtid_slave_pos::do_check(THD *thd, set_var *var)
15381538
}
15391539

15401540
mysql_mutex_lock(&LOCK_active_mi);
1541-
running= master_info_index->give_error_if_slave_running();
1541+
running= (!master_info_index ||
1542+
master_info_index->give_error_if_slave_running());
15421543
mysql_mutex_unlock(&LOCK_active_mi);
15431544
if (running)
15441545
return true;
@@ -1578,7 +1579,7 @@ Sys_var_gtid_slave_pos::global_update(THD *thd, set_var *var)
15781579

15791580
mysql_mutex_unlock(&LOCK_global_system_variables);
15801581
mysql_mutex_lock(&LOCK_active_mi);
1581-
if (master_info_index->give_error_if_slave_running())
1582+
if (!master_info_index || master_info_index->give_error_if_slave_running())
15821583
err= true;
15831584
else
15841585
err= rpl_gtid_pos_update(thd, var->save_result.string_value.str,
@@ -1767,7 +1768,8 @@ check_slave_parallel_threads(sys_var *self, THD *thd, set_var *var)
17671768
bool running;
17681769

17691770
mysql_mutex_lock(&LOCK_active_mi);
1770-
running= master_info_index->give_error_if_slave_running();
1771+
running= (!master_info_index ||
1772+
master_info_index->give_error_if_slave_running());
17711773
mysql_mutex_unlock(&LOCK_active_mi);
17721774
if (running)
17731775
return true;
@@ -1782,7 +1784,8 @@ fix_slave_parallel_threads(sys_var *self, THD *thd, enum_var_type type)
17821784

17831785
mysql_mutex_unlock(&LOCK_global_system_variables);
17841786
mysql_mutex_lock(&LOCK_active_mi);
1785-
err= master_info_index->give_error_if_slave_running();
1787+
err= (!master_info_index ||
1788+
master_info_index->give_error_if_slave_running());
17861789
mysql_mutex_unlock(&LOCK_active_mi);
17871790
mysql_mutex_lock(&LOCK_global_system_variables);
17881791

@@ -1809,7 +1812,8 @@ check_slave_domain_parallel_threads(sys_var *self, THD *thd, set_var *var)
18091812
bool running;
18101813

18111814
mysql_mutex_lock(&LOCK_active_mi);
1812-
running= master_info_index->give_error_if_slave_running();
1815+
running= (!master_info_index ||
1816+
master_info_index->give_error_if_slave_running());
18131817
mysql_mutex_unlock(&LOCK_active_mi);
18141818
if (running)
18151819
return true;
@@ -1824,7 +1828,8 @@ fix_slave_domain_parallel_threads(sys_var *self, THD *thd, enum_var_type type)
18241828

18251829
mysql_mutex_unlock(&LOCK_global_system_variables);
18261830
mysql_mutex_lock(&LOCK_active_mi);
1827-
running= master_info_index->give_error_if_slave_running();
1831+
running= (!master_info_index ||
1832+
master_info_index->give_error_if_slave_running());
18281833
mysql_mutex_unlock(&LOCK_active_mi);
18291834
mysql_mutex_lock(&LOCK_global_system_variables);
18301835

@@ -1862,7 +1867,8 @@ check_gtid_ignore_duplicates(sys_var *self, THD *thd, set_var *var)
18621867
bool running;
18631868

18641869
mysql_mutex_lock(&LOCK_active_mi);
1865-
running= master_info_index->give_error_if_slave_running();
1870+
running= (!master_info_index ||
1871+
master_info_index->give_error_if_slave_running());
18661872
mysql_mutex_unlock(&LOCK_active_mi);
18671873
if (running)
18681874
return true;
@@ -1877,7 +1883,8 @@ fix_gtid_ignore_duplicates(sys_var *self, THD *thd, enum_var_type type)
18771883

18781884
mysql_mutex_unlock(&LOCK_global_system_variables);
18791885
mysql_mutex_lock(&LOCK_active_mi);
1880-
running= master_info_index->give_error_if_slave_running();
1886+
running= (!master_info_index ||
1887+
master_info_index->give_error_if_slave_running());
18811888
mysql_mutex_unlock(&LOCK_active_mi);
18821889
mysql_mutex_lock(&LOCK_global_system_variables);
18831890

@@ -2830,7 +2837,7 @@ Sys_var_replicate_events_marked_for_skip::global_update(THD *thd, set_var *var)
28302837

28312838
mysql_mutex_unlock(&LOCK_global_system_variables);
28322839
mysql_mutex_lock(&LOCK_active_mi);
2833-
if (!master_info_index->give_error_if_slave_running())
2840+
if (master_info_index && !master_info_index->give_error_if_slave_running())
28342841
result= Sys_var_enum::global_update(thd, var);
28352842
mysql_mutex_unlock(&LOCK_active_mi);
28362843
mysql_mutex_lock(&LOCK_global_system_variables);

0 commit comments

Comments
 (0)