MDEV-26578 ERROR: AddressSanitizer: heap-use-after-free around dict_table_t::is_temporary_name

- Purge thread is trying to access the table name when other thread
does rename of the table name. It leads to heap use after free error
by purge thread. purge thread should check whether the table name
is temporary while holding dict_sys.mutex.
parent bf70532e
......@@ -921,12 +921,14 @@ template dict_table_t*
dict_acquire_mdl_shared<true>(dict_table_t*,THD*,MDL_ticket**,dict_table_op_t);
/** Look up a table by numeric identifier.
@tparam purge_thd Whether the function is called by purge thread
@param[in] table_id table identifier
@param[in] dict_locked data dictionary locked
@param[in] table_op operation to perform when opening
@param[in,out] thd background thread, or NULL to not acquire MDL
@param[out] mdl mdl ticket, or NULL
@return table, NULL if does not exist */
template<bool purge_thd>
dict_table_t*
dict_table_open_on_id(table_id_t table_id, bool dict_locked,
dict_table_op_t table_op, THD *thd,
......@@ -948,6 +950,10 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked,
table_op == DICT_TABLE_OP_OPEN_ONLY_IF_CACHED);
if (table != NULL) {
if (purge_thd && table->name.is_temporary()) {
mutex_exit(&dict_sys.mutex);
return nullptr;
}
dict_sys.acquire(table);
MONITOR_INC(MONITOR_TABLE_REFERENCE);
}
......@@ -965,6 +971,11 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked,
return table;
}
template dict_table_t* dict_table_open_on_id<false>
(table_id_t, bool, dict_table_op_t, THD *, MDL_ticket **);
template dict_table_t* dict_table_open_on_id<true>
(table_id_t, bool, dict_table_op_t, THD *, MDL_ticket **);
/********************************************************************//**
Looks for column n position in the clustered index.
@return position in internal representation of the clustered index */
......
......@@ -140,12 +140,14 @@ dict_acquire_mdl_shared(dict_table_t *table,
dict_table_op_t table_op= DICT_TABLE_OP_NORMAL);
/** Look up a table by numeric identifier.
@tparam purge_thd Whether the function is called by purge thread
@param[in] table_id table identifier
@param[in] dict_locked data dictionary locked
@param[in] table_op operation to perform when opening
@param[in,out] thd background thread, or NULL to not acquire MDL
@param[out] mdl mdl ticket, or NULL
@return table, NULL if does not exist */
template<bool purge_thd= false>
dict_table_t*
dict_table_open_on_id(table_id_t table_id, bool dict_locked,
dict_table_op_t table_op, THD *thd= nullptr,
......
......@@ -933,11 +933,11 @@ row_purge_parse_undo_rec(
}
try_again:
node->table = dict_table_open_on_id(
node->table = dict_table_open_on_id<true>(
table_id, false, DICT_TABLE_OP_NORMAL, node->purge_thd,
&node->mdl_ticket);
if (node->table == NULL || node->table->name.is_temporary()) {
if (!node->table) {
/* The table has been dropped: no need to do purge and
release mdl happened as a part of open process itself */
goto err_exit;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment