Skip to content

Commit

Permalink
MDEV-32640 Reset thd->lex->mi.connection_name.str towards the end of …
Browse files Browse the repository at this point in the history
…mysql_execute_command

Reset the connection_name to contain a null string, if the pointer
points to the same space as that of the system variable
default_master_connection.

We do this because the system variable may be updated which could free
the pointer and create a new one, causing use-after-free for
re-execution of prepared statements and stored procedures where the
LEX may be reused.

This allows connection_name to be set again be to the system variable
pointer in the next call of this function (see earlier in this
function), after any possible updates to the system variable.
  • Loading branch information
mariadb-YuchenPei committed May 7, 2024
1 parent 0e8e157 commit b86a2f0
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 0 deletions.
15 changes: 15 additions & 0 deletions mysql-test/suite/sys_vars/r/mdev_32640.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
PREPARE s_1 FROM 'SHOW RELAYLOG EVENTS';
/* 1 */ SET default_master_connection='MASTER';
/* 1 */ EXECUTE s_1;
ERROR HY000: There is no master connection 'MASTER'
/* 2 */ SET default_master_connection='MASTER';
/* 2 */ EXECUTE s_1;
ERROR HY000: There is no master connection 'MASTER'
create procedure p() SHOW RELAYLOG EVENTS;
/* 1 */ SET default_master_connection='MASTER';
/* 1 */ call p;
ERROR HY000: There is no master connection 'MASTER'
/* 2 */ SET default_master_connection='MASTER';
/* 2 */ call p;
ERROR HY000: There is no master connection 'MASTER'
drop procedure p;
18 changes: 18 additions & 0 deletions mysql-test/suite/sys_vars/t/mdev_32640.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--source include/not_embedded.inc

PREPARE s_1 FROM 'SHOW RELAYLOG EVENTS';
/* 1 */ SET default_master_connection='MASTER';
--error WARN_NO_MASTER_INFO
/* 1 */ EXECUTE s_1;
/* 2 */ SET default_master_connection='MASTER';
--error WARN_NO_MASTER_INFO
/* 2 */ EXECUTE s_1;

create procedure p() SHOW RELAYLOG EVENTS;
/* 1 */ SET default_master_connection='MASTER';
--error WARN_NO_MASTER_INFO
/* 1 */ call p;
/* 2 */ SET default_master_connection='MASTER';
--error WARN_NO_MASTER_INFO
/* 2 */ call p;
drop procedure p;
18 changes: 18 additions & 0 deletions sql/sql_parse.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5993,6 +5993,24 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt)
thd->wsrep_PA_safe= true;
#endif /* WITH_WSREP */

/*
Reset the connection_name to contain a null string, if the
pointer points to the same space as that of the system variable
default_master_connection.
We do this because the system variable may be updated which could
free the pointer and create a new one, causing use-after-free for
re-execution of prepared statements and stored procedures where
the LEX may be reused.
This allows connection_name to be set again be to the system
variable pointer in the next call of this function (see earlier in
this function), after any possible updates to the system variable.
*/
if (thd->lex->mi.connection_name.str ==
thd->variables.default_master_connection.str)
thd->lex->mi.connection_name= null_clex_str;

if (lex->sql_command != SQLCOM_SET_OPTION)
DEBUG_SYNC(thd, "end_of_statement");
DBUG_RETURN(res || thd->is_error());
Expand Down

0 comments on commit b86a2f0

Please sign in to comment.