Bug #37594 mysqld crash if if invalid basedir
Submitted: 23 Jun 2008 20:06 Modified: 10 Aug 2009 15:11
Reporter: Peter Gulutzan Email Updates:
Status: Can't repeat Impact on me:
None 
Category:MySQL Server: Backup Severity:S3 (Non-critical)
Version:6.0.6-alpha-debug / mysql-6.0-backup tree OS:Linux (SUSE 10 | 32-bit, Ubuntu 8.04 32bit)
Assigned to: Chuck Bell CPU Architecture:Any

[23 Jun 2008 20:06] Peter Gulutzan
Description:
I'm using mysql-6.0-backup.

I try to start mysqld with invalid values
for basedir or datadir.
Crash.

How to repeat:
mysqld --basedir=/
mysqld --datadir=/
[24 Jun 2008 12:41] Hartmut Holzgraefe
mysql-6.0-backup > libexec/mysqld --core-file --datadir=/
080624 14:38:30 [ERROR] Fatal error: Please read "Security" section of the manual to find out how to run mysqld as root!

080624 14:38:30 [ERROR] Aborting

safe_mutex: Trying to destroy unitialized mutex at kernel.cc, line 101
080624 14:38:30 - mysqld got signal 6 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
We will try our best to scrape up some info that will hopefully help diagnose
the problem, but since we have already crashed, something is definitely wrong
and this may fail.

key_buffer_size=0
read_buffer_size=131072
max_used_connections=0
max_threads=151
thread_count=0
connection_count=0
It is possible that mysqld could use up to 
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 329590 K
bytes of memory
Hope that's ok; if not, decrease some variables in the equation.

thd: 0x0
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
libexec/mysqld[0x84e3986]
libexec/mysqld(print_stacktrace+0xb)[0x84e39c2]
libexec/mysqld(handle_segfault+0x2cd)[0x8320b1d]
[0xb7f77420]
/lib/tls/i686/cmov/libc.so.6(abort+0x101)[0xb7c83a01]
libexec/mysqld(safe_mutex_destroy+0x4e)[0x88c2b99]
libexec/mysqld(_Z15backup_shutdownv+0x32)[0x895ab88]
libexec/mysqld[0x83224f2]
libexec/mysqld(unireg_abort+0x94)[0x83229d0]
libexec/mysqld[0x8324e6d]
libexec/mysqld(main+0x1d1)[0x832510b]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0)[0xb7c6d450]
libexec/mysqld(__gxx_personality_v0+0x3e9)[0x8239531]
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains
information that should help you find out what is causing the crash.
Writing a core file
Aborted (core dumped)
[24 Jun 2008 12:48] Hartmut Holzgraefe
Also crashes if existing, but empty, datadir is given.

Only crashes if mysqld is started without --user=... option,
if --user=... is given and the specified datadir is empty the
error message is

mysql-6.0-backup > libexec/mysqld --user=root --datadir=./emptydir/
libexec/mysqld: Table 'mysql.plugin' doesn't exist
080624 14:46:16 [ERROR] Can't open the mysql.plugin table. Please run mysql_upgr
ade to create it.
InnoDB: The first specified data file ./ibdata1 did not exist:
InnoDB: a new database to be created!
080624 14:46:16  InnoDB: Setting file ./ibdata1 size to 10 MB
InnoDB: Database physically writes the file full: wait...
080624 14:46:17  InnoDB: Log file ./ib_logfile0 did not exist: new to be created
InnoDB: Setting log file ./ib_logfile0 size to 5 MB
InnoDB: Database physically writes the file full: wait...
080624 14:46:18  InnoDB: Log file ./ib_logfile1 did not exist: new to be created
InnoDB: Setting log file ./ib_logfile1 size to 5 MB
InnoDB: Database physically writes the file full: wait...
InnoDB: Doublewrite buffer not found: creating new
InnoDB: Doublewrite buffer created
InnoDB: Creating foreign key constraint system tables
InnoDB: Foreign key constraint system tables created
080624 14:46:18  InnoDB: Started; log sequence number 0 0
080624 14:46:18 [ERROR] Fatal error: Can't open and lock privilege tables: Table
 'mysql.host' doesn't exist
080624 14:46:18 [Note] Got signal 15 to shutdown mysqld

If giving a nonexistent dir the --user option doesn't matter though, 

  libexec/mysqld --user=root --datadir=./nosuchdir/

