List:Commits« Previous MessageNext Message »
From:Tatiana Azundris Nurnberg Date:March 3 2011 10:27am
Subject:bzr commit into mysql-5.0-bugteam branch (azundris:2894) Bug#58677
View as plain text  
#At file:///Users/tnurnberg/forest/58677/50-58677/ based on revid:kent.boortz@stripped

 2894 Tatiana Azundris Nurnberg	2011-03-03
      Bug#58677: No privilege on table / view, but can know #rows / underlying table's name
      
      EXPLAIN SELECT on a view should require SELECT on the 
      underlying table; as it is, SUID (SQL SECURITY DEFINER)
      is applied, allowing the INVOKER to learn information
      about the underlying table, such as its name, number of
      rows, etc.
     @ mysql-test/t/view_grant.test
        Test cases for bug and some corner cases.
     @ sql/sql_view.cc
        Rather than just disable SUID (table->security_ctx= NULL)
        in EXPLAIN, we specify the necessary privileges for
        traversal. This helps with some corner cases.

    modified:
      mysql-test/r/view_grant.result
      mysql-test/t/view_grant.test
      sql/sql_view.cc
=== modified file 'mysql-test/r/view_grant.result'
--- a/mysql-test/r/view_grant.result	2009-08-21 14:10:55 +0000
+++ b/mysql-test/r/view_grant.result	2011-03-03 10:27:11 +0000
@@ -945,4 +945,104 @@ DROP USER foo;
 DROP VIEW db1.v1;
 DROP TABLE db1.t1;
 DROP DATABASE db1;
