diff --git a/mysql-test/suite/rpl/r/rpl_change_master_long_channel_name.result b/mysql-test/suite/rpl/r/rpl_change_master_long_channel_name.result new file mode 100644 index 0000000000000..9859c92f0f2c7 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_change_master_long_channel_name.result @@ -0,0 +1,17 @@ +include/master-slave.inc +[connection master] +connection slave; +CHANGE MASTER TO MASTER_DELAY=1 FOR CHANNEL '################################################'; +ERROR HY000: Could not initialize master info structure for '################################################'; more error messages can be found in the MariaDB error log +connection master; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +connection slave; +connection slave; +include/diff_tables.inc [master:t1, slave:t1] +CHANGE MASTER 'new_channel' TO MASTER_HOST='127.0.0.1', MASTER_PORT=1, MASTER_USER='root'; +RESET SLAVE 'new_channel' ALL; +connection master; +DROP TABLE t1; +connection slave; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_change_master_long_channel_name.test b/mysql-test/suite/rpl/t/rpl_change_master_long_channel_name.test new file mode 100644 index 0000000000000..1cb94c87f5a19 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_change_master_long_channel_name.test @@ -0,0 +1,40 @@ +# +# CHANGE MASTER ... FOR CHANNEL with a name that overflows the relay +# log file name once escaped should return an error, not crash. +# +# STEPS: +# 1. Issue CHANGE MASTER ... FOR CHANNEL with a channel name that is +# within MAX_CONNECTION_NAME, but expands past the file name +# limit once escaped into the relay log file name. +# 2. Verify the statement fails with a clean error, not a crash. +# 3. Verify the server is still usable: a normal CHANGE MASTER for a +# new, short-named channel succeeds. +# +--source include/master-slave.inc + +--connection slave +--let $channel= `SELECT REPEAT('#', 48)` +--error ER_MASTER_INFO +eval CHANGE MASTER TO MASTER_DELAY=1 FOR CHANNEL '$channel'; + +--connection master +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1); +--sync_slave_with_master + +--connection slave +--let $diff_tables= master:t1, slave:t1 +--source include/diff_tables.inc + +CHANGE MASTER 'new_channel' TO MASTER_HOST='127.0.0.1', MASTER_PORT=1, MASTER_USER='root'; +RESET SLAVE 'new_channel' ALL; + +--disable_query_log +call mtr.add_suppression("Failed when trying to open logs"); +--enable_query_log + +--connection master +DROP TABLE t1; +--sync_slave_with_master + +--source include/rpl_end.inc diff --git a/sql/log.cc b/sql/log.cc index 00544f71b17cc..a4254256cfddc 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -3871,15 +3871,15 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg, Create an index file that will hold all file names uses for logging. Add new entries to the end of it. */ - myf opt= MY_UNPACK_FILENAME; + myf opt= MY_UNPACK_FILENAME | MY_SAFE_PATH; if (!index_file_name_arg) { index_file_name_arg= log_name; // Use same basename for index file - opt= MY_UNPACK_FILENAME | MY_REPLACE_EXT; + opt= MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_SAFE_PATH; } - fn_format(index_file_name, index_file_name_arg, mysql_data_home, - ".index", opt); - if ((index_file_nr= mysql_file_open(m_key_file_log_index, + if (!fn_format(index_file_name, index_file_name_arg, mysql_data_home, + ".index", opt) || + (index_file_nr= mysql_file_open(m_key_file_log_index, index_file_name, O_RDWR | O_CREAT | O_BINARY | O_CLOEXEC, MYF(MY_WME))) < 0 || diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index 106c9047cc187..8061b643af52f 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -1483,7 +1483,8 @@ bool Master_info_index::remove_master_info(Master_info *mi, bool clear_log_files /* This code is only executed when change_master() failes to create a new master info */ // Delete any temporary relay log files that could have been created by change_master() - mi->rli.relay_log.reset_logs(current_thd, 0, (rpl_gtid*) 0, 0, 0); + if (mi->rli.relay_log.is_open()) + mi->rli.relay_log.reset_logs(current_thd, 0, (rpl_gtid*) 0, 0, 0); /* Delete master-'connection'.info */ create_logfile_name_with_suffix(tmp_name, sizeof(tmp_name),