summaryrefslogtreecommitdiff
path: root/mysql-test/t/sp-security.test
diff options
context:
space:
mode:
authorunknown <kroki/tomash@moonlight.intranet>2006-07-13 17:12:31 +0400
committerunknown <kroki/tomash@moonlight.intranet>2006-07-13 17:12:31 +0400
commit06bf59ad3381522f4f5ba272a478271c741f0049 (patch)
tree1de91a48fd485ddebde7c556a0e2ccd7d70ed581 /mysql-test/t/sp-security.test
parentfc085d77ade3e0cd77aebe1456c59b951301d722 (diff)
downloadmariadb-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.test78
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.