MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:kroki Date:January 18 2007 9:48am
Subject:bk commit into 5.0 tree (kroki:1.2320) BUG#24404
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of tomash. When tomash does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-01-18 12:48:17+03:00, kroki@stripped +3 -0
  Bug#24404: strange bug with view+permission+prepared statement.
  
  The problem was that if a prepared statement accessed a view, the
  access to the tables listed in the query after that view was done in
  the security context of the view.
  
  The bug was in the assigning of the security context to the tables
  belonging to a view: we traversed the list of all query tables
  instead.  It didn't show up in the normal (non-prepared) statements
  because of the different order of the steps of checking privileges
  and descending into a view for normal and prepared statements.
  
  The solution is to traverse the list and stop once the last table
  belonging to the view was processed.

  mysql-test/r/view_grant.result@stripped, 2007-01-18 12:48:15+03:00, kroki@stripped +43 -0
    Add result for bug#24404: strange bug with view+permission+prepared
    statement.

  mysql-test/t/view_grant.test@stripped, 2007-01-18 12:48:15+03:00, kroki@stripped +71 -1
    Add test case for bug#24404: strange bug with view+permission+prepared
    statement.

  sql/sql_view.cc@stripped, 2007-01-18 12:48:15+03:00, kroki@stripped +7 -3
    Remove dead line.
    When setting security context, we should traverse the list of tables
    belonging to a given view, not all query tables.  We achieve that by
    stopping at the first table past view_tables_tail.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	kroki
# Host:	moonlight.home
# Root:	/home/tomash/src/mysql_ab/mysql-5.0-bug24404

