List:Commits« Previous MessageNext Message »
From:Martin Hansson Date:September 21 2009 1:09pm
Subject:bzr commit into mysql-5.1-bugteam branch (mhansson:3115) Bug#35996
View as plain text  
#At file:///data0/martin/bzr/bug35996/5.1bt/ based on revid:li-bing.song@stripped

 3115 Martin Hansson	2009-09-21
      Bug#35996: Security Breach In Smashed TEMPTABLE Views During SHOW CREATE VIEW there is no reason to 'anonymize' errors that name objects that a user does not have access to. Moreover it was inconsistently implemented. For example base tables being referenced from a view appear to be ok, but not views. The manual on the other hand is clear: If a user has the privileges SELECT and SHOW VIEW, the view definition is available to that user, period. The fix changes the behavior to support the manual. 

    modified:
      mysql-test/r/information_schema_db.result
      mysql-test/r/view_grant.result
      mysql-test/t/information_schema_db.test
      mysql-test/t/view_grant.test
      sql/sql_acl.cc
      sql/sql_show.cc
      sql/table.cc
=== modified file 'mysql-test/r/information_schema_db.result'
--- a/mysql-test/r/information_schema_db.result	2009-05-15 15:47:50 +0000
+++ b/mysql-test/r/information_schema_db.result	2009-09-21 13:09:48 +0000
@@ -139,7 +139,7 @@ show create view testdb_1.v7;
 View	Create View	character_set_client	collation_connection
 v7	CREATE ALGORITHM=UNDEFINED DEFINER=`no_such_user`@`no_such_host` SQL SECURITY DEFINER VIEW `v7` AS select `testdb_1`.`t2`.`f1` AS `f1` from `t2`	latin1	latin1_swedish_ci
 Warnings:
-Warning	1356	View 'testdb_1.v7' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+Note	1449	The user specified as a definer ('no_such_user'@'no_such_host') does not exist
 show fields from testdb_1.v7;
 Field	Type	Null	Key	Default	Extra
 f1	char(4)	YES		NULL	
@@ -169,7 +169,7 @@ show create view testdb_1.v7;
 View	Create View	character_set_client	collation_connection
 v7	CREATE ALGORITHM=UNDEFINED DEFINER=`no_such_user`@`no_such_host` SQL SECURITY DEFINER VIEW `v7` AS select `testdb_1`.`t2`.`f1` AS `f1` from `t2`	latin1	latin1_swedish_ci
 Warnings:
-Warning	1356	View 'testdb_1.v7' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+Note	1449	The user specified as a definer ('no_such_user'@'no_such_host') does not exist
 revoke insert(f1) on v3 from testdb_2@localhost;
 revoke show view on v5 from testdb_2@localhost;
 use testdb_1;
@@ -187,7 +187,8 @@ ERROR 42000: SELECT command denied to us
 show create view testdb_1.v7;
 ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v7'
 show create view v4;
-ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+View	Create View	character_set_client	collation_connection
+v4	CREATE ALGORITHM=UNDEFINED DEFINER=`testdb_2`@`localhost` SQL SECURITY DEFINER VIEW `v4` AS select `v3`.`f1` AS `f1`,`v3`.`f2` AS `f2` from `testdb_1`.`v3`	latin1	latin1_swedish_ci
 show fields from v4;
 Field	Type	Null	Key	Default	Extra
 f1	char(4)	YES		NULL	

=== modified file 'mysql-test/r/view_grant.result'
--- a/mysql-test/r/view_grant.result	2009-08-21 14:41:48 +0000
+++ b/mysql-test/r/view_grant.result	2009-09-21 13:09:48 +0000
@@ -606,7 +606,7 @@ SHOW CREATE VIEW v;
 View	Create View	character_set_client	collation_connection
 v	CREATE ALGORITHM=UNDEFINED DEFINER=`no-such-user`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select `test`.`t1`.`a` AS `a` from `t1`	latin1	latin1_swedish_ci
 Warnings:
-Warning	1356	View 'test.v' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+Note	1449	The user specified as a definer ('no-such-user'@'localhost') does not exist
 SELECT * FROM v;
 ERROR HY000: The user specified as a definer ('no-such-user'@'localhost') does not exist
 DROP VIEW v;
@@ -963,7 +963,7 @@ SHOW CREATE VIEW v1;
 View	Create View	character_set_client	collation_connection
 v1	CREATE ALGORITHM=UNDEFINED DEFINER=`no_such`@`user_1` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`i` AS `i` from `t1`	latin1	latin1_swedish_ci
 Warnings:
-Warning	1356	View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+Note	1449	The user specified as a definer ('no_such'@'user_1') does not exist
 ALTER ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1;
 Warnings:
 Note	1449	The user specified as a definer ('no_such'@'user_1') does not exist
@@ -971,7 +971,7 @@ SHOW CREATE VIEW v1;
 View	Create View	character_set_client	collation_connection
 v1	CREATE ALGORITHM=MERGE DEFINER=`no_such`@`user_1` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`i` AS `i` from `t1`	latin1	latin1_swedish_ci
 Warnings:
-Warning	1356	View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+Note	1449	The user specified as a definer ('no_such'@'user_1') does not exist
 ALTER ALGORITHM=TEMPTABLE DEFINER=no_such@user_2 VIEW v1 AS SELECT * FROM t1;
 Warnings:
 Note	1449	The user specified as a definer ('no_such'@'user_2') does not exist
@@ -979,7 +979,7 @@ SHOW CREATE VIEW v1;
 View	Create View	character_set_client	collation_connection
 v1	CREATE ALGORITHM=TEMPTABLE DEFINER=`no_such`@`user_2` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`i` AS `i` from `t1`	latin1	latin1_swedish_ci
 Warnings:
-Warning	1356	View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+Note	1449	The user specified as a definer ('no_such'@'user_2') does not exist
 DROP VIEW v1;
 DROP TABLE t1;
 CREATE USER mysqluser1@localhost;
@@ -1044,3 +1044,185 @@ DROP DATABASE mysqltest1;
 DROP VIEW test.v3;
 DROP USER mysqluser1@localhost;
 USE test;
+#
+# Bug#35996: Security Breach In Smashed TEMPTABLE Views
+#
+CREATE USER mysqluser1@localhost;
+CREATE DATABASE mysqltest1;
+CREATE DATABASE mysqltest2;
+GRANT USAGE, SELECT, CREATE VIEW, SHOW VIEW 
+ON mysqltest2.* TO mysqluser1@localhost;
+USE mysqltest1;
+CREATE TABLE t1( a INT );
+CREATE TABLE t2( a INT, b INT );
+CREATE FUNCTION f1() RETURNS INT RETURN 1;
+CREATE VIEW v1 AS SELECT 1 AS a;
+CREATE VIEW v2 AS SELECT 1 AS a, 2 AS b;
+GRANT SELECT        ON TABLE    t1 TO mysqluser1@localhost;
+GRANT SELECT (a, b) ON TABLE    t2 TO mysqluser1@localhost;
+GRANT EXECUTE       ON FUNCTION f1 TO mysqluser1@localhost;
+GRANT SELECT        ON TABLE    v1 TO mysqluser1@localhost;
+GRANT SELECT (a, b) ON TABLE    v2 TO mysqluser1@localhost;
+CREATE VIEW v_t1 AS SELECT * FROM t1;
+CREATE VIEW v_t2 AS SELECT * FROM t2;
+CREATE VIEW v_f1 AS SELECT f1() AS a;
+CREATE VIEW v_v1 AS SELECT * FROM v1;
+CREATE VIEW v_v2 AS SELECT * FROM v2;
+GRANT SELECT, SHOW VIEW ON v_t1 TO mysqluser1@localhost;
+GRANT SELECT, SHOW VIEW ON v_t2 TO mysqluser1@localhost;
+GRANT SELECT, SHOW VIEW ON v_f1 TO mysqluser1@localhost;
+GRANT SELECT, SHOW VIEW ON v_v1 TO mysqluser1@localhost;
+GRANT SELECT, SHOW VIEW ON v_v2 TO mysqluser1@localhost;
+CREATE VIEW v_mysqluser1_t1 AS SELECT * FROM mysqltest1.t1;
+CREATE VIEW v_mysqluser1_t2 AS SELECT * FROM mysqltest1.t2;
+CREATE VIEW v_mysqluser1_f1 AS SELECT mysqltest1.f1() AS a;
+CREATE VIEW v_mysqluser1_v1 AS SELECT * FROM mysqltest1.v1;
+CREATE VIEW v_mysqluser1_v2 AS SELECT * FROM mysqltest1.v2;
+SHOW CREATE VIEW mysqltest1.v_t1;
+View	Create View	character_set_client	collation_connection
+v_t1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1`	latin1	latin1_swedish_ci
+SHOW CREATE VIEW mysqltest1.v_t2;
+View	Create View	character_set_client	collation_connection
+v_t2	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_t2` AS select `mysqltest1`.`t2`.`a` AS `a`,`mysqltest1`.`t2`.`b` AS `b` from `mysqltest1`.`t2`	latin1	latin1_swedish_ci
+SHOW CREATE VIEW mysqltest1.v_f1;
+View	Create View	character_set_client	collation_connection
+v_f1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_f1` AS select `f1`() AS `a`	latin1	latin1_swedish_ci
+SHOW CREATE VIEW mysqltest1.v_v1;
+View	Create View	character_set_client	collation_connection
+v_v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_v1` AS select `v1`.`a` AS `a` from `mysqltest1`.`v1`	latin1	latin1_swedish_ci
+SHOW CREATE VIEW mysqltest1.v_v2;
+View	Create View	character_set_client	collation_connection
+v_v2	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_v2` AS select `v2`.`a` AS `a`,`v2`.`b` AS `b` from `mysqltest1`.`v2`	latin1	latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_t1;
+View	Create View	character_set_client	collation_connection
+v_mysqluser1_t1	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1`	latin1	latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_t2;
+View	Create View	character_set_client	collation_connection
+v_mysqluser1_t2	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_t2` AS select `mysqltest1`.`t2`.`a` AS `a`,`mysqltest1`.`t2`.`b` AS `b` from `mysqltest1`.`t2`	latin1	latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_f1;
+View	Create View	character_set_client	collation_connection
+v_mysqluser1_f1	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_f1` AS select `mysqltest1`.`f1`() AS `a`	latin1	latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_v1;
+View	Create View	character_set_client	collation_connection
+v_mysqluser1_v1	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_v1` AS select `v1`.`a` AS `a` from `mysqltest1`.`v1`	latin1	latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_v2;
+View	Create View	character_set_client	collation_connection
+v_mysqluser1_v2	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_v2` AS select `v2`.`a` AS `a`,`v2`.`b` AS `b` from `mysqltest1`.`v2`	latin1	latin1_swedish_ci
+REVOKE SELECT     ON TABLE    t1 FROM mysqluser1@localhost;
+REVOKE SELECT (a) ON TABLE    t2 FROM mysqluser1@localhost;
+REVOKE EXECUTE    ON FUNCTION f1 FROM mysqluser1@localhost;
+REVOKE SELECT     ON TABLE    v1 FROM mysqluser1@localhost;
+SHOW CREATE VIEW mysqltest1.v_t1;
+View	Create View	character_set_client	collation_connection
+v_t1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1`	latin1	latin1_swedish_ci
+SHOW CREATE VIEW mysqltest1.v_t2;
+View	Create View	character_set_client	collation_connection
+v_t2	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_t2` AS select `mysqltest1`.`t2`.`a` AS `a`,`mysqltest1`.`t2`.`b` AS `b` from `mysqltest1`.`t2`	latin1	latin1_swedish_ci
+SHOW CREATE VIEW mysqltest1.v_f1;
+View	Create View	character_set_client	collation_connection
+v_f1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_f1` AS select `f1`() AS `a`	latin1	latin1_swedish_ci
+SHOW CREATE VIEW mysqltest1.v_v1;
+View	Create View	character_set_client	collation_connection
+v_v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_v1` AS select `v1`.`a` AS `a` from `mysqltest1`.`v1`	latin1	latin1_swedish_ci
+SHOW CREATE VIEW mysqltest1.v_v2;
+View	Create View	character_set_client	collation_connection
+v_v2	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_v2` AS select `v2`.`a` AS `a`,`v2`.`b` AS `b` from `mysqltest1`.`v2`	latin1	latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_t1;
+View	Create View	character_set_client	collation_connection
+v_mysqluser1_t1	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1`	latin1	latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_t2;
+View	Create View	character_set_client	collation_connection
+v_mysqluser1_t2	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_t2` AS select `mysqltest1`.`t2`.`a` AS `a`,`mysqltest1`.`t2`.`b` AS `b` from `mysqltest1`.`t2`	latin1	latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_f1;
+View	Create View	character_set_client	collation_connection
+v_mysqluser1_f1	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_f1` AS select `mysqltest1`.`f1`() AS `a`	latin1	latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_v1;
+View	Create View	character_set_client	collation_connection
+v_mysqluser1_v1	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_v1` AS select `v1`.`a` AS `a` from `mysqltest1`.`v1`	latin1	latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_v2;
+View	Create View	character_set_client	collation_connection
+v_mysqluser1_v2	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_v2` AS select `v2`.`a` AS `a`,`v2`.`b` AS `b` from `mysqltest1`.`v2`	latin1	latin1_swedish_ci
+DROP TABLE t1;
+DROP FUNCTION f1;
+DROP VIEW v1;
+SHOW CREATE VIEW mysqltest1.v_t1;
+View	Create View	character_set_client	collation_connection
+v_t1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1`	latin1	latin1_swedish_ci
+Warnings:
+Warning	1356	View 'mysqltest1.v_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+SHOW CREATE VIEW mysqltest1.v_t2;
+View	Create View	character_set_client	collation_connection
+v_t2	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_t2` AS select `mysqltest1`.`t2`.`a` AS `a`,`mysqltest1`.`t2`.`b` AS `b` from `mysqltest1`.`t2`	latin1	latin1_swedish_ci
+SHOW CREATE VIEW mysqltest1.v_f1;
+View	Create View	character_set_client	collation_connection
+v_f1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_f1` AS select `f1`() AS `a`	latin1	latin1_swedish_ci
+Warnings:
+Warning	1356	View 'mysqltest1.v_f1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+SHOW CREATE VIEW mysqltest1.v_v1;
+View	Create View	character_set_client	collation_connection
+v_v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_v1` AS select `v1`.`a` AS `a` from `mysqltest1`.`v1`	latin1	latin1_swedish_ci
+Warnings:
+Warning	1356	View 'mysqltest1.v_v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+SHOW CREATE VIEW mysqltest1.v_v2;
+View	Create View	character_set_client	collation_connection
+v_v2	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest1`.`v_v2` AS select `v2`.`a` AS `a`,`v2`.`b` AS `b` from `mysqltest1`.`v2`	latin1	latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_t1;
+View	Create View	character_set_client	collation_connection
+v_mysqluser1_t1	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1`	latin1	latin1_swedish_ci
+Warnings:
+Warning	1356	View 'mysqltest2.v_mysqluser1_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+SHOW CREATE VIEW v_mysqluser1_t2;
+View	Create View	character_set_client	collation_connection
+v_mysqluser1_t2	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_t2` AS select `mysqltest1`.`t2`.`a` AS `a`,`mysqltest1`.`t2`.`b` AS `b` from `mysqltest1`.`t2`	latin1	latin1_swedish_ci
+SHOW CREATE VIEW v_mysqluser1_f1;
+View	Create View	character_set_client	collation_connection
+v_mysqluser1_f1	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_f1` AS select `mysqltest1`.`f1`() AS `a`	latin1	latin1_swedish_ci
+Warnings:
+Warning	1356	View 'mysqltest2.v_mysqluser1_f1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+SHOW CREATE VIEW v_mysqluser1_v1;
+View	Create View	character_set_client	collation_connection
+v_mysqluser1_v1	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_v1` AS select `v1`.`a` AS `a` from `mysqltest1`.`v1`	latin1	latin1_swedish_ci
+Warnings:
+Warning	1356	View 'mysqltest2.v_mysqluser1_v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+SHOW CREATE VIEW v_mysqluser1_v2;
+View	Create View	character_set_client	collation_connection
+v_mysqluser1_v2	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_v2` AS select `v2`.`a` AS `a`,`v2`.`b` AS `b` from `mysqltest1`.`v2`	latin1	latin1_swedish_ci
+REVOKE SHOW VIEW ON v_t1 FROM mysqluser1@localhost;
+REVOKE SHOW VIEW ON v_f1 FROM mysqluser1@localhost;
+REVOKE SHOW VIEW ON v_v1 FROM mysqluser1@localhost;
+SHOW CREATE VIEW mysqltest1.v_t1;
+ERROR 42000: SHOW VIEW command denied to user 'mysqluser1'@'localhost' for table 'v_t1'
+SHOW CREATE VIEW mysqltest1.v_f1;
+ERROR 42000: SHOW VIEW command denied to user 'mysqluser1'@'localhost' for table 'v_f1'
+SHOW CREATE VIEW mysqltest1.v_v1;
+ERROR 42000: SHOW VIEW command denied to user 'mysqluser1'@'localhost' for table 'v_v1'
+SHOW CREATE VIEW v_mysqluser1_t1;
+View	Create View	character_set_client	collation_connection
+v_mysqluser1_t1	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_t1` AS select `mysqltest1`.`t1`.`a` AS `a` from `mysqltest1`.`t1`	latin1	latin1_swedish_ci
+Warnings:
+Warning	1356	View 'mysqltest2.v_mysqluser1_t1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+SHOW CREATE VIEW v_mysqluser1_f1;
+View	Create View	character_set_client	collation_connection
+v_mysqluser1_f1	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_f1` AS select `mysqltest1`.`f1`() AS `a`	latin1	latin1_swedish_ci
+Warnings:
+Warning	1356	View 'mysqltest2.v_mysqluser1_f1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+SHOW CREATE VIEW v_mysqluser1_v1;
+View	Create View	character_set_client	collation_connection
+v_mysqluser1_v1	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqluser1`@`localhost` SQL SECURITY DEFINER VIEW `v_mysqluser1_v1` AS select `v1`.`a` AS `a` from `mysqltest1`.`v1`	latin1	latin1_swedish_ci
+Warnings:
+Warning	1356	View 'mysqltest2.v_mysqluser1_v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+DROP USER mysqluser1@localhost;
+DROP DATABASE mysqltest1;
+DROP DATABASE mysqltest2;
+USE test;
+CREATE TABLE t1( a INT );
+CREATE DEFINER = no_such_user@no_such_host VIEW v1 AS SELECT * FROM t1;
+Warnings:
+Note	1449	The user specified as a definer ('no_such_user'@'no_such_host') does not exist
+SHOW CREATE VIEW v1;
+View	Create View	character_set_client	collation_connection
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`no_such_user`@`no_such_host` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`a` AS `a` from `t1`	latin1	latin1_swedish_ci
+Warnings:
+Note	1449	The user specified as a definer ('no_such_user'@'no_such_host') does not exist
+DROP TABLE t1;
+DROP VIEW v1;

=== modified file 'mysql-test/t/information_schema_db.test'
--- a/mysql-test/t/information_schema_db.test	2009-05-15 09:59:31 +0000
+++ b/mysql-test/t/information_schema_db.test	2009-09-21 13:09:48 +0000
@@ -184,7 +184,6 @@ show fields from testdb_1.v7;
 --error ER_TABLEACCESS_DENIED_ERROR
 show create view testdb_1.v7;
 
---error ER_VIEW_NO_EXPLAIN
 show create view v4;
 #--error ER_VIEW_NO_EXPLAIN
 show fields from v4;

=== modified file 'mysql-test/t/view_grant.test'
--- a/mysql-test/t/view_grant.test	2009-08-21 14:41:48 +0000
+++ b/mysql-test/t/view_grant.test	2009-09-21 13:09:48 +0000
@@ -1382,6 +1382,127 @@ DROP VIEW test.v3;
 DROP USER mysqluser1@localhost;
 USE test;
 
+--echo #
+--echo # Bug#35996: Security Breach In Smashed TEMPTABLE Views
+--echo #
+-- source include/not_embedded.inc
+CREATE USER mysqluser1@localhost;
+CREATE DATABASE mysqltest1;
+CREATE DATABASE mysqltest2;
+GRANT USAGE, SELECT, CREATE VIEW, SHOW VIEW 
+ON mysqltest2.* TO mysqluser1@localhost;
+
+USE mysqltest1;
+
+CREATE TABLE t1( a INT );
+CREATE TABLE t2( a INT, b INT );
+CREATE FUNCTION f1() RETURNS INT RETURN 1;
+CREATE VIEW v1 AS SELECT 1 AS a;
+CREATE VIEW v2 AS SELECT 1 AS a, 2 AS b;
+
+GRANT SELECT        ON TABLE    t1 TO mysqluser1@localhost;
+GRANT SELECT (a, b) ON TABLE    t2 TO mysqluser1@localhost;
+GRANT EXECUTE       ON FUNCTION f1 TO mysqluser1@localhost;
+GRANT SELECT        ON TABLE    v1 TO mysqluser1@localhost;
+GRANT SELECT (a, b) ON TABLE    v2 TO mysqluser1@localhost;
+
+CREATE VIEW v_t1 AS SELECT * FROM t1;
+CREATE VIEW v_t2 AS SELECT * FROM t2;
+CREATE VIEW v_f1 AS SELECT f1() AS a;
+CREATE VIEW v_v1 AS SELECT * FROM v1;
+CREATE VIEW v_v2 AS SELECT * FROM v2;
+
+GRANT SELECT, SHOW VIEW ON v_t1 TO mysqluser1@localhost;
+GRANT SELECT, SHOW VIEW ON v_t2 TO mysqluser1@localhost;
+GRANT SELECT, SHOW VIEW ON v_f1 TO mysqluser1@localhost;
+GRANT SELECT, SHOW VIEW ON v_v1 TO mysqluser1@localhost;
+GRANT SELECT, SHOW VIEW ON v_v2 TO mysqluser1@localhost;
+
+--connect (connection1, localhost, mysqluser1,, mysqltest2)
+CREATE VIEW v_mysqluser1_t1 AS SELECT * FROM mysqltest1.t1;
+CREATE VIEW v_mysqluser1_t2 AS SELECT * FROM mysqltest1.t2;
+CREATE VIEW v_mysqluser1_f1 AS SELECT mysqltest1.f1() AS a;
+CREATE VIEW v_mysqluser1_v1 AS SELECT * FROM mysqltest1.v1;
+CREATE VIEW v_mysqluser1_v2 AS SELECT * FROM mysqltest1.v2;
+
+SHOW CREATE VIEW mysqltest1.v_t1;
+SHOW CREATE VIEW mysqltest1.v_t2;
+SHOW CREATE VIEW mysqltest1.v_f1;
+SHOW CREATE VIEW mysqltest1.v_v1;
+SHOW CREATE VIEW mysqltest1.v_v2;
+
+SHOW CREATE VIEW v_mysqluser1_t1;
+SHOW CREATE VIEW v_mysqluser1_t2;
+SHOW CREATE VIEW v_mysqluser1_f1;
+SHOW CREATE VIEW v_mysqluser1_v1;
+SHOW CREATE VIEW v_mysqluser1_v2;
+
+--connection default
+REVOKE SELECT     ON TABLE    t1 FROM mysqluser1@localhost;
+REVOKE SELECT (a) ON TABLE    t2 FROM mysqluser1@localhost;
+REVOKE EXECUTE    ON FUNCTION f1 FROM mysqluser1@localhost;
+REVOKE SELECT     ON TABLE    v1 FROM mysqluser1@localhost;
+
+--connection connection1
+SHOW CREATE VIEW mysqltest1.v_t1;
+SHOW CREATE VIEW mysqltest1.v_t2;
+SHOW CREATE VIEW mysqltest1.v_f1;
+SHOW CREATE VIEW mysqltest1.v_v1;
+SHOW CREATE VIEW mysqltest1.v_v2;
+
+SHOW CREATE VIEW v_mysqluser1_t1;
+SHOW CREATE VIEW v_mysqluser1_t2;
+SHOW CREATE VIEW v_mysqluser1_f1;
+SHOW CREATE VIEW v_mysqluser1_v1;
+SHOW CREATE VIEW v_mysqluser1_v2;
+
+--connection default
+DROP TABLE t1;
+DROP FUNCTION f1;
+DROP VIEW v1;
+
+--connection connection1
+SHOW CREATE VIEW mysqltest1.v_t1;
+SHOW CREATE VIEW mysqltest1.v_t2;
+SHOW CREATE VIEW mysqltest1.v_f1;
+SHOW CREATE VIEW mysqltest1.v_v1;
+SHOW CREATE VIEW mysqltest1.v_v2;
+
+SHOW CREATE VIEW v_mysqluser1_t1;
+SHOW CREATE VIEW v_mysqluser1_t2;
+SHOW CREATE VIEW v_mysqluser1_f1;
+SHOW CREATE VIEW v_mysqluser1_v1;
+SHOW CREATE VIEW v_mysqluser1_v2;
+
+--connection default
+REVOKE SHOW VIEW ON v_t1 FROM mysqluser1@localhost;
+REVOKE SHOW VIEW ON v_f1 FROM mysqluser1@localhost;
+REVOKE SHOW VIEW ON v_v1 FROM mysqluser1@localhost;
+
+--connection connection1
+--error ER_TABLEACCESS_DENIED_ERROR
+SHOW CREATE VIEW mysqltest1.v_t1;
+--error ER_TABLEACCESS_DENIED_ERROR
+SHOW CREATE VIEW mysqltest1.v_f1;
+--error ER_TABLEACCESS_DENIED_ERROR
+SHOW CREATE VIEW mysqltest1.v_v1;
+SHOW CREATE VIEW v_mysqluser1_t1;
+SHOW CREATE VIEW v_mysqluser1_f1;
+SHOW CREATE VIEW v_mysqluser1_v1;
+
+--disconnect connection1
+--connection default
+DROP USER mysqluser1@localhost;
+DROP DATABASE mysqltest1;
+DROP DATABASE mysqltest2;
+USE test;
+
+CREATE TABLE t1( a INT );
+CREATE DEFINER = no_such_user@no_such_host VIEW v1 AS SELECT * FROM t1;
+SHOW CREATE VIEW v1;
+DROP TABLE t1;
+DROP VIEW v1;
+
 # Wait till we reached the initial number of concurrent sessions
 --source include/wait_until_count_sessions.inc
 

=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc	2009-08-28 16:21:54 +0000
+++ b/sql/sql_acl.cc	2009-09-21 13:09:48 +0000
@@ -4072,8 +4072,7 @@ bool check_column_grant_in_table_ref(THD
     db_name= table_ref->view_db.str;
     table_name= table_ref->view_name.str;
     if (table_ref->belong_to_view && 
-        (thd->lex->sql_command == SQLCOM_SHOW_FIELDS ||
-         thd->lex->sql_command == SQLCOM_SHOW_CREATE))
+        thd->lex->sql_command == SQLCOM_SHOW_FIELDS)
     {
       view_privs= get_column_grant(thd, grant, db_name, table_name, name);
       if (view_privs & VIEW_ANY_ACL)

=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc	2009-08-28 16:21:54 +0000
+++ b/sql/sql_show.cc	2009-09-21 13:09:48 +0000
@@ -581,6 +581,136 @@ find_files(THD *thd, List<LEX_STRING> *f
 }
 
 
+/**
+   An Internal_error_handler that suppresses errors regarding views'
+   underlying tables that occur during privilege checking within SHOW CREATE
+   VIEW commands. This happens in the cases when
+
+   - A view's underlying table (e.g. referenced in its SELECT list) does not
+     exist. There should not be an error as no attempt was made to access it
+     per se.
+
+   - Access is denied for some table, column, function or stored procedure
+     such as mentioned above. This error gets raised automatically, since we
+     can't untangle its access checking from that of the view itself.
+ */
+class Show_create_error_handler : public Internal_error_handler {
+  
+  TABLE_LIST *m_top_view;
+  bool m_handling;
+  Security_context *m_sctx;
+
+  char m_view_access_denied_message[MYSQL_ERRMSG_SIZE];
+  char *m_view_access_denied_message_ptr;
+
+public:
+
+  /**
+     Creates a new Show_create_error_handler for the particular security
+     context and view. 
+
+     @thd Thread context, used for security context information if needed.
+     @top_view The view. We do not verify at this point that top_view is in
+     fact a view since, alas, these things do not stay constant.
+  */
+  explicit Show_create_error_handler(THD *thd, TABLE_LIST *top_view) : 
+    m_top_view(top_view), m_handling(FALSE),
+    m_view_access_denied_message_ptr(NULL) {
+    
+    m_sctx = test(m_top_view->security_ctx) ?
+      m_top_view->security_ctx : thd->security_ctx;
+  }
+
+  /**
+     Lazy instantiation of 'view access denied' message. The purpose of the
+     Show_create_error_handler is to hide details of underlying tables for
+     which we have no privileges behind ER_VIEW_INVALID messages. But this
+     obviously does not apply if we lack privileges on the view itself.
+     Unfortunately the information about for which table privilege checking
+     failed is not available at this point. The only way for us to check is by
+     reconstructing the actual error message and see if it's the same.
+  */
+  char* get_view_access_denied_message() {
+    if (!m_view_access_denied_message_ptr)
+    {
+      m_view_access_denied_message_ptr= m_view_access_denied_message;
+      my_snprintf(m_view_access_denied_message, MYSQL_ERRMSG_SIZE,
+                  ER(ER_TABLEACCESS_DENIED_ERROR), "SHOW VIEW",
+                  m_sctx->priv_user,
+                  m_sctx->host_or_ip, m_top_view->get_table_name());
+    }
+    return m_view_access_denied_message_ptr;
+  }
+
+  bool handle_error(uint sql_errno, const char *message, 
+                    MYSQL_ERROR::enum_warning_level level, THD *thd) {
+    /* 
+       The handler does not handle the errors raised by itself.
+       At this point we know if top_view is really a view.
+    */
+    if (m_handling || !m_top_view->view)
+      return FALSE;
+
+    m_handling= TRUE;
+
+    bool is_handled;
+    
+    switch (sql_errno)
+    {
+    case ER_TABLEACCESS_DENIED_ERROR:
+      if (!strcmp(get_view_access_denied_message(), message))
+        /* Access to top view is not granted, don't interfere. */
+        is_handled= FALSE;
+      else
+        /* Current user has no access to underlying table, irrelevant */
+        is_handled= TRUE;
+      break;
+
+    case ER_COLUMNACCESS_DENIED_ERROR:
+      /* Current user has no access to underlying table, irrelevant */
+      is_handled= TRUE;
+      break;
+
+    case ER_VIEW_NO_EXPLAIN:
+      /* 
+         Current user has no access to an underlying table, and the error
+         message was anonymized. We ignore this.
+      */
+      is_handled= TRUE;
+      break;
+
+    case ER_NO_SUCH_TABLE:
+      /* Established behavior: warn if underlying tables are missing. */
+      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 
+                          ER_VIEW_INVALID,
+                          ER(ER_VIEW_INVALID),
+                          m_top_view->get_db_name(),
+                          m_top_view->get_table_name());
+      is_handled= TRUE;
+      break;
+    case ER_PROCACCESS_DENIED_ERROR:
+      /* Current user has no access to underlying function/proc, irrelevant */
+      is_handled= TRUE;
+      break;
+    case ER_SP_DOES_NOT_EXIST:
+      /* Established behavior: warn if underlying functions are missing. */
+      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 
+                          ER_VIEW_INVALID,
+                          ER(ER_VIEW_INVALID),
+                          m_top_view->get_db_name(),
+                          m_top_view->get_table_name());
+      is_handled= TRUE;
+      break;
+    default:
+      is_handled= FALSE;
+    }
+
+    m_handling= FALSE;
+    return is_handled;
+  }
+};
+
+
 bool
 mysqld_show_create(THD *thd, TABLE_LIST *table_list)
 {
@@ -594,26 +724,13 @@ mysqld_show_create(THD *thd, TABLE_LIST 
   /* We want to preserve the tree for views. */
   thd->lex->view_prepare_mode= TRUE;
 
-  /* Only one table for now, but VIEW can involve several tables */
-  if (open_normal_and_derived_tables(thd, table_list, 0))
   {
-    if (!table_list->view ||
-        (thd->is_error() && thd->main_da.sql_errno() != ER_VIEW_INVALID))
+    Show_create_error_handler view_error_suppressor(thd, table_list);
+    thd->push_internal_handler(&view_error_suppressor);
+    bool error= open_normal_and_derived_tables(thd, table_list, 0);
+    thd->pop_internal_handler();
+    if (error && thd->main_da.is_error())
       DBUG_RETURN(TRUE);
-
-    /*
-      Clear all messages with 'error' level status and
-      issue a warning with 'warning' level status in 
-      case of invalid view and last error is ER_VIEW_INVALID
-    */
-    mysql_reset_errors(thd, true);
-    thd->clear_error();
-
-    push_warning_printf(thd,MYSQL_ERROR::WARN_LEVEL_WARN,
-                        ER_VIEW_INVALID,
-                        ER(ER_VIEW_INVALID),
-                        table_list->view_db.str,
-                        table_list->view_name.str);
   }
 
   /* TODO: add environment variables show when it become possible */

=== modified file 'sql/table.cc'
--- a/sql/table.cc	2009-08-12 09:46:08 +0000
+++ b/sql/table.cc	2009-09-21 13:09:48 +0000
@@ -3338,7 +3338,12 @@ bool TABLE_LIST::prep_check_option(THD *
 
 
 /**
-  Hide errors which show view underlying table information
+  Hide errors which show view underlying table information. 
+  There are currently two mechanisms at work that handle errors for views,
+  this one and a more general mechanism based on an Internal_error_handler,
+  see Show_create_error_handler. The latter handles errors encountered during
+  execution of SHOW CREATE VIEW, while the machanism using this method is
+  handles SELECT from views. The two methods should not clash.
 
   @param[in,out]  thd     thread handler
 
@@ -3347,6 +3352,8 @@ bool TABLE_LIST::prep_check_option(THD *
 
 void TABLE_LIST::hide_view_error(THD *thd)
 {
+  if (thd->get_internal_handler())
+    return;
   /* Hide "Unknown column" or "Unknown function" error */
   DBUG_ASSERT(thd->is_error());
 


Attachment: [text/bzr-bundle] bzr/mhansson@mysql.com-20090921130948-d7pbswqm5on6aqpc.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (mhansson:3115) Bug#35996Martin Hansson21 Sep