From 179424db5ffd7f65e49dce9746177db6ad3234a6 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 4 Sep 2023 14:12:12 +0400 Subject: [PATCH] MDEV-32025 Crashes in MDL_key::mdl_key_init with lower-case-table-names=2 Backporting a part of MDEV-32026 (which also fixed MDEV-32025 in 11.3) from 11.3 to 10.4. The reported crash happened with --lower-case-table-names=2 on statements like: ALTER DATABASE Db1 DEFAULT CHARACTER SET utf8; ALTER DATABASE `#mysql50#D+b1` UPGRADE DATA DIRECTORY NAME; lock_schema_name() expects a normalized database name and assert if a non-normalized name comes. mysql_alter_db_internal() and mysql_upgrade_db() get a non-normalized database name in the parameter. Fixing them to normalize the database name before passing it to lock_schema_name(). --- mysql-test/main/lowercase_table2.result | 21 +++++++++++++++++++++ mysql-test/main/lowercase_table2.test | 18 +++++++++++++++++- sql/sql_db.cc | 11 +++++++++-- 3 files changed, 47 insertions(+), 3 deletions(-) mode change 100644 => 100755 mysql-test/main/lowercase_table2.result diff --git a/mysql-test/main/lowercase_table2.result b/mysql-test/main/lowercase_table2.result old mode 100644 new mode 100755 index fe06fb671a2..039e87b90ae --- a/mysql-test/main/lowercase_table2.result +++ b/mysql-test/main/lowercase_table2.result @@ -358,3 +358,24 @@ disconnect conn1; drop user 'mysqltest_1'@'localhost'; drop tables a, B; drop database db1; +# +# MDEV-32025 Crashes in MDL_key::mdl_key_init with lower-case-table-names=2 +# +CREATE DATABASE `#mysql50#D+b1`; +ALTER DATABASE `#mysql50#D+b1` UPGRADE DATA DIRECTORY NAME; +SHOW CREATE DATABASE `D+b1`; +Database Create Database +D+b1 CREATE DATABASE `D+b1` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */ +SHOW CREATE DATABASE `d+b1`; +Database Create Database +d+b1 CREATE DATABASE `d+b1` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */ +DROP DATABASE `D+b1`; +CREATE DATABASE Db1; +ALTER DATABASE Db1 DEFAULT CHARACTER SET utf8; +SHOW CREATE DATABASE Db1; +Database Create Database +Db1 CREATE DATABASE `Db1` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci */ +SHOW CREATE DATABASE db1; +Database Create Database +db1 CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci */ +DROP DATABASE Db1; diff --git a/mysql-test/main/lowercase_table2.test b/mysql-test/main/lowercase_table2.test index 82c07bf9345..791119c0f7b 100644 --- a/mysql-test/main/lowercase_table2.test +++ b/mysql-test/main/lowercase_table2.test @@ -313,4 +313,20 @@ connection default; disconnect conn1; drop user 'mysqltest_1'@'localhost'; drop tables a, B; -drop database db1; \ No newline at end of file +drop database db1; + +--echo # +--echo # MDEV-32025 Crashes in MDL_key::mdl_key_init with lower-case-table-names=2 +--echo # + +CREATE DATABASE `#mysql50#D+b1`; +ALTER DATABASE `#mysql50#D+b1` UPGRADE DATA DIRECTORY NAME; +SHOW CREATE DATABASE `D+b1`; +SHOW CREATE DATABASE `d+b1`; +DROP DATABASE `D+b1`; + +CREATE DATABASE Db1; +ALTER DATABASE Db1 DEFAULT CHARACTER SET utf8; +SHOW CREATE DATABASE Db1; +SHOW CREATE DATABASE db1; +DROP DATABASE Db1; diff --git a/sql/sql_db.cc b/sql/sql_db.cc index b2b591464f7..5ef2e186ff2 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -715,7 +715,10 @@ mysql_alter_db_internal(THD *thd, const LEX_CSTRING *db, int error= 0; DBUG_ENTER("mysql_alter_db"); - if (lock_schema_name(thd, db->str)) + char dbnorm_buffer[SAFE_NAME_LEN + 1]; + const char *dbnorm= normalize_db_name(db->str, dbnorm_buffer, + sizeof(dbnorm_buffer)); + if (lock_schema_name(thd, dbnorm)) DBUG_RETURN(TRUE); /* @@ -1686,8 +1689,12 @@ bool mysql_upgrade_db(THD *thd, const LEX_CSTRING *old_db) new_db.str= old_db->str + MYSQL50_TABLE_NAME_PREFIX_LENGTH; new_db.length= old_db->length - MYSQL50_TABLE_NAME_PREFIX_LENGTH; + char dbnorm_buffer_old[SAFE_NAME_LEN + 1]; + const char *old_dbnorm= normalize_db_name(old_db->str, dbnorm_buffer_old, + sizeof(dbnorm_buffer_old)); + /* Lock the old name, the new name will be locked by mysql_create_db().*/ - if (lock_schema_name(thd, old_db->str)) + if (lock_schema_name(thd, old_dbnorm)) DBUG_RETURN(1); /*