From: Date: March 13 2006 7:11pm Subject: bk commit into 5.0 tree (evgen:1.2079) BUG#17366 List-Archive: http://lists.mysql.com/commits/3811 X-Bug: 17366 Message-Id: <20060313181120.9C47350D23C@sunlight.local> Below is the list of changes that have just been committed into a local 5.0 repository of evgen. When evgen does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet 1.2079 06/03/13 21:11:15 evgen@stripped +3 -0 Fixed bug#17366: Unchecked Item_int results in server crash When there is conjunction of conds, the substitute_for_best_equal_field() will call the eliminate_item_equal() function in loop to build final expression. But if eliminate_item_equal() finds that some cond will always evaluate to 0, then that cond will be substituted by Item_int with value == 0. In this case on the next iteration eliminate_item_equal() will get that Item_int and treat it as Item_cond. This is leads to memory corruption and server crash on cleanup phase. To the eliminate_item_equal() function was added DBUG_ASSERT for checking that all items treaten as Item_cond are really Item_cond. The substitute_for_best_equal_field() now checks that if eliminate_item_equal() returns Item_int and it's value is 0 then this value is returned as the result of whole conjunction. sql/sql_select.cc 1.396 06/03/13 21:09:00 evgen@stripped +8 -0 Fixed bug#17366: Unchecked Item_int results in server crash To the eliminate_item_equal() function was added DBUG_ASSERT for checking that all items treaten as Item_cond are really Item_cond. The substitute_for_best_equal_field() now checks that if eliminate_item_equal() returns something other than Item_cond and if it is then this value is returned as the result of whole conjunction. mysql-test/r/subselect.result 1.135 06/03/13 21:07:30 evgen@stripped +7 -0 Added test for bug#17366: Unchecked Item_int results in server crash mysql-test/t/subselect.test 1.114 06/03/13 21:06:43 evgen@stripped +7 -0 Added test for bug#17366: Unchecked Item_int results in server crash # This is a BitKeeper patch. What follows are the unified diffs for the # set of deltas contained in the patch. The rest of the patch, the part # that BitKeeper cares about, is below these diffs. # User: evgen # Host: sunlight.local # Root: /work_local/17336-bug-5.0-mysql --- 1.395/sql/sql_select.cc 2006-02-20 04:25:59 +03:00 +++ 1.396/sql/sql_select.cc 2006-03-13 21:09:00 +03:00 @@ -7066,7 +7066,10 @@ static Item *eliminate_item_equal(COND * if (!cond) cond= new Item_cond_and(eq_list); else + { + DBUG_ASSERT(cond->type() == Item::COND_ITEM); ((Item_cond *) cond)->add_at_head(&eq_list); + } cond->quick_fix_field(); cond->update_used_tables(); @@ -7151,6 +7154,11 @@ static COND* substitute_for_best_equal_f while ((item_equal= it++)) { cond= eliminate_item_equal(cond, cond_equal->upper_levels, item_equal); + // This occurs when eliminate_item_equal() founds that cond is + // always false and substitues it with Item_int 0. + // Due to this, value of item_equal will be 0, so just return it. + if (cond->type() != Item::ITEM_COND) + break; } } } --- 1.134/mysql-test/r/subselect.result 2006-02-20 04:25:59 +03:00 +++ 1.135/mysql-test/r/subselect.result 2006-03-13 21:07:30 +03:00 @@ -3157,3 +3157,10 @@ id select_type table type possible_keys 1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where 2 DEPENDENT SUBQUERY t1 index NULL a 8 NULL 9 Using filesort DROP TABLE t1; +create table t1( f1 int,f2 int); +insert into t1 values (1,1),(2,2); +select tt.t from (select 'crash1' as t, f2 from t1) as tt left join t1 on tt.t = 'crash2' and tt.f2 = t1.f2 where tt.t = 'crash1'; +t +crash1 +crash1 +drop table t1; --- 1.113/mysql-test/t/subselect.test 2006-02-14 05:50:00 +03:00 +++ 1.114/mysql-test/t/subselect.test 2006-03-13 21:06:43 +03:00 @@ -2073,3 +2073,10 @@ SELECT * FROM t1 WHERE (a,b) = ANY (SELE DROP TABLE t1; +# +# Bug#17366: Unchecked Item_int results in server crash +# +create table t1( f1 int,f2 int); +insert into t1 values (1,1),(2,2); +select tt.t from (select 'crash1' as t, f2 from t1) as tt left join t1 on tt.t = 'crash2' and tt.f2 = t1.f2 where tt.t = 'crash1'; +drop table t1;