--- 1.99/sql/sql_view.cc	2007-01-18 12:48:26 +03:00
+++ 1.100/sql/sql_view.cc	2007-01-18 12:48:26 +03:00
@@ -1136,13 +1136,17 @@ bool mysql_make_view(THD *thd, File_pars
       /*
         Prepare a security context to check underlying objects of the view
       */
-      Security_context *save_security_ctx= thd->security_ctx;
       if (!(table->view_sctx= (Security_context *)
             thd->stmt_arena->alloc(sizeof(Security_context))))
         goto err;
       /* Assign the context to the tables referenced in the view */
-      for (tbl= view_tables; tbl; tbl= tbl->next_global)
-        tbl->security_ctx= table->view_sctx;
+      if (view_tables)
+      {
+        DBUG_ASSERT(view_tables_tail);
+        for (tbl= view_tables; tbl != view_tables_tail->next_global;
+             tbl= tbl->next_global)
+          tbl->security_ctx= table->view_sctx;
+      }
       /* assign security context to SELECT name resolution contexts of view */
       for(SELECT_LEX *sl= lex->all_selects_list;
           sl;

--- 1.19/mysql-test/r/view_grant.result	2007-01-18 12:48:26 +03:00
+++ 1.20/mysql-test/r/view_grant.result	2007-01-18 12:48:26 +03:00
@@ -712,3 +712,46 @@ DROP FUNCTION f1;
 DROP VIEW v2;
 DROP VIEW v1;
 DROP USER mysqltest_u1@localhost;
+DROP DATABASE IF EXISTS mysqltest_db1;
+DROP DATABASE IF EXISTS mysqltest_db2;
+DROP USER mysqltest_u1;
+DROP USER mysqltest_u2;
+CREATE USER mysqltest_u1@localhost;
+CREATE USER mysqltest_u2@localhost;
+CREATE DATABASE mysqltest_db1;
+CREATE DATABASE mysqltest_db2;
+GRANT ALL ON mysqltest_db1.* TO mysqltest_u1@localhost WITH GRANT OPTION;
+GRANT ALL ON mysqltest_db2.* TO mysqltest_u2@localhost;
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (1);
+CREATE VIEW v1 AS SELECT i FROM t1 WHERE 1 IN (SELECT * FROM t1);
+CREATE TABLE t2 (s CHAR(7));
+INSERT INTO t2 VALUES ('public');
+GRANT SELECT ON v1 TO mysqltest_u2@localhost;
+GRANT SELECT ON t2 TO mysqltest_u2@localhost;
+SELECT * FROM mysqltest_db1.v1, mysqltest_db1.t2;
+i	s
+1	public
+PREPARE stmt1 FROM "SELECT * FROM mysqltest_db1.t2";
+EXECUTE stmt1;
+s
+public
+PREPARE stmt2 FROM "SELECT * FROM mysqltest_db1.v1, mysqltest_db1.t2";
+EXECUTE stmt2;
+i	s
+1	public
+REVOKE SELECT ON t2 FROM mysqltest_u2@localhost;
+UPDATE t2 SET s = 'private' WHERE s = 'public';
+SELECT * FROM mysqltest_db1.v1, mysqltest_db1.t2;
+ERROR 42000: SELECT command denied to user 'mysqltest_u2'@'localhost' for table 't2'
+EXECUTE stmt1;
+ERROR 42000: SELECT command denied to user 'mysqltest_u2'@'localhost' for table 't2'
+EXECUTE stmt2;
+ERROR 42000: SELECT command denied to user 'mysqltest_u2'@'localhost' for table 't2'
+REVOKE ALL ON mysqltest_db1.* FROM mysqltest_u1@localhost;
+REVOKE ALL ON mysqltest_db2.* FROM mysqltest_u2@localhost;
+DROP DATABASE mysqltest_db1;
+DROP DATABASE mysqltest_db2;
+DROP USER mysqltest_u1@localhost;
+DROP USER mysqltest_u2@localhost;
+End of 5.0 tests.

--- 1.18/mysql-test/t/view_grant.test	2007-01-18 12:48:26 +03:00
+++ 1.19/mysql-test/t/view_grant.test	2007-01-18 12:48:26 +03:00
@@ -927,4 +927,74 @@ DROP VIEW v2;
 DROP VIEW v1;
 DROP USER mysqltest_u1@localhost;
 
-# End of 5.0 tests.
+
+#
+# BUG#24404: strange bug with view+permission+prepared statement
+#
+--disable_warnings
+DROP DATABASE IF EXISTS mysqltest_db1;
+DROP DATABASE IF EXISTS mysqltest_db2;
+--enable_warnings
+--error 0,ER_CANNOT_USER
+DROP USER mysqltest_u1;
+--error 0,ER_CANNOT_USER
+DROP USER mysqltest_u2;
+
+CREATE USER mysqltest_u1@localhost;
+CREATE USER mysqltest_u2@localhost;
+
+CREATE DATABASE mysqltest_db1;
+CREATE DATABASE mysqltest_db2;
+
+GRANT ALL ON mysqltest_db1.* TO mysqltest_u1@localhost WITH GRANT OPTION;
+GRANT ALL ON mysqltest_db2.* TO mysqltest_u2@localhost;
+
+connect (conn1, localhost, mysqltest_u1, , mysqltest_db1);
+
+CREATE TABLE t1 (i INT);
+INSERT INTO t1 VALUES (1);
+
+# Use view with subquery for better coverage.
+CREATE VIEW v1 AS SELECT i FROM t1 WHERE 1 IN (SELECT * FROM t1);
+
+CREATE TABLE t2 (s CHAR(7));
+INSERT INTO t2 VALUES ('public');
+
+GRANT SELECT ON v1 TO mysqltest_u2@localhost;
+GRANT SELECT ON t2 TO mysqltest_u2@localhost;
+
+connect (conn2, localhost, mysqltest_u2, , mysqltest_db2);
+
+SELECT * FROM mysqltest_db1.v1, mysqltest_db1.t2;
+PREPARE stmt1 FROM "SELECT * FROM mysqltest_db1.t2";
+EXECUTE stmt1;
+PREPARE stmt2 FROM "SELECT * FROM mysqltest_db1.v1, mysqltest_db1.t2";
+EXECUTE stmt2;
+
+connection conn1;
+# Make table 't2' private.
+REVOKE SELECT ON t2 FROM mysqltest_u2@localhost;
+UPDATE t2 SET s = 'private' WHERE s = 'public';
+
+connection conn2;
+--error ER_TABLEACCESS_DENIED_ERROR
+SELECT * FROM mysqltest_db1.v1, mysqltest_db1.t2;
+--error ER_TABLEACCESS_DENIED_ERROR
+EXECUTE stmt1;
+# Original bug was here: the statement didn't fail.
+--error ER_TABLEACCESS_DENIED_ERROR
+EXECUTE stmt2;
+
+# Cleanup.
+disconnect conn2;
+disconnect conn1;
+connection default;
+REVOKE ALL ON mysqltest_db1.* FROM mysqltest_u1@localhost;
+REVOKE ALL ON mysqltest_db2.* FROM mysqltest_u2@localhost;
+DROP DATABASE mysqltest_db1;
+DROP DATABASE mysqltest_db2;
+DROP USER mysqltest_u1@localhost;
+DROP USER mysqltest_u2@localhost;
+
+
+--echo End of 5.0 tests.
Thread
bk commit into 5.0 tree (kroki:1.2320) BUG#24404kroki18 Jan