[Commits] a639eff: MDEV-15813 ASAN use-after-poison in hp_hashnr upon HANDLER READ on a versioned HEAP table.
revision-id: a639eff5940ed4147709511aeaee922fa7095284 (mariadb-10.3.6-193-ga639eff) parent(s): cd15e764a8a4f3e799f1efaede413c95e3233df6 committer: Alexey Botchkov timestamp: 2018-05-16 09:44:22 +0400 message: MDEV-15813 ASAN use-after-poison in hp_hashnr upon HANDLER READ on a versioned HEAP table. Check index capabilities before executing HANDLER READ command. --- mysql-test/suite/handler/heap.result | 21 +++++++++++++- mysql-test/suite/handler/heap.test | 20 ++++++++++++- mysql-test/suite/handler/interface.result | 22 +++++++++++++++ mysql-test/suite/handler/interface.test | 25 ++++++++++++++++ .../suite/innodb_fts/r/innodb_fts_misc.result | 2 +- mysql-test/suite/innodb_fts/t/innodb_fts_misc.test | 1 + sql/share/errmsg-utf8.txt | 2 ++ sql/sql_handler.cc | 33 +++++++++++++++++++--- sql/sql_handler.h | 3 +- sql/sql_prepare.cc | 1 + 10 files changed, 122 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/handler/heap.result b/mysql-test/suite/handler/heap.result index fc42e43..9679b48 100644 --- a/mysql-test/suite/handler/heap.result +++ b/mysql-test/suite/handler/heap.result @@ -1738,7 +1738,7 @@ connection default; CREATE TABLE t1(a INT, b INT, KEY(a), KEY b using btree (b), KEY ab using btree(a, b)) engine=memory; INSERT INTO t1 VALUES (2, 20), (2,20), (1, 10), (4, 40), (3, 30), (5,50), (6,50); HANDLER t1 OPEN; -HANDLER t1 READ a>=(2) limit 3; +HANDLER t1 READ a=(2) limit 3; a b 2 20 2 20 @@ -1841,3 +1841,22 @@ ERROR HY000: Storage engine MEMORY of the table `test`.`t1` doesn't have this op HANDLER t1 CLOSE; DROP TABLE t1; End of 5.3 tests +# +# MDEV-15813 ASAN use-after-poison in hp_hashnr upon +# HANDLER READ on a versioned HEAP table +# +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, CONSTRAINT PRIMARY KEY (a, b), UNIQUE ba(b, a) USING HASH) ENGINE=HEAP; +INSERT INTO t1 VALUES (1, 10), (2, 20), (3,30), (4,40); +HANDLER t1 OPEN AS m; +HANDLER m READ `PRIMARY`= (3,30); +a b +3 30 +HANDLER m READ `PRIMARY`> (3,30); +ERROR HY000: HASH index `PRIMARY` does not support this operation +HANDLER m READ `ba`= (30,3); +a b +3 30 +HANDLER m READ `ba`= (30); +ERROR HY000: HASH index `ba` does not support this operation +HANDLER m CLOSE; +DROP TABLE t1; diff --git a/mysql-test/suite/handler/heap.test b/mysql-test/suite/handler/heap.test index bc070cf..d60f92d 100644 --- a/mysql-test/suite/handler/heap.test +++ b/mysql-test/suite/handler/heap.test @@ -18,7 +18,7 @@ CREATE TABLE t1(a INT, b INT, KEY(a), KEY b using btree (b), KEY ab using btree( INSERT INTO t1 VALUES (2, 20), (2,20), (1, 10), (4, 40), (3, 30), (5,50), (6,50); HANDLER t1 OPEN; -HANDLER t1 READ a>=(2) limit 3; +HANDLER t1 READ a=(2) limit 3; HANDLER t1 READ a PREV; HANDLER t1 READ a PREV; HANDLER t1 READ a PREV; @@ -85,3 +85,21 @@ HANDLER t1 CLOSE; DROP TABLE t1; --echo End of 5.3 tests + +--echo # +--echo # MDEV-15813 ASAN use-after-poison in hp_hashnr upon +--echo # HANDLER READ on a versioned HEAP table +--echo # + +CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL, CONSTRAINT PRIMARY KEY (a, b), UNIQUE ba(b, a) USING HASH) ENGINE=HEAP; +INSERT INTO t1 VALUES (1, 10), (2, 20), (3,30), (4,40); +HANDLER t1 OPEN AS m; +HANDLER m READ `PRIMARY`= (3,30); +--error ER_KEY_DOESNT_SUPPORT +HANDLER m READ `PRIMARY`> (3,30); +HANDLER m READ `ba`= (30,3); +--error ER_KEY_DOESNT_SUPPORT +HANDLER m READ `ba`= (30); +HANDLER m CLOSE; +DROP TABLE t1; + diff --git a/mysql-test/suite/handler/interface.result b/mysql-test/suite/handler/interface.result index a4ac32c..c4a169b 100644 --- a/mysql-test/suite/handler/interface.result +++ b/mysql-test/suite/handler/interface.result @@ -312,3 +312,25 @@ Note 1050 Table 'v' already exists handler v read next; ERROR 42S02: Unknown table 'v' in HANDLER drop view v; +# +# MDEV-15813 ASAN use-after-poison in hp_hashnr upon +# HANDLER READ on a versioned HEAP table +# +CREATE TABLE t1 (g GEOMETRY NOT NULL, SPATIAL gi(g)); +INSERT INTO t1 VALUES (POINT(0,0)); +HANDLER t1 OPEN AS h; +HANDLER h READ `gi`= (10); +ERROR HY000: SPATIAL index `gi` does not support this operation +HANDLER h READ `gi`> (10); +ERROR HY000: SPATIAL index `gi` does not support this operation +HANDLER h CLOSE; +DROP TABLE t1; +CREATE TABLE t1 (w VARCHAR(100), FULLTEXT fk(w)); +INSERT INTO t1 VALUES ('one two three'); +HANDLER t1 OPEN AS h; +HANDLER h READ `fk`= (10); +ERROR HY000: FULLTEXT index `fk` does not support this operation +HANDLER h READ `fk`> (10); +ERROR HY000: FULLTEXT index `fk` does not support this operation +HANDLER h CLOSE; +DROP TABLE t1; diff --git a/mysql-test/suite/handler/interface.test b/mysql-test/suite/handler/interface.test index 2f576c9..15853df 100644 --- a/mysql-test/suite/handler/interface.test +++ b/mysql-test/suite/handler/interface.test @@ -354,3 +354,28 @@ execute stmt; --error ER_UNKNOWN_TABLE handler v read next; drop view v; + +--echo # +--echo # MDEV-15813 ASAN use-after-poison in hp_hashnr upon +--echo # HANDLER READ on a versioned HEAP table +--echo # + +CREATE TABLE t1 (g GEOMETRY NOT NULL, SPATIAL gi(g)); +INSERT INTO t1 VALUES (POINT(0,0)); +HANDLER t1 OPEN AS h; +--error ER_KEY_DOESNT_SUPPORT +HANDLER h READ `gi`= (10); +--error ER_KEY_DOESNT_SUPPORT +HANDLER h READ `gi`> (10); +HANDLER h CLOSE; +DROP TABLE t1; + +CREATE TABLE t1 (w VARCHAR(100), FULLTEXT fk(w)); +INSERT INTO t1 VALUES ('one two three'); +HANDLER t1 OPEN AS h; +--error ER_KEY_DOESNT_SUPPORT +HANDLER h READ `fk`= (10); +--error ER_KEY_DOESNT_SUPPORT +HANDLER h READ `fk`> (10); +HANDLER h CLOSE; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/r/innodb_fts_misc.result b/mysql-test/suite/innodb_fts/r/innodb_fts_misc.result index ac8fcd1..1322867 100644 --- a/mysql-test/suite/innodb_fts/r/innodb_fts_misc.result +++ b/mysql-test/suite/innodb_fts/r/innodb_fts_misc.result @@ -688,7 +688,7 @@ INSERT INTO t1 VALUES (1,'aaa'),(2,'bbb'),(3,'ccc'); CREATE FULLTEXT INDEX i ON t1 (char_column); HANDLER t1 OPEN; HANDLER t1 READ i = ('aaa'); -id char_column +ERROR HY000: FULLTEXT index `i` does not support this operation DROP TABLE t1; "----------Test25---------" CREATE TABLE t1 ( id INT , char_column VARCHAR(60) CHARACTER SET UTF8 COLLATE UTF8_CROATIAN_CI) ENGINE=InnoDB; diff --git a/mysql-test/suite/innodb_fts/t/innodb_fts_misc.test b/mysql-test/suite/innodb_fts/t/innodb_fts_misc.test index 68ca897..150d632 100644 --- a/mysql-test/suite/innodb_fts/t/innodb_fts_misc.test +++ b/mysql-test/suite/innodb_fts/t/innodb_fts_misc.test @@ -648,6 +648,7 @@ CREATE TABLE t1 ( id INT , char_column VARCHAR(60) CHARACTER SET UTF8) ENGINE = INSERT INTO t1 VALUES (1,'aaa'),(2,'bbb'),(3,'ccc'); CREATE FULLTEXT INDEX i ON t1 (char_column); HANDLER t1 OPEN; +--error ER_KEY_DOESNT_SUPPORT HANDLER t1 READ i = ('aaa'); DROP TABLE t1; #23. Duplicate key error when there are no unique indexes (procedure test) diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 4d1d739..7734747 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -7917,3 +7917,5 @@ ER_EMPTY_ROW_IN_TVC eng "Row with no elements is not allowed in table value constructor in this context" ER_VERS_QUERY_IN_PARTITION eng "SYSTEM_TIME partitions in table %`s does not support historical query" +ER_KEY_DOESNT_SUPPORT + eng "%s index %`s does not support this operation" diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 187a746..02d5bbf 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -618,7 +618,7 @@ static SQL_HANDLER *mysql_ha_find_handler(THD *thd, const LEX_CSTRING *name) static bool mysql_ha_fix_cond_and_key(SQL_HANDLER *handler, enum enum_ha_read_modes mode, const char *keyname, - List<Item> *key_expr, + List<Item> *key_expr, enum ha_rkey_function ha_rkey_mode, Item *cond, bool in_prepare) { THD *thd= handler->thd; @@ -660,6 +660,18 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler, Item *item; key_part_map keypart_map; uint key_len; + const KEY *c_key= table->s->key_info + handler->keyno; + + if ((c_key->flags & HA_SPATIAL) || + c_key->algorithm == HA_KEY_ALG_FULLTEXT || + (ha_rkey_mode != HA_READ_KEY_EXACT && + (table->file->index_flags(handler->keyno, 0, TRUE) & + (HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE)) == 0)) + { + my_error(ER_KEY_DOESNT_SUPPORT, MYF(0), + table->file->index_type(handler->keyno), keyinfo->name); + return 1; + } if (key_expr->elements > keyinfo->user_defined_key_parts) { @@ -667,6 +679,16 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler, keyinfo->user_defined_key_parts); return 1; } + + if (key_expr->elements < keyinfo->user_defined_key_parts && + (table->file->index_flags(handler->keyno, 0, TRUE) & + HA_ONLY_WHOLE_INDEX)) + { + my_error(ER_KEY_DOESNT_SUPPORT, MYF(0), + table->file->index_type(handler->keyno), keyinfo->name); + return 1; + } + for (keypart_map= key_len=0 ; (item=it_ke++) ; key_part++) { my_bitmap_map *old_map; @@ -841,7 +863,8 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, goto err0; // mysql_lock_tables() printed error message already } - if (mysql_ha_fix_cond_and_key(handler, mode, keyname, key_expr, cond, 0)) + if (mysql_ha_fix_cond_and_key(handler, mode, keyname, key_expr, + ha_rkey_mode, cond, 0)) goto err; mode= handler->mode; keyno= handler->keyno; @@ -1000,14 +1023,16 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, SQL_HANDLER *mysql_ha_read_prepare(THD *thd, TABLE_LIST *tables, enum enum_ha_read_modes mode, const char *keyname, - List<Item> *key_expr, Item *cond) + List<Item> *key_expr, enum ha_rkey_function ha_rkey_mode, + Item *cond) { SQL_HANDLER *handler; DBUG_ENTER("mysql_ha_read_prepare"); if (!(handler= mysql_ha_find_handler(thd, &tables->alias))) DBUG_RETURN(0); tables->table= handler->table; // This is used by fix_fields - if (mysql_ha_fix_cond_and_key(handler, mode, keyname, key_expr, cond, 1)) + if (mysql_ha_fix_cond_and_key(handler, mode, keyname, key_expr, + ha_rkey_mode, cond, 1)) DBUG_RETURN(0); DBUG_RETURN(handler); } diff --git a/sql/sql_handler.h b/sql/sql_handler.h index ffefec9..4c16f7e 100644 --- a/sql/sql_handler.h +++ b/sql/sql_handler.h @@ -80,5 +80,6 @@ void mysql_ha_rm_temporary_tables(THD *thd); SQL_HANDLER *mysql_ha_read_prepare(THD *thd, TABLE_LIST *tables, enum enum_ha_read_modes mode, const char *keyname, - List<Item> *key_expr, Item *cond); + List<Item> *key_expr, enum ha_rkey_function ha_rkey_mode, + Item *cond); #endif diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index b149727..2b5bac8 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2204,6 +2204,7 @@ static int mysql_test_handler_read(Prepared_statement *stmt, if (!(ha_table= mysql_ha_read_prepare(thd, tables, lex->ha_read_mode, lex->ident.str, lex->insert_list, + lex->ha_rkey_mode, lex->select_lex.where))) DBUG_RETURN(1);
participants (1)
-
holyfoot@askmonty.org