mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
MDEV-40324 use-of-uninitialized-value after creation of FULLTEXT table failure
Problem: ======= For fulltext index, row_create_index_for_mysql() calls fts_create_index_tables(). If creating FTS auxiliary table fails, error handling performs trx->rollback() of the dictionary transaction. Rollback removes the parent table from dictionary cache and frees it. After that, convert_error_code_to_mysql() reads table->flags after table->heap. This leads to read of freed memory. Solution: ======== create_index(): Read table->flags into a local variable before calling row_create_index_for_mysql()
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
--- misc_debug.result
|
||||
+++ misc_debug.reject
|
||||
+++ misc_debug,vers.result
|
||||
@@ -7,14 +7,14 @@
|
||||
SET @saved_debug_dbug = @@SESSION.debug_dbug;
|
||||
SET SESSION debug_dbug="+d,ib_dict_create_index_tree_fail";
|
||||
@@ -51,7 +51,7 @@
|
||||
# MDEV-25663 Double free of transaction during TRUNCATE
|
||||
#
|
||||
call mtr.add_suppression("InnoDB: \\(Too many concurrent transactions\\)");
|
||||
@@ -65,12 +39,3 @@
|
||||
@@ -65,15 +39,6 @@
|
||||
SET debug_dbug=@saved_debug_dbug;
|
||||
DROP TABLE t1;
|
||||
# End of 10.3 tests
|
||||
@@ -64,3 +64,6 @@
|
||||
-ALTER TABLE t1 ADD FULLTEXT(f2);
|
||||
-ERROR HY000: Tablespace has been discarded for table `t1`
|
||||
-DROP TABLE t1;
|
||||
#
|
||||
# MDEV-40324 use-of-uninitialized-value after creation of
|
||||
# FULLTEXT table failure
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
--- misc_debug.result
|
||||
+++ misc_debug.reject
|
||||
+++ misc_debug,vers_trx.result
|
||||
@@ -7,14 +7,14 @@
|
||||
SET @saved_debug_dbug = @@SESSION.debug_dbug;
|
||||
SET SESSION debug_dbug="+d,ib_dict_create_index_tree_fail";
|
||||
@@ -51,7 +51,7 @@
|
||||
# MDEV-25663 Double free of transaction during TRUNCATE
|
||||
#
|
||||
call mtr.add_suppression("InnoDB: \\(Too many concurrent transactions\\)");
|
||||
@@ -65,12 +39,3 @@
|
||||
@@ -65,15 +39,6 @@
|
||||
SET debug_dbug=@saved_debug_dbug;
|
||||
DROP TABLE t1;
|
||||
# End of 10.3 tests
|
||||
@@ -64,3 +64,6 @@
|
||||
-ALTER TABLE t1 ADD FULLTEXT(f2);
|
||||
-ERROR HY000: Tablespace has been discarded for table `t1`
|
||||
-DROP TABLE t1;
|
||||
#
|
||||
# MDEV-40324 use-of-uninitialized-value after creation of
|
||||
# FULLTEXT table failure
|
||||
|
||||
@@ -74,3 +74,11 @@ ALTER TABLE t1 DISCARD TABLESPACE;
|
||||
ALTER TABLE t1 ADD FULLTEXT(f2);
|
||||
ERROR HY000: Tablespace has been discarded for table `t1`
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MDEV-40324 use-of-uninitialized-value after creation of
|
||||
# FULLTEXT table failure
|
||||
#
|
||||
call mtr.add_suppression("InnoDB: Failed to create FTS index table");
|
||||
SET STATEMENT DEBUG_DBUG="+d,fts_index_table_fail" FOR
|
||||
CREATE TABLE t1(f1 TEXT, FULLTEXT(f1))ENGINE=InnoDB;
|
||||
ERROR HY000: Can't create table `test`.`t1` (errno: 168 "Unknown (generic) error from engine")
|
||||
|
||||
@@ -131,3 +131,12 @@ ALTER TABLE t1 DISCARD TABLESPACE;
|
||||
ALTER TABLE t1 ADD FULLTEXT(f2);
|
||||
DROP TABLE t1;
|
||||
}
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-40324 use-of-uninitialized-value after creation of
|
||||
--echo # FULLTEXT table failure
|
||||
--echo #
|
||||
call mtr.add_suppression("InnoDB: Failed to create FTS index table");
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
SET STATEMENT DEBUG_DBUG="+d,fts_index_table_fail" FOR
|
||||
CREATE TABLE t1(f1 TEXT, FULLTEXT(f1))ENGINE=InnoDB;
|
||||
|
||||
@@ -2040,6 +2040,10 @@ fts_create_one_index_table(
|
||||
dict_table_add_system_columns(new_table, heap);
|
||||
error = row_create_table_for_mysql(new_table, trx);
|
||||
|
||||
DBUG_EXECUTE_IF("fts_index_table_fail",
|
||||
trx->rollback();
|
||||
error = DB_FAIL;);
|
||||
|
||||
if (error == DB_SUCCESS) {
|
||||
dict_index_t* index = dict_mem_index_create(
|
||||
new_table, "FTS_INDEX_TABLE_IND",
|
||||
|
||||
@@ -11063,12 +11063,16 @@ create_index(
|
||||
& HA_REVERSE_SORT);
|
||||
}
|
||||
|
||||
/* On failure, row_create_index_for_mysql() may roll
|
||||
back the dictionary transaction, which will remove
|
||||
the table from the cache and free it. */
|
||||
const ulint table_flags = table->flags;
|
||||
DBUG_RETURN(convert_error_code_to_mysql(
|
||||
row_create_index_for_mysql(
|
||||
index, trx, NULL,
|
||||
fil_encryption_t(o.encryption),
|
||||
uint32_t(o.encryption_key_id)),
|
||||
table->flags, NULL));
|
||||
table_flags, NULL));
|
||||
}
|
||||
|
||||
ulint ind_type = 0;
|
||||
|
||||
Reference in New Issue
Block a user