+Bug #58677: No privilege on table / view, but can know #rows / underlying table's name
+CREATE DATABASE db1;
+USE db1;
+CREATE TABLE t1 (f1 INT);
+CREATE VIEW v_inner AS SELECT * FROM t1;
+CREATE VIEW v_outer AS SELECT * FROM v_inner;
+CREATE USER user2@localhost IDENTIFIED BY '';
+GRANT SELECT ON v_outer TO user2@localhost;
+USE db1;
+user can SELECT v_outer
+SELECT * FROM v_outer;
+f1
+but not do EXPLAIN as it would show underlying table's name
+EXPLAIN SELECT * /* #1 */ FROM v_outer;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+GRANT SHOW VIEW ON v_outer TO user2@localhost;
+user cannot see definition of v_inner
+SHOW CREATE VIEW v_inner;
+ERROR 42000: SELECT command denied to user 'user2'@'localhost' for table 'v_inner'
+neither its underlying table's name
+EXPLAIN SELECT * /* #2 */ FROM v_inner;
+ERROR 42000: SELECT command denied to user 'user2'@'localhost' for table 'v_inner'
+neither t1 directly
+EXPLAIN SELECT * /* #3 */ FROM t1;
+ERROR 42000: SELECT command denied to user 'user2'@'localhost' for table 't1'
+can see v_outer's definition
+SHOW CREATE VIEW v_outer;
+View	Create View
+v_outer	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_outer` AS select `v_inner`.`f1` AS `f1` from `v_inner`
+EXPLAIN SELECT * /* #4 */ FROM v_outer;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+GRANT SHOW VIEW ON v_inner TO user2@localhost;
+fail, invoker now has has SHOW VIEW on inner, but still no SELECT on t1
+EXPLAIN SELECT * /* #5 */ FROM v_outer;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+EXPLAIN SELECT * /* #6 */ FROM v_inner;
+ERROR 42000: SELECT command denied to user 'user2'@'localhost' for table 'v_inner'
+this must succeed; we have SHOW VIEW on v_inner
+SHOW CREATE VIEW v_inner;
+View	Create View
+v_inner	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_inner` AS select `t1`.`f1` AS `f1` from `t1`
+GRANT SELECT ON t1 TO user2@localhost;
+SELECT * FROM t1;
+f1
+EXPLAIN SELECT * /* #7 */ FROM t1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	system	NULL	NULL	NULL	NULL	0	const row not found
+don't have SELECT on v_inner
+SELECT * FROM v_inner;
+ERROR 42000: SELECT command denied to user 'user2'@'localhost' for table 'v_inner'
+EXPLAIN SELECT * /* #8 */ FROM v_inner;
+ERROR 42000: SELECT command denied to user 'user2'@'localhost' for table 'v_inner'
+SHOW CREATE VIEW v_inner;
+View	Create View
+v_inner	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_inner` AS select `t1`.`f1` AS `f1` from `t1`
+fail, invoker has SELECT on v_outer and t1, but not v_inner
+EXPLAIN SELECT * /* #9 */ FROM v_inner;
+ERROR 42000: SELECT command denied to user 'user2'@'localhost' for table 'v_inner'
+succeed, have SELECT on t1, and SHOW VIEW on both v_outer and v_inner
+EXPLAIN SELECT * /* #10 */ FROM v_outer;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	system	NULL	NULL	NULL	NULL	0	const row not found
+REVOKE SHOW VIEW ON v_inner FROM user2@localhost;
+FLUSH PRIVILEGES;
+SELECT * FROM t1;
+f1
+EXPLAIN SELECT * /* #11 */ FROM t1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	system	NULL	NULL	NULL	NULL	0	const row not found
+don't have SELECT on v_inner
+SELECT * FROM v_inner;
+ERROR 42000: SELECT command denied to user 'user2'@'localhost' for table 'v_inner'
+EXPLAIN SELECT * /* #12 */ FROM v_inner;
+ERROR 42000: SELECT command denied to user 'user2'@'localhost' for table 'v_inner'
+SHOW CREATE VIEW v_inner;
+ERROR 42000: SELECT command denied to user 'user2'@'localhost' for table 'v_inner'
+fail, invoker has SELECT on v_outer and t1, but not v_inner
+EXPLAIN SELECT * /* #13 */ FROM v_inner;
+ERROR 42000: SELECT command denied to user 'user2'@'localhost' for table 'v_inner'
+fail, neither SHOW VIEW nor SELECT on v_inner
+EXPLAIN SELECT * /* #14 */ FROM v_outer;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+GRANT SELECT ON v_inner TO user2@localhost;
+SELECT on outer/inner/t1; SHOW VIEW on outer
+EXPLAIN SELECT * /* #15 */  FROM v_outer;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	system	NULL	NULL	NULL	NULL	0	const row not found
+EXPLAIN SELECT * /* #16 */ FROM v_inner;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	system	NULL	NULL	NULL	NULL	0	const row not found
+REVOKE SELECT ON t1 FROM user2@localhost;
+FLUSH PRIVILEGES;
+fail, no SELECT on t1
+EXPLAIN SELECT * /* #17 */  FROM v_outer;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+fail, no SELECT on t1
+EXPLAIN SELECT * /* #18 */ FROM v_inner;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+DROP DATABASE db1;
+DROP USER user2@localhost;
 End of 5.0 tests.

=== modified file 'mysql-test/t/view_grant.test'
--- a/mysql-test/t/view_grant.test	2009-08-21 14:10:55 +0000
+++ b/mysql-test/t/view_grant.test	2011-03-03 10:27:11 +0000
@@ -1232,6 +1232,131 @@ DROP TABLE db1.t1;
 DROP DATABASE db1;
 
 connection default;
+
+
+--echo Bug #58677: No privilege on table / view, but can know #rows / underlying table's name
+
+CREATE DATABASE db1;
+USE db1;
+
+CREATE TABLE t1 (f1 INT);
+CREATE VIEW v_inner AS SELECT * FROM t1;
+CREATE VIEW v_outer AS SELECT * FROM v_inner;
+
+CREATE USER user2@localhost IDENTIFIED BY '';
+GRANT SELECT ON v_outer TO user2@localhost;
+
+connect (con2, localhost, user2,,);
+connection con2;
+USE db1;
+--echo user can SELECT v_outer
+SELECT * FROM v_outer;
+--echo but not do EXPLAIN as it would show underlying table's name
+--error 1345
+EXPLAIN SELECT * /* #1 */ FROM v_outer;
+
+connection default;
+GRANT SHOW VIEW ON v_outer TO user2@localhost;
+
+connection con2;
+--echo user cannot see definition of v_inner
+--error 1142
+SHOW CREATE VIEW v_inner;
+--echo neither its underlying table's name
+--error 1142
+EXPLAIN SELECT * /* #2 */ FROM v_inner;
+--echo neither t1 directly
+--error 1142
+EXPLAIN SELECT * /* #3 */ FROM t1;
+
+--echo can see v_outer's definition
+SHOW CREATE VIEW v_outer;
+--error 1345
+EXPLAIN SELECT * /* #4 */ FROM v_outer;
+
+connection default;
+GRANT SHOW VIEW ON v_inner TO user2@localhost;
+
+connection con2;
+
+--echo fail, invoker now has has SHOW VIEW on inner, but still no SELECT on t1
+--error 1345
+EXPLAIN SELECT * /* #5 */ FROM v_outer;
+--error 1142
+EXPLAIN SELECT * /* #6 */ FROM v_inner;
+
+--echo this must succeed; we have SHOW VIEW on v_inner
+SHOW CREATE VIEW v_inner;
+
+connection default;
+GRANT SELECT ON t1 TO user2@localhost;
+
+connection con2;
+
+SELECT * FROM t1;
+EXPLAIN SELECT * /* #7 */ FROM t1;
+
+--echo don't have SELECT on v_inner
+--error 1142
+SELECT * FROM v_inner;
+--error 1142
+EXPLAIN SELECT * /* #8 */ FROM v_inner;
+SHOW CREATE VIEW v_inner;
+
+--echo fail, invoker has SELECT on v_outer and t1, but not v_inner
+--error 1142
+EXPLAIN SELECT * /* #9 */ FROM v_inner;
+--echo succeed, have SELECT on t1, and SHOW VIEW on both v_outer and v_inner
+EXPLAIN SELECT * /* #10 */ FROM v_outer;
+
+connection default;
+REVOKE SHOW VIEW ON v_inner FROM user2@localhost;
+FLUSH PRIVILEGES;
+
+connection con2;
+SELECT * FROM t1;
+EXPLAIN SELECT * /* #11 */ FROM t1;
+
+--echo don't have SELECT on v_inner
+--error 1142
+SELECT * FROM v_inner;
+--error 1142
+EXPLAIN SELECT * /* #12 */ FROM v_inner;
+--error 1142
+SHOW CREATE VIEW v_inner;
+
+--echo fail, invoker has SELECT on v_outer and t1, but not v_inner
+--error 1142
+EXPLAIN SELECT * /* #13 */ FROM v_inner;
+--echo fail, neither SHOW VIEW nor SELECT on v_inner
+--error 1345
+EXPLAIN SELECT * /* #14 */ FROM v_outer;
+
+connection default;
+GRANT SELECT ON v_inner TO user2@localhost;
+
+connection con2;
+--echo SELECT on outer/inner/t1; SHOW VIEW on outer
+EXPLAIN SELECT * /* #15 */  FROM v_outer;
+EXPLAIN SELECT * /* #16 */ FROM v_inner;
+
+connection default;
+REVOKE SELECT ON t1 FROM user2@localhost;
+FLUSH PRIVILEGES;
+
+connection con2;
+--echo fail, no SELECT on t1
+--error 1345
+EXPLAIN SELECT * /* #17 */  FROM v_outer;
+--echo fail, no SELECT on t1
+--error 1345
+EXPLAIN SELECT * /* #18 */ FROM v_inner;
+
+connection default;
+disconnect con2;
+DROP DATABASE db1;
+DROP USER user2@localhost;
+
 --echo End of 5.0 tests.
 
 # Wait till we reached the initial number of concurrent sessions

=== modified file 'sql/sql_view.cc'
--- a/sql/sql_view.cc	2009-08-28 15:51:31 +0000
+++ b/sql/sql_view.cc	2011-03-03 10:27:11 +0000
@@ -1147,8 +1147,10 @@ bool mysql_make_view(THD *thd, File_pars
     if (!table->prelocking_placeholder &&
         (old_lex->sql_command == SQLCOM_SELECT && old_lex->describe))
     {
-      if (check_table_access(thd, SELECT_ACL, view_tables, 1) &&
-          check_table_access(thd, SHOW_VIEW_ACL, table, 1))
+      if (!(!check_table_access(thd, SELECT_ACL, view_tables, 1) ||
+            !check_table_access(thd, SHOW_VIEW_ACL, view_tables, 1)) ||
+          (!(!check_table_access(thd, SELECT_ACL, table, 1) ||
+             !check_table_access(thd, SHOW_VIEW_ACL, table, 1))))
       {
         my_message(ER_VIEW_NO_EXPLAIN, ER(ER_VIEW_NO_EXPLAIN), MYF(0));
         goto err;


Attachment: [text/bzr-bundle] bzr/azundris@sun.com-20110303102711-6lmk02o2yxgb29u6.bundle
Thread
bzr commit into mysql-5.0-bugteam branch (azundris:2894) Bug#58677Tatiana Azundris Nurnberg3 Mar