Commit 00c74738 authored by unknown's avatar unknown

Bug#27836

  "sql_plugin.cc, dynamic_array is not dynamic"
  When the DYNAMIC_ARRAYs were resized, pointers became invalid.
  Solved by only storing pointers within the DYNAMIC_ARRAYs.


sql/sql_plugin.cc:
  Bug27836
    Store pointers to data structures in dynamic arrays: plugin_dl_array, plugin_array
    Allocate data structures in plugin_mem_root
parent c9d7c8f9
...@@ -278,7 +278,7 @@ static struct st_plugin_dl *plugin_dl_find(const LEX_STRING *dl) ...@@ -278,7 +278,7 @@ static struct st_plugin_dl *plugin_dl_find(const LEX_STRING *dl)
DBUG_ENTER("plugin_dl_find"); DBUG_ENTER("plugin_dl_find");
for (i= 0; i < plugin_dl_array.elements; i++) for (i= 0; i < plugin_dl_array.elements; i++)
{ {
tmp= dynamic_element(&plugin_dl_array, i, struct st_plugin_dl *); tmp= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **);
if (tmp->ref_count && if (tmp->ref_count &&
! my_strnncoll(files_charset_info, ! my_strnncoll(files_charset_info,
(const uchar *)dl->str, dl->length, (const uchar *)dl->str, dl->length,
...@@ -296,17 +296,20 @@ static st_plugin_dl *plugin_dl_insert_or_reuse(struct st_plugin_dl *plugin_dl) ...@@ -296,17 +296,20 @@ static st_plugin_dl *plugin_dl_insert_or_reuse(struct st_plugin_dl *plugin_dl)
DBUG_ENTER("plugin_dl_insert_or_reuse"); DBUG_ENTER("plugin_dl_insert_or_reuse");
for (i= 0; i < plugin_dl_array.elements; i++) for (i= 0; i < plugin_dl_array.elements; i++)
{ {
tmp= dynamic_element(&plugin_dl_array, i, struct st_plugin_dl *); tmp= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **);
if (! tmp->ref_count) if (! tmp->ref_count)
{ {
memcpy(tmp, plugin_dl, sizeof(struct st_plugin_dl)); memcpy(tmp, plugin_dl, sizeof(struct st_plugin_dl));
DBUG_RETURN(tmp); DBUG_RETURN(tmp);
} }
} }
if (insert_dynamic(&plugin_dl_array, (gptr)plugin_dl)) if (insert_dynamic(&plugin_dl_array, (gptr)&plugin_dl))
DBUG_RETURN(0); DBUG_RETURN(0);
DBUG_RETURN(dynamic_element(&plugin_dl_array, plugin_dl_array.elements - 1, tmp= *dynamic_element(&plugin_dl_array, plugin_dl_array.elements - 1,
struct st_plugin_dl *)); struct st_plugin_dl **)=
(struct st_plugin_dl *) memdup_root(&plugin_mem_root, (gptr)plugin_dl,
sizeof(struct st_plugin_dl));
DBUG_RETURN(tmp);
} }
#endif /* HAVE_DLOPEN */ #endif /* HAVE_DLOPEN */
...@@ -516,8 +519,8 @@ static void plugin_dl_del(const LEX_STRING *dl) ...@@ -516,8 +519,8 @@ static void plugin_dl_del(const LEX_STRING *dl)
for (i= 0; i < plugin_dl_array.elements; i++) for (i= 0; i < plugin_dl_array.elements; i++)
{ {
struct st_plugin_dl *tmp= dynamic_element(&plugin_dl_array, i, struct st_plugin_dl *tmp= *dynamic_element(&plugin_dl_array, i,
struct st_plugin_dl *); struct st_plugin_dl **);
if (tmp->ref_count && if (tmp->ref_count &&
! my_strnncoll(files_charset_info, ! my_strnncoll(files_charset_info,
(const uchar *)dl->str, dl->length, (const uchar *)dl->str, dl->length,
...@@ -665,21 +668,24 @@ plugin_ref plugin_lock_by_name(THD *thd, const LEX_STRING *name, int type ...@@ -665,21 +668,24 @@ plugin_ref plugin_lock_by_name(THD *thd, const LEX_STRING *name, int type
static st_plugin_int *plugin_insert_or_reuse(struct st_plugin_int *plugin) static st_plugin_int *plugin_insert_or_reuse(struct st_plugin_int *plugin)
{ {
uint i; uint i;
struct st_plugin_int *tmp;
DBUG_ENTER("plugin_insert_or_reuse"); DBUG_ENTER("plugin_insert_or_reuse");
for (i= 0; i < plugin_array.elements; i++) for (i= 0; i < plugin_array.elements; i++)
{ {
struct st_plugin_int *tmp= dynamic_element(&plugin_array, i, tmp= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
struct st_plugin_int *);
if (tmp->state == PLUGIN_IS_FREED) if (tmp->state == PLUGIN_IS_FREED)
{ {
memcpy(tmp, plugin, sizeof(struct st_plugin_int)); memcpy(tmp, plugin, sizeof(struct st_plugin_int));
DBUG_RETURN(tmp); DBUG_RETURN(tmp);
} }
} }
if (insert_dynamic(&plugin_array, (gptr)plugin)) if (insert_dynamic(&plugin_array, (gptr)&plugin))
DBUG_RETURN(0); DBUG_RETURN(0);
DBUG_RETURN(dynamic_element(&plugin_array, plugin_array.elements - 1, tmp= *dynamic_element(&plugin_array, plugin_array.elements - 1,
struct st_plugin_int *)); struct st_plugin_int **)=
(struct st_plugin_int *) memdup_root(&plugin_mem_root, (gptr)plugin,
sizeof(struct st_plugin_int));
DBUG_RETURN(tmp);
} }
...@@ -874,7 +880,7 @@ static void reap_plugins(void) ...@@ -874,7 +880,7 @@ static void reap_plugins(void)
for (idx= 0; idx < count; idx++) for (idx= 0; idx < count; idx++)
{ {
plugin= dynamic_element(&plugin_array, idx, struct st_plugin_int *); plugin= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
if (plugin->state == PLUGIN_IS_DELETED && !plugin->ref_count) if (plugin->state == PLUGIN_IS_DELETED && !plugin->ref_count)
{ {
/* change the status flag to prevent reaping by another thread */ /* change the status flag to prevent reaping by another thread */
...@@ -1097,9 +1103,9 @@ int plugin_init(int *argc, char **argv, int flags) ...@@ -1097,9 +1103,9 @@ int plugin_init(int *argc, char **argv, int flags)
pthread_mutex_init(&LOCK_plugin, MY_MUTEX_INIT_FAST); pthread_mutex_init(&LOCK_plugin, MY_MUTEX_INIT_FAST);
if (my_init_dynamic_array(&plugin_dl_array, if (my_init_dynamic_array(&plugin_dl_array,
sizeof(struct st_plugin_dl),16,16) || sizeof(struct st_plugin_dl *),16,16) ||
my_init_dynamic_array(&plugin_array, my_init_dynamic_array(&plugin_array,
sizeof(struct st_plugin_int),16,16)) sizeof(struct st_plugin_int *),16,16))
goto err; goto err;
for (i= 0; i < MYSQL_MAX_PLUGIN_TYPE_NUM; i++) for (i= 0; i < MYSQL_MAX_PLUGIN_TYPE_NUM; i++)
...@@ -1185,7 +1191,7 @@ int plugin_init(int *argc, char **argv, int flags) ...@@ -1185,7 +1191,7 @@ int plugin_init(int *argc, char **argv, int flags)
for (i= 0; i < plugin_array.elements; i++) for (i= 0; i < plugin_array.elements; i++)
{ {
plugin_ptr= dynamic_element(&plugin_array, i, struct st_plugin_int *); plugin_ptr= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
if (plugin_ptr->state == PLUGIN_IS_UNINITIALIZED) if (plugin_ptr->state == PLUGIN_IS_UNINITIALIZED)
{ {
if (plugin_initialize(plugin_ptr)) if (plugin_initialize(plugin_ptr))
...@@ -1232,11 +1238,13 @@ static bool register_builtin(struct st_mysql_plugin *plugin, ...@@ -1232,11 +1238,13 @@ static bool register_builtin(struct st_mysql_plugin *plugin,
tmp->ref_count= 0; tmp->ref_count= 0;
tmp->plugin_dl= 0; tmp->plugin_dl= 0;
if (insert_dynamic(&plugin_array, (gptr)tmp)) if (insert_dynamic(&plugin_array, (gptr)&tmp))
DBUG_RETURN(1); DBUG_RETURN(1);
*ptr= dynamic_element(&plugin_array, plugin_array.elements - 1, *ptr= *dynamic_element(&plugin_array, plugin_array.elements - 1,
struct st_plugin_int *); struct st_plugin_int **)=
(struct st_plugin_int *) memdup_root(&plugin_mem_root, (gptr)tmp,
sizeof(struct st_plugin_int));
if (my_hash_insert(&plugin_hash[plugin->type],(byte*) *ptr)) if (my_hash_insert(&plugin_hash[plugin->type],(byte*) *ptr))
DBUG_RETURN(1); DBUG_RETURN(1);
...@@ -1458,7 +1466,7 @@ void plugin_shutdown(void) ...@@ -1458,7 +1466,7 @@ void plugin_shutdown(void)
reap_plugins(); reap_plugins();
for (i= free_slots= 0; i < count; i++) for (i= free_slots= 0; i < count; i++)
{ {
plugin= dynamic_element(&plugin_array, i, struct st_plugin_int *); plugin= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
switch (plugin->state) { switch (plugin->state) {
case PLUGIN_IS_READY: case PLUGIN_IS_READY:
plugin->state= PLUGIN_IS_DELETED; plugin->state= PLUGIN_IS_DELETED;
...@@ -1490,7 +1498,7 @@ void plugin_shutdown(void) ...@@ -1490,7 +1498,7 @@ void plugin_shutdown(void)
*/ */
for (i= 0; i < count; i++) for (i= 0; i < count; i++)
{ {
plugins[i]= dynamic_element(&plugin_array, i, struct st_plugin_int *); plugins[i]= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
/* change the state to ensure no reaping races */ /* change the state to ensure no reaping races */
if (plugins[i]->state == PLUGIN_IS_DELETED) if (plugins[i]->state == PLUGIN_IS_DELETED)
plugins[i]->state= PLUGIN_IS_DYING; plugins[i]->state= PLUGIN_IS_DYING;
...@@ -1555,7 +1563,7 @@ void plugin_shutdown(void) ...@@ -1555,7 +1563,7 @@ void plugin_shutdown(void)
count= plugin_dl_array.elements; count= plugin_dl_array.elements;
dl= (struct st_plugin_dl **)my_alloca(sizeof(void*) * count); dl= (struct st_plugin_dl **)my_alloca(sizeof(void*) * count);
for (i= 0; i < count; i++) for (i= 0; i < count; i++)
dl[i]= dynamic_element(&plugin_dl_array, i, struct st_plugin_dl *); dl[i]= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **);
for (i= 0; i < plugin_dl_array.elements; i++) for (i= 0; i < plugin_dl_array.elements; i++)
free_plugin_mem(dl[i]); free_plugin_mem(dl[i]);
my_afree(dl); my_afree(dl);
...@@ -1714,7 +1722,7 @@ bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func, ...@@ -1714,7 +1722,7 @@ bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func,
{ {
for (idx= 0; idx < total; idx++) for (idx= 0; idx < total; idx++)
{ {
plugin= dynamic_element(&plugin_array, idx, struct st_plugin_int *); plugin= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
plugins[idx]= !(plugin->state & state_mask) ? plugin : NULL; plugins[idx]= !(plugin->state & state_mask) ? plugin : NULL;
} }
} }
...@@ -3139,7 +3147,7 @@ void my_print_help_inc_plugins(my_option *main_options, uint size) ...@@ -3139,7 +3147,7 @@ void my_print_help_inc_plugins(my_option *main_options, uint size)
if (initialized) if (initialized)
for (uint idx= 0; idx < plugin_array.elements; idx++) for (uint idx= 0; idx < plugin_array.elements; idx++)
{ {
p= dynamic_element(&plugin_array, idx, struct st_plugin_int *); p= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
if (!p->plugin->system_vars || if (!p->plugin->system_vars ||
!(opt= construct_help_options(&mem_root, p))) !(opt= construct_help_options(&mem_root, p)))
......
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