← Back to team overview

maria-developers team mailing list archive

MDEV-10020 InnoDB NOT IN Query Crash When One Item Is NULL

 

Hi Sergei,

Please review a patch for mdev-10020.

The problem was that the loop in get_func_mm_tree()
accessed an improperly initialized instance of String,
which is a bzero'ed part of the in_vector::base array.

Strings in in_vector::base are initialized
in Item_func_in::fix_length_and_dec():
in in_vector::in_vector() using sql_calloc,
rather than a String constructor, so its str_charset member
of this String is NULL.

Strings in in_vector::base are later initialized in
Item_func_in::fix_length_and_dec(), using array->set(),
in this code:


      uint j=0;
      for (uint i=1 ; i < arg_count ; i++)
      {
        array->set(j,args[i]);
        if (!args[i]->null_value)                      // Skip NULL values
          j++;
        else
          have_null= 1;
      }
      if ((array->used_count= j))
        array->sort();


NULLs are not taken into account, so array->used_count can
be smaller than array->count.

This patch fixes the loop in opt_range.cc, in get_func_mm_tree(),
to access only properly initialized elements in in_vector::base,
preventing access to its bzero'ed non-initialized tail.

Thanks.
diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result
index fc56660..210b0a9 100644
--- a/mysql-test/r/func_in.result
+++ b/mysql-test/r/func_in.result
@@ -812,3 +812,22 @@ EXECUTE s;
 1
 DROP TABLE t1;
 # End of 5.3 tests
+#
+# Start of 10.0 tests
+#
+#
+# MDEV-10020 InnoDB NOT IN Query Crash When One Item Is NULL
+#
+CREATE TABLE t1
+(
+a INT(11),
+b VARCHAR(10),
+KEY (b)
+);
+INSERT INTO t1 VALUES (1,'x'),(2,'y'),(3,'z');
+SELECT * FROM t1 WHERE b NOT IN (NULL, '', 'A');
+a	b
+DROP TABLE t1;
+#
+# End of 10.0 tests
+#
diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test
index 1e69514..17736ac 100644
--- a/mysql-test/t/func_in.test
+++ b/mysql-test/t/func_in.test
@@ -606,3 +606,24 @@ EXECUTE s;
 DROP TABLE t1;
 
 --echo # End of 5.3 tests
+
+--echo #
+--echo # Start of 10.0 tests
+--echo #
+
+--echo #
+--echo # MDEV-10020 InnoDB NOT IN Query Crash When One Item Is NULL
+--echo #
+CREATE TABLE t1
+(
+  a INT(11),
+  b VARCHAR(10),
+  KEY (b)
+);
+INSERT INTO t1 VALUES (1,'x'),(2,'y'),(3,'z');
+SELECT * FROM t1 WHERE b NOT IN (NULL, '', 'A');
+DROP TABLE t1;
+
+--echo #
+--echo # End of 10.0 tests
+--echo #
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index f051ed0..ae5899d 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -7730,7 +7730,7 @@ static SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param, Item_func *cond_func,
           break;
         }
         SEL_TREE *tree2;
-        for (; i < func->array->count; i++)
+        for (; i < func->array->used_count; i++)
         {
           if (func->array->compare_elems(i, i-1))
           {

Follow ups