3257 Jon Olav Hauglid 2011-07-14
Bug#11756966 - 48958: STORED PROCEDURES CAN BE LEVERAGED TO BYPASS
DATABASE SECURITY
The problem was that CREATE PROCEDURE/FUCTION could be used to
check the existence of databases for which the user had no
privileges and therefore should not be allowed to see.
The reason was that existence of a given database was checked
before privileges. So trying to create a stored routine in
a non-existent database would give a different error than trying
to create a stored routine in a restricted database.
This patch fixes the problem by changing the order of the checks
for CREATE PROCEDURE/FUNCTION so that privileges are checked first.
This means that trying to create a stored routine in a
non-existent database and in a restricted database both will
give ER_DBACCESS_DENIED_ERROR error.
Test case added to grant.test.
modified:
mysql-test/r/grant.result
mysql-test/r/information_schema.result
mysql-test/t/grant.test
mysql-test/t/information_schema.test
sql/sql_parse.cc
3256 Jon Olav Hauglid 2011-07-13
Bug #11757397 49437: CANNOT DO SHOW FIELDS FOR BIG VIEW
The problem was that views with too many columns in some
cases would appear to work correctly, while in other cases gave
various error messages. For example, DESCRIBE and SHOW commands
could give "Incorrect key file for table..." errors.
Depending on column datatypes used, views are materialized
as either MyISAM or Memory internal temporary tables.
The root cause of the problem was that MyISAM tables support
a limited number of columns. This is due too a 64K file header
size limitation. This limitation was not checked by CREATE VIEW.
Therefore views with unsupported sizes could be made, leading to
various errors when the view was later used.
This patch fixes the problem by reporting ER_TOO_MANY_FIELDS
error ("Too many columns") if views with more than 4096 columns
are created. Thus ensuring that any MyISAM table which might
be created for view processing will fit into the 64K header limit.
Note that 4096 was chosen as limit as this number is already the
limit on the number of columns for base tables.
Test case added to view.test.
modified:
mysql-test/r/view.result
mysql-test/t/view.test
sql/sql_select.cc
sql/sql_view.cc
=== modified file 'mysql-test/r/grant.result'
--- a/mysql-test/r/grant.result 2011-05-10 13:37:37 +0000
+++ b/mysql-test/r/grant.result 2011-07-14 07:32:01 +0000
@@ -2559,3 +2559,29 @@ Grants for mysqltest_u1@%
GRANT USAGE ON *.* TO 'mysqltest_u1'@'%'
drop database mysqltest_db1;
drop user mysqltest_u1;
+#
+# Bug#11756966 - 48958: STORED PROCEDURES CAN BE LEVERAGED TO BYPASS
+# DATABASE SECURITY
+#
+DROP DATABASE IF EXISTS secret;
+DROP DATABASE IF EXISTS no_such_db;
+CREATE DATABASE secret;
+GRANT USAGE ON *.* TO 'untrusted'@localhost;
+# Connection con1
+SHOW GRANTS;
+Grants for untrusted@localhost
+GRANT USAGE ON *.* TO 'untrusted'@'localhost'
+SHOW DATABASES;
+Database
+information_schema
+test
+# Both statements below should fail with the same error.
+# They used to give different errors, thereby
+# hinting that the secret database exists.
+CREATE PROCEDURE no_such_db.foo() BEGIN END;
+ERROR 42000: Access denied for user 'untrusted'@'localhost' to database 'no_such_db'
+CREATE PROCEDURE secret.peek_at_secret() BEGIN END;
+ERROR 42000: Access denied for user 'untrusted'@'localhost' to database 'secret'
+# Connection default
+DROP USER 'untrusted'@localhost;
+DROP DATABASE secret;
=== modified file 'mysql-test/r/information_schema.result'
--- a/mysql-test/r/information_schema.result 2011-03-11 18:53:12 +0000
+++ b/mysql-test/r/information_schema.result 2011-07-14 07:32:01 +0000
@@ -1111,7 +1111,7 @@ CREATE PROCEDURE p1 ()
BEGIN
SELECT 'foo' FROM DUAL;
END |
-ERROR 42000: Unknown database 'information_schema'
+ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
select ROUTINE_NAME from routines where ROUTINE_SCHEMA='information_schema';
ROUTINE_NAME
grant all on information_schema.* to 'user1'@'localhost';
=== modified file 'mysql-test/t/grant.test'
--- a/mysql-test/t/grant.test 2011-04-22 12:59:10 +0000
+++ b/mysql-test/t/grant.test 2011-07-14 07:32:01 +0000
@@ -1863,9 +1863,6 @@ revoke select on Foo.* from myuser@local
delete from mysql.user where User='myuser';
flush privileges;
-# Wait till we reached the initial number of concurrent sessions
---source include/wait_until_count_sessions.inc
-
--echo #########################################################################
--echo #
--echo # Bug#38347: ALTER ROUTINE privilege allows SHOW CREATE TABLE.
@@ -2212,3 +2209,40 @@ grant select on mysqltest_db1.t1 to mysq
show grants for mysqltest_u1;
drop database mysqltest_db1;
drop user mysqltest_u1;
+
+
+--echo #
+--echo # Bug#11756966 - 48958: STORED PROCEDURES CAN BE LEVERAGED TO BYPASS
+--echo # DATABASE SECURITY
+--echo #
+
+--disable_warnings
+DROP DATABASE IF EXISTS secret;
+DROP DATABASE IF EXISTS no_such_db;
+--enable_warnings
+
+CREATE DATABASE secret;
+GRANT USAGE ON *.* TO 'untrusted'@localhost;
+
+--echo # Connection con1
+connect (con1, localhost, untrusted);
+SHOW GRANTS;
+SHOW DATABASES;
+
+--echo # Both statements below should fail with the same error.
+--echo # They used to give different errors, thereby
+--echo # hinting that the secret database exists.
+--error ER_DBACCESS_DENIED_ERROR
+CREATE PROCEDURE no_such_db.foo() BEGIN END;
+--error ER_DBACCESS_DENIED_ERROR
+CREATE PROCEDURE secret.peek_at_secret() BEGIN END;
+
+--echo # Connection default
+--connection default
+disconnect con1;
+DROP USER 'untrusted'@localhost;
+DROP DATABASE secret;
+
+
+# Wait till we reached the initial number of concurrent sessions
+--source include/wait_until_count_sessions.inc
=== modified file 'mysql-test/t/information_schema.test'
--- a/mysql-test/t/information_schema.test 2011-05-04 09:54:04 +0000
+++ b/mysql-test/t/information_schema.test 2011-07-14 07:32:01 +0000
@@ -750,7 +750,7 @@ create temporary table schemata(f1 char(
# Bug#10708 SP's can use INFORMATION_SCHEMA as ROUTINE_SCHEMA
#
delimiter |;
---error ER_BAD_DB_ERROR
+--error ER_DBACCESS_DENIED_ERROR
CREATE PROCEDURE p1 ()
BEGIN
SELECT 'foo' FROM DUAL;
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2011-07-07 12:44:34 +0000
+++ b/sql/sql_parse.cc 2011-07-14 07:32:01 +0000
@@ -3927,6 +3927,10 @@ end_with_restore_list:
goto create_sp_error;
}
+ if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str,
+ NULL, NULL, 0, 0))
+ goto create_sp_error;
+
/*
Check that a database directory with this name
exists. Design note: This won't work on virtual databases
@@ -3938,10 +3942,6 @@ end_with_restore_list:
goto create_sp_error;
}
- if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str,
- NULL, NULL, 0, 0))
- goto create_sp_error;
-
name= lex->sphead->name(&namelen);
#ifdef HAVE_DLOPEN
if (lex->sphead->m_type == TYPE_ENUM_FUNCTION)
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-trunk branch (jon.hauglid:3256 to 3257) Bug#11756966 | Jon Olav Hauglid | 17 Jul |