Commit e06c0298 authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-15465 Server crash or ASAN heap-use-after-free in...

MDEV-15465 Server crash or ASAN heap-use-after-free in Item_func_match::cleanup upon using FT search with partitioning.

Partition engine FT keys are implemented in such a way that
the FT function's cleanup() methods use table's internals.
So calling them after close_thread_tables is unsafe.
parent a0048378
...@@ -61,3 +61,28 @@ connection default; ...@@ -61,3 +61,28 @@ connection default;
disconnect con2; disconnect con2;
disconnect con3; disconnect con3;
DROP TABLE tbl_with_partitions; DROP TABLE tbl_with_partitions;
#
# MDEV-15465 Server crash or ASAN heap-use-after-free in Item_func_match::cleanup
# upon using FT search with partitioning.
#
connect con1,localhost,root,,test;
CREATE OR REPLACE TABLE t1 (c CHAR(8)) ENGINE=MyISAM PARTITION BY KEY(c);
connection default;
set debug_sync= 'execute_command_after_close_tables SIGNAL opened WAIT_FOR go';
DELETE FROM t1 WHERE MATCH(c) AGAINST ('foo' IN BOOLEAN MODE);
connection con1;
set debug_sync= 'now WAIT_FOR opened';
FLUSH TABLES;
set debug_sync= 'now SIGNAL go';
connection default;
set debug_sync= 'execute_command_after_close_tables SIGNAL opened WAIT_FOR go';
SELECT * FROM t1 WHERE MATCH(c) AGAINST ('foo' IN BOOLEAN MODE);
connection con1;
set debug_sync= 'now WAIT_FOR opened';
FLUSH TABLES;
set debug_sync= 'now SIGNAL go';
disconnect con1;
connection default;
c
DROP TABLE t1;
set debug_sync= 'RESET';
...@@ -77,6 +77,42 @@ disconnect con2; ...@@ -77,6 +77,42 @@ disconnect con2;
disconnect con3; disconnect con3;
DROP TABLE tbl_with_partitions; DROP TABLE tbl_with_partitions;
--echo #
--echo # MDEV-15465 Server crash or ASAN heap-use-after-free in Item_func_match::cleanup
--echo # upon using FT search with partitioning.
--echo #
--connect (con1,localhost,root,,test)
CREATE OR REPLACE TABLE t1 (c CHAR(8)) ENGINE=MyISAM PARTITION BY KEY(c);
--connection default
set debug_sync= 'execute_command_after_close_tables SIGNAL opened WAIT_FOR go';
--send
DELETE FROM t1 WHERE MATCH(c) AGAINST ('foo' IN BOOLEAN MODE);
--connection con1
set debug_sync= 'now WAIT_FOR opened';
FLUSH TABLES;
set debug_sync= 'now SIGNAL go';
--connection default
--reap
set debug_sync= 'execute_command_after_close_tables SIGNAL opened WAIT_FOR go';
--send
SELECT * FROM t1 WHERE MATCH(c) AGAINST ('foo' IN BOOLEAN MODE);
--connection con1
set debug_sync= 'now WAIT_FOR opened';
FLUSH TABLES;
set debug_sync= 'now SIGNAL go';
# Cleanup
--disconnect con1
--connection default
--reap
DROP TABLE t1;
set debug_sync= 'RESET';
# Check that all connections opened by test cases in this file are really # Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence. # gone so execution of other tests won't be affected by their presence.
......
...@@ -8639,6 +8639,19 @@ int setup_ftfuncs(SELECT_LEX *select_lex) ...@@ -8639,6 +8639,19 @@ int setup_ftfuncs(SELECT_LEX *select_lex)
} }
void cleanup_ftfuncs(SELECT_LEX *select_lex)
{
List_iterator<Item_func_match> li(*(select_lex->ftfunc_list)),
lj(*(select_lex->ftfunc_list));
Item_func_match *ftf;
while ((ftf=li++))
{
ftf->cleanup();
}
}
int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order) int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order)
{ {
if (select_lex->ftfunc_list->elements) if (select_lex->ftfunc_list->elements)
......
...@@ -216,6 +216,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves, ...@@ -216,6 +216,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
COND **conds); COND **conds);
void wrap_ident(THD *thd, Item **conds); void wrap_ident(THD *thd, Item **conds);
int setup_ftfuncs(SELECT_LEX* select); int setup_ftfuncs(SELECT_LEX* select);
void cleanup_ftfuncs(SELECT_LEX *select_lex);
int init_ftfuncs(THD *thd, SELECT_LEX* select, bool no_order); int init_ftfuncs(THD *thd, SELECT_LEX* select, bool no_order);
bool lock_table_names(THD *thd, const DDL_options_st &options, bool lock_table_names(THD *thd, const DDL_options_st &options,
TABLE_LIST *table_list, TABLE_LIST *table_list,
......
...@@ -1916,6 +1916,7 @@ bool st_select_lex::cleanup() ...@@ -1916,6 +1916,7 @@ bool st_select_lex::cleanup()
cleanup_order(order_list.first); cleanup_order(order_list.first);
cleanup_order(group_list.first); cleanup_order(group_list.first);
cleanup_ftfuncs(this);
if (join) if (join)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment