[Commits] 4625830b679: MDEV-17783: AddressSanitizer: stack-buffer-overflow in table_cond_selectivity
revision-id: 4625830b6794184a57c2702436e810be941a51c0 (mariadb-10.2.31-960-g4625830b679) parent(s): af8d4a97e29905f2806e7f26b420ce517e96c723 author: Sergei Petrunia committer: Sergei Petrunia timestamp: 2021-05-20 18:23:12 +0300 message: MDEV-17783: AddressSanitizer: stack-buffer-overflow in table_cond_selectivity A less-intrusive fix: don't have table_cond_selectivity() assume that there are less than MAX_REF_PARTS hash-join KEYUSEs. If there are more than that, switch to using an array. Allocate the array on the heap: we can't allocate it on MEM_ROOT as table_cond_selectivity() is called many times during the optimization. --- mysql-test/r/selectivity_innodb.result | 29 +++++++++++++++++++++++++++++ mysql-test/t/selectivity_innodb.test | 34 ++++++++++++++++++++++++++++++++++ sql/sql_select.cc | 25 ++++++++++++++++++++++++- 3 files changed, 87 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/selectivity_innodb.result b/mysql-test/r/selectivity_innodb.result index 5452919aa6d..23e0fcc9387 100644 --- a/mysql-test/r/selectivity_innodb.result +++ b/mysql-test/r/selectivity_innodb.result @@ -2103,6 +2103,35 @@ drop view v1; # # End of 10.1 tests # +# +# MDEV-17783: AddressSanitizer: stack-buffer-overflow in table_cond_selectivity +# +set +@tmp_jcl=@@join_cache_level, +@tmp_sel=@@optimizer_use_condition_selectivity; +set +join_cache_level=3, +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 +) ENGINE=InnoDB; +SELECT * FROM t1 +WHERE +(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) IN (SELECT * FROM t1) ; +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 +set +join_cache_level=@tmp_jcl, +optimizer_use_condition_selectivity=@tmp_sel; +drop table t1; +# +# End of 10.1 tests +# set use_stat_tables= @tmp_ust; set optimizer_use_condition_selectivity= @tmp_oucs; set @@global.histogram_size=@save_histogram_size; diff --git a/mysql-test/t/selectivity_innodb.test b/mysql-test/t/selectivity_innodb.test index 6c457e2848b..eb05091e43a 100644 --- a/mysql-test/t/selectivity_innodb.test +++ b/mysql-test/t/selectivity_innodb.test @@ -174,6 +174,40 @@ drop view v1; --echo # End of 10.1 tests --echo # +--echo # +--echo # MDEV-17783: AddressSanitizer: stack-buffer-overflow in table_cond_selectivity +--echo # + +set + @tmp_jcl=@@join_cache_level, + @tmp_sel=@@optimizer_use_condition_selectivity; +set + join_cache_level=3, + 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 +) ENGINE=InnoDB; + +SELECT * FROM t1 +WHERE + (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) IN (SELECT * FROM t1) ; + +set + join_cache_level=@tmp_jcl, + optimizer_use_condition_selectivity=@tmp_sel; +drop table t1; + +--echo # +--echo # End of 10.1 tests +--echo # + set use_stat_tables= @tmp_ust; set optimizer_use_condition_selectivity= @tmp_oucs; set @@global.histogram_size=@save_histogram_size; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ce706209017..950d8f8fa70 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7949,7 +7949,9 @@ static double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, table_map rem_tables) { - uint16 ref_keyuse_steps[MAX_REF_PARTS - 1]; + uint16 ref_keyuse_steps_buf[MAX_REF_PARTS - 1]; + uint ref_keyuse_size= MAX_REF_PARTS - 1; + uint16 *ref_keyuse_steps= ref_keyuse_steps_buf; Field *field; TABLE *table= s->table; MY_BITMAP *read_set= table->read_set; @@ -8096,6 +8098,24 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, } if (keyparts > 1) { + if (keyparts - 2 >= ref_keyuse_size) + { + uint new_size= MY_MAX(ref_keyuse_size*2, keyparts); + void *new_buf; + if (!(new_buf= my_malloc(sizeof(uint16)*new_size, MYF(0)))) + { + if (ref_keyuse_steps != ref_keyuse_steps_buf) + my_free(ref_keyuse_steps); + return 1.0; // As if no selectivity was computed + } + memcpy(new_buf, ref_keyuse_steps, + sizeof(uint16)*ref_keyuse_size); + if (ref_keyuse_steps != ref_keyuse_steps_buf) + my_free(ref_keyuse_steps); + + ref_keyuse_steps= (uint16*)new_buf; + ref_keyuse_size= new_size; + } ref_keyuse_steps[keyparts-2]= (uint16)(keyuse - prev_ref_keyuse); prev_ref_keyuse= keyuse; } @@ -8151,6 +8171,9 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s, sel*= table_multi_eq_cond_selectivity(join, idx, s, rem_tables, keyparts, ref_keyuse_steps); + if (ref_keyuse_steps != ref_keyuse_steps_buf) + my_free(ref_keyuse_steps); + return sel; }
participants (1)
-
Sergei Petrunia