Commit cf50379b authored by Oleksandr Byelkin's avatar Oleksandr Byelkin

MDEV-25237 crash after setting global session_track_system_variables to an invalid value

Fix of typo in checking variable list corectness.

Fix of error handling in case of variable list parse error
parent 03c2157d
...@@ -57,3 +57,33 @@ ERROR 42000: Variable 'session_track_system_variables' can't be set to the value ...@@ -57,3 +57,33 @@ ERROR 42000: Variable 'session_track_system_variables' can't be set to the value
SET SESSION session_track_system_variables=NULL; SET SESSION session_track_system_variables=NULL;
ERROR 42000: Variable 'session_track_system_variables' can't be set to the value of 'NULL' ERROR 42000: Variable 'session_track_system_variables' can't be set to the value of 'NULL'
# End of 10.3 tests # End of 10.3 tests
#
# MDEV-25237: crash after setting global session_track_system_variables
# to an invalid value
#
SET GLOBAL session_track_system_variables='a';
ERROR HY000: Unknown system variable 'a'
SET GLOBAL event_scheduler=1;
# check that value really returns as it was
set GLOBAL session_track_system_variables='character_set_connection';
SET GLOBAL session_track_system_variables='a';
ERROR HY000: Unknown system variable 'a'
connect con,localhost,root,,test;
SET NAMES 'utf8';
-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES
-- character_set_connection
-- utf8
SET NAMES 'big5';
-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES
-- character_set_connection
-- big5
select @@session_track_system_variables;
@@session_track_system_variables
character_set_connection
connection default;
disconnect con;
SET GLOBAL session_track_system_variables=default;
SET GLOBAL event_scheduler=default;
# End of 10.4 test
...@@ -60,3 +60,35 @@ SET @@GLOBAL.session_track_system_variables=NULL; ...@@ -60,3 +60,35 @@ SET @@GLOBAL.session_track_system_variables=NULL;
SET SESSION session_track_system_variables=NULL; SET SESSION session_track_system_variables=NULL;
--echo # End of 10.3 tests --echo # End of 10.3 tests
--echo #
--echo # MDEV-25237: crash after setting global session_track_system_variables
--echo # to an invalid value
--echo #
--error ER_UNKNOWN_SYSTEM_VARIABLE
SET GLOBAL session_track_system_variables='a';
SET GLOBAL event_scheduler=1;
--echo # check that value really returns as it was
set GLOBAL session_track_system_variables='character_set_connection';
--error ER_UNKNOWN_SYSTEM_VARIABLE
SET GLOBAL session_track_system_variables='a';
connect (con,localhost,root,,test);
--enable_session_track_info
SET NAMES 'utf8';
SET NAMES 'big5';
--disable_session_track_info
select @@session_track_system_variables;
connection default;
disconnect con;
SET GLOBAL session_track_system_variables=default;
SET GLOBAL event_scheduler=default;
--echo # End of 10.4 test
set @save_session_track_system_variables=@@session_track_system_variables;
#
# MDEV-25237: Assertion `global_system_variables.
# session_track_system_variables' failed in
# Session_sysvars_tracker::init | SIGSEGV's in __strlen_avx2 |
# UBSAN: runtime error: null pointer passed as argument 1, which
# is declared to never be null in my_strdup
#
# check that that parser problems do not lead to crash
SET @old_debug= @@session.debug;
set debug_dbug="+d,dbug_session_tracker_parse_error";
SET GLOBAL session_track_system_variables='query_cache_size';
ERROR HY001: Out of memory; restart server and try again (needed 1 bytes)
set debug_dbug=@old_debug;
SELECT @@global.session_track_system_variables;
@@global.session_track_system_variables
NULL
SET GLOBAL event_scheduler=1;
SET GLOBAL session_track_system_variables=default;
SET GLOBAL event_scheduler=default;
# End of 10.4 test
--source include/have_debug.inc
--source include/no_protocol.inc
--source include/not_embedded.inc
set @save_session_track_system_variables=@@session_track_system_variables;
--echo #
--echo # MDEV-25237: Assertion `global_system_variables.
--echo # session_track_system_variables' failed in
--echo # Session_sysvars_tracker::init | SIGSEGV's in __strlen_avx2 |
--echo # UBSAN: runtime error: null pointer passed as argument 1, which
--echo # is declared to never be null in my_strdup
--echo #
--echo # check that that parser problems do not lead to crash
SET @old_debug= @@session.debug;
set debug_dbug="+d,dbug_session_tracker_parse_error";
--error ER_OUTOFMEMORY
SET GLOBAL session_track_system_variables='query_cache_size';
set debug_dbug=@old_debug;
SELECT @@global.session_track_system_variables;
SET GLOBAL event_scheduler=1;
SET GLOBAL session_track_system_variables=default;
SET GLOBAL event_scheduler=default;
--echo # End of 10.4 test
...@@ -221,7 +221,7 @@ bool sysvartrack_validate_value(THD *thd, const char *str, size_t len) ...@@ -221,7 +221,7 @@ bool sysvartrack_validate_value(THD *thd, const char *str, size_t len)
/* Remove leading/trailing whitespace. */ /* Remove leading/trailing whitespace. */
trim_whitespace(system_charset_info, &var); trim_whitespace(system_charset_info, &var);
if (!strcmp(var.str, "*") && !find_sys_var(thd, var.str, var.length)) if (strcmp(var.str, "*") && !find_sys_var(thd, var.str, var.length))
return true; return true;
if (lasts) if (lasts)
...@@ -331,9 +331,8 @@ void Session_sysvars_tracker::init(THD *thd) ...@@ -331,9 +331,8 @@ void Session_sysvars_tracker::init(THD *thd)
mysql_mutex_assert_owner(&LOCK_global_system_variables); mysql_mutex_assert_owner(&LOCK_global_system_variables);
DBUG_ASSERT(thd->variables.session_track_system_variables == DBUG_ASSERT(thd->variables.session_track_system_variables ==
global_system_variables.session_track_system_variables); global_system_variables.session_track_system_variables);
DBUG_ASSERT(global_system_variables.session_track_system_variables);
thd->variables.session_track_system_variables= thd->variables.session_track_system_variables=
my_strdup(global_system_variables.session_track_system_variables, my_strdup(safe_str(global_system_variables.session_track_system_variables),
MYF(MY_WME | MY_THREAD_SPECIFIC)); MYF(MY_WME | MY_THREAD_SPECIFIC));
} }
...@@ -572,6 +571,12 @@ bool sysvartrack_global_update(THD *thd, char *str, size_t len) ...@@ -572,6 +571,12 @@ bool sysvartrack_global_update(THD *thd, char *str, size_t len)
{ {
LEX_STRING tmp= { str, len }; LEX_STRING tmp= { str, len };
Session_sysvars_tracker::vars_list dummy; Session_sysvars_tracker::vars_list dummy;
DBUG_EXECUTE_IF("dbug_session_tracker_parse_error",
{
my_error(ER_OUTOFMEMORY, MYF(0), 1);
return true;
});
if (!dummy.parse_var_list(thd, tmp, false, system_charset_info)) if (!dummy.parse_var_list(thd, tmp, false, system_charset_info))
{ {
dummy.construct_var_list(str, len + 1); dummy.construct_var_list(str, len + 1);
......
...@@ -620,7 +620,11 @@ class Sys_var_sesvartrack: public Sys_var_charptr_base ...@@ -620,7 +620,11 @@ class Sys_var_sesvartrack: public Sys_var_charptr_base
{ {
if (sysvartrack_global_update(thd, new_val, if (sysvartrack_global_update(thd, new_val,
var->save_result.string_value.length)) var->save_result.string_value.length))
{
if (new_val)
my_free(new_val);
new_val= 0; new_val= 0;
}
} }
global_update_finish(new_val); global_update_finish(new_val);
return (new_val == 0 && var->save_result.string_value.str != 0); return (new_val == 0 && var->save_result.string_value.str != 0);
......
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