diff options
author | Alexander Barkov <bar@mariadb.com> | 2020-05-30 13:50:37 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2020-05-30 14:00:56 +0400 |
commit | 0bf843cd13981b03920bfc49c646b28a130f5d47 (patch) | |
tree | b66a252f27ac6e4d1fbe3430ad09fc478ec20592 /sql/sql_yacc.yy | |
parent | ccdfcedf10610a32ce7d173e2936c29cb10df75c (diff) | |
download | mariadb-git-0bf843cd13981b03920bfc49c646b28a130f5d47.tar.gz |
MDEV-20366 Server crashes in get_current_user upon SET PASSWORD via SP
The opt_for_user subrule was incorrectly scanned before sp_create_assignment_lex(),
so the user name and the host were created on a wrong memory root.
- Reoganizing the grammar to make sure that sp_create_assignment_lex()
is called immediately after PASSWORD_SYM is scanned, so all attributes
are then allocated on its memory root.
- Moving the semantic code as methods to LEX, so the grammar looks as simple as possible.
- Changing text_or_password to be of the data type USER_AUTH*.
As a side effect, the LEX::definer member is now not used when processing
the SET PASSWORD statement. Everything is done using Bison's stack.
The bug sas introduced by this commit:
commit bf5a144e1692f6cc6a6d781b7e75ff4abf32bdf3
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r-- | sql/sql_yacc.yy | 61 |
1 files changed, 25 insertions, 36 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 6fe7d871f40..da752c0a3cb 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1543,6 +1543,7 @@ End SQL_MODE_ORACLE_SPECIFIC */ admin_option_for_role user_maybe_role %type <user_auth> opt_auth_str auth_expression auth_token + text_or_password %type <charset> opt_collate @@ -16433,25 +16434,30 @@ option_value_no_option_type: unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } - | PASSWORD_SYM opt_for_user text_or_password + | PASSWORD_SYM equal { if (sp_create_assignment_lex(thd, $1.pos())) MYSQL_YYABORT; - LEX *lex = Lex; - set_var_password *var= (new (thd->mem_root) - set_var_password(lex->definer)); - if (unlikely(var == NULL) || - unlikely(lex->var_list.push_back(var, thd->mem_root))) + } + text_or_password + { + if (unlikely(Lex->sp_create_set_password_instr(thd, $4, + yychar == YYEMPTY))) MYSQL_YYABORT; - lex->autocommit= TRUE; - if (lex->sphead) - lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; - if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + } + | PASSWORD_SYM FOR_SYM + { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; + } + user equal text_or_password + { + if (unlikely(Lex->sp_create_set_password_instr(thd, $4, $6, + yychar == YYEMPTY))) MYSQL_YYABORT; } ; - transaction_characteristics: transaction_access_mode | isolation_level @@ -16508,42 +16514,25 @@ isolation_types: | SERIALIZABLE_SYM { $$= ISO_SERIALIZABLE; } ; -opt_for_user: - equal - { - LEX *lex= thd->lex; - sp_pcontext *spc= lex->spcont; - LEX_CSTRING pw= { STRING_WITH_LEN("password") }; - - if (unlikely(spc && spc->find_variable(&pw, false))) - my_yyabort_error((ER_SP_BAD_VAR_SHADOW, MYF(0), pw.str)); - if (unlikely(!(lex->definer= (LEX_USER*) - thd->calloc(sizeof(LEX_USER))))) - MYSQL_YYABORT; - lex->definer->user= current_user; - lex->definer->auth= new (thd->mem_root) USER_AUTH(); - } - | FOR_SYM user equal { Lex->definer= $2; } - ; text_or_password: TEXT_STRING { - Lex->definer->auth= new (thd->mem_root) USER_AUTH(); - Lex->definer->auth->auth_str= $1; + $$= new (thd->mem_root) USER_AUTH(); + $$->auth_str= $1; } | PASSWORD_SYM '(' TEXT_STRING ')' { - Lex->definer->auth= new (thd->mem_root) USER_AUTH(); - Lex->definer->auth->pwtext= $3; + $$= new (thd->mem_root) USER_AUTH(); + $$->pwtext= $3; } | OLD_PASSWORD_SYM '(' TEXT_STRING ')' { - Lex->definer->auth= new (thd->mem_root) USER_AUTH(); - Lex->definer->auth->pwtext= $3; - Lex->definer->auth->auth_str.str= Item_func_password::alloc(thd, + $$= new (thd->mem_root) USER_AUTH(); + $$->pwtext= $3; + $$->auth_str.str= Item_func_password::alloc(thd, $3.str, $3.length, Item_func_password::OLD); - Lex->definer->auth->auth_str.length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323; + $$->auth_str.length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323; } ; |