From c0cfce21d6cf6d1a1fbd8b080f91ed6a88b78329 Mon Sep 17 00:00:00 2001 From: Martin Hansson Date: Tue, 9 Sep 2008 12:49:08 +0200 Subject: [PATCH] Bug#35600: Security breach via view, I_S table and prepared statement/stored procedure View privileges are properly checked after the fix for bug no 36086, so the method TABLE_LIST::get_db_name() must be used instead of field TABLE_LIST::db, as this only works for tables. Bug appears when accessing views in prepared statements. mysql-test/r/view_grant.result: Bug#35600: Extended existing test case. mysql-test/t/view_grant.test: Bug#35600: Extended existing test result. sql/sql_parse.cc: Bug#35600: Using method to retrieve database name instead of field. --- mysql-test/r/view_grant.result | 7 +++++++ mysql-test/t/view_grant.test | 11 ++++++++++- sql/sql_parse.cc | 10 ++++++---- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result index 9a4fa95912d..1821e50e294 100644 --- a/mysql-test/r/view_grant.result +++ b/mysql-test/r/view_grant.result @@ -978,7 +978,9 @@ CREATE DATABASE mysqltest1; USE mysqltest1; CREATE VIEW v1 AS SELECT * FROM information_schema.tables LIMIT 1; CREATE ALGORITHM = TEMPTABLE VIEW v2 AS SELECT 1 AS A; +CREATE VIEW test.v3 AS SELECT 1 AS a; GRANT SELECT ON mysqltest1.* to mysqluser1@localhost; +GRANT ALL ON test.* TO mysqluser1@localhost; PREPARE stmt_v1 FROM "SELECT * FROM mysqltest1.v1"; PREPARE stmt_v2 FROM "SELECT * FROM mysqltest1.v2"; REVOKE SELECT ON mysqltest1.* FROM mysqluser1@localhost; @@ -986,6 +988,11 @@ EXECUTE stmt_v1; ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 'v1' EXECUTE stmt_v2; ERROR 42000: SELECT command denied to user 'mysqluser1'@'localhost' for table 'v2' +PREPARE stmt FROM "SELECT a FROM v3"; +EXECUTE stmt; +a +1 DROP VIEW v1, v2; DROP DATABASE mysqltest1; +DROP VIEW test.v3; DROP USER mysqluser1@localhost; diff --git a/mysql-test/t/view_grant.test b/mysql-test/t/view_grant.test index afef5c5bc7b..4e8d97e4444 100644 --- a/mysql-test/t/view_grant.test +++ b/mysql-test/t/view_grant.test @@ -1265,8 +1265,11 @@ USE mysqltest1; CREATE VIEW v1 AS SELECT * FROM information_schema.tables LIMIT 1; CREATE ALGORITHM = TEMPTABLE VIEW v2 AS SELECT 1 AS A; +CREATE VIEW test.v3 AS SELECT 1 AS a; + --connection default GRANT SELECT ON mysqltest1.* to mysqluser1@localhost; +GRANT ALL ON test.* TO mysqluser1@localhost; --connect (connection1, localhost, mysqluser1, , test) PREPARE stmt_v1 FROM "SELECT * FROM mysqltest1.v1"; @@ -1281,9 +1284,15 @@ REVOKE SELECT ON mysqltest1.* FROM mysqluser1@localhost; EXECUTE stmt_v1; --error ER_TABLEACCESS_DENIED_ERROR EXECUTE stmt_v2; - --disconnect connection1 + +--connect (connection2, localhost, mysqluser1,,) +PREPARE stmt FROM "SELECT a FROM v3"; +EXECUTE stmt; +--disconnect connection2 + --connection default DROP VIEW v1, v2; DROP DATABASE mysqltest1; +DROP VIEW test.v3; DROP USER mysqluser1@localhost; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 9bfa21b5e4b..ee52a516147 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5196,12 +5196,14 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, tables->grant.privilege= want_access; else if (tables->db && thd->db && strcmp(tables->db, thd->db) == 0) { - if (check_access(thd,want_access,tables->db,&tables->grant.privilege, - 0, no_errors, test(tables->schema_table))) + if (check_access(thd, want_access, tables->get_db_name(), + &tables->grant.privilege, 0, no_errors, + test(tables->schema_table))) goto deny; // Access denied } - else if (check_access(thd,want_access,tables->db,&tables->grant.privilege, - 0, no_errors, test(tables->schema_table))) + else if (check_access(thd, want_access, tables->get_db_name(), + &tables->grant.privilege, 0, no_errors, + test(tables->schema_table))) goto deny; } thd->security_ctx= backup_ctx;