mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
lp:910817: Race condition in kill_threads_for_user()
The code was accessing a pointer in a mem_root that might be freed by another concurrent thread. Fix by moving the access to be done while the LOCK_thd_data is held, preventing the memory from being freed too early.
This commit is contained in:
@ -7363,13 +7363,23 @@ static uint kill_threads_for_user(THD *thd, LEX_USER *user,
|
|||||||
if (!threads_to_kill.is_empty())
|
if (!threads_to_kill.is_empty())
|
||||||
{
|
{
|
||||||
List_iterator_fast<THD> it(threads_to_kill);
|
List_iterator_fast<THD> it(threads_to_kill);
|
||||||
THD *ptr;
|
THD *next_ptr;
|
||||||
while ((ptr= it++))
|
THD *ptr= it++;
|
||||||
|
do
|
||||||
{
|
{
|
||||||
ptr->awake(kill_signal);
|
ptr->awake(kill_signal);
|
||||||
|
/*
|
||||||
|
Careful here: The list nodes are allocated on the memroots of the
|
||||||
|
THDs to be awakened.
|
||||||
|
But those THDs may be terminated and deleted as soon as we release
|
||||||
|
LOCK_thd_data, which will make the list nodes invalid.
|
||||||
|
Since the operation "it++" dereferences the "next" pointer of the
|
||||||
|
previous list node, we need to do this while holding LOCK_thd_data.
|
||||||
|
*/
|
||||||
|
next_ptr= it++;
|
||||||
pthread_mutex_unlock(&ptr->LOCK_thd_data);
|
pthread_mutex_unlock(&ptr->LOCK_thd_data);
|
||||||
(*rows)++;
|
(*rows)++;
|
||||||
}
|
} while ((ptr= next_ptr));
|
||||||
}
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user