From 4d14785546022ea8dc4e249e0b57b55328a12876 Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Wed, 9 Oct 2019 03:09:48 +0300 Subject: [PATCH] MDEV-20778 UBSAN: call to function free_rpl_filter() through pointer to incorrect function type Proper C-style type erasure is done via void*, not via char* or something else. free_key_cache() free_rpl_filter(): types were fixed to avoid function pointer type cast which is still undefined behavior. Note, that casting from void* to any other pointer type is safe and correct. --- sql/keycaches.cc | 13 ++++++------- sql/keycaches.h | 5 ++--- sql/mysqld.cc | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/sql/keycaches.cc b/sql/keycaches.cc index bc0f43a4d69..43ec85d707c 100644 --- a/sql/keycaches.cc +++ b/sql/keycaches.cc @@ -84,7 +84,7 @@ bool NAMED_ILIST::delete_element(const char *name, uint length, void (*free_elem DBUG_RETURN(1); } -void NAMED_ILIST::delete_elements(void (*free_element)(const char *name, uchar*)) +void NAMED_ILIST::delete_elements(void (*free_element)(const char *name, void*)) { NAMED_ILINK *element; DBUG_ENTER("NAMED_ILIST::delete_elements"); @@ -156,9 +156,9 @@ KEY_CACHE *get_or_create_key_cache(const char *name, uint length) } -void free_key_cache(const char *name, KEY_CACHE *key_cache) +void free_key_cache(const char *name, void *key_cache) { - end_key_cache(key_cache, 1); // Can never fail + end_key_cache(static_cast(key_cache), 1); // Can never fail my_free(key_cache); } @@ -220,13 +220,12 @@ Rpl_filter *get_or_create_rpl_filter(const char *name, uint length) return filter; } -void free_rpl_filter(const char *name, Rpl_filter *filter) +void free_rpl_filter(const char *name, void *filter) { - delete filter; - filter= 0; + delete static_cast(filter); } void free_all_rpl_filters() { - rpl_filters.delete_elements((void (*)(const char*, uchar*)) free_rpl_filter); + rpl_filters.delete_elements(free_rpl_filter); } diff --git a/sql/keycaches.h b/sql/keycaches.h index 99528682d0e..e06c8da3d0d 100644 --- a/sql/keycaches.h +++ b/sql/keycaches.h @@ -30,7 +30,7 @@ class NAMED_ILINK; class NAMED_ILIST: public I_List { public: - void delete_elements(void (*free_element)(const char*, uchar*)); + void delete_elements(void (*free_element)(const char*, void*)); bool delete_element(const char *name, uint length, void (*free_element)(const char*, uchar*)); }; @@ -42,7 +42,7 @@ extern NAMED_ILIST key_caches; KEY_CACHE *create_key_cache(const char *name, uint length); KEY_CACHE *get_key_cache(const LEX_STRING *cache_name); KEY_CACHE *get_or_create_key_cache(const char *name, uint length); -void free_key_cache(const char *name, KEY_CACHE *key_cache); +void free_key_cache(const char *name, void *key_cache); bool process_key_caches(process_key_cache_t func, void *param); /* For Rpl_filter */ @@ -52,7 +52,6 @@ extern NAMED_ILIST rpl_filters; Rpl_filter *create_rpl_filter(const char *name, uint length); Rpl_filter *get_rpl_filter(LEX_STRING *filter_name); Rpl_filter *get_or_create_rpl_filter(const char *name, uint length); -void free_rpl_filter(const char *name, Rpl_filter *filter); void free_all_rpl_filters(void); #endif /* KEYCACHES_INCLUDED */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 889072a4cf5..34e5704bcfe 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2232,7 +2232,7 @@ void clean_up(bool print_message) tdc_deinit(); mdl_destroy(); dflt_key_cache= 0; - key_caches.delete_elements((void (*)(const char*, uchar*)) free_key_cache); + key_caches.delete_elements(free_key_cache); wt_end(); multi_keycache_free(); sp_cache_end();