summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2021-01-11 13:21:42 +0100
committerSergei Golubchik <serg@mariadb.org>2021-01-11 21:54:47 +0100
commit9b750dcbd89ecf455211a77348a85464b282abee (patch)
tree11d890ef87348bfc2bfc7dc1873f83ce1518c269 /sql
parent66f4900b517681da2aed3b562158ef58679961e4 (diff)
downloadmariadb-git-9b750dcbd89ecf455211a77348a85464b282abee.tar.gz
MDEV-23536 Race condition between KILL and transaction commit
Server part: kill_handlerton() was accessing thd->ha_data[] for some other thd, while it could be concurrently modified by its owner thd. protect thd->ha_data[] modifications with a mutex. require this mutex when accessing thd->ha_data[] from kill_handlerton. InnoDB part: on close_connection, detach trx from thd before freeing the trx
Diffstat (limited to 'sql')
-rw-r--r--sql/handler.cc1
-rw-r--r--sql/sql_class.cc3
2 files changed, 4 insertions, 0 deletions
diff --git a/sql/handler.cc b/sql/handler.cc
index c38c604347a..29b01763e8b 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -838,6 +838,7 @@ static my_bool kill_handlerton(THD *thd, plugin_ref plugin,
{
handlerton *hton= plugin_hton(plugin);
+ mysql_mutex_assert_owner(&thd->LOCK_thd_data);
if (hton->state == SHOW_OPTION_YES && hton->kill_query &&
thd_get_ha_data(thd, hton))
hton->kill_query(hton, thd, *(enum thd_kill_levels *) level);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 2595717572a..c3274ae9b82 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -444,6 +444,7 @@ void thd_set_ha_data(THD *thd, const struct handlerton *hton,
const void *ha_data)
{
plugin_ref *lock= &thd->ha_data[hton->slot].lock;
+ DBUG_ASSERT(thd == current_thd);
if (ha_data && !*lock)
*lock= ha_lock_engine(NULL, (handlerton*) hton);
else if (!ha_data && *lock)
@@ -451,7 +452,9 @@ void thd_set_ha_data(THD *thd, const struct handlerton *hton,
plugin_unlock(NULL, *lock);
*lock= NULL;
}
+ mysql_mutex_lock(&thd->LOCK_thd_data);
*thd_ha_data(thd, hton)= (void*) ha_data;
+ mysql_mutex_unlock(&thd->LOCK_thd_data);
}