mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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. (Variant 2, with review input addressed)
This commit is contained in:
@ -2103,6 +2103,35 @@ drop view v1;
|
|||||||
#
|
#
|
||||||
# End of 10.1 tests
|
# 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 use_stat_tables= @tmp_ust;
|
||||||
set optimizer_use_condition_selectivity= @tmp_oucs;
|
set optimizer_use_condition_selectivity= @tmp_oucs;
|
||||||
set @@global.histogram_size=@save_histogram_size;
|
set @@global.histogram_size=@save_histogram_size;
|
||||||
|
@ -174,6 +174,40 @@ drop view v1;
|
|||||||
--echo # End of 10.1 tests
|
--echo # End of 10.1 tests
|
||||||
--echo #
|
--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 use_stat_tables= @tmp_ust;
|
||||||
set optimizer_use_condition_selectivity= @tmp_oucs;
|
set optimizer_use_condition_selectivity= @tmp_oucs;
|
||||||
set @@global.histogram_size=@save_histogram_size;
|
set @@global.histogram_size=@save_histogram_size;
|
||||||
|
@ -7943,7 +7943,9 @@ static
|
|||||||
double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
|
double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
|
||||||
table_map rem_tables)
|
table_map rem_tables)
|
||||||
{
|
{
|
||||||
uint16 ref_keyuse_steps[MAX_REF_PARTS - 1];
|
uint16 ref_keyuse_steps_buf[MAX_REF_PARTS];
|
||||||
|
uint ref_keyuse_size= MAX_REF_PARTS;
|
||||||
|
uint16 *ref_keyuse_steps= ref_keyuse_steps_buf;
|
||||||
Field *field;
|
Field *field;
|
||||||
TABLE *table= s->table;
|
TABLE *table= s->table;
|
||||||
MY_BITMAP *read_set= table->read_set;
|
MY_BITMAP *read_set= table->read_set;
|
||||||
@ -8090,6 +8092,29 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
|
|||||||
}
|
}
|
||||||
if (keyparts > 1)
|
if (keyparts > 1)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
Prepare to set ref_keyuse_steps[keyparts-2]: resize the array
|
||||||
|
if it is not large enough
|
||||||
|
*/
|
||||||
|
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(*ref_keyuse_steps)*new_size,
|
||||||
|
MYF(0))))
|
||||||
|
{
|
||||||
|
sel= 1.0; // As if no selectivity was computed
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
memcpy(new_buf, ref_keyuse_steps,
|
||||||
|
sizeof(*ref_keyuse_steps)*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);
|
ref_keyuse_steps[keyparts-2]= (uint16)(keyuse - prev_ref_keyuse);
|
||||||
prev_ref_keyuse= keyuse;
|
prev_ref_keyuse= keyuse;
|
||||||
}
|
}
|
||||||
@ -8144,7 +8169,9 @@ double table_cond_selectivity(JOIN *join, uint idx, JOIN_TAB *s,
|
|||||||
|
|
||||||
sel*= table_multi_eq_cond_selectivity(join, idx, s, rem_tables,
|
sel*= table_multi_eq_cond_selectivity(join, idx, s, rem_tables,
|
||||||
keyparts, ref_keyuse_steps);
|
keyparts, ref_keyuse_steps);
|
||||||
|
exit:
|
||||||
|
if (ref_keyuse_steps != ref_keyuse_steps_buf)
|
||||||
|
my_free(ref_keyuse_steps);
|
||||||
return sel;
|
return sel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user