diff options
author | Sergei Golubchik <serg@mariadb.org> | 2017-02-20 19:53:12 +0100 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2017-02-27 12:35:10 +0100 |
commit | 955f2f036d6252b90e2bffcec521dd4a7db0a30a (patch) | |
tree | 9ebe926cffe1e80ff852ee85da7ae42b18de7c64 | |
parent | 93cb0246b8c883c4f5010468892986fa1d5ba379 (diff) | |
download | mariadb-git-955f2f036d6252b90e2bffcec521dd4a7db0a30a.tar.gz |
race-condition safe implementation of test_if_data_home_dir()
don't realpath() twice
-rw-r--r-- | sql/mysqld.cc | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 44 | ||||
-rw-r--r-- | sql/sql_parse.h | 3 |
3 files changed, 34 insertions, 15 deletions
diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 2e8a62ecb12..3d2de3126ff 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -7267,7 +7267,7 @@ static int mysql_init_variables(void) mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0; #if defined(HAVE_REALPATH) && !defined(HAVE_valgrind) && !defined(HAVE_BROKEN_REALPATH) /* We can only test for sub paths if my_symlink.c is using realpath */ - mysys_test_invalid_symlink= test_if_data_home_dir; + mysys_test_invalid_symlink= path_starts_from_data_home_dir; #endif opt_log= opt_slow_log= 0; opt_bin_log= opt_bin_log_used= 0; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 32784f6432a..c3170d04304 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7697,26 +7697,20 @@ bool check_ident_length(LEX_STRING *ident) Check if path does not contain mysql data home directory SYNOPSIS - test_if_data_home_dir() - dir directory + path_starts_from_data_home_dir() + dir directory, with all symlinks resolved RETURN VALUES 0 ok 1 error ; Given path contains data directory */ -C_MODE_START +extern "C" { -int test_if_data_home_dir(const char *dir) +int path_starts_from_data_home_dir(const char *path) { - char path[FN_REFLEN]; - int dir_len; - DBUG_ENTER("test_if_data_home_dir"); + int dir_len= strlen(path); + DBUG_ENTER("path_starts_from_data_home_dir"); - if (!dir) - DBUG_RETURN(0); - - (void) fn_format(path, dir, "", "", MY_RETURN_REAL_PATH); - dir_len= strlen(path); if (mysql_unpacked_real_data_home_len<= dir_len) { if (dir_len > mysql_unpacked_real_data_home_len && @@ -7744,7 +7738,31 @@ int test_if_data_home_dir(const char *dir) DBUG_RETURN(0); } -C_MODE_END +} + +/* + Check if path does not contain mysql data home directory + + SYNOPSIS + test_if_data_home_dir() + dir directory + + RETURN VALUES + 0 ok + 1 error ; Given path contains data directory +*/ + +int test_if_data_home_dir(const char *dir) +{ + char path[FN_REFLEN]; + DBUG_ENTER("test_if_data_home_dir"); + + if (!dir) + DBUG_RETURN(0); + + (void) fn_format(path, dir, "", "", MY_RETURN_REAL_PATH); + DBUG_RETURN(path_starts_from_data_home_dir(path)); +} /** diff --git a/sql/sql_parse.h b/sql/sql_parse.h index 66a8f6efc7d..c5ea38706c4 100644 --- a/sql/sql_parse.h +++ b/sql/sql_parse.h @@ -33,7 +33,8 @@ enum enum_mysql_completiontype { COMMIT_RELEASE=-1, COMMIT=0, COMMIT_AND_CHAIN=6 }; -extern "C" int test_if_data_home_dir(const char *dir); +extern "C" int path_starts_from_data_home_dir(const char *dir); +int test_if_data_home_dir(const char *dir); bool multi_update_precheck(THD *thd, TABLE_LIST *tables); bool multi_delete_precheck(THD *thd, TABLE_LIST *tables); |