summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergei Petrunia <sergey@mariadb.com>2022-04-26 23:03:34 +0300
committerSergei Petrunia <sergey@mariadb.com>2022-04-28 11:20:12 +0300
commiteea15803ec875a27801ed9d32b7f5fbc4aec1fc7 (patch)
tree5c92cc16dfed9d2ca5e1c230264ff8df456e41eb /sql
parentc711abd182f6d581b71d6988eff9c5c480bca62d (diff)
downloadmariadb-git-eea15803ec875a27801ed9d32b7f5fbc4aec1fc7.tar.gz
MDEV-28268: Server crashes in Expression_cache_tracker::fetch_current_stats
Expression_cache_tmptable object uses an Expression_cache_tracker object to report the statistics. In the common scenario, Expression_cache_tmptable destructor sets tracker->cache=NULL. The tracker object survives after the expression cache is deleted and one may call cache_tracker->fetch_current_stats() for it with no harm. However a degenerate cache with no parameters does not set tracker->cache=NULL in Expression_cache_tmptable destructor which results in an attempt to use freed data in the cache_tracker->fetch_current_stats() call. Fixed by setting tracker->cache to NULL and wrapping the assignment into a function.
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_expression_cache.cc4
-rw-r--r--sql/sql_expression_cache.h5
2 files changed, 8 insertions, 1 deletions
diff --git a/sql/sql_expression_cache.cc b/sql/sql_expression_cache.cc
index 4b6d4b4472e..5ce50a3fe52 100644
--- a/sql/sql_expression_cache.cc
+++ b/sql/sql_expression_cache.cc
@@ -63,7 +63,7 @@ void Expression_cache_tmptable::disable_cache()
cache_table= NULL;
update_tracker();
if (tracker)
- tracker->cache= NULL;
+ tracker->detach_from_cache();
}
@@ -188,6 +188,8 @@ Expression_cache_tmptable::~Expression_cache_tmptable()
else
{
update_tracker();
+ if (tracker)
+ tracker->detach_from_cache();
tracker= NULL;
}
}
diff --git a/sql/sql_expression_cache.h b/sql/sql_expression_cache.h
index 61e0c4c69b3..d4bb252dccb 100644
--- a/sql/sql_expression_cache.h
+++ b/sql/sql_expression_cache.h
@@ -83,7 +83,11 @@ public:
cache(c), hit(0), miss(0), state(UNINITED)
{}
+private:
+ // This can be NULL if the cache is already deleted
Expression_cache *cache;
+
+public:
ulong hit, miss;
enum expr_cache_state state;
@@ -91,6 +95,7 @@ public:
void set(ulong h, ulong m, enum expr_cache_state s)
{hit= h; miss= m; state= s;}
+ void detach_from_cache() { cache= NULL; }
void fetch_current_stats()
{
if (cache)