Fixed BUG#14233: Crash after tampering with the mysql.proc table
Post-review version. Some minor review fixes, but also changed the way some errors are handled: Don't return specific parse errors; instead always use the more general "table corrupt" error (amended accordingly). mysql-test/r/sp-destruct.result: Updated results. mysql-test/r/sp-error.result: Updated for fully qualified name in "no return" error message. mysql-test/t/sp-destruct.test: Adopted the more consistent error handling for a corrupted mysql.proc table. (No more "parse error" et al). sql/share/errmsg.txt: Changed ER_SP_PROC_TABLE_CORRUPT to be more explicit. sql/sp.cc: Review fixes. Changed the handling of parse errors, and added the routine name to the "table corrupt" error message. sql/sql_base.cc: Review changes: Change error tests and added comments. sql/sql_parse.cc: Mored ER_SP_NORETURN test of functions to sql_yacc.yy for more general error handling. sql/sql_yacc.yy: Mored ER_SP_NORETURN test of functions from sql_parse.cc for more general error handling.
This commit is contained in:
parent
df22630555
commit
d4088df5e9
@ -11,11 +11,11 @@ create table t1 (id int);
|
||||
create trigger t1_ai after insert on t1 for each row call bug14233();
|
||||
alter table mysql.proc drop type;
|
||||
call bug14233();
|
||||
ERROR HY000: The table mysql.proc is missing, corrupt, or contains bad data (internal code -5)
|
||||
ERROR HY000: Failed to load routine test.bug14233. The table mysql.proc is missing, corrupt, or contains bad data (internal code -5)
|
||||
create view v1 as select bug14233_f();
|
||||
ERROR HY000: The table mysql.proc is missing, corrupt, or contains bad data (internal code -5)
|
||||
ERROR HY000: Failed to load routine test.bug14233_f. The table mysql.proc is missing, corrupt, or contains bad data (internal code -5)
|
||||
insert into t1 values (0);
|
||||
ERROR HY000: The table mysql.proc is missing, corrupt, or contains bad data (internal code -5)
|
||||
ERROR HY000: Failed to load routine test.bug14233. The table mysql.proc is missing, corrupt, or contains bad data (internal code -5)
|
||||
flush table mysql.proc;
|
||||
call bug14233();
|
||||
ERROR HY000: Incorrect information in file: './mysql/proc.frm'
|
||||
@ -59,21 +59,19 @@ values
|
||||
'root@localhost', NOW() , '0000-00-00 00:00:00', '', ''
|
||||
);
|
||||
select bug14233_1();
|
||||
ERROR 0A000: Not allowed to return a result set from a function
|
||||
ERROR HY000: Failed to load routine test.bug14233_1. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||
create view v1 as select bug14233_1();
|
||||
ERROR 0A000: Not allowed to return a result set from a function
|
||||
ERROR HY000: Failed to load routine test.bug14233_1. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||
select bug14233_2();
|
||||
ERROR 2F005: FUNCTION bug14233_2 ended without RETURN
|
||||
ERROR HY000: Failed to load routine test.bug14233_2. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||
create view v1 as select bug14233_2();
|
||||
select * from v1;
|
||||
ERROR 2F005: FUNCTION bug14233_2 ended without RETURN
|
||||
ERROR HY000: Failed to load routine test.bug14233_2. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||
call bug14233_3();
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'wpsj sa ^#!@ ' at line 3
|
||||
ERROR HY000: Failed to load routine test.bug14233_3. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||
drop trigger t1_ai;
|
||||
create trigger t1_ai after insert on t1 for each row call bug14233_3();
|
||||
insert into t1 values (0);
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'wpsj sa ^#!@ ' at line 3
|
||||
ERROR HY000: Failed to load routine test.bug14233_3. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||
delete from mysql.proc where name like 'bug14233%';
|
||||
drop trigger t1_ai;
|
||||
drop table t1;
|
||||
drop view v1;
|
||||
|
@ -124,7 +124,7 @@ begin
|
||||
declare x int;
|
||||
set x = val+3;
|
||||
end|
|
||||
ERROR 42000: No RETURN found in FUNCTION f
|
||||
ERROR 42000: No RETURN found in FUNCTION test.f
|
||||
create function f(val int) returns int
|
||||
begin
|
||||
declare x int;
|
||||
|
@ -101,26 +101,24 @@ values
|
||||
'root@localhost', NOW() , '0000-00-00 00:00:00', '', ''
|
||||
);
|
||||
|
||||
--error ER_SP_NO_RETSET
|
||||
--error ER_SP_PROC_TABLE_CORRUPT
|
||||
select bug14233_1();
|
||||
--error ER_SP_NO_RETSET
|
||||
--error ER_SP_PROC_TABLE_CORRUPT
|
||||
create view v1 as select bug14233_1();
|
||||
|
||||
--error ER_SP_NORETURNEND
|
||||
--error ER_SP_PROC_TABLE_CORRUPT
|
||||
select bug14233_2();
|
||||
--error ER_SP_PROC_TABLE_CORRUPT
|
||||
create view v1 as select bug14233_2();
|
||||
--error ER_SP_NORETURNEND
|
||||
select * from v1;
|
||||
|
||||
--error ER_PARSE_ERROR
|
||||
--error ER_SP_PROC_TABLE_CORRUPT
|
||||
call bug14233_3();
|
||||
drop trigger t1_ai;
|
||||
create trigger t1_ai after insert on t1 for each row call bug14233_3();
|
||||
--error ER_PARSE_ERROR
|
||||
--error ER_SP_PROC_TABLE_CORRUPT
|
||||
insert into t1 values (0);
|
||||
|
||||
# Clean-up
|
||||
delete from mysql.proc where name like 'bug14233%';
|
||||
drop trigger t1_ai;
|
||||
drop table t1;
|
||||
drop view v1;
|
||||
|
@ -5422,4 +5422,4 @@ ER_NO_REFERENCED_ROW_2 23000
|
||||
ER_SP_BAD_VAR_SHADOW 42000
|
||||
eng "Variable '%-.64s' must be quoted with `...`, or renamed"
|
||||
ER_SP_PROC_TABLE_CORRUPT
|
||||
eng "The table mysql.proc is missing, corrupt, or contains bad data (internal code %d)"
|
||||
eng "Failed to load routine %s. The table mysql.proc is missing, corrupt, or contains bad data (internal code %d)"
|
||||
|
45
sql/sp.cc
45
sql/sp.cc
@ -1420,8 +1420,8 @@ static void sp_update_stmt_used_routines(THD *thd, LEX *lex, SQL_LIST *src)
|
||||
Instead this fact will be discovered during query execution.
|
||||
|
||||
RETURN VALUE
|
||||
0 - success
|
||||
-x - failure (error code, like SP_PARSE_ERROR et al)
|
||||
0 - success
|
||||
non-0 - failure
|
||||
*/
|
||||
|
||||
static int
|
||||
@ -1430,7 +1430,7 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
|
||||
bool first_no_prelock, bool *tabs_changed)
|
||||
{
|
||||
int ret= 0;
|
||||
bool result= FALSE;
|
||||
int tabschnd= 0; /* Set if tables changed */
|
||||
bool first= TRUE;
|
||||
DBUG_ENTER("sp_cache_routines_and_add_tables_aux");
|
||||
|
||||
@ -1478,11 +1478,21 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
|
||||
/* Fall through */
|
||||
default:
|
||||
/*
|
||||
In some cases no error has been set (e.g. get field failed,
|
||||
when the proc table has been tampered with).
|
||||
*/
|
||||
if (! thd->net.report_error)
|
||||
my_error(ER_SP_PROC_TABLE_CORRUPT, MYF(0), ret);
|
||||
Any error when loading an existing routine is either some problem
|
||||
with the mysql.proc table, or a parse error because the contents
|
||||
has been tampered with (in which case we clear that error).
|
||||
*/
|
||||
if (ret == SP_PARSE_ERROR)
|
||||
thd->clear_error();
|
||||
if (!thd->net.report_error)
|
||||
{
|
||||
char n[NAME_LEN*2+2];
|
||||
|
||||
/* m_qname.str is not always \0 terminated */
|
||||
memcpy(n, name.m_qname.str, name.m_qname.length);
|
||||
n[name.m_qname.length]= '\0';
|
||||
my_error(ER_SP_PROC_TABLE_CORRUPT, MYF(0), n, ret);
|
||||
}
|
||||
break;
|
||||
}
|
||||
delete newlex;
|
||||
@ -1493,13 +1503,14 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
|
||||
if (!(first && first_no_prelock))
|
||||
{
|
||||
sp_update_stmt_used_routines(thd, lex, &sp->m_sroutines);
|
||||
result|= sp->add_used_tables_to_table_list(thd, &lex->query_tables_last);
|
||||
tabschnd|=
|
||||
sp->add_used_tables_to_table_list(thd, &lex->query_tables_last);
|
||||
}
|
||||
}
|
||||
first= FALSE;
|
||||
}
|
||||
if (tabs_changed)
|
||||
*tabs_changed= result;
|
||||
if (tabs_changed) /* it can be NULL */
|
||||
*tabs_changed= tabschnd;
|
||||
DBUG_RETURN(ret);
|
||||
}
|
||||
|
||||
@ -1518,8 +1529,8 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
|
||||
tabs_changed - Set to TRUE some tables were added, FALSE otherwise
|
||||
|
||||
RETURN VALUE
|
||||
0 - success
|
||||
-x - failure (error code, like SP_PARSE_ERROR et al)
|
||||
0 - success
|
||||
non-0 - failure
|
||||
*/
|
||||
|
||||
int
|
||||
@ -1544,8 +1555,8 @@ sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock,
|
||||
aux_lex - LEX representing view
|
||||
|
||||
RETURN VALUE
|
||||
0 - success
|
||||
-x - failure (error code, like SP_PARSE_ERROR et al)
|
||||
0 - success
|
||||
non-0 - failure
|
||||
*/
|
||||
|
||||
int
|
||||
@ -1572,8 +1583,8 @@ sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, LEX *aux_lex)
|
||||
triggers - triggers of the table
|
||||
|
||||
RETURN VALUE
|
||||
0 - success
|
||||
-x - failure (error code, like SP_PARSE_ERROR et al)
|
||||
0 - success
|
||||
non-0 - failure
|
||||
*/
|
||||
|
||||
int
|
||||
|
@ -1986,9 +1986,14 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
||||
|
||||
if (sp_cache_routines_and_add_tables(thd, thd->lex,
|
||||
first_no_prelocking,
|
||||
&tabs_changed) < 0)
|
||||
&tabs_changed))
|
||||
{
|
||||
result= -1; // Fatal error
|
||||
/*
|
||||
Serious error during reading stored routines from mysql.proc table.
|
||||
Something's wrong with the table or its contents, and an error has
|
||||
been emitted; we must abort.
|
||||
*/
|
||||
result= -1;
|
||||
goto err;
|
||||
}
|
||||
else if ((tabs_changed || *start) && need_prelocking)
|
||||
@ -2117,9 +2122,14 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
||||
if (!query_tables_last_own)
|
||||
query_tables_last_own= thd->lex->query_tables_last;
|
||||
if (sp_cache_routines_and_add_tables_for_triggers(thd, thd->lex,
|
||||
tables->table->triggers) < 0)
|
||||
tables->table->triggers))
|
||||
{
|
||||
result= -1; // Fatal error
|
||||
/*
|
||||
Serious error during reading stored routines from mysql.proc table.
|
||||
Something's wrong with the table or its contents, and an error has
|
||||
been emitted; we must abort.
|
||||
*/
|
||||
result= -1;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
@ -2143,9 +2153,14 @@ process_view_routines:
|
||||
if (!query_tables_last_own)
|
||||
query_tables_last_own= thd->lex->query_tables_last;
|
||||
if (sp_cache_routines_and_add_tables_for_view(thd, thd->lex,
|
||||
tables->view) < 0)
|
||||
tables->view))
|
||||
{
|
||||
result= -1; // Fatal error
|
||||
/*
|
||||
Serious error during reading stored routines from mysql.proc table.
|
||||
Something's wrong with the table or its contents, and an error has
|
||||
been emitted; we must abort.
|
||||
*/
|
||||
result= -1;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
@ -4111,14 +4111,6 @@ end_with_restore_list:
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (lex->sphead->m_type == TYPE_ENUM_FUNCTION &&
|
||||
!(lex->sphead->m_flags & sp_head::HAS_RETURN))
|
||||
{
|
||||
my_error(ER_SP_NORETURN, MYF(0), name);
|
||||
delete lex->sphead;
|
||||
lex->sphead= 0;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
We need to copy name and db in order to use them for
|
||||
|
@ -1475,6 +1475,11 @@ create_function_tail:
|
||||
YYABORT;
|
||||
lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
|
||||
sp->init_strings(YYTHD, lex, lex->spname);
|
||||
if (!(sp->m_flags & sp_head::HAS_RETURN))
|
||||
{
|
||||
my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str);
|
||||
YYABORT;
|
||||
}
|
||||
/* Restore flag if it was cleared above */
|
||||
if (sp->m_old_cmq)
|
||||
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
|
||||
|
Loading…
x
Reference in New Issue
Block a user