mirror of
https://github.com/MariaDB/server.git
synced 2026-05-07 15:45:33 +02:00
Fix for bug #11555 "Stored procedures: current SP tables locking make
impossible view security". We should not expose names of tables which are explicitly or implicitly (via routine or trigger) used by view even if we find that they are missing. So during building of list of prelocked tables for statement we track which routines (and therefore tables for these routines) are used from views. We mark elements of LEX::routines set which correspond to routines used in views by setting Sroutine_hash_entry::belong_to_view member to point to TABLE_LIST object for topmost view which uses routine. We propagate this mark to all routines which are used by this routine and which we add to this set. We also mark tables used by such routine which we add to the list of tables for prelocking as belonging to this view. mysql-test/r/sp-error.result: Added test for bug #11555 "Stored procedures: current SP tables locking make impossible view security". mysql-test/r/view.result: We should not expose tables which are expicitly/implicitly used in view in check table statement. mysql-test/t/sp-error.test: Added test for bug #11555 "Stored procedures: current SP tables locking make impossible view security". mysql-test/t/view.test: Removed comment obsoleted by bugfix. sql/sp.cc: We should not expose names of tables which are explicitly or implicitly (via routine or trigger) used by view even if we find that they are missing. So during building of list of prelocked tables for statement we track which routines (and therefore tables for these routines) are used from views. We mark elements of LEX::routines set which correspond to routines used in views by setting Sroutine_hash_entry::belong_to_view member to point to TABLE_LIST object for topmost view which uses routine. We propagate this mark to all routines which are used by this routine and which we add to this set. We also mark tables used by such routine which we add to the list of tables for prelocking as belonging to this view. sql/sp.h: sp_cache_routines_and_add_tables_for_view()/for_triggers(): To be able to determine correctly uppermost view which uses this view/table with trigger we have to pass pointer to TABLE_LIST object instead of pointer to view's LEX or to Table_triggers_list object. sql/sp_head.cc: sp_head::add_used_tables_to_table_list(): Added new argument which allows to mark tables which are added to table list for prelocking as belonging to view (this allows properly hide names of tables which are used in routines used by views). sql/sp_head.h: sp_head::add_used_tables_to_table_list(): Added new argument which allows to mark tables which are added to table list for prelocking as belonging to view (this allows properly hide names of tables which are used in routines used by views). sql/sql_base.cc: open_tables(): sp_cache_routines_and_add_tables_for_view()/for_triggers() now accept pointer to table list element as last argument, this allows them to determine correctly uppermost view which uses this view/table with trigger. sql/sql_trigger.h: Table_triggers_list: sp_cache_routines_and_add_tables_for_triggers() now accept pointer to table list element as last argument, this allows to determine correctly uppermost view which uses this table with trigger.
This commit is contained in:
parent
e0367223d1
commit
361977c0da
10 changed files with 173 additions and 46 deletions
83
sql/sp.cc
83
sql/sp.cc
|
|
@ -1199,6 +1199,12 @@ struct Sroutine_hash_entry
|
|||
for LEX::sroutine/sroutine_list and sp_head::m_sroutines.
|
||||
*/
|
||||
Sroutine_hash_entry *next;
|
||||
/*
|
||||
Uppermost view which directly or indirectly uses this routine.
|
||||
0 if routine is not used in view. Note that it also can be 0 if
|
||||
statement uses routine both via view and directly.
|
||||
*/
|
||||
TABLE_LIST *belong_to_view;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1253,9 +1259,11 @@ void sp_get_prelocking_info(THD *thd, bool *need_prelocking,
|
|||
|
||||
SYNOPSIS
|
||||
add_used_routine()
|
||||
lex - LEX representing statement
|
||||
arena - arena in which memory for new element will be allocated
|
||||
key - key for the hash representing set
|
||||
lex LEX representing statement
|
||||
arena Arena in which memory for new element will be allocated
|
||||
key Key for the hash representing set
|
||||
belong_to_view Uppermost view which uses this routine
|
||||
(0 if routine is not used by view)
|
||||
|
||||
NOTES
|
||||
Will also add element to end of 'LEX::sroutines_list' list.
|
||||
|
|
@ -1278,7 +1286,8 @@ void sp_get_prelocking_info(THD *thd, bool *need_prelocking,
|
|||
*/
|
||||
|
||||
static bool add_used_routine(LEX *lex, Query_arena *arena,
|
||||
const LEX_STRING *key)
|
||||
const LEX_STRING *key,
|
||||
TABLE_LIST *belong_to_view)
|
||||
{
|
||||
if (!hash_search(&lex->sroutines, (byte *)key->str, key->length))
|
||||
{
|
||||
|
|
@ -1292,6 +1301,7 @@ static bool add_used_routine(LEX *lex, Query_arena *arena,
|
|||
memcpy(rn->key.str, key->str, key->length);
|
||||
my_hash_insert(&lex->sroutines, (byte *)rn);
|
||||
lex->sroutines_list.link_in_list((byte *)rn, (byte **)&rn->next);
|
||||
rn->belong_to_view= belong_to_view;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
|
@ -1322,7 +1332,7 @@ void sp_add_used_routine(LEX *lex, Query_arena *arena,
|
|||
sp_name *rt, char rt_type)
|
||||
{
|
||||
rt->set_routine_type(rt_type);
|
||||
(void)add_used_routine(lex, arena, &rt->m_sroutines_key);
|
||||
(void)add_used_routine(lex, arena, &rt->m_sroutines_key, 0);
|
||||
lex->sroutines_list_own_last= lex->sroutines_list.next;
|
||||
lex->sroutines_list_own_elements= lex->sroutines_list.elements;
|
||||
}
|
||||
|
|
@ -1392,20 +1402,23 @@ void sp_update_sp_used_routines(HASH *dst, HASH *src)
|
|||
|
||||
SYNOPSIS
|
||||
sp_update_stmt_used_routines()
|
||||
thd - thread context
|
||||
lex - LEX representing statement
|
||||
src - hash representing set from which routines will be added
|
||||
thd Thread context
|
||||
lex LEX representing statement
|
||||
src Hash representing set from which routines will be added
|
||||
belong_to_view Uppermost view which uses these routines, 0 if none
|
||||
|
||||
NOTE
|
||||
It will also add elements to end of 'LEX::sroutines_list' list.
|
||||
*/
|
||||
|
||||
static void sp_update_stmt_used_routines(THD *thd, LEX *lex, HASH *src)
|
||||
static void
|
||||
sp_update_stmt_used_routines(THD *thd, LEX *lex, HASH *src,
|
||||
TABLE_LIST *belong_to_view)
|
||||
{
|
||||
for (uint i=0 ; i < src->records ; i++)
|
||||
{
|
||||
Sroutine_hash_entry *rt= (Sroutine_hash_entry *)hash_element(src, i);
|
||||
(void)add_used_routine(lex, thd->stmt_arena, &rt->key);
|
||||
(void)add_used_routine(lex, thd->stmt_arena, &rt->key, belong_to_view);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1416,19 +1429,21 @@ static void sp_update_stmt_used_routines(THD *thd, LEX *lex, HASH *src)
|
|||
|
||||
SYNOPSIS
|
||||
sp_update_stmt_used_routines()
|
||||
thd Thread context
|
||||
lex LEX representing statement
|
||||
src List representing set from which routines will be added
|
||||
thd Thread context
|
||||
lex LEX representing statement
|
||||
src List representing set from which routines will be added
|
||||
belong_to_view Uppermost view which uses these routines, 0 if none
|
||||
|
||||
NOTE
|
||||
It will also add elements to end of 'LEX::sroutines_list' list.
|
||||
*/
|
||||
|
||||
static void sp_update_stmt_used_routines(THD *thd, LEX *lex, SQL_LIST *src)
|
||||
static void sp_update_stmt_used_routines(THD *thd, LEX *lex, SQL_LIST *src,
|
||||
TABLE_LIST *belong_to_view)
|
||||
{
|
||||
for (Sroutine_hash_entry *rt= (Sroutine_hash_entry *)src->first;
|
||||
rt; rt= rt->next)
|
||||
(void)add_used_routine(lex, thd->stmt_arena, &rt->key);
|
||||
(void)add_used_routine(lex, thd->stmt_arena, &rt->key, belong_to_view);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1493,8 +1508,11 @@ 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);
|
||||
sp_update_stmt_used_routines(thd, lex, &sp->m_sroutines,
|
||||
rt->belong_to_view);
|
||||
result|= sp->add_used_tables_to_table_list(thd,
|
||||
&lex->query_tables_last,
|
||||
rt->belong_to_view);
|
||||
}
|
||||
}
|
||||
first= FALSE;
|
||||
|
|
@ -1536,17 +1554,18 @@ sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock)
|
|||
|
||||
SYNOPSIS
|
||||
sp_cache_routines_and_add_tables_for_view()
|
||||
thd - thread context
|
||||
lex - LEX representing statement
|
||||
aux_lex - LEX representing view
|
||||
thd Thread context
|
||||
lex LEX representing statement
|
||||
view Table list element representing view
|
||||
*/
|
||||
|
||||
void
|
||||
sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, LEX *aux_lex)
|
||||
sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, TABLE_LIST *view)
|
||||
{
|
||||
Sroutine_hash_entry **last_cached_routine_ptr=
|
||||
(Sroutine_hash_entry **)lex->sroutines_list.next;
|
||||
sp_update_stmt_used_routines(thd, lex, &aux_lex->sroutines_list);
|
||||
sp_update_stmt_used_routines(thd, lex, &view->view->sroutines_list,
|
||||
view->top_table());
|
||||
(void)sp_cache_routines_and_add_tables_aux(thd, lex,
|
||||
*last_cached_routine_ptr, FALSE);
|
||||
}
|
||||
|
|
@ -1559,16 +1578,18 @@ sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, LEX *aux_lex)
|
|||
|
||||
SYNOPSIS
|
||||
sp_cache_routines_and_add_tables_for_triggers()
|
||||
thd - thread context
|
||||
lex - LEX respresenting statement
|
||||
triggers - triggers of the table
|
||||
thd thread context
|
||||
lex LEX respresenting statement
|
||||
table Table list element for table with trigger
|
||||
*/
|
||||
|
||||
void
|
||||
sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
||||
Table_triggers_list *triggers)
|
||||
TABLE_LIST *table)
|
||||
{
|
||||
if (add_used_routine(lex, thd->stmt_arena, &triggers->sroutines_key))
|
||||
Table_triggers_list *triggers= table->table->triggers;
|
||||
if (add_used_routine(lex, thd->stmt_arena, &triggers->sroutines_key,
|
||||
table->belong_to_view))
|
||||
{
|
||||
Sroutine_hash_entry **last_cached_routine_ptr=
|
||||
(Sroutine_hash_entry **)lex->sroutines_list.next;
|
||||
|
|
@ -1578,10 +1599,12 @@ sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
|||
{
|
||||
if (triggers->bodies[i][j])
|
||||
{
|
||||
(void)triggers->bodies[i][j]->add_used_tables_to_table_list(thd,
|
||||
&lex->query_tables_last);
|
||||
(void)triggers->bodies[i][j]->
|
||||
add_used_tables_to_table_list(thd, &lex->query_tables_last,
|
||||
table->belong_to_view);
|
||||
sp_update_stmt_used_routines(thd, lex,
|
||||
&triggers->bodies[i][j]->m_sroutines);
|
||||
&triggers->bodies[i][j]->m_sroutines,
|
||||
table->belong_to_view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue