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.
parent 36da0963
...@@ -27,4 +27,18 @@ create database `inf%`; ...@@ -27,4 +27,18 @@ create database `inf%`;
use `inf%`; use `inf%`;
show tables; show tables;
Tables_in_inf% 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%`; drop database `inf%`;
...@@ -8,4 +8,35 @@ show tables from INFORMATION_SCHEMA like 'T%'; ...@@ -8,4 +8,35 @@ show tables from INFORMATION_SCHEMA like 'T%';
create database `inf%`; create database `inf%`;
use `inf%`; use `inf%`;
show tables; 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%`; drop database `inf%`;
...@@ -3537,6 +3537,13 @@ end: ...@@ -3537,6 +3537,13 @@ end:
RETURN RETURN
0 ok 0 ok
1 Error: User did not have the requested privileges 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, bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
......
...@@ -328,7 +328,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, ...@@ -328,7 +328,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
table_list.table_name= file->name; table_list.table_name= file->name;
table_list.table_name_length= strlen(file->name); table_list.table_name_length= strlen(file->name);
table_list.grant.privilege=col_access; 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; continue;
} }
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment