Commit 108ad9e4 authored by Jon Olav Hauglid's avatar Jon Olav Hauglid

Bug#11882603 SELECT_ACL ON ANY COLUMN IN MYSQL.PROC ALLOWS TO SEE

             DEFINITION OF ANY ROUTINE.

The problem was that having the SELECT privilege any column of the
mysql.proc table by mistake allowed the user to see the definition
of all routines (using SHOW CREATE PROCEDURE/FUNCTION and SHOW
PROCEDURE/FUNCTION CODE).

This patch fixes the problem by making sure that those commands
are only allowed if the user has the SELECT privilege on the
mysql.proc table itself.

Test case added to sp-security.test.
parent 26c03dbf
...@@ -576,3 +576,33 @@ DROP USER 'tester'; ...@@ -576,3 +576,33 @@ DROP USER 'tester';
DROP USER 'Tester'; DROP USER 'Tester';
DROP DATABASE B48872; DROP DATABASE B48872;
End of 5.0 tests. End of 5.0 tests.
#
# Bug#11882603 SELECT_ACL ON ANY COLUMN IN MYSQL.PROC ALLOWS TO SEE
# DEFINITION OF ANY ROUTINE.
#
DROP DATABASE IF EXISTS db1;
CREATE DATABASE db1;
CREATE PROCEDURE db1.p1() SELECT 1;
CREATE USER user2@localhost IDENTIFIED BY '';
GRANT SELECT(db) ON mysql.proc TO user2@localhost;
# Connection con2 as user2
# The below statements before disclosed info from body_utf8 column.
SHOW CREATE PROCEDURE db1.p1;
ERROR 42000: PROCEDURE p1 does not exist
SHOW PROCEDURE CODE db1.p1;
ERROR 42000: PROCEDURE p1 does not exist
# Check that SHOW works with SELECT grant on whole table
# Connection default
GRANT SELECT ON mysql.proc TO user2@localhost;
# Connection con2
# This should work
SHOW CREATE PROCEDURE db1.p1;
Procedure sql_mode Create Procedure
p1 CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
SELECT 1
SHOW PROCEDURE CODE db1.p1;
Pos Instruction
0 stmt 0 "SELECT 1"
# Connection default
DROP USER user2@localhost;
DROP DATABASE db1;
...@@ -950,6 +950,46 @@ DROP DATABASE B48872; ...@@ -950,6 +950,46 @@ DROP DATABASE B48872;
--echo End of 5.0 tests. --echo End of 5.0 tests.
--echo #
--echo # Bug#11882603 SELECT_ACL ON ANY COLUMN IN MYSQL.PROC ALLOWS TO SEE
--echo # DEFINITION OF ANY ROUTINE.
--echo #
--disable_warnings
DROP DATABASE IF EXISTS db1;
--enable_warnings
CREATE DATABASE db1;
CREATE PROCEDURE db1.p1() SELECT 1;
CREATE USER user2@localhost IDENTIFIED BY '';
GRANT SELECT(db) ON mysql.proc TO user2@localhost;
--echo # Connection con2 as user2
connect (con2, localhost, user2);
--echo # The below statements before disclosed info from body_utf8 column.
--error ER_SP_DOES_NOT_EXIST
SHOW CREATE PROCEDURE db1.p1;
--error ER_SP_DOES_NOT_EXIST
SHOW PROCEDURE CODE db1.p1;
--echo # Check that SHOW works with SELECT grant on whole table
--echo # Connection default
connection default;
GRANT SELECT ON mysql.proc TO user2@localhost;
--echo # Connection con2
connection con2;
--echo # This should work
SHOW CREATE PROCEDURE db1.p1;
SHOW PROCEDURE CODE db1.p1;
--echo # Connection default
connection default;
disconnect con2;
DROP USER user2@localhost;
DROP DATABASE db1;
# Wait till all disconnects are completed # Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc --source include/wait_until_count_sessions.inc
...@@ -2168,7 +2168,8 @@ bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access) ...@@ -2168,7 +2168,8 @@ bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access)
bzero((char*) &tables,sizeof(tables)); bzero((char*) &tables,sizeof(tables));
tables.db= (char*) "mysql"; tables.db= (char*) "mysql";
tables.table_name= tables.alias= (char*) "proc"; tables.table_name= tables.alias= (char*) "proc";
*full_access= (!check_table_access(thd, SELECT_ACL, &tables, 1) || *full_access= ((!check_table_access(thd, SELECT_ACL, &tables, TRUE) &&
(tables.grant.privilege & SELECT_ACL) != 0) ||
(!strcmp(sp->m_definer_user.str, (!strcmp(sp->m_definer_user.str,
thd->security_ctx->priv_user) && thd->security_ctx->priv_user) &&
!strcmp(sp->m_definer_host.str, !strcmp(sp->m_definer_host.str,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment