Bug#18319790 QUERY TO INFORMATION_SCHEMA CRASHES SERVER
Before this fix, specially crafted queries using the INFORMATION_SCHEMA could crash the server. The root cause was a buffer overflow, see the (private) bug comments for details. With this fix, the buffer overflow condition is properly handled, and the queries involved do return the expected result.
This commit is contained in:
parent
1a8ae4d705
commit
659bee497b
@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -2394,10 +2394,38 @@ void calc_sum_of_all_status(STATUS_VAR *to)
|
||||
/* This is only used internally, but we need it here as a forward reference */
|
||||
extern ST_SCHEMA_TABLE schema_tables[];
|
||||
|
||||
/**
|
||||
Condition pushdown used for INFORMATION_SCHEMA / SHOW queries.
|
||||
This structure is to implement an optimization when
|
||||
accessing data dictionary data in the INFORMATION_SCHEMA
|
||||
or SHOW commands.
|
||||
When the query contain a TABLE_SCHEMA or TABLE_NAME clause,
|
||||
narrow the search for data based on the constraints given.
|
||||
*/
|
||||
typedef struct st_lookup_field_values
|
||||
{
|
||||
LEX_STRING db_value, table_value;
|
||||
bool wild_db_value, wild_table_value;
|
||||
/**
|
||||
Value of a TABLE_SCHEMA clause.
|
||||
Note that this value length may exceed @c NAME_LEN.
|
||||
@sa wild_db_value
|
||||
*/
|
||||
LEX_STRING db_value;
|
||||
/**
|
||||
Value of a TABLE_NAME clause.
|
||||
Note that this value length may exceed @c NAME_LEN.
|
||||
@sa wild_table_value
|
||||
*/
|
||||
LEX_STRING table_value;
|
||||
/**
|
||||
True when @c db_value is a LIKE clause,
|
||||
false when @c db_value is an '=' clause.
|
||||
*/
|
||||
bool wild_db_value;
|
||||
/**
|
||||
True when @c table_value is a LIKE clause,
|
||||
false when @c table_value is an '=' clause.
|
||||
*/
|
||||
bool wild_table_value;
|
||||
} LOOKUP_FIELD_VALUES;
|
||||
|
||||
|
||||
@ -2801,14 +2829,22 @@ int make_db_list(THD *thd, List<LEX_STRING> *files,
|
||||
|
||||
|
||||
/*
|
||||
If we have db lookup vaule we just add it to list and
|
||||
If we have db lookup value we just add it to list and
|
||||
exit from the function.
|
||||
We don't do this for database names longer than the maximum
|
||||
path length.
|
||||
name length.
|
||||
*/
|
||||
if (lookup_field_vals->db_value.str &&
|
||||
lookup_field_vals->db_value.length < FN_REFLEN)
|
||||
if (lookup_field_vals->db_value.str)
|
||||
{
|
||||
if (lookup_field_vals->db_value.length > NAME_LEN)
|
||||
{
|
||||
/*
|
||||
Impossible value for a database name,
|
||||
found in a WHERE DATABASE_NAME = 'xxx' clause.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (is_infoschema_db(lookup_field_vals->db_value.str,
|
||||
lookup_field_vals->db_value.length))
|
||||
{
|
||||
@ -2945,6 +2981,15 @@ make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
|
||||
if (!lookup_field_vals->wild_table_value &&
|
||||
lookup_field_vals->table_value.str)
|
||||
{
|
||||
if (lookup_field_vals->table_value.length > NAME_LEN)
|
||||
{
|
||||
/*
|
||||
Impossible value for a table name,
|
||||
found in a WHERE TABLE_NAME = 'xxx' clause.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (with_i_schema)
|
||||
{
|
||||
LEX_STRING *name;
|
||||
@ -3411,6 +3456,9 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables,
|
||||
bzero((char*) &table_list, sizeof(TABLE_LIST));
|
||||
bzero((char*) &tbl, sizeof(TABLE));
|
||||
|
||||
DBUG_ASSERT(db_name->length <= NAME_LEN);
|
||||
DBUG_ASSERT(table_name->length <= NAME_LEN);
|
||||
|
||||
if (lower_case_table_names)
|
||||
{
|
||||
/*
|
||||
@ -3742,6 +3790,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
||||
it.rewind(); /* To get access to new elements in basis list */
|
||||
while ((db_name= it++))
|
||||
{
|
||||
DBUG_ASSERT(db_name->length <= NAME_LEN);
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (!(check_access(thd, SELECT_ACL, db_name->str,
|
||||
&thd->col_access, NULL, 0, 1) ||
|
||||
@ -3763,6 +3812,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
||||
List_iterator_fast<LEX_STRING> it_files(table_names);
|
||||
while ((table_name= it_files++))
|
||||
{
|
||||
DBUG_ASSERT(table_name->length <= NAME_LEN);
|
||||
restore_record(table, s->default_values);
|
||||
table->field[schema_table->idx_field1]->
|
||||
store(db_name->str, db_name->length, system_charset_info);
|
||||
@ -3909,6 +3959,7 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond)
|
||||
List_iterator_fast<LEX_STRING> it(db_names);
|
||||
while ((db_name=it++))
|
||||
{
|
||||
DBUG_ASSERT(db_name->length <= NAME_LEN);
|
||||
if (with_i_schema) // information schema name is always first in list
|
||||
{
|
||||
if (store_schema_shemata(thd, table, db_name,
|
||||
|
Loading…
x
Reference in New Issue
Block a user