mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-363 - Server crashes in intern_plugin_lock on concurrent installing
semisync plugin and setting rpl_semi_sync_master_enabled There was race condition between INSTALL PLUGIN and SET. It was caused by a gap in INSTALL PLUGIN when plugin variables were registered but not fully initialized. Accessing such variables concurrently may reference uninitialized memory, specifically sys_var_pluginvar::plugin. Fixed by initializing sys_var_pluginvar::plugin early, before variable is registered.
This commit is contained in:
@ -271,13 +271,15 @@ public:
|
|||||||
{ TRASH(ptr_arg, size); }
|
{ TRASH(ptr_arg, size); }
|
||||||
|
|
||||||
sys_var_pluginvar(sys_var_chain *chain, const char *name_arg,
|
sys_var_pluginvar(sys_var_chain *chain, const char *name_arg,
|
||||||
struct st_mysql_sys_var *plugin_var_arg)
|
struct st_mysql_sys_var *plugin_var_arg,
|
||||||
|
struct st_plugin_int *plugin_arg)
|
||||||
:sys_var(chain, name_arg, plugin_var_arg->comment,
|
:sys_var(chain, name_arg, plugin_var_arg->comment,
|
||||||
(plugin_var_arg->flags & PLUGIN_VAR_THDLOCAL ? SESSION : GLOBAL) |
|
(plugin_var_arg->flags & PLUGIN_VAR_THDLOCAL ? SESSION : GLOBAL) |
|
||||||
(plugin_var_arg->flags & PLUGIN_VAR_READONLY ? READONLY : 0),
|
(plugin_var_arg->flags & PLUGIN_VAR_READONLY ? READONLY : 0),
|
||||||
0, -1, NO_ARG, pluginvar_show_type(plugin_var_arg), 0, 0,
|
0, -1, NO_ARG, pluginvar_show_type(plugin_var_arg), 0, 0,
|
||||||
VARIABLE_NOT_IN_BINLOG, NULL, NULL, NULL),
|
VARIABLE_NOT_IN_BINLOG, NULL, NULL, NULL),
|
||||||
plugin_var(plugin_var_arg), orig_pluginvar_name(plugin_var_arg->name)
|
plugin(plugin_arg), plugin_var(plugin_var_arg),
|
||||||
|
orig_pluginvar_name(plugin_var_arg->name)
|
||||||
{ plugin_var->name= name_arg; }
|
{ plugin_var->name= name_arg; }
|
||||||
sys_var_pluginvar *cast_pluginvar() { return this; }
|
sys_var_pluginvar *cast_pluginvar() { return this; }
|
||||||
bool check_update_type(Item_result type);
|
bool check_update_type(Item_result type);
|
||||||
@ -1407,22 +1409,6 @@ static int plugin_initialize(MEM_ROOT *tmp_root, struct st_plugin_int *plugin,
|
|||||||
#endif /* FIX_LATER */
|
#endif /* FIX_LATER */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
set the plugin attribute of plugin's sys vars so they are pointing
|
|
||||||
to the active plugin
|
|
||||||
*/
|
|
||||||
if (plugin->system_vars)
|
|
||||||
{
|
|
||||||
sys_var_pluginvar *var= plugin->system_vars->cast_pluginvar();
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
var->plugin= plugin;
|
|
||||||
if (!var->next)
|
|
||||||
break;
|
|
||||||
var= var->next->cast_pluginvar();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret= 0;
|
ret= 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
@ -3925,7 +3911,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
|
|||||||
if (o->flags & PLUGIN_VAR_NOSYSVAR)
|
if (o->flags & PLUGIN_VAR_NOSYSVAR)
|
||||||
continue;
|
continue;
|
||||||
if ((var= find_bookmark(plugin_name.str, o->name, o->flags)))
|
if ((var= find_bookmark(plugin_name.str, o->name, o->flags)))
|
||||||
v= new (mem_root) sys_var_pluginvar(&chain, var->key + 1, o);
|
v= new (mem_root) sys_var_pluginvar(&chain, var->key + 1, o, tmp);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
len= plugin_name.length + strlen(o->name) + 2;
|
len= plugin_name.length + strlen(o->name) + 2;
|
||||||
@ -3933,7 +3919,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
|
|||||||
strxmov(varname, plugin_name.str, "-", o->name, NullS);
|
strxmov(varname, plugin_name.str, "-", o->name, NullS);
|
||||||
my_casedn_str(&my_charset_latin1, varname);
|
my_casedn_str(&my_charset_latin1, varname);
|
||||||
convert_dash_to_underscore(varname, len-1);
|
convert_dash_to_underscore(varname, len-1);
|
||||||
v= new (mem_root) sys_var_pluginvar(&chain, varname, o);
|
v= new (mem_root) sys_var_pluginvar(&chain, varname, o, tmp);
|
||||||
}
|
}
|
||||||
DBUG_ASSERT(v); /* check that an object was actually constructed */
|
DBUG_ASSERT(v); /* check that an object was actually constructed */
|
||||||
} /* end for */
|
} /* end for */
|
||||||
|
Reference in New Issue
Block a user