diff options
author | Alexey Botchkov <holyfoot@askmonty.org> | 2018-05-16 09:44:22 +0400 |
---|---|---|
committer | Alexey Botchkov <holyfoot@askmonty.org> | 2018-05-16 09:44:22 +0400 |
commit | a639eff5940ed4147709511aeaee922fa7095284 (patch) | |
tree | 7d8faf3e9668d27904fc37b18a701ef9155f1b54 /sql/sql_handler.cc | |
parent | cd15e764a8a4f3e799f1efaede413c95e3233df6 (diff) | |
download | mariadb-git-a639eff5940ed4147709511aeaee922fa7095284.tar.gz |
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.
Diffstat (limited to 'sql/sql_handler.cc')
-rw-r--r-- | sql/sql_handler.cc | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 187a7462c87..02d5bbfc84f 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 @@ retry: 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 @@ err0: 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); } |