From 6bc7aabd71103d479a1c4a6b23209acab3ca412d Mon Sep 17 00:00:00 2001 From: mariadb-PranavTiwari Date: Tue, 13 Oct 2026 16:44:11 +0530 Subject: [PATCH] MDEV-37719: mysql_create_like_table() kept a stale TABLE pointer in table->table after OR REPLACE dropped the old table 1- temporary target: drop_temporary_table() frees the old TABLE but table->table was left pointing at it, so the table->table block that picks up the new table never ran and the binlog branch dereferenced freed memory. Reset table->table after the create so the new TABLE is used. 2- locked tables: if reopen_tables() failed, the function continued into the binlog branch with the freed pointer. Leave via err: instead. Note- Remove this fix when merging into main. --- mysql-test/main/tmp_table_binlog.result | 21 +++++++++++++++++++++ mysql-test/main/tmp_table_binlog.test | 20 ++++++++++++++++++++ sql/sql_table.cc | 6 ++++++ 3 files changed, 47 insertions(+) diff --git a/mysql-test/main/tmp_table_binlog.result b/mysql-test/main/tmp_table_binlog.result index 0b69913230f..a508b785116 100644 --- a/mysql-test/main/tmp_table_binlog.result +++ b/mysql-test/main/tmp_table_binlog.result @@ -29,3 +29,24 @@ INSERT INTO t2 (c) VALUES ('b'); INSERT INTO t2 (c) VALUES ('b'); ERROR 23000: Duplicate entry 'b' for key 'PRIMARY' drop table t1,t2; +# +# MDEV-37719 use-after-free on logged CREATE OR REPLACE TEMPORARY TABLE LIKE not-logged-table +# +set binlog_format='MIXED'; +create temporary table t1 (x int); +create temporary table t2 (y int); +set create_tmp_table_binlog_formats='MIXED'; +Warnings: +Warning 1292 Truncated incorrect create_tmp_table_binlog_formats value: 'MIXED' +create or replace temporary table t2 like t1; +drop table t1, t2; +SET binlog_format='MIXED'; +CREATE TEMPORARY TABLE t1 (x INT); +CREATE TEMPORARY TABLE t2 (y INT); +SET create_tmp_table_binlog_formats='MIXED'; +Warnings: +Warning 1292 Truncated incorrect create_tmp_table_binlog_formats value: 'MIXED' +PREPARE s FROM 'CREATE OR REPLACE TEMPORARY TABLE t2 LIKE t1'; +EXECUTE s; +DEALLOCATE PREPARE s; +DROP TABLE t1, t2; diff --git a/mysql-test/main/tmp_table_binlog.test b/mysql-test/main/tmp_table_binlog.test index 79b05e078ac..96f927791dd 100644 --- a/mysql-test/main/tmp_table_binlog.test +++ b/mysql-test/main/tmp_table_binlog.test @@ -31,3 +31,23 @@ INSERT INTO t2 (c) VALUES ('b'); --error ER_DUP_ENTRY INSERT INTO t2 (c) VALUES ('b'); drop table t1,t2; + +--echo # +--echo # MDEV-37719 use-after-free on logged CREATE OR REPLACE TEMPORARY TABLE LIKE not-logged-table +--echo # + +set binlog_format='MIXED'; +create temporary table t1 (x int); +create temporary table t2 (y int); +set create_tmp_table_binlog_formats='MIXED'; +create or replace temporary table t2 like t1; +drop table t1, t2; + +SET binlog_format='MIXED'; +CREATE TEMPORARY TABLE t1 (x INT); +CREATE TEMPORARY TABLE t2 (y INT); +SET create_tmp_table_binlog_formats='MIXED'; +PREPARE s FROM 'CREATE OR REPLACE TEMPORARY TABLE t2 LIKE t1'; +EXECUTE s; +DEALLOCATE PREPARE s; +DROP TABLE t1, t2; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 6b233ea8051..5dbe41ddccd 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5948,6 +5948,10 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, do_logging= thd->log_current_statement(); if (res) goto err; + // TODO: Remove this fix when merging into main. + /* OR REPLACE of a temporary table frees the old TABLE */ + if (create_info->tmp_table()) + table->table= 0; /* Check if we are doing CREATE OR REPLACE TABLE under LOCK TABLES @@ -5965,6 +5969,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, { thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0); res= 1; // We got an error + // TODO: Remove this fix when merging into main. + goto err; } else {