Bug #95294 non-existent log_bin dir cause mysqld SIGSEGV crash at startup
Submitted: 8 May 2019 11:39 Modified: 8 May 2019 12:15
Reporter: Fungo Wang (OCA) Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Replication Severity:S3 (Non-critical)
Version:5.6, 5.7, 8.0, 5.6.44, 5.7.26 OS:Any
Assigned to: CPU Architecture:Any

[8 May 2019 11:39] Fungo Wang
Description:
A crash bug spotted while playing with log_bin configuration.

If give --log-bin a non-existed directory, mysqld will crash with signal SIGSEGV at start up, stack as bellow (with 8.0.13):

```
#0  0x00007f5c3ec2e97c in pthread_kill () from /lib64/libpthread.so.0                                                                                                                                                                                          
#1  0x00000000054398c3 in my_write_core (sig=11) at /Projects/mysql-server-8/mysys/stacktrace.cc:278                                                                                                                                          
#2  0x0000000002f4bc03 in handle_fatal_signal (sig=11) at /Projects/mysql-server-8/sql/signal_handler.cc:249
#3  <signal handler called>            
#4  0x00000000031a0334 in ER_THD (thd=0x0, mysql_errno=1098) at /Projects/mysql-server-8/sql/derror.cc:103
#5  0x0000000004c3a65d in MYSQL_BIN_LOG::generate_new_name (this=0xadf46a0 <mysql_bin_log>, new_name=0xadf46e0 <mysql_bin_log+64> "/Projects/mysql-server-8/mysql-test/var/not_exsit_dir/mysql-bin.1", log_name=0xc0ccd30 "/Projects/mysql-server-8/mysql-test/var/not_exsit_dir/mysql-bin", new_index_number=0) at /Projects/mysql-server-8/sql/binlog.cc:3380
#6  0x0000000004c3ac83 in MYSQL_BIN_LOG::init_and_set_log_file_name (this=0xadf46a0 <mysql_bin_log>, log_name=0xc0ccd30 "/Projects/mysql-server-8/mysql-test/var/not_exsit_dir/mysql-bin", new_name=0x0, new_index_number=0) at /Projects/mysql-server-8/sql/binlog.cc:3420
#7  0x0000000004c438db in MYSQL_BIN_LOG::open_binlog (this=0xadf46a0 <mysql_bin_log>, log_name=0xc0ccd30 "/Projects/mysql-server-8/mysql-test/var/not_exsit_dir/mysql-bin", new_name=0x0, max_size_arg=1073741824, null_created_arg=false, need_lock_index=true, need_sid_lock=true, extra_description_event=0x0, new_index_number=0) at /Projects/mysql-server-8/sql/binlog.cc:4521
#8  0x000000000291f9e6 in init_server_components () at /Projects/mysql-server-8/sql/mysqld.cc:5489
#9  0x000000000292658a in mysqld_main (argc=69, argv=0xbf90988) at /Projects/mysql-server-8/sql/mysqld.cc:6143
#10 0x00000000028fad29 in main (argc=8, argv=0x7fff5bf82b18) at /Projects/mysql-server-8/sql/main.cc:30
```

How to repeat:
testcase:
cat t/fungo.test
select 1;

with options:
cat t/fungo-master.opt
--log-bin=$MYSQLTEST_VARDIR/not_exsit_dir/mysql-bin  --log_bin-index=master-log-bin.index

Suggested fix:
```
3375int MYSQL_BIN_LOG::generate_new_name(char *new_name, const char *log_name,
3376                                     uint32 new_index_number) {
3377  fn_format(new_name, log_name, mysql_data_home, "", 4);
3378  if (!fn_ext(log_name)[0]) {
3379    if (find_uniq_filename(new_name, new_index_number)) {
3380      my_printf_error(ER_NO_UNIQUE_LOGFILE,
3381                      ER_THD(current_thd, ER_NO_UNIQUE_LOGFILE),
3382                      MYF(ME_FATALERROR), log_name);
3383      LogErr(ERROR_LEVEL, ER_FAILED_TO_GENERATE_UNIQUE_LOGFILE, log_name);
3384      return 1;
3385    }
3386  }
3387  return 0;
3388}
```

In the initialization thread, current_thd is not set and invalid.

 A simple fix could be change ER_THD to ER_DEFAULT

diff --git a/sql/binlog.cc b/sql/binlog.cc
index a3a6bf51a11..14b77663dfe 100644
--- a/sql/binlog.cc
+++ b/sql/binlog.cc
@@ -3378,7 +3378,7 @@ int MYSQL_BIN_LOG::generate_new_name(char *new_name, const char *log_name,
   if (!fn_ext(log_name)[0]) {
     if (find_uniq_filename(new_name, new_index_number)) {
       my_printf_error(ER_NO_UNIQUE_LOGFILE,
-                      ER_THD(current_thd, ER_NO_UNIQUE_LOGFILE),
+                      ER_DEFAULT(ER_NO_UNIQUE_LOGFILE),
                       MYF(ME_FATALERROR), log_name);
       LogErr(ERROR_LEVEL, ER_FAILED_TO_GENERATE_UNIQUE_LOGFILE, log_name);
       return 1;
[8 May 2019 12:15] MySQL Verification Team
Hello Fungo Wang,

Thank you for the report and test case.
Observed with 5.6.44, 5.7.26.

regards,
Umesh
[10 May 2019 12:09] Erlend Dahl
Direct repro w/o test case file:

./mtr --mem --mysqld=--log-bin=/does/not/exist/mysql-bin --mysqld=--log_bin_index=master-log-bin.index 1st

8.0 reports:

2019-05-10T12:07:19.615370Z 0 [ERROR] [MY-010905] [Server] Can't generate a unique log-filename /does/not/exist/mysql-bin.(1-999).
2019-05-10T12:07:19.615398Z 0 [ERROR] [MY-010822] [Server] MYSQL_BIN_LOG::open failed to generate new file name.
2019-05-10T12:07:19.615995Z 0 [ERROR] [MY-010119] [Server] Aborting