diff options
author | Sergei Petrunia <sergey@mariadb.com> | 2022-04-26 23:03:34 +0300 |
---|---|---|
committer | Sergei Petrunia <sergey@mariadb.com> | 2022-04-28 11:20:12 +0300 |
commit | eea15803ec875a27801ed9d32b7f5fbc4aec1fc7 (patch) | |
tree | 5c92cc16dfed9d2ca5e1c230264ff8df456e41eb /sql | |
parent | c711abd182f6d581b71d6988eff9c5c480bca62d (diff) | |
download | mariadb-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.cc | 4 | ||||
-rw-r--r-- | sql/sql_expression_cache.h | 5 |
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) |