Skip to content

Commit bf0aa99

Browse files
committed
MDEV-34237: On Startup: UBSAN: runtime error: call to function MDL_lock::lf_hash_initializer lf_hash_insert through pointer to incorrect function type 'void (*)(st_lf_hash *, void *, const void *)'
A few different incorrect function type UBSAN issues have been grouped into this patch. The only real potentially undefined behavior is an error about show_func_mutex_instances_lost, which when invoked in sql_show.cc::show_status_array(), puts 5 arguments onto the stack; however, the implementing function only actually has 3 parameters (so only 3 would be popped). This was fixed by adding in the remaining parameters to satisfy the type mysql_show_var_func. The rest of the findings are pointer type mismatches that wouldn't lead to actual undefined behavior. The lf_hash_initializer function type definition is typedef void (*lf_hash_initializer)(LF_HASH *hash, void *dst, const void *src); but the MDL_lock and table cache's implementations of this function do not have that signature. The MDL_lock has specific MDL object parameters: static void lf_hash_initializer(LF_HASH *hash __attribute__((unused)), MDL_lock *lock, MDL_key *key_arg) and the table cache has specific TDC parameters: static void tdc_hash_initializer(LF_HASH *, TDC_element *element, LEX_STRING *key) leading to UBSAN runtime errors when invoking these functions. This patch fixes these type mis-matches by changing the implementing functions to use void * and const void * for their respective parameters, and later casting them to their expected type in the function body. Note too the functions tdc_hash_key and tc_purge_callback had a similar problem to tdc_hash_initializer and was fixed similarly. Reviewed By: ============ Sergei Golubchik <serg@mariadb.com>
1 parent 0d85c90 commit bf0aa99

File tree

4 files changed

+16
-7
lines changed

4 files changed

+16
-7
lines changed

sql/mdl.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,8 +673,10 @@ class MDL_lock
673673
{ ((MDL_lock*)(arg + LF_HASH_OVERHEAD))->~MDL_lock(); }
674674

675675
static void lf_hash_initializer(LF_HASH *hash __attribute__((unused)),
676-
MDL_lock *lock, MDL_key *key_arg)
676+
void *_lock, const void *_key_arg)
677677
{
678+
MDL_lock *lock= static_cast<MDL_lock *>(_lock);
679+
const MDL_key *key_arg= static_cast<const MDL_key *>(_key_arg);
678680
DBUG_ASSERT(key_arg->mdl_namespace() != MDL_key::BACKUP);
679681
new (&lock->key) MDL_key(key_arg);
680682
if (key_arg->mdl_namespace() == MDL_key::SCHEMA)

sql/sql_show.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3789,7 +3789,7 @@ static bool show_status_array(THD *thd, const char *wild,
37893789
*/
37903790
for (var=variables; var->type == SHOW_FUNC ||
37913791
var->type == SHOW_SIMPLE_FUNC; var= &tmp)
3792-
((mysql_show_var_func)(var->value))(thd, &tmp, buff,
3792+
((mysql_show_var_func)(var->value))(thd, &tmp, (void *) buff,
37933793
status_var, scope);
37943794

37953795
SHOW_TYPE show_type=var->type;

sql/table_cache.cc

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -293,9 +293,11 @@ static void tc_remove_all_unused_tables(TDC_element *element,
293293
periodicly flush all not used tables.
294294
*/
295295

296-
static my_bool tc_purge_callback(TDC_element *element,
297-
Share_free_tables::List *purge_tables)
296+
static my_bool tc_purge_callback(void *_element, void *_purge_tables)
298297
{
298+
TDC_element *element= static_cast<TDC_element *>(_element);
299+
Share_free_tables::List *purge_tables=
300+
static_cast<Share_free_tables::List *>(_purge_tables);
299301
mysql_mutex_lock(&element->LOCK_table_share);
300302
tc_remove_all_unused_tables(element, purge_tables);
301303
mysql_mutex_unlock(&element->LOCK_table_share);
@@ -566,17 +568,20 @@ static void lf_alloc_destructor(uchar *arg)
566568

567569

568570
static void tdc_hash_initializer(LF_HASH *,
569-
TDC_element *element, LEX_STRING *key)
571+
void *_element, const void *_key)
570572
{
573+
TDC_element *element= static_cast<TDC_element *>(_element);
574+
const LEX_STRING *key= static_cast<const LEX_STRING *>(_key);
571575
memcpy(element->m_key, key->str, key->length);
572576
element->m_key_length= (uint)key->length;
573577
tdc_assert_clean_share(element);
574578
}
575579

576580

577-
static uchar *tdc_hash_key(const TDC_element *element, size_t *length,
581+
static uchar *tdc_hash_key(const unsigned char *_element, size_t *length,
578582
my_bool)
579583
{
584+
const TDC_element *element= (const TDC_element *) _element;
580585
*length= element->m_key_length;
581586
return (uchar*) element->m_key;
582587
}

storage/perfschema/ha_perfschema.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,9 @@ static int pfs_done_func(void *p)
133133
DBUG_RETURN(0);
134134
}
135135

136-
static int show_func_mutex_instances_lost(THD *thd, SHOW_VAR *var, char *buff)
136+
static int show_func_mutex_instances_lost(THD *thd, SHOW_VAR *var, void *buff,
137+
struct system_status_var *status_var,
138+
enum enum_var_type)
137139
{
138140
var->type= SHOW_LONG;
139141
var->value= buff;

0 commit comments

Comments
 (0)