From ce39d2949351e2b01b8839c0ce6c273eac53f080 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 20 Mar 2006 13:42:02 +0400 Subject: [PATCH] Fix for bug #18113 "SELECT * FROM information_schema.xxx crashes server" Crash happened when one selected data from one of INFORMATION_SCHEMA tables and in order to build its contents server had to open view which used stored function and table or view on which one had not global or database-level privileges (e.g. had only table-level or had no privileges at all). The crash was caused by usage of check_grant() function, which assumes that either number of tables to be inspected by it is limited explicitly or table list used and thd->lex->query_tables_own_last value correspond to each other (the latter should be either 0 or point to next_global member of one of elements of this table list), in conditions when above assumptions were not true. This fix just explicitly limits number of tables to be inspected. Other negative effects which are caused by the fact that thd->lex->query_tables_own_last might not be set properly during processing of I_S tables are less disastrous and will be reported and fixed separetely. mysql-test/r/information_schema_db.result: Fix for bug #18113 "SELECT * FROM information_schema.xxx crashes server" test case mysql-test/t/information_schema_db.test: Fix for bug #18113 "SELECT * FROM information_schema.xxx crashes server" test case sql/sql_acl.cc: added note --- mysql-test/r/information_schema_db.result | 14 ++++++++++ mysql-test/t/information_schema_db.test | 31 +++++++++++++++++++++++ sql/sql_acl.cc | 7 +++++ sql/sql_show.cc | 2 +- 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result index 0229fdef2d5..6295bac34a0 100644 --- a/mysql-test/r/information_schema_db.result +++ b/mysql-test/r/information_schema_db.result @@ -27,4 +27,18 @@ create database `inf%`; use `inf%`; show tables; Tables_in_inf% +grant all privileges on `inf%`.* to 'mysqltest_1'@'localhost'; +create table t1 (f1 int); +create function func1(curr_int int) returns int +begin +declare ret_val int; +select max(f1) from t1 into ret_val; +return ret_val; +end| +create view v1 as select f1 from t1 where f1 = func1(f1); +select * from information_schema.tables; +drop user mysqltest_1@localhost; +drop view v1; +drop function func1; +drop table t1; drop database `inf%`; diff --git a/mysql-test/t/information_schema_db.test b/mysql-test/t/information_schema_db.test index efb738d682c..b65135a621d 100644 --- a/mysql-test/t/information_schema_db.test +++ b/mysql-test/t/information_schema_db.test @@ -8,4 +8,35 @@ show tables from INFORMATION_SCHEMA like 'T%'; create database `inf%`; use `inf%`; show tables; + +# +# Bug#18113 SELECT * FROM information_schema.xxx crashes server +# Crash happened when one selected data from one of INFORMATION_SCHEMA +# tables and in order to build its contents server had to open view which +# used stored function and table or view on which one had not global or +# database-level privileges (e.g. had only table-level or had no +# privileges at all). +# +grant all privileges on `inf%`.* to 'mysqltest_1'@'localhost'; +create table t1 (f1 int); +delimiter |; +create function func1(curr_int int) returns int +begin + declare ret_val int; + select max(f1) from t1 into ret_val; + return ret_val; +end| +delimiter ;| +create view v1 as select f1 from t1 where f1 = func1(f1); +connect (user1,localhost,mysqltest_1,,); +connection user1; +--disable_result_log +select * from information_schema.tables; +--enable_result_log +connection default; +drop user mysqltest_1@localhost; +drop view v1; +drop function func1; +drop table t1; + drop database `inf%`; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index ee604ae1daf..d66a631dbcc 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3537,6 +3537,13 @@ end: RETURN 0 ok 1 Error: User did not have the requested privileges + + NOTE + This functions assumes that either number of tables to be inspected + by it is limited explicitly (i.e. is is not UINT_MAX) or table list + used and thd->lex->query_tables_own_last value correspond to each + other (the latter should be either 0 or point to next_global member + of one of elements of this table list). ****************************************************************************/ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 403781b330d..4b5b4d0dc0e 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -328,7 +328,7 @@ mysql_find_files(THD *thd,List *files, const char *db,const char *path, table_list.table_name= file->name; table_list.table_name_length= strlen(file->name); table_list.grant.privilege=col_access; - if (check_grant(thd, TABLE_ACLS, &table_list, 1, UINT_MAX, 1)) + if (check_grant(thd, TABLE_ACLS, &table_list, 1, 1, 1)) continue; } #endif