revision-id: 65a1bb56c05b9fe80c88f26da5bf11674ba3cffd (mariadb-10.1.38-27-g65a1bb56c05)
parent(s): 84645366c459b01771223a6d1a20bf7ac38adf48
author: Varun Gupta
committer: Varun Gupta
timestamp: 2019-03-07 13:38:18 +0530
message:
MDEV-17783: AddressSanitizer: stack-buffer-overflow in table_cond_selectivity with optimizer_use_condition_selectivity > 1, join_cache_level >2
This case happens when we pick hash-join in best_access_path but the number of keyparts
in the hash_key are > MAX_REF_PARTS.
hash join should not use more than MAX_REF_PARTS for hash index.
---
mysql-test/r/selectivity.result | 24 ++++++++++++++++++++++++
mysql-test/r/selectivity_innodb.result | 24 ++++++++++++++++++++++++
mysql-test/t/selectivity.test | 24 ++++++++++++++++++++++++
sql/sql_select.cc | 13 +++++++++----
4 files changed, 81 insertions(+), 4 deletions(-)
diff --git a/mysql-test/r/selectivity.result b/mysql-test/r/selectivity.result
index 2e69f674ea3..bf1cae3c787 100644
--- a/mysql-test/r/selectivity.result
+++ b/mysql-test/r/selectivity.result
@@ -1635,3 +1635,27 @@ set @@use_stat_tables= @save_use_stat_tables;
set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
drop table t1;
drop function f1;
+#
+# MDEV-17783: AddressSanitizer: stack-buffer-overflow in table_cond_selectivity
+# with optimizer_use_condition_selectivity > 1, join_cache_level >2
+#
+set @save_join_cache_level= @@join_cache_level;
+set @save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity;
+set join_cache_level=3;
+set optimizer_use_condition_selectivity=2;
+CREATE TABLE t1 (c1 int, c2 int, c3 int, c4 int, c5 int, c6 int, c7 int, c8 int, c9 int, c10 int, c11 int, c12 int, c13 int, c14 int, c15 int, c16 int, c17 int, c18 int, c19 int, c20 int, c21 int, c22 int, c23 int, c24 int, c25 int, c26 int, c27 int, c28 int, c29 int, c30 int, c31 int, c32 int, c33 int, c34 int);
+insert into t1 values
+(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33),(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33);
+explain select * from t1, t1 t where t1.c1 = t.c1 and t1.c2 = t.c2 and t1.c3 = t.c3 and t1.c4 = t.c4 and t1.c5 = t.c5 and t1.c6 = t.c6 and t1.c7 = t.c7 and t1.c8 = t.c8 and t1.c9 = t.c9 and t1.c10 = t.c10 and t1.c11 = t.c11 and t1.c12 = t.c12 and t1.c13 = t.c13 and t1.c14 = t.c14 and t1.c15 = t.c15 and t1.c16 = t.c16 and t1.c17 = t.c17 and t1.c18 = t.c18 and t1.c19 = t.c19 and t1.c20 = t.c20 and t1.c21 = t.c21 and t1.c22 = t.c22 and t1.c23 = t.c23 and t1.c24 = t.c24 and t1.c25 = t.c25 and t1.c26 = t.c26 and t1.c27 = t.c27 and t1.c28 = t.c28 and t1.c29 = t.c29 and t1.c30 = t.c30 and t1.c31 = t.c31 and t1.c32 = t.c32 and t1.c33 = t.c33 and t1.c34 = t.c34;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t hash_ALL NULL #hash#$hj 160 test.t1.c1,test.t1.c2,test.t1.c3,test.t1.c4,test.t1.c5,test.t1.c6,test.t1.c7,test.t1.c8,test.t1.c9,test.t1.c10,test.t1.c11,test.t1.c12,test.t1.c13,test.t1.c14,test.t1.c15,test.t1.c16,test.t1.c17,test.t1.c18,test.t1.c19,test.t1.c20,test.t1.c21,test.t1.c22,test.t1.c23,test.t1.c24,test.t1.c25,test.t1.c26,test.t1.c27,test.t1.c28,test.t1.c29,test.t1.c30,test.t1.c31,test.t1.c32 2 Using where; Using join buffer (flat, BNLH join)
+select * from t1, t1 t where t1.c1 = t.c1 and t1.c2 = t.c2 and t1.c3 = t.c3 and t1.c4 = t.c4 and t1.c5 = t.c5 and t1.c6 = t.c6 and t1.c7 = t.c7 and t1.c8 = t.c8 and t1.c9 = t.c9 and t1.c10 = t.c10 and t1.c11 = t.c11 and t1.c12 = t.c12 and t1.c13 = t.c13 and t1.c14 = t.c14 and t1.c15 = t.c15 and t1.c16 = t.c16 and t1.c17 = t.c17 and t1.c18 = t.c18 and t1.c19 = t.c19 and t1.c20 = t.c20 and t1.c21 = t.c21 and t1.c22 = t.c22 and t1.c23 = t.c23 and t1.c24 = t.c24 and t1.c25 = t.c25 and t1.c26 = t.c26 and t1.c27 = t.c27 and t1.c28 = t.c28 and t1.c29 = t.c29 and t1.c30 = t.c30 and t1.c31 = t.c31 and t1.c32 = t.c32 and t1.c33 = t.c33 and t1.c34 = t.c34;
+c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34
+0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
+0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
+0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
+0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
+set join_cache_level= @save_join_cache_level;
+set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
+drop table t1;
diff --git a/mysql-test/r/selectivity_innodb.result b/mysql-test/r/selectivity_innodb.result
index d3e71088f87..4027315826e 100644
--- a/mysql-test/r/selectivity_innodb.result
+++ b/mysql-test/r/selectivity_innodb.result
@@ -1645,6 +1645,30 @@ set @@use_stat_tables= @save_use_stat_tables;
set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
drop table t1;
drop function f1;
+#
+# MDEV-17783: AddressSanitizer: stack-buffer-overflow in table_cond_selectivity
+# with optimizer_use_condition_selectivity > 1, join_cache_level >2
+#
+set @save_join_cache_level= @@join_cache_level;
+set @save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity;
+set join_cache_level=3;
+set optimizer_use_condition_selectivity=2;
+CREATE TABLE t1 (c1 int, c2 int, c3 int, c4 int, c5 int, c6 int, c7 int, c8 int, c9 int, c10 int, c11 int, c12 int, c13 int, c14 int, c15 int, c16 int, c17 int, c18 int, c19 int, c20 int, c21 int, c22 int, c23 int, c24 int, c25 int, c26 int, c27 int, c28 int, c29 int, c30 int, c31 int, c32 int, c33 int, c34 int);
+insert into t1 values
+(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33),(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33);
+explain select * from t1, t1 t where t1.c1 = t.c1 and t1.c2 = t.c2 and t1.c3 = t.c3 and t1.c4 = t.c4 and t1.c5 = t.c5 and t1.c6 = t.c6 and t1.c7 = t.c7 and t1.c8 = t.c8 and t1.c9 = t.c9 and t1.c10 = t.c10 and t1.c11 = t.c11 and t1.c12 = t.c12 and t1.c13 = t.c13 and t1.c14 = t.c14 and t1.c15 = t.c15 and t1.c16 = t.c16 and t1.c17 = t.c17 and t1.c18 = t.c18 and t1.c19 = t.c19 and t1.c20 = t.c20 and t1.c21 = t.c21 and t1.c22 = t.c22 and t1.c23 = t.c23 and t1.c24 = t.c24 and t1.c25 = t.c25 and t1.c26 = t.c26 and t1.c27 = t.c27 and t1.c28 = t.c28 and t1.c29 = t.c29 and t1.c30 = t.c30 and t1.c31 = t.c31 and t1.c32 = t.c32 and t1.c33 = t.c33 and t1.c34 = t.c34;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t hash_ALL NULL #hash#$hj 160 test.t1.c1,test.t1.c2,test.t1.c3,test.t1.c4,test.t1.c5,test.t1.c6,test.t1.c7,test.t1.c8,test.t1.c9,test.t1.c10,test.t1.c11,test.t1.c12,test.t1.c13,test.t1.c14,test.t1.c15,test.t1.c16,test.t1.c17,test.t1.c18,test.t1.c19,test.t1.c20,test.t1.c21,test.t1.c22,test.t1.c23,test.t1.c24,test.t1.c25,test.t1.c26,test.t1.c27,test.t1.c28,test.t1.c29,test.t1.c30,test.t1.c31,test.t1.c32 2 Using where; Using join buffer (flat, BNLH join)
+select * from t1, t1 t where t1.c1 = t.c1 and t1.c2 = t.c2 and t1.c3 = t.c3 and t1.c4 = t.c4 and t1.c5 = t.c5 and t1.c6 = t.c6 and t1.c7 = t.c7 and t1.c8 = t.c8 and t1.c9 = t.c9 and t1.c10 = t.c10 and t1.c11 = t.c11 and t1.c12 = t.c12 and t1.c13 = t.c13 and t1.c14 = t.c14 and t1.c15 = t.c15 and t1.c16 = t.c16 and t1.c17 = t.c17 and t1.c18 = t.c18 and t1.c19 = t.c19 and t1.c20 = t.c20 and t1.c21 = t.c21 and t1.c22 = t.c22 and t1.c23 = t.c23 and t1.c24 = t.c24 and t1.c25 = t.c25 and t1.c26 = t.c26 and t1.c27 = t.c27 and t1.c28 = t.c28 and t1.c29 = t.c29 and t1.c30 = t.c30 and t1.c31 = t.c31 and t1.c32 = t.c32 and t1.c33 = t.c33 and t1.c34 = t.c34;
+c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c23 c24 c25 c26 c27 c28 c29 c30 c31 c32 c33 c34
+0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
+0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
+0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
+0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
+set join_cache_level= @save_join_cache_level;
+set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
+drop table t1;
set optimizer_switch=@save_optimizer_switch_for_selectivity_test;
set @tmp_ust= @@use_stat_tables;
set @tmp_oucs= @@optimizer_use_condition_selectivity;
diff --git a/mysql-test/t/selectivity.test b/mysql-test/t/selectivity.test
index 3df49456332..078f7e2e8f6 100644
--- a/mysql-test/t/selectivity.test
+++ b/mysql-test/t/selectivity.test
@@ -1102,3 +1102,27 @@ set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectiv
drop table t1;
drop function f1;
+--echo #
+--echo # MDEV-17783: AddressSanitizer: stack-buffer-overflow in table_cond_selectivity
+--echo # with optimizer_use_condition_selectivity > 1, join_cache_level >2
+--echo #
+
+set @save_join_cache_level= @@join_cache_level;
+set @save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity;
+set join_cache_level=3;
+set optimizer_use_condition_selectivity=2;
+
+CREATE TABLE t1 (c1 int, c2 int, c3 int, c4 int, c5 int, c6 int, c7 int, c8 int, c9 int, c10 int, c11 int, c12 int, c13 int, c14 int, c15 int, c16 int, c17 int, c18 int, c19 int, c20 int, c21 int, c22 int, c23 int, c24 int, c25 int, c26 int, c27 int, c28 int, c29 int, c30 int, c31 int, c32 int, c33 int, c34 int);
+
+insert into t1 values
+(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33),(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33);
+
+let $x=
+select * from t1, t1 t where t1.c1 = t.c1 and t1.c2 = t.c2 and t1.c3 = t.c3 and t1.c4 = t.c4 and t1.c5 = t.c5 and t1.c6 = t.c6 and t1.c7 = t.c7 and t1.c8 = t.c8 and t1.c9 = t.c9 and t1.c10 = t.c10 and t1.c11 = t.c11 and t1.c12 = t.c12 and t1.c13 = t.c13 and t1.c14 = t.c14 and t1.c15 = t.c15 and t1.c16 = t.c16 and t1.c17 = t.c17 and t1.c18 = t.c18 and t1.c19 = t.c19 and t1.c20 = t.c20 and t1.c21 = t.c21 and t1.c22 = t.c22 and t1.c23 = t.c23 and t1.c24 = t.c24 and t1.c25 = t.c25 and t1.c26 = t.c26 and t1.c27 = t.c27 and t1.c28 = t.c28 and t1.c29 = t.c29 and t1.c30 = t.c30 and t1.c31 = t.c31 and t1.c32 = t.c32 and t1.c33 = t.c33 and t1.c34 = t.c34;
+
+eval explain $x;
+eval $x;
+
+set join_cache_level= @save_join_cache_level;
+set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
+drop table t1;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 155e261ac34..65dff40f050 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -7634,7 +7634,7 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
*/
keyuse= pos->key;
keyparts=0;
- while (keyuse->table == table && keyuse->key == key)
+ while (keyuse->table == table && keyuse->key == key && keyparts < MAX_REF_PARTS)
{
if (!(keyuse->used_tables & (rem_tables | table->map)))
{
@@ -8935,7 +8935,8 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab,
}
first_keyuse= FALSE;
keyuse++;
- } while (keyuse->table == table && keyuse->is_for_hash_join());
+ } while (keyuse->table == table && keyuse->is_for_hash_join() &&
+ key_parts < MAX_REF_PARTS);
if (!key_parts)
DBUG_RETURN(TRUE);
/* This memory is allocated only once for the joined table join_tab */
@@ -8958,6 +8959,7 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab,
first_keyuse= TRUE;
keyuse= org_keyuse;
+ key_parts= 0;
do
{
if (!(~used_tables & keyuse->used_tables) &&
@@ -8988,11 +8990,13 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab,
table->create_key_part_by_field(key_part_info, field, fieldnr);
keyinfo->key_length += key_part_info->store_length;
key_part_info++;
+ key_parts++;
}
}
first_keyuse= FALSE;
keyuse++;
- } while (keyuse->table == table && keyuse->is_for_hash_join());
+ } while (keyuse->table == table && keyuse->is_for_hash_join() &&
+ key_parts < MAX_REF_PARTS);
keyinfo->ext_key_parts= keyinfo->user_defined_key_parts;
keyinfo->ext_key_flags= keyinfo->flags;
@@ -9090,7 +9094,8 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
}
}
keyuse++;
- } while (keyuse->table == table && keyuse->key == key);
+ } while (keyuse->table == table && keyuse->key == key &&
+ keyparts < MAX_REF_PARTS);
if (!keyparts && allow_full_scan)
{