diff options
author | unknown <kroki/tomash@moonlight.intranet> | 2006-07-13 17:12:31 +0400 |
---|---|---|
committer | unknown <kroki/tomash@moonlight.intranet> | 2006-07-13 17:12:31 +0400 |
commit | 06bf59ad3381522f4f5ba272a478271c741f0049 (patch) | |
tree | 1de91a48fd485ddebde7c556a0e2ccd7d70ed581 /mysql-test/t/sp-security.test | |
parent | fc085d77ade3e0cd77aebe1456c59b951301d722 (diff) | |
download | mariadb-git-06bf59ad3381522f4f5ba272a478271c741f0049.tar.gz |
Bug#18630: Arguments of suid routine calculated in wrong security
context.
Routine arguments were evaluated in the security context of the routine
itself, not in the caller's context.
The bug is fixed the following way:
- Item_func_sp::find_and_check_access() has been split into two
functions: Item_func_sp::find_and_check_access() itself only
finds the function and check that the caller have EXECUTE privilege
on it. New function set_routine_security_ctx() changes security
context for SUID routines and checks that definer have EXECUTE
privilege too.
- new function sp_head::execute_trigger() is called from
Table_triggers_list::process_triggers() instead of
sp_head::execute_function(), and is effectively just as the
sp_head::execute_function() is, with all non-trigger related code
removed, and added trigger-specific security context switch.
- call to Item_func_sp::find_and_check_access() stays outside
of sp_head::execute_function(), and there is a code in
sql_parse.cc before the call to sp_head::execute_procedure() that
checks that the caller have EXECUTE privilege, but both
sp_head::execute_function() and sp_head::execute_procedure() call
set_routine_security_ctx() after evaluating their parameters,
and restore the context after the body is executed.
mysql-test/r/sp-security.result:
Add test case for bug#18630: Arguments of suid routine calculated
in wrong security context.
mysql-test/t/sp-security.test:
Add result for bug#18630: Arguments of suid routine calculated
in wrong security context.
sql/item_func.cc:
Do not change security context before executing the function, as it
will be changed after argument evaluation.
Do not change security context in Item_func_sp::find_and_check_access().
sql/item_func.h:
Change prototype for Item_func_sp::find_and_check_access().
sql/sp_head.cc:
Add set_routine_security_ctx() function.
Add sp_head::execute_trigger() method.
Change security context in sp_head::execute_trigger(), and in
sp_head::execute_function() and sp_head::execute_procedure()
after argument evaluation.
Move pop_all_cursors() call to sp_head::execute().
sql/sp_head.h:
Add declaration for sp_head::execute_trigger() and
set_routine_security_ctx().
sql/sql_parse.cc:
Do not change security context before executing the procedure, as it
will be changed after argument evaluation.
sql/sql_trigger.cc:
Call new sp_head::execute_trigger() instead of
sp_head::execute_function(), which is responsible to switch
security context.
Diffstat (limited to 'mysql-test/t/sp-security.test')
-rw-r--r-- | mysql-test/t/sp-security.test | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/mysql-test/t/sp-security.test b/mysql-test/t/sp-security.test index d323b180216..a5d509f29b7 100644 --- a/mysql-test/t/sp-security.test +++ b/mysql-test/t/sp-security.test @@ -790,4 +790,80 @@ SELECT Host,User,Password FROM mysql.user WHERE User='user19857'; DROP USER user19857@localhost; -# End of 5.0 bugs. +--disconnect con1root +--connection default + + +# +# BUG#18630: Arguments of suid routine calculated in wrong security +# context +# +# Arguments of suid routines were calculated in definer's security +# context instead of caller's context thus creating security hole. +# +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP VIEW IF EXISTS v1; +DROP FUNCTION IF EXISTS f_suid; +DROP PROCEDURE IF EXISTS p_suid; +DROP FUNCTION IF EXISTS f_evil; +--enable_warnings +DELETE FROM mysql.user WHERE user LIKE 'mysqltest\_%'; +DELETE FROM mysql.db WHERE user LIKE 'mysqltest\_%'; +DELETE FROM mysql.tables_priv WHERE user LIKE 'mysqltest\_%'; +DELETE FROM mysql.columns_priv WHERE user LIKE 'mysqltest\_%'; +FLUSH PRIVILEGES; + +CREATE TABLE t1 (i INT); +CREATE FUNCTION f_suid(i INT) RETURNS INT SQL SECURITY DEFINER RETURN 0; +CREATE PROCEDURE p_suid(IN i INT) SQL SECURITY DEFINER SET @c:= 0; + +CREATE USER mysqltest_u1@localhost; +# Thanks to this grant statement privileges of anonymous users on +# 'test' database are not applicable for mysqltest_u1@localhost. +GRANT EXECUTE ON test.* TO mysqltest_u1@localhost; + +delimiter |; +CREATE DEFINER=mysqltest_u1@localhost FUNCTION f_evil () RETURNS INT + SQL SECURITY INVOKER +BEGIN + SET @a:= CURRENT_USER(); + SET @b:= (SELECT COUNT(*) FROM t1); + RETURN @b; +END| +delimiter ;| + +CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT f_evil(); + +connect (conn1, localhost, mysqltest_u1,,); + +--error ER_TABLEACCESS_DENIED_ERROR +SELECT COUNT(*) FROM t1; + +--error ER_TABLEACCESS_DENIED_ERROR +SELECT f_evil(); +SELECT @a, @b; + +--error ER_TABLEACCESS_DENIED_ERROR +SELECT f_suid(f_evil()); +SELECT @a, @b; + +--error ER_TABLEACCESS_DENIED_ERROR +CALL p_suid(f_evil()); +SELECT @a, @b; + +--error ER_TABLEACCESS_DENIED_ERROR +SELECT * FROM v1; +SELECT @a, @b; + +disconnect conn1; +connection default; + +DROP VIEW v1; +DROP FUNCTION f_evil; +DROP USER mysqltest_u1@localhost; +DROP PROCEDURE p_suid; +DROP FUNCTION f_suid; +DROP TABLE t1; + +--echo End of 5.0 tests. |