From 3bb5c6b0c21707ed04f93fb30c654caabba69f06 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 2 Apr 2020 14:03:19 +0200 Subject: [PATCH] MDEV-22113 SIGSEGV, ASAN use-after-poison, Assertion `next_insert_id == 0' in handler::ha_external_lock if the lookup_handler is allocated on the THD's memroot, it may not live long enough to be deleted in handler::ha_external_lock() --- mysql-test/main/long_unique_bugs.result | 9 +++++++++ mysql-test/main/long_unique_bugs.test | 13 +++++++++++++ sql/handler.cc | 15 +++++++-------- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/mysql-test/main/long_unique_bugs.result b/mysql-test/main/long_unique_bugs.result index 9aca32c24eb..8fa65f74992 100644 --- a/mysql-test/main/long_unique_bugs.result +++ b/mysql-test/main/long_unique_bugs.result @@ -10,6 +10,7 @@ create temporary table tmp (a varchar(1024), b int, c int, d int, e linestring, load data infile 'load.data' into table tmp; delete from tmp; drop table t1; +drop table tmp; create table t1 (b blob) engine=innodb; alter table t1 add unique (b); alter table t1 force; @@ -270,3 +271,11 @@ ERROR 42000: Specified key was too long; max key length is 2000 bytes create table t1(a int, unique(a) using hash); #BULK insert > 100 rows (MI_MIN_ROWS_TO_DISABLE_INDEXES) drop table t1; +create temporary table tmp ( a int, b int, c blob not null, d int, e int default 0, f int, unique key (c)) engine=innodb; +create table t2 (x int); +lock table t2 write; +update tmp set c = 'foo'; +start transaction; +alter table tmp alter column a set default 8; +unlock tables; +drop table t2; diff --git a/mysql-test/main/long_unique_bugs.test b/mysql-test/main/long_unique_bugs.test index 13a4e1367a0..3019fe52d3e 100644 --- a/mysql-test/main/long_unique_bugs.test +++ b/mysql-test/main/long_unique_bugs.test @@ -18,6 +18,7 @@ delete from tmp; drop table t1; --let $datadir= `SELECT @@datadir` --remove_file $datadir/test/load.data +drop table tmp; # # MDEV-18712 InnoDB indexes are inconsistent with what defined in .frm for table after rebuilding table with index on blob @@ -340,3 +341,15 @@ while ($count) --eval $insert_stmt --enable_query_log drop table t1; + +# +# MDEV-22113 SIGSEGV, ASAN use-after-poison, Assertion `next_insert_id == 0' in handler::ha_external_lock +# +create temporary table tmp ( a int, b int, c blob not null, d int, e int default 0, f int, unique key (c)) engine=innodb; +create table t2 (x int); +lock table t2 write; +update tmp set c = 'foo'; +start transaction; +alter table tmp alter column a set default 8; +unlock tables; +drop table t2; diff --git a/sql/handler.cc b/sql/handler.cc index a3d4b676166..68344aa06d5 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -6481,14 +6481,6 @@ int handler::ha_external_lock(THD *thd, int lock_type) mysql_audit_external_lock(thd, table_share, lock_type); } - if (lock_type == F_UNLCK && lookup_handler != this) - { - lookup_handler->ha_external_lock(table->in_use, F_UNLCK); - lookup_handler->close(); - delete lookup_handler; - lookup_handler= this; - } - if (MYSQL_HANDLER_RDLOCK_DONE_ENABLED() || MYSQL_HANDLER_WRLOCK_DONE_ENABLED() || MYSQL_HANDLER_UNLOCK_DONE_ENABLED()) @@ -6540,6 +6532,13 @@ int handler::ha_reset() /* Reset information about pushed index conditions */ cancel_pushed_rowid_filter(); clear_top_table_fields(); + if (lookup_handler != this) + { + lookup_handler->ha_external_lock(table->in_use, F_UNLCK); + lookup_handler->close(); + delete lookup_handler; + lookup_handler= this; + } DBUG_RETURN(reset()); }