will still crash
[24 Jun 2008 15:10] Hartmut Holzgraefe
only mysql-6.0-backup seems to be affected, regular mysql-6.0 build from today doesn't crash on this
[24 Jun 2008 15:16] Hartmut Holzgraefe
GDB backtrace:

Core was generated by `libexec/mysqld --core-file --debug --datadir=./emptydir/'.
Program terminated with signal 6, Aborted.
[New process 23175]
#0  0xb7f04410 in __kernel_vsyscall ()
(gdb) bt full
#0  0xb7f04410 in __kernel_vsyscall ()
No symbol table info available.
#1  0xb7ebfae7 in pthread_kill () from /lib/tls/i686/cmov/libpthread.so.0
No symbol table info available.
#2  0x084e39f3 in write_core (sig=6) at stacktrace.c:302
No locals.
#3  0x08320d4a in handle_segfault (sig=6) at mysqld.cc:2651
        curr_time = 1214320505
        tm = {tm_sec = 5, tm_min = 15, tm_hour = 17, tm_mday = 24, tm_mon = 5, tm_year = 108, 
  tm_wday = 2, tm_yday = 175, tm_isdst = 1, tm_gmtoff = 7200, tm_zone = 0x8d8d428 "CEST"}
        thd = (class THD *) 0x0
#4  <signal handler called>
No symbol table info available.
#5  0xb7f04410 in __kernel_vsyscall ()
No symbol table info available.
#6  0xb7c0f085 in raise () from /lib/tls/i686/cmov/libc.so.6
No symbol table info available.
#7  0xb7c10a01 in abort () from /lib/tls/i686/cmov/libc.so.6
No symbol table info available.
#8  0x088c2b99 in safe_mutex_destroy (mp=0x8d8a7c0, file=0x8ad8bb9 "kernel.cc", line=101)
    at thr_mutex.c:308
        error = 0
#9  0x0895ab88 in backup_shutdown () at kernel.cc:101
No locals.
#10 0x083224f2 in clean_up (print_message=true) at mysqld.cc:1341
No locals.
#11 0x083229d0 in unireg_abort (exit_code=1) at mysqld.cc:1277
        _db_func_ = 0x89c7317 "fix_slave_exec_mode"
        _db_file_ = 0x89c7049 "set_var.cc"
        _db_level_ = 2
        _db_framep_ = (char **) 0x2
#12 0x08324e6d in check_user (user=0x0) at mysqld.cc:1565
        tmp_user_info = (passwd *) 0xb7d2eff4
        user_id = 0
#13 0x0832510b in main (argc=4, argv=0xbf903974) at mysqld.cc:4422
        stack_size = 196608
[24 Jun 2008 15:17] Hartmut Holzgraefe
--debug tracefile

Attachment: mysqld.trace (application/octet-stream, text), 0 bytes.

[19 Nov 2008 13:51] MySQL Verification Team
Bug: http://bugs.mysql.com/bug.php?id=40853 has been marked as duplicate of this one.
[2 Jan 2009 21:28] MySQL Verification Team
See bug: http://bugs.mysql.com/bug.php?id=41832.
[7 Jul 2009 14:47] Rafal Somla
At first glance looks like backup_shutdown() is called without prior backup_init() call. However these functions are protected against such scenario.  Here is the code (from sql/backup/kernel.cc):

int backup_init()
{
  pthread_mutex_init(&Backup_restore_ctx::run_lock, MY_MUTEX_INIT_FAST);
  Backup_restore_ctx::run_lock_initialized= TRUE;
  return 0;
}

void backup_shutdown()
{
  if (Backup_restore_ctx::run_lock_initialized)
  {
    pthread_mutex_destroy(&Backup_restore_ctx::run_lock);
    Backup_restore_ctx::run_lock_initialized= FALSE;
  }
}

Backup_restore_ctx::run_lock_initialized is a static boolean flag initially set to FALSE. So it seems that backup_init() was called after all. Then the only reason for the failure I can come up with is that pthread_mutex_init() in backup_init() failed to initialize the mutex and then backup_shutdown() calls pthread_mutex_destroy() on invalid mutex instance.

Suggested fix:

In backup_init() check result of pthread_mutex_init() and set run_lock_initialized accordingly.
[10 Aug 2009 15:11] Chuck Bell
Cannot repeat crash with test case provided in current mysql-6.0-backup tree.

Tested on Windows - server failed to start with appropriate error messages.
Tested on Linux - server failed to start with appropriate error messages.

No crash, no core dump. Problem no longer exists.