Commit 47bb750c authored by Gleb Shchepa's avatar Gleb Shchepa

backport: Bug #55568 from 5.1-security to 5.0-security

> revision-id: alexey.kopytov@sun.com-20100824103548-ikm79qlfrvggyj9h
> parent: sunny.bains@oracle.com-20100816001222-xqc447tr6jwh8c53
> committer: Alexey Kopytov <Alexey.Kopytov@Sun.com>
> branch nick: 5.1-security
> timestamp: Tue 2010-08-24 14:35:48 +0400
> message:
>   Bug #55568: user variable assignments crash server when used
>               within query
>   
>   The server could crash after materializing a derived table
>   which requires a temporary table for grouping.
>   
>   When destroying the temporary table used to execute a query for
>   a derived table, JOIN::destroy() did not clean up Item_fields
>   pointing to fields in the temporary table. This led to
>   dereferencing a dangling pointer when printing out the items
>   tree later in the outer SELECT.
>   
>   The solution is an addendum to the patch for bug37362: in
>   addition to cleaning up items in tmp_all_fields3, do the same
>   for items in tmp_all_fields1, since now we have an example
>   where this is necessary.


sql/field.cc:
  Make sure field->table_name is not set to NULL in
  Field::make_field() to avoid assertion failure in 
  Item_field::make_field() after cleaning up items
  (the assertion fired in udf.test when running
  the test suite with the patch applied).
sql/sql_select.cc:
  In addition to cleaning up items in tmp_all_fields3, do the
  same for items in tmp_all_fields1.
  Introduce a new helper function to avoid code duplication.
sql/sql_select.h:
  Introduce a new helper function to avoid code duplication in
  JOIN::destroy().
parent 50a3c55e
......@@ -952,4 +952,55 @@ a b a b
0 0 0 0
1 1 1 1
DROP TABLE t1;
#
# Bug #55568: user variable assignments crash server when used within
# query
#
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (0), (1);
SELECT MULTIPOINT(
1,
(
SELECT MULTIPOINT(
MULTIPOINT(
1,
(SELECT COUNT(*) FROM (SELECT 1 FROM t1 GROUP BY a,a) d)
)
) FROM t1
)
) != COUNT(*) q FROM t1 GROUP BY a;
q
NULL
NULL
SELECT MULTIPOINT(
1,
(
SELECT MULTIPOINT(
MULTIPOINT(
1,
(SELECT COUNT(*) FROM (SELECT 1 FROM t1 GROUP BY a,a) d)
)
) FROM t1
)
) != COUNT(*) q FROM t1 GROUP BY a;
q
NULL
NULL
DROP TABLE t1;
#
# Bug #54468: crash after item's print() function when ordering/grouping
# by subquery
#
CREATE TABLE t1(a INT, b INT);
INSERT INTO t1 VALUES (), ();
SELECT 1 FROM t1
GROUP BY
GREATEST(t1.a,
(SELECT 1 FROM
(SELECT t1.b FROM t1,t1 t2
ORDER BY t1.a, t1.a LIMIT 1) AS d)
);
1
1
DROP TABLE t1;
End of 5.0 tests.
......@@ -747,4 +747,50 @@ SELECT * FROM t1 STRAIGHT_JOIN t1 t2 ON t1.a=t2.a AND t1.a=t2.b ORDER BY t2.a, t
DROP TABLE t1;
--echo #
--echo # Bug #55568: user variable assignments crash server when used within
--echo # query
--echo #
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (0), (1);
let $i=2;
while ($i)
{
SELECT MULTIPOINT(
1,
(
SELECT MULTIPOINT(
MULTIPOINT(
1,
(SELECT COUNT(*) FROM (SELECT 1 FROM t1 GROUP BY a,a) d)
)
) FROM t1
)
) != COUNT(*) q FROM t1 GROUP BY a;
dec $i;
}
DROP TABLE t1;
--echo #
--echo # Bug #54468: crash after item's print() function when ordering/grouping
--echo # by subquery
--echo #
CREATE TABLE t1(a INT, b INT);
INSERT INTO t1 VALUES (), ();
SELECT 1 FROM t1
GROUP BY
GREATEST(t1.a,
(SELECT 1 FROM
(SELECT t1.b FROM t1,t1 t2
ORDER BY t1.a, t1.a LIMIT 1) AS d)
);
DROP TABLE t1;
--echo End of 5.0 tests.
......@@ -1365,7 +1365,7 @@ void Field::make_field(Send_field *field)
}
else
field->org_table_name= field->db_name= "";
if (orig_table)
if (orig_table && orig_table->alias)
{
field->table_name= orig_table->alias;
field->org_col_name= field_name;
......
......@@ -2226,13 +2226,8 @@ JOIN::destroy()
cleanup(1);
/* Cleanup items referencing temporary table columns */
if (!tmp_all_fields3.is_empty())
{
List_iterator_fast<Item> it(tmp_all_fields3);
Item *item;
while ((item= it++))
item->cleanup();
}
cleanup_item_list(tmp_all_fields1);
cleanup_item_list(tmp_all_fields3);
if (exec_tmp_table1)
free_tmp_table(thd, exec_tmp_table1);
if (exec_tmp_table2)
......@@ -2243,6 +2238,19 @@ JOIN::destroy()
DBUG_RETURN(error);
}
void JOIN::cleanup_item_list(List<Item> &items) const
{
if (!items.is_empty())
{
List_iterator_fast<Item> it(items);
Item *item;
while ((item= it++))
item->cleanup();
}
}
/*
An entry point to single-unit select (a select without UNION).
......
......@@ -489,6 +489,7 @@ public:
}
private:
bool make_simple_join(JOIN *join, TABLE *tmp_table);
void cleanup_item_list(List<Item> &items) const;
};
......
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