summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2019-09-10 17:31:10 +0200
committerSergei Golubchik <serg@mariadb.org>2019-10-28 08:17:56 +0100
commitc075c7a861e4d6062d02ac07fe496f9021601b50 (patch)
treea5c0c153ec03fab9f9d5af47c00873214f1ee47d
parentbe780c05559731e09aed2e8a06f93a72d5d51b7f (diff)
downloadmariadb-git-c075c7a861e4d6062d02ac07fe496f9021601b50.tar.gz
MDEV-20549 SQL SECURITY DEFINER does not work for INFORMATION_SCHEMA tables
switch to definer privileges when populating I_S tables
-rw-r--r--mysql-test/r/information_schema_db.result79
-rw-r--r--mysql-test/suite/funcs_1/r/is_basics_mixed.result2
-rw-r--r--mysql-test/suite/funcs_1/t/is_basics_mixed.test5
-rw-r--r--mysql-test/suite/innodb/r/information_schema_grants.result304
-rw-r--r--mysql-test/suite/innodb/t/information_schema_grants.opt33
-rw-r--r--mysql-test/suite/innodb/t/information_schema_grants.test311
-rw-r--r--mysql-test/t/information_schema_db.test44
-rw-r--r--sql/sql_show.cc1
8 files changed, 776 insertions, 3 deletions
diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result
index ca1ab45b98b..6cc158a567e 100644
--- a/mysql-test/r/information_schema_db.result
+++ b/mysql-test/r/information_schema_db.result
@@ -244,3 +244,82 @@ connection user1;
disconnect user1;
connection default;
set global sql_mode=default;
+create user foo@localhost;
+grant select on test.* to foo@localhost;
+create procedure rootonly() select 1;
+create sql security definer view v1d as select current_user(),user from information_schema.processlist;
+create sql security invoker view v1i as select current_user(),user from information_schema.processlist;
+create sql security definer view v2d as select table_name from information_schema.tables where table_schema='mysql' and table_name like '%user%';
+create sql security invoker view v2i as select table_name from information_schema.tables where table_schema='mysql' and table_name like '%user%';
+create sql security definer view v3d as select schema_name from information_schema.schemata where schema_name like '%mysql%';
+create sql security invoker view v3i as select schema_name from information_schema.schemata where schema_name like '%mysql%';
+create sql security definer view v4d as select routine_name from information_schema.routines where routine_schema='test';
+create sql security invoker view v4i as select routine_name from information_schema.routines where routine_schema='test';
+create sql security definer view v5d as select view_definition > '' from information_schema.views where table_name='v1d';
+create sql security invoker view v5i as select view_definition > '' from information_schema.views where table_name='v1d';
+connect foo,localhost,foo;
+select * from v1d;
+current_user() user
+root@localhost root
+root@localhost root
+select * from v1i;
+current_user() user
+foo@localhost foo
+select * from v2d;
+table_name
+user
+select * from v2i;
+table_name
+select * from v3d;
+schema_name
+mysql
+select * from v3i;
+schema_name
+select * from v4d;
+routine_name
+rootonly
+select * from v4i;
+routine_name
+select * from v5d;
+view_definition > ''
+1
+select * from v5i;
+view_definition > ''
+0
+connection default;
+select * from v1d;
+current_user() user
+root@localhost foo
+root@localhost root
+select * from v1i;
+current_user() user
+root@localhost foo
+root@localhost root
+select * from v2d;
+table_name
+user
+select * from v2i;
+table_name
+user
+select * from v3d;
+schema_name
+mysql
+select * from v3i;
+schema_name
+mysql
+select * from v4d;
+routine_name
+rootonly
+select * from v4i;
+routine_name
+rootonly
+select * from v5d;
+view_definition > ''
+1
+select * from v5i;
+view_definition > ''
+1
+disconnect foo;
+drop view v1d, v1i, v2d, v2i, v3d, v3i, v4d, v4i, v5d, v5i;
+drop user foo@localhost;
+drop procedure rootonly;
diff --git a/mysql-test/suite/funcs_1/r/is_basics_mixed.result b/mysql-test/suite/funcs_1/r/is_basics_mixed.result
index 2d14ada4f89..770435475a3 100644
--- a/mysql-test/suite/funcs_1/r/is_basics_mixed.result
+++ b/mysql-test/suite/funcs_1/r/is_basics_mixed.result
@@ -337,7 +337,7 @@ GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE
SELECT * FROM information_schema.schema_privileges
WHERE table_schema = 'information_schema';
GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE IS_GRANTABLE
-CREATE VIEW db_datadict.v2 AS
+CREATE SQL SECURITY INVOKER VIEW db_datadict.v2 AS
SELECT TABLE_SCHEMA,TABLE_NAME,TABLE_TYPE
FROM information_schema.tables WHERE table_schema = 'db_datadict';
SELECT TABLE_SCHEMA,TABLE_NAME,TABLE_TYPE
diff --git a/mysql-test/suite/funcs_1/t/is_basics_mixed.test b/mysql-test/suite/funcs_1/t/is_basics_mixed.test
index c0b03a84478..2bbd751a010 100644
--- a/mysql-test/suite/funcs_1/t/is_basics_mixed.test
+++ b/mysql-test/suite/funcs_1/t/is_basics_mixed.test
@@ -281,8 +281,9 @@ WHERE table_schema = 'information_schema';
# 2. This user (testuser1) is also able to GRANT the SELECT privilege
# on this VIEW to another user (testuser2).
# 3. The other user (testuser2) must be able to SELECT on this VIEW
-# but gets a different result set than testuser1.
-CREATE VIEW db_datadict.v2 AS
+# but gets a different result set than testuser1, if the view
+# has SQL SECURITY INVOKER.
+CREATE SQL SECURITY INVOKER VIEW db_datadict.v2 AS
SELECT TABLE_SCHEMA,TABLE_NAME,TABLE_TYPE
FROM information_schema.tables WHERE table_schema = 'db_datadict';
SELECT TABLE_SCHEMA,TABLE_NAME,TABLE_TYPE
diff --git a/mysql-test/suite/innodb/r/information_schema_grants.result b/mysql-test/suite/innodb/r/information_schema_grants.result
new file mode 100644
index 00000000000..6ef1ce170cd
--- /dev/null
+++ b/mysql-test/suite/innodb/r/information_schema_grants.result
@@ -0,0 +1,304 @@
+select plugin_name,plugin_status as 'Must be ACTIVE' from information_schema.plugins where plugin_name like 'inno%' and plugin_status!='ACTIVE';
+plugin_name Must be ACTIVE
+create user select_only@localhost;
+grant select on *.* to select_only@localhost;
+connect select_only,localhost,select_only;
+connection default;
+create sql security invoker view i_buffer_page as select * from information_schema.innodb_buffer_page;
+create sql security definer view d_buffer_page as select * from information_schema.innodb_buffer_page;
+create sql security invoker view i_buffer_page_lru as select * from information_schema.innodb_buffer_page_lru;
+create sql security definer view d_buffer_page_lru as select * from information_schema.innodb_buffer_page_lru;
+create sql security invoker view i_buffer_pool_stats as select * from information_schema.innodb_buffer_pool_stats;
+create sql security definer view d_buffer_pool_stats as select * from information_schema.innodb_buffer_pool_stats;
+create sql security invoker view i_cmp as select * from information_schema.innodb_cmp;
+create sql security definer view d_cmp as select * from information_schema.innodb_cmp;
+create sql security invoker view i_cmp_per_index as select * from information_schema.innodb_cmp_per_index;
+create sql security definer view d_cmp_per_index as select * from information_schema.innodb_cmp_per_index;
+create sql security invoker view i_cmp_per_index_reset as select * from information_schema.innodb_cmp_per_index_reset;
+create sql security definer view d_cmp_per_index_reset as select * from information_schema.innodb_cmp_per_index_reset;
+create sql security invoker view i_cmp_reset as select * from information_schema.innodb_cmp_reset;
+create sql security definer view d_cmp_reset as select * from information_schema.innodb_cmp_reset;
+create sql security invoker view i_cmpmem as select * from information_schema.innodb_cmpmem;
+create sql security definer view d_cmpmem as select * from information_schema.innodb_cmpmem;
+create sql security invoker view i_cmpmem_reset as select * from information_schema.innodb_cmpmem_reset;
+create sql security definer view d_cmpmem_reset as select * from information_schema.innodb_cmpmem_reset;
+create sql security invoker view i_ft_being_deleted as select * from information_schema.innodb_ft_being_deleted;
+create sql security definer view d_ft_being_deleted as select * from information_schema.innodb_ft_being_deleted;
+create sql security invoker view i_ft_config as select * from information_schema.innodb_ft_config;
+create sql security definer view d_ft_config as select * from information_schema.innodb_ft_config;
+create sql security invoker view i_ft_default_stopword as select * from information_schema.innodb_ft_default_stopword;
+create sql security definer view d_ft_default_stopword as select * from information_schema.innodb_ft_default_stopword;
+create sql security invoker view i_ft_deleted as select * from information_schema.innodb_ft_deleted;
+create sql security definer view d_ft_deleted as select * from information_schema.innodb_ft_deleted;
+create sql security invoker view i_ft_index_cache as select * from information_schema.innodb_ft_index_cache;
+create sql security definer view d_ft_index_cache as select * from information_schema.innodb_ft_index_cache;
+create sql security invoker view i_ft_index_table as select * from information_schema.innodb_ft_index_table;
+create sql security definer view d_ft_index_table as select * from information_schema.innodb_ft_index_table;
+create sql security invoker view i_lock_waits as select * from information_schema.innodb_lock_waits;
+create sql security definer view d_lock_waits as select * from information_schema.innodb_lock_waits;
+create sql security invoker view i_locks as select * from information_schema.innodb_locks;
+create sql security definer view d_locks as select * from information_schema.innodb_locks;
+create sql security invoker view i_metrics as select * from information_schema.innodb_metrics;
+create sql security definer view d_metrics as select * from information_schema.innodb_metrics;
+create sql security invoker view i_mutexes as select * from information_schema.innodb_mutexes;
+create sql security definer view d_mutexes as select * from information_schema.innodb_mutexes;
+create sql security invoker view i_sys_columns as select * from information_schema.innodb_sys_columns;
+create sql security definer view d_sys_columns as select * from information_schema.innodb_sys_columns;
+create sql security invoker view i_sys_datafiles as select * from information_schema.innodb_sys_datafiles;
+create sql security definer view d_sys_datafiles as select * from information_schema.innodb_sys_datafiles;
+create sql security invoker view i_sys_fields as select * from information_schema.innodb_sys_fields;
+create sql security definer view d_sys_fields as select * from information_schema.innodb_sys_fields;
+create sql security invoker view i_sys_foreign as select * from information_schema.innodb_sys_foreign;
+create sql security definer view d_sys_foreign as select * from information_schema.innodb_sys_foreign;
+create sql security invoker view i_sys_foreign_cols as select * from information_schema.innodb_sys_foreign_cols;
+create sql security definer view d_sys_foreign_cols as select * from information_schema.innodb_sys_foreign_cols;
+create sql security invoker view i_sys_indexes as select * from information_schema.innodb_sys_indexes;
+create sql security definer view d_sys_indexes as select * from information_schema.innodb_sys_indexes;
+create sql security invoker view i_sys_semaphore_waits as select * from information_schema.innodb_sys_semaphore_waits;
+create sql security definer view d_sys_semaphore_waits as select * from information_schema.innodb_sys_semaphore_waits;
+create sql security invoker view i_sys_tables as select * from information_schema.innodb_sys_tables;
+create sql security definer view d_sys_tables as select * from information_schema.innodb_sys_tables;
+create sql security invoker view i_sys_tablespaces as select * from information_schema.innodb_sys_tablespaces;
+create sql security definer view d_sys_tablespaces as select * from information_schema.innodb_sys_tablespaces;
+create sql security invoker view i_sys_tablestats as select * from information_schema.innodb_sys_tablestats;
+create sql security definer view d_sys_tablestats as select * from information_schema.innodb_sys_tablestats;
+create sql security invoker view i_sys_virtual as select * from information_schema.innodb_sys_virtual;
+create sql security definer view d_sys_virtual as select * from information_schema.innodb_sys_virtual;
+create sql security invoker view i_tablespaces_encryption as select * from information_schema.innodb_tablespaces_encryption;
+create sql security definer view d_tablespaces_encryption as select * from information_schema.innodb_tablespaces_encryption;
+create sql security invoker view i_tablespaces_scrubbing as select * from information_schema.innodb_tablespaces_scrubbing;
+create sql security definer view d_tablespaces_scrubbing as select * from information_schema.innodb_tablespaces_scrubbing;
+create sql security invoker view i_trx as select * from information_schema.innodb_trx;
+create sql security definer view d_trx as select * from information_schema.innodb_trx;
+connection select_only;
+select count(*) > -1 from information_schema.innodb_buffer_page;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_buffer_page;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_buffer_page;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_buffer_page_lru;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_buffer_page_lru;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_buffer_page_lru;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_buffer_pool_stats;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_buffer_pool_stats;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_buffer_pool_stats;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_cmp;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_cmp;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_cmp;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_cmp_per_index;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_cmp_per_index;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_cmp_per_index;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_cmp_per_index_reset;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_cmp_per_index_reset;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_cmp_per_index_reset;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_cmp_reset;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_cmp_reset;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_cmp_reset;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_cmpmem;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_cmpmem;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_cmpmem;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_cmpmem_reset;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_cmpmem_reset;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_cmpmem_reset;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_ft_being_deleted;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_ft_being_deleted;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_ft_being_deleted;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_ft_config;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_ft_config;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_ft_config;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_ft_default_stopword;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_ft_deleted;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_ft_deleted;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_ft_deleted;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_ft_index_cache;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_ft_index_cache;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_ft_index_cache;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_ft_index_table;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_ft_index_table;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_ft_index_table;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_lock_waits;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_lock_waits;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_lock_waits;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_locks;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_locks;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_locks;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_metrics;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_metrics;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_metrics;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_mutexes;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_mutexes;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_mutexes;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_sys_columns;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_sys_columns;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_sys_columns;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_sys_datafiles;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_sys_datafiles;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_sys_datafiles;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_sys_fields;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_sys_fields;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_sys_fields;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_sys_foreign;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_sys_foreign;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_sys_foreign;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_sys_foreign_cols;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_sys_foreign_cols;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_sys_foreign_cols;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_sys_indexes;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_sys_indexes;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_sys_indexes;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_sys_semaphore_waits;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_sys_semaphore_waits;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_sys_semaphore_waits;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_sys_tables;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_sys_tables;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_sys_tables;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_sys_tablespaces;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_sys_tablespaces;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_sys_tablespaces;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_sys_tablestats;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_sys_tablestats;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_sys_tablestats;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_sys_virtual;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_sys_virtual;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_sys_virtual;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_tablespaces_encryption;
+ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
+select count(*) > -1 from i_tablespaces_encryption;
+ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
+select count(*) > -1 from d_tablespaces_encryption;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_tablespaces_scrubbing;
+ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
+select count(*) > -1 from i_tablespaces_scrubbing;
+ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
+select count(*) > -1 from d_tablespaces_scrubbing;
+count(*) > -1
+1
+select count(*) > -1 from information_schema.innodb_trx;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from i_trx;
+ERROR 42000: Access denied; you need (at least one of) the PROCESS privilege(s) for this operation
+select count(*) > -1 from d_trx;
+count(*) > -1
+1
+connection default;
+drop database test;
+create database test;
+drop user select_only@localhost;
diff --git a/mysql-test/suite/innodb/t/information_schema_grants.opt b/mysql-test/suite/innodb/t/information_schema_grants.opt
new file mode 100644
index 00000000000..ce08c46f047
--- /dev/null
+++ b/mysql-test/suite/innodb/t/information_schema_grants.opt
@@ -0,0 +1,33 @@
+--enable-plugin-innodb-trx
+--enable-plugin-innodb-locks
+--enable-plugin-innodb-lock-waits
+--enable-plugin-innodb-cmp
+--enable-plugin-innodb-cmp-reset
+--enable-plugin-innodb-cmpmem
+--enable-plugin-innodb-cmpmem-reset
+--enable-plugin-innodb-cmp-per-index
+--enable-plugin-innodb-cmp-per-index-reset
+--enable-plugin-innodb-buffer-page
+--enable-plugin-innodb-buffer-page-lru
+--enable-plugin-innodb-buffer-pool-stats
+--enable-plugin-innodb-metrics
+--enable-plugin-innodb-ft-default-stopword
+--enable-plugin-innodb-ft-deleted
+--enable-plugin-innodb-ft-being-deleted
+--enable-plugin-innodb-ft-config
+--enable-plugin-innodb-ft-index-cache
+--enable-plugin-innodb-ft-index-table
+--enable-plugin-innodb-sys-tables
+--enable-plugin-innodb-sys-tablestats
+--enable-plugin-innodb-sys-indexes
+--enable-plugin-innodb-sys-columns
+--enable-plugin-innodb-sys-fields
+--enable-plugin-innodb-sys-foreign
+--enable-plugin-innodb-sys-foreign-cols
+--enable-plugin-innodb-sys-tablespaces
+--enable-plugin-innodb-sys-datafiles
+--enable-plugin-innodb-sys-virtual
+--enable-plugin-innodb-mutexes
+--enable-plugin-innodb-sys-semaphore-waits
+--enable-plugin-innodb-tablespaces-encryption
+--enable-plugin-innodb-tablespaces-scrubbing
diff --git a/mysql-test/suite/innodb/t/information_schema_grants.test b/mysql-test/suite/innodb/t/information_schema_grants.test
new file mode 100644
index 00000000000..34565f76352
--- /dev/null
+++ b/mysql-test/suite/innodb/t/information_schema_grants.test
@@ -0,0 +1,311 @@
+source include/have_innodb.inc;
+source include/not_embedded.inc;
+
+# make sure we've enabled everything:
+select plugin_name,plugin_status as 'Must be ACTIVE' from information_schema.plugins where plugin_name like 'inno%' and plugin_status!='ACTIVE';
+
+create user select_only@localhost;
+grant select on *.* to select_only@localhost;
+
+connect select_only,localhost,select_only;
+connection default;
+
+create sql security invoker view i_buffer_page as select * from information_schema.innodb_buffer_page;
+create sql security definer view d_buffer_page as select * from information_schema.innodb_buffer_page;
+
+create sql security invoker view i_buffer_page_lru as select * from information_schema.innodb_buffer_page_lru;
+create sql security definer view d_buffer_page_lru as select * from information_schema.innodb_buffer_page_lru;
+
+create sql security invoker view i_buffer_pool_stats as select * from information_schema.innodb_buffer_pool_stats;
+create sql security definer view d_buffer_pool_stats as select * from information_schema.innodb_buffer_pool_stats;
+
+create sql security invoker view i_cmp as select * from information_schema.innodb_cmp;
+create sql security definer view d_cmp as select * from information_schema.innodb_cmp;
+
+create sql security invoker view i_cmp_per_index as select * from information_schema.innodb_cmp_per_index;
+create sql security definer view d_cmp_per_index as select * from information_schema.innodb_cmp_per_index;
+
+create sql security invoker view i_cmp_per_index_reset as select * from information_schema.innodb_cmp_per_index_reset;
+create sql security definer view d_cmp_per_index_reset as select * from information_schema.innodb_cmp_per_index_reset;
+
+create sql security invoker view i_cmp_reset as select * from information_schema.innodb_cmp_reset;
+create sql security definer view d_cmp_reset as select * from information_schema.innodb_cmp_reset;
+
+create sql security invoker view i_cmpmem as select * from information_schema.innodb_cmpmem;
+create sql security definer view d_cmpmem as select * from information_schema.innodb_cmpmem;
+
+create sql security invoker view i_cmpmem_reset as select * from information_schema.innodb_cmpmem_reset;
+create sql security definer view d_cmpmem_reset as select * from information_schema.innodb_cmpmem_reset;
+
+create sql security invoker view i_ft_being_deleted as select * from information_schema.innodb_ft_being_deleted;
+create sql security definer view d_ft_being_deleted as select * from information_schema.innodb_ft_being_deleted;
+
+create sql security invoker view i_ft_config as select * from information_schema.innodb_ft_config;
+create sql security definer view d_ft_config as select * from information_schema.innodb_ft_config;
+
+create sql security invoker view i_ft_default_stopword as select * from information_schema.innodb_ft_default_stopword;
+create sql security definer view d_ft_default_stopword as select * from information_schema.innodb_ft_default_stopword;
+
+create sql security invoker view i_ft_deleted as select * from information_schema.innodb_ft_deleted;
+create sql security definer view d_ft_deleted as select * from information_schema.innodb_ft_deleted;
+
+create sql security invoker view i_ft_index_cache as select * from information_schema.innodb_ft_index_cache;
+create sql security definer view d_ft_index_cache as select * from information_schema.innodb_ft_index_cache;
+
+create sql security invoker view i_ft_index_table as select * from information_schema.innodb_ft_index_table;
+create sql security definer view d_ft_index_table as select * from information_schema.innodb_ft_index_table;
+
+create sql security invoker view i_lock_waits as select * from information_schema.innodb_lock_waits;
+create sql security definer view d_lock_waits as select * from information_schema.innodb_lock_waits;
+
+create sql security invoker view i_locks as select * from information_schema.innodb_locks;
+create sql security definer view d_locks as select * from information_schema.innodb_locks;
+
+create sql security invoker view i_metrics as select * from information_schema.innodb_metrics;
+create sql security definer view d_metrics as select * from information_schema.innodb_metrics;
+
+create sql security invoker view i_mutexes as select * from information_schema.innodb_mutexes;
+create sql security definer view d_mutexes as select * from information_schema.innodb_mutexes;
+
+create sql security invoker view i_sys_columns as select * from information_schema.innodb_sys_columns;
+create sql security definer view d_sys_columns as select * from information_schema.innodb_sys_columns;
+
+create sql security invoker view i_sys_datafiles as select * from information_schema.innodb_sys_datafiles;
+create sql security definer view d_sys_datafiles as select * from information_schema.innodb_sys_datafiles;
+
+create sql security invoker view i_sys_fields as select * from information_schema.innodb_sys_fields;
+create sql security definer view d_sys_fields as select * from information_schema.innodb_sys_fields;
+
+create sql security invoker view i_sys_foreign as select * from information_schema.innodb_sys_foreign;
+create sql security definer view d_sys_foreign as select * from information_schema.innodb_sys_foreign;
+
+create sql security invoker view i_sys_foreign_cols as select * from information_schema.innodb_sys_foreign_cols;
+create sql security definer view d_sys_foreign_cols as select * from information_schema.innodb_sys_foreign_cols;
+
+create sql security invoker view i_sys_indexes as select * from information_schema.innodb_sys_indexes;
+create sql security definer view d_sys_indexes as select * from information_schema.innodb_sys_indexes;
+
+create sql security invoker view i_sys_semaphore_waits as select * from information_schema.innodb_sys_semaphore_waits;
+create sql security definer view d_sys_semaphore_waits as select * from information_schema.innodb_sys_semaphore_waits;
+
+create sql security invoker view i_sys_tables as select * from information_schema.innodb_sys_tables;
+create sql security definer view d_sys_tables as select * from information_schema.innodb_sys_tables;
+
+create sql security invoker view i_sys_tablespaces as select * from information_schema.innodb_sys_tablespaces;
+create sql security definer view d_sys_tablespaces as select * from information_schema.innodb_sys_tablespaces;
+
+create sql security invoker view i_sys_tablestats as select * from information_schema.innodb_sys_tablestats;
+create sql security definer view d_sys_tablestats as select * from information_schema.innodb_sys_tablestats;
+
+create sql security invoker view i_sys_virtual as select * from information_schema.innodb_sys_virtual;
+create sql security definer view d_sys_virtual as select * from information_schema.innodb_sys_virtual;
+
+create sql security invoker view i_tablespaces_encryption as select * from information_schema.innodb_tablespaces_encryption;
+create sql security definer view d_tablespaces_encryption as select * from information_schema.innodb_tablespaces_encryption;
+
+create sql security invoker view i_tablespaces_scrubbing as select * from information_schema.innodb_tablespaces_scrubbing;
+create sql security definer view d_tablespaces_scrubbing as select * from information_schema.innodb_tablespaces_scrubbing;
+
+create sql security invoker view i_trx as select * from information_schema.innodb_trx;
+create sql security definer view d_trx as select * from information_schema.innodb_trx;
+
+connection select_only;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_buffer_page;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_buffer_page;
+select count(*) > -1 from d_buffer_page;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_buffer_page_lru;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_buffer_page_lru;
+select count(*) > -1 from d_buffer_page_lru;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_buffer_pool_stats;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_buffer_pool_stats;
+select count(*) > -1 from d_buffer_pool_stats;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_cmp;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_cmp;
+select count(*) > -1 from d_cmp;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_cmp_per_index;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_cmp_per_index;
+select count(*) > -1 from d_cmp_per_index;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_cmp_per_index_reset;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_cmp_per_index_reset;
+select count(*) > -1 from d_cmp_per_index_reset;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_cmp_reset;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_cmp_reset;
+select count(*) > -1 from d_cmp_reset;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_cmpmem;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_cmpmem;
+select count(*) > -1 from d_cmpmem;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_cmpmem_reset;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_cmpmem_reset;
+select count(*) > -1 from d_cmpmem_reset;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_ft_being_deleted;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_ft_being_deleted;
+select count(*) > -1 from d_ft_being_deleted;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_ft_config;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_ft_config;
+select count(*) > -1 from d_ft_config;
+
+# non-privileged table
+select count(*) > -1 from information_schema.innodb_ft_default_stopword;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_ft_deleted;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_ft_deleted;
+select count(*) > -1 from d_ft_deleted;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_ft_index_cache;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_ft_index_cache;
+select count(*) > -1 from d_ft_index_cache;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_ft_index_table;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_ft_index_table;
+select count(*) > -1 from d_ft_index_table;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_lock_waits;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_lock_waits;
+select count(*) > -1 from d_lock_waits;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_locks;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_locks;
+select count(*) > -1 from d_locks;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_metrics;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_metrics;
+select count(*) > -1 from d_metrics;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_mutexes;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_mutexes;
+select count(*) > -1 from d_mutexes;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_sys_columns;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_sys_columns;
+select count(*) > -1 from d_sys_columns;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_sys_datafiles;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_sys_datafiles;
+select count(*) > -1 from d_sys_datafiles;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_sys_fields;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_sys_fields;
+select count(*) > -1 from d_sys_fields;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_sys_foreign;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_sys_foreign;
+select count(*) > -1 from d_sys_foreign;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_sys_foreign_cols;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_sys_foreign_cols;
+select count(*) > -1 from d_sys_foreign_cols;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_sys_indexes;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_sys_indexes;
+select count(*) > -1 from d_sys_indexes;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_sys_semaphore_waits;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_sys_semaphore_waits;
+select count(*) > -1 from d_sys_semaphore_waits;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_sys_tables;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_sys_tables;
+select count(*) > -1 from d_sys_tables;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_sys_tablespaces;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_sys_tablespaces;
+select count(*) > -1 from d_sys_tablespaces;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_sys_tablestats;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_sys_tablestats;
+select count(*) > -1 from d_sys_tablestats;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_sys_virtual;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_sys_virtual;
+select count(*) > -1 from d_sys_virtual;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_tablespaces_encryption;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_tablespaces_encryption;
+select count(*) > -1 from d_tablespaces_encryption;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_tablespaces_scrubbing;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_tablespaces_scrubbing;
+select count(*) > -1 from d_tablespaces_scrubbing;
+
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from information_schema.innodb_trx;
+--error ER_SPECIFIC_ACCESS_DENIED_ERROR
+select count(*) > -1 from i_trx;
+select count(*) > -1 from d_trx;
+
+connection default;
+drop database test;
+create database test;
+drop user select_only@localhost;
diff --git a/mysql-test/t/information_schema_db.test b/mysql-test/t/information_schema_db.test
index 70ad9b5b920..d6d4e9a4d43 100644
--- a/mysql-test/t/information_schema_db.test
+++ b/mysql-test/t/information_schema_db.test
@@ -255,3 +255,47 @@ disconnect user1;
connection default;
set global sql_mode=default;
+
+#
+# MDEV-20549 SQL SECURITY DEFINER does not work for INFORMATION_SCHEMA tables
+#
+
+create user foo@localhost;
+grant select on test.* to foo@localhost;
+create procedure rootonly() select 1;
+create sql security definer view v1d as select current_user(),user from information_schema.processlist;
+create sql security invoker view v1i as select current_user(),user from information_schema.processlist;
+create sql security definer view v2d as select table_name from information_schema.tables where table_schema='mysql' and table_name like '%user%';
+create sql security invoker view v2i as select table_name from information_schema.tables where table_schema='mysql' and table_name like '%user%';
+create sql security definer view v3d as select schema_name from information_schema.schemata where schema_name like '%mysql%';
+create sql security invoker view v3i as select schema_name from information_schema.schemata where schema_name like '%mysql%';
+create sql security definer view v4d as select routine_name from information_schema.routines where routine_schema='test';
+create sql security invoker view v4i as select routine_name from information_schema.routines where routine_schema='test';
+create sql security definer view v5d as select view_definition > '' from information_schema.views where table_name='v1d';
+create sql security invoker view v5i as select view_definition > '' from information_schema.views where table_name='v1d';
+connect foo,localhost,foo;
+select * from v1d;
+select * from v1i;
+select * from v2d;
+select * from v2i;
+select * from v3d;
+select * from v3i;
+select * from v4d;
+select * from v4i;
+select * from v5d;
+select * from v5i;
+connection default;
+select * from v1d;
+select * from v1i;
+select * from v2d;
+select * from v2i;
+select * from v3d;
+select * from v3i;
+select * from v4d;
+select * from v4i;
+select * from v5d;
+select * from v5i;
+disconnect foo;
+drop view v1d, v1i, v2d, v2i, v3d, v3i, v4d, v4i, v5d, v5i;
+drop user foo@localhost;
+drop procedure rootonly;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 4bc9870f422..8fc0784b77f 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -8429,6 +8429,7 @@ bool get_schema_tables_result(JOIN *join,
cond= tab->cache_select->cond;
}
+ Switch_to_definer_security_ctx backup_ctx(thd, table_list);
if (table_list->schema_table->fill_table(thd, table_list, cond))
{
result= 1;