diff options
author | Nikita Malyavin <nikitamalyavin@gmail.com> | 2023-03-26 17:50:37 +0300 |
---|---|---|
committer | Nikita Malyavin <nikitamalyavin@gmail.com> | 2023-05-05 16:12:01 +0300 |
commit | 667d0eaffa1f3cc459ce7ad412b65e2bffbddf5a (patch) | |
tree | 8106100b54dcc5287331eaa064dbbb9fa9a2bee5 | |
parent | 20c104e00c007f3ef6896872237574976483141d (diff) | |
download | mariadb-git-667d0eaffa1f3cc459ce7ad412b65e2bffbddf5a.tar.gz |
MDEV-30924 Server crashes in MYSQL_LOG::is_open upon ALTER vs FUNCTION
ASAN showed use-after-free in binlog_online_alter_end_trans, during
running through thd->online_alter_cache_list.
In online_alter_binlog_get_cache_data, new_cache_data was allocated on
thd->mem_root, in case of autocommit=1, but this mem_root could be freed
in sp_head::execute, upon using stored functions.
It appears that thd->transaction->mem_root exists even in single-stmt
transaction mode (i.e autocommit=1), so it can be used in all cases.
This mem_root will remain valid till the end of transaction, including
commit phase.
-rw-r--r-- | mysql-test/main/alter_table_online_debug.result | 22 | ||||
-rw-r--r-- | mysql-test/main/alter_table_online_debug.test | 28 | ||||
-rw-r--r-- | sql/log.cc | 3 |
3 files changed, 51 insertions, 2 deletions
diff --git a/mysql-test/main/alter_table_online_debug.result b/mysql-test/main/alter_table_online_debug.result index c4c1cf67504..40a1bad7f68 100644 --- a/mysql-test/main/alter_table_online_debug.result +++ b/mysql-test/main/alter_table_online_debug.result @@ -1190,5 +1190,27 @@ set debug_sync= 'now signal goon'; connection default; drop table t; # +# MDEV-30924 Server crashes in MYSQL_LOG::is_open upon ALTER vs FUNCTION +# +create table t (a int); +insert into t values (1),(2); +create function f () returns int +begin +update t set a = 10; +return 0; +end $ +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for goon'; +alter table t force, algorithm=copy; +connection con1; +set debug_sync= 'now wait_for downgraded'; +select f(); +f() +0 +set debug_sync= 'now signal goon'; +connection default; +drop table t; +drop function f; +disconnect con1; +# # End of 10.10 tests # diff --git a/mysql-test/main/alter_table_online_debug.test b/mysql-test/main/alter_table_online_debug.test index 9e118d73996..424a69d1a47 100644 --- a/mysql-test/main/alter_table_online_debug.test +++ b/mysql-test/main/alter_table_online_debug.test @@ -1371,5 +1371,33 @@ set debug_sync= 'now signal goon'; drop table t; --echo # +--echo # MDEV-30924 Server crashes in MYSQL_LOG::is_open upon ALTER vs FUNCTION +--echo # +create table t (a int); +insert into t values (1),(2); + +--delimiter $ +create function f () returns int +begin + update t set a = 10; + return 0; +end $ +--delimiter ; + +set debug_sync= 'alter_table_online_downgraded signal downgraded wait_for goon'; +send alter table t force, algorithm=copy; + +--connection con1 +set debug_sync= 'now wait_for downgraded'; +select f(); +set debug_sync= 'now signal goon'; + +--connection default +--reap +drop table t; +drop function f; +--disconnect con1 + +--echo # --echo # End of 10.10 tests --echo # diff --git a/sql/log.cc b/sql/log.cc index 5fda1563ec6..f30ce3bcbd1 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -6422,8 +6422,7 @@ online_alter_cache_data *online_alter_binlog_get_cache_data(THD *thd, TABLE *tab return &cache; } - MEM_ROOT *root= thd->in_multi_stmt_transaction_mode() - ? &thd->transaction->mem_root : thd->mem_root; + MEM_ROOT *root= &thd->transaction->mem_root; auto *new_cache_data= binlog_setup_cache_data(root, table->s); list.push_back(*new_cache_data); |