From 5bacb0969db974af7eac60f7e56f6557d8a56102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 15 Jan 2025 09:44:30 +0200 Subject: [PATCH] MDEV-35852 : ASAN heap-use-after-free in WSREP_DEBUG after INSERT DELAYED Problem was that in case of INSERT DELAYED thd->query() is freed before we call trans_rollback where WSREP_DEBUG could access thd->query() in wsrep_thd_query(). Fix is to reset thd->query() to NULL in delayed_insert destructor after it is freed. There is already null guard at wsrep_thd_query(). --- mysql-test/suite/galera/r/MDEV-35852.result | 8 ++++++++ mysql-test/suite/galera/t/MDEV-35852.cnf | 4 ++++ mysql-test/suite/galera/t/MDEV-35852.test | 9 +++++++++ sql/handler.cc | 13 ++++++++----- sql/service_wsrep.cc | 4 +++- sql/sql_insert.cc | 1 + 6 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 mysql-test/suite/galera/r/MDEV-35852.result create mode 100644 mysql-test/suite/galera/t/MDEV-35852.cnf create mode 100644 mysql-test/suite/galera/t/MDEV-35852.test diff --git a/mysql-test/suite/galera/r/MDEV-35852.result b/mysql-test/suite/galera/r/MDEV-35852.result new file mode 100644 index 0000000000000..f9d07043cf950 --- /dev/null +++ b/mysql-test/suite/galera/r/MDEV-35852.result @@ -0,0 +1,8 @@ +connection node_2; +connection node_1; +CREATE TABLE t (a INT) ENGINE=InnoDB; +INSERT DELAYED INTO t VALUES (); +ERROR HY000: DELAYED option not supported for table 't' +DROP TABLE t; +INSERT DELAYED t1 () VALUES (); +ERROR 42S02: Table 'test.t1' doesn't exist diff --git a/mysql-test/suite/galera/t/MDEV-35852.cnf b/mysql-test/suite/galera/t/MDEV-35852.cnf new file mode 100644 index 0000000000000..ebd79612b8180 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-35852.cnf @@ -0,0 +1,4 @@ +!include ../galera_2nodes.cnf + +[mysqld] +wsrep-debug=1 diff --git a/mysql-test/suite/galera/t/MDEV-35852.test b/mysql-test/suite/galera/t/MDEV-35852.test new file mode 100644 index 0000000000000..6dce2974dd431 --- /dev/null +++ b/mysql-test/suite/galera/t/MDEV-35852.test @@ -0,0 +1,9 @@ +--source include/galera_cluster.inc + +CREATE TABLE t (a INT) ENGINE=InnoDB; +--error ER_DELAYED_NOT_SUPPORTED +INSERT DELAYED INTO t VALUES (); +DROP TABLE t; + +--error ER_NO_SUCH_TABLE +INSERT DELAYED t1 () VALUES (); diff --git a/sql/handler.cc b/sql/handler.cc index 286f65db1aec1..3cdcbecccce8d 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2286,8 +2286,10 @@ int ha_rollback_trans(THD *thd, bool all) my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err); error=1; #ifdef WITH_WSREP - WSREP_WARN("handlerton rollback failed, thd %lld %lld conf %d SQL %s", + WSREP_WARN("handlerton rollback failed, thd %lld %lld " + "conf %d wsrep_err %s SQL %s", thd->thread_id, thd->query_id, thd->wsrep_trx().state(), + wsrep::to_c_string(thd->wsrep_cs().current_error()), thd->query()); #endif /* WITH_WSREP */ } @@ -2300,11 +2302,12 @@ int ha_rollback_trans(THD *thd, bool all) } #ifdef WITH_WSREP - if (thd->is_error()) + if (WSREP(thd) && thd->is_error()) { - WSREP_DEBUG("ha_rollback_trans(%lld, %s) rolled back: %s: %s; is_real %d", - thd->thread_id, all?"TRUE":"FALSE", wsrep_thd_query(thd), - thd->get_stmt_da()->message(), is_real_trans); + WSREP_DEBUG("ha_rollback_trans(%lld, %s) rolled back: msg %s is_real %d wsrep_err %s", + thd->thread_id, all? "TRUE" : "FALSE", + thd->get_stmt_da()->message(), is_real_trans, + wsrep::to_c_string(thd->wsrep_cs().current_error())); } // REPLACE|INSERT INTO ... SELECT uses TOI in consistency check diff --git a/sql/service_wsrep.cc b/sql/service_wsrep.cc index d58a05b3eb54e..42b63db3491fa 100644 --- a/sql/service_wsrep.cc +++ b/sql/service_wsrep.cc @@ -1,4 +1,4 @@ -/* Copyright 2018-2024 Codership Oy +/* Copyright 2018-2025 Codership Oy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -86,7 +86,9 @@ extern "C" const char *wsrep_thd_query(const THD *thd) return "SET PASSWORD"; /* fallthrough */ default: + { return (thd->query() ? thd->query() : "NULL"); + } } return "NULL"; } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 854359dbbac57..c799f1eb02c31 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2433,6 +2433,7 @@ class Delayed_insert :public ilink { delayed_insert_threads--; my_free(thd.query()); + thd->reset_query_inner(); thd.security_ctx->user= 0; thd.security_ctx->host= 0; }