MDEV-33867 main.query_cache_debug fails with heap-use-after-free

What's happening:
1. Query_cache::insert() locks the QC and verifies that it's enabled
2. parallel thread tries to disable it. trylock fails (QC is locked)
   so the status becomes DISABLE_REQUEST
3. Query_cache::insert() calls Query_cache::write_result_data()
   which allocates a new block and unlocks the QC.
4. Query_cache::unlock() notices there are no more QC users and a
   pending DISABLE_REQUEST so it disables the QC and frees all the
   memory, including the new block that was just allocated
5. Query_cache::write_result_data() proceeds to write into the freed block

Fix: change m_cache_status under a mutex.

Approved by Oleksandr Byelkin <sanja@mariadb.com>
This commit is contained in:
Sergei Golubchik 2024-04-09 13:07:23 +02:00
parent d4936c8b26
commit 4980fcb990

View file

@ -2530,14 +2530,9 @@ void Query_cache::destroy()
void Query_cache::disable_query_cache(THD *thd)
{
lock(thd);
m_cache_status= DISABLE_REQUEST;
/*
If there is no requests in progress try to free buffer.
try_lock(TRY) will exit immediately if there is lock.
unlock() should free block.
*/
if (m_requests_in_progress == 0 && !try_lock(thd, TRY))
unlock();
unlock();
}