[Commits] 5469d88e7b4: MDEV-19049 Server crashes in check_duplicate_long_entry_key, ASAN stack-buffer-overflow in Field_blob::get_key_image

sachin.setiya at mariadb.com sachin.setiya at mariadb.com
Tue Apr 23 15:28:40 EEST 2019


revision-id: 5469d88e7b4e723e545cd7d511801a16a3642dc4 (mariadb-10.4.3-104-g5469d88e7b4)
parent(s): 0bc42602266815b81fe86b08c2228912c1a95340
author: Sachin
committer: Sachin
timestamp: 2019-03-28 11:29:25 +0530
message:

MDEV-19049 Server crashes in check_duplicate_long_entry_key, ASAN stack-buffer-overflow in Field_blob::get_key_image

Long Unique keys should always be last unique key.

---
 mysql-test/main/long_unique.result        | 64 +++++++++++++++----------------
 mysql-test/main/long_unique_bugs.result   | 46 ++++++++++++++++++++++
 mysql-test/main/long_unique_bugs.test     | 22 ++++++++++-
 mysql-test/main/long_unique_innodb.result |  4 +-
 mysql-test/main/long_unique_update.result |  8 ++--
 sql/sql_table.cc                          |  9 +++++
 6 files changed, 114 insertions(+), 39 deletions(-)

diff --git a/mysql-test/main/long_unique.result b/mysql-test/main/long_unique.result
index 3843ff4aff0..8ea6d36c321 100644
--- a/mysql-test/main/long_unique.result
+++ b/mysql-test/main/long_unique.result
@@ -184,8 +184,8 @@ t1	CREATE TABLE `t1` (
   `a` blob DEFAULT NULL,
   `c` int(11) DEFAULT NULL,
   `db_row_hash_1` int(11) DEFAULT NULL,
-  UNIQUE KEY `a` (`a`) USING HASH,
-  UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`)
+  UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`),
+  UNIQUE KEY `a` (`a`) USING HASH
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 insert into t1 values(45,1,55),(46,1,55);
 ERROR 23000: Duplicate entry '55' for key 'db_row_hash_1'
@@ -507,13 +507,13 @@ t1	CREATE TABLE `t1` (
   `db_row_hash_1` int(11) DEFAULT NULL,
   `db_row_hash_2` int(11) DEFAULT NULL,
   `db_row_hash_3` int(11) DEFAULT NULL,
+  UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`),
+  UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`),
+  UNIQUE KEY `db_row_hash_3` (`db_row_hash_3`),
   UNIQUE KEY `a` (`a`) USING HASH,
   UNIQUE KEY `c` (`c`) USING HASH,
   UNIQUE KEY `d` (`d`) USING HASH,
-  UNIQUE KEY `e` (`e`) USING HASH,
-  UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`),
-  UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`),
-  UNIQUE KEY `db_row_hash_3` (`db_row_hash_3`)
+  UNIQUE KEY `e` (`e`) USING HASH
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 alter table t1 add column db_row_hash_7 int, add column db_row_hash_5 int , add column db_row_hash_4 int ;
 alter table t1 drop column db_row_hash_7,drop column db_row_hash_3, drop column db_row_hash_4;
@@ -543,17 +543,17 @@ t1	CREATE TABLE `t1` (
   `db_row_hash_1` int(11) DEFAULT NULL,
   `db_row_hash_2` int(11) DEFAULT NULL,
   `db_row_hash_5` int(11) DEFAULT NULL,
-  UNIQUE KEY `d` (`d`) USING HASH,
-  UNIQUE KEY `e` (`e`) USING HASH,
   UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`),
-  UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`)
+  UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`),
+  UNIQUE KEY `d` (`d`) USING HASH,
+  UNIQUE KEY `e` (`e`) USING HASH
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 show keys from t1;
 Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
-t1	0	d	1	d	A	NULL	NULL	NULL	YES	HASH		
-t1	0	e	1	e	A	NULL	NULL	NULL	YES	HASH		
 t1	0	db_row_hash_1	1	db_row_hash_1	A	NULL	NULL	NULL	YES	BTREE		
 t1	0	db_row_hash_2	1	db_row_hash_2	A	NULL	NULL	NULL	YES	BTREE		
+t1	0	d	1	d	A	NULL	NULL	NULL	YES	HASH		
+t1	0	e	1	e	A	NULL	NULL	NULL	YES	HASH		
 #add column with unique index on blob;
 alter table t1 add column a blob unique;
 show create table t1;
@@ -567,18 +567,18 @@ t1	CREATE TABLE `t1` (
   `db_row_hash_2` int(11) DEFAULT NULL,
   `db_row_hash_5` int(11) DEFAULT NULL,
   `a` blob DEFAULT NULL,
-  UNIQUE KEY `d` (`d`) USING HASH,
-  UNIQUE KEY `e` (`e`) USING HASH,
   UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`),
   UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`),
+  UNIQUE KEY `d` (`d`) USING HASH,
+  UNIQUE KEY `e` (`e`) USING HASH,
   UNIQUE KEY `a` (`a`) USING HASH
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 show keys from t1;
 Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
-t1	0	d	1	d	A	NULL	NULL	NULL	YES	HASH		
-t1	0	e	1	e	A	NULL	NULL	NULL	YES	HASH		
 t1	0	db_row_hash_1	1	db_row_hash_1	A	NULL	NULL	NULL	YES	BTREE		
 t1	0	db_row_hash_2	1	db_row_hash_2	A	NULL	NULL	NULL	YES	BTREE		
+t1	0	d	1	d	A	NULL	NULL	NULL	YES	HASH		
+t1	0	e	1	e	A	NULL	NULL	NULL	YES	HASH		
 t1	0	a	1	a	A	NULL	NULL	NULL	YES	HASH		
 #try to change the blob unique column name;
 #this will change index to b tree;
@@ -594,19 +594,19 @@ t1	CREATE TABLE `t1` (
   `db_row_hash_2` int(11) DEFAULT NULL,
   `db_row_hash_5` int(11) DEFAULT NULL,
   `a` int(11) DEFAULT NULL,
-  UNIQUE KEY `d` (`d`) USING HASH,
-  UNIQUE KEY `e` (`e`),
   UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`),
   UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`),
-  UNIQUE KEY `a` (`a`)
+  UNIQUE KEY `e` (`e`),
+  UNIQUE KEY `a` (`a`),
+  UNIQUE KEY `d` (`d`) USING HASH
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 show keys from t1;
 Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
-t1	0	d	1	d	A	NULL	NULL	NULL	YES	HASH		
-t1	0	e	1	e	A	NULL	NULL	NULL	YES	BTREE		
 t1	0	db_row_hash_1	1	db_row_hash_1	A	NULL	NULL	NULL	YES	BTREE		
 t1	0	db_row_hash_2	1	db_row_hash_2	A	NULL	NULL	NULL	YES	BTREE		
+t1	0	e	1	e	A	NULL	NULL	NULL	YES	BTREE		
 t1	0	a	1	a	A	NULL	NULL	NULL	YES	BTREE		
+t1	0	d	1	d	A	NULL	NULL	NULL	YES	HASH		
 alter table t1 add column clm1 blob unique,add column clm2 blob unique;
 #try changing the name; 
 alter table t1 change column clm1 clm_changed1 blob, change column clm2 clm_changed2 blob;
@@ -623,21 +623,21 @@ t1	CREATE TABLE `t1` (
   `a` int(11) DEFAULT NULL,
   `clm_changed1` blob DEFAULT NULL,
   `clm_changed2` blob DEFAULT NULL,
-  UNIQUE KEY `d` (`d`) USING HASH,
-  UNIQUE KEY `e` (`e`),
   UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`),
   UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`),
+  UNIQUE KEY `e` (`e`),
   UNIQUE KEY `a` (`a`),
+  UNIQUE KEY `d` (`d`) USING HASH,
   UNIQUE KEY `clm1` (`clm_changed1`) USING HASH,
   UNIQUE KEY `clm2` (`clm_changed2`) USING HASH
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 show keys from t1;
 Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
-t1	0	d	1	d	A	NULL	NULL	NULL	YES	HASH		
-t1	0	e	1	e	A	NULL	NULL	NULL	YES	BTREE		
 t1	0	db_row_hash_1	1	db_row_hash_1	A	NULL	NULL	NULL	YES	BTREE		
 t1	0	db_row_hash_2	1	db_row_hash_2	A	NULL	NULL	NULL	YES	BTREE		
+t1	0	e	1	e	A	NULL	NULL	NULL	YES	BTREE		
 t1	0	a	1	a	A	NULL	NULL	NULL	YES	BTREE		
+t1	0	d	1	d	A	NULL	NULL	NULL	YES	HASH		
 t1	0	clm1	1	clm_changed1	A	NULL	NULL	NULL	YES	HASH		
 t1	0	clm2	1	clm_changed2	A	NULL	NULL	NULL	YES	HASH		
 #now drop the unique key;
@@ -655,19 +655,19 @@ t1	CREATE TABLE `t1` (
   `a` int(11) DEFAULT NULL,
   `clm_changed1` blob DEFAULT NULL,
   `clm_changed2` blob DEFAULT NULL,
-  UNIQUE KEY `d` (`d`) USING HASH,
-  UNIQUE KEY `e` (`e`),
   UNIQUE KEY `db_row_hash_1` (`db_row_hash_1`),
   UNIQUE KEY `db_row_hash_2` (`db_row_hash_2`),
-  UNIQUE KEY `a` (`a`)
+  UNIQUE KEY `e` (`e`),
+  UNIQUE KEY `a` (`a`),
+  UNIQUE KEY `d` (`d`) USING HASH
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 show keys from t1;
 Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
-t1	0	d	1	d	A	NULL	NULL	NULL	YES	HASH		
-t1	0	e	1	e	A	NULL	NULL	NULL	YES	BTREE		
 t1	0	db_row_hash_1	1	db_row_hash_1	A	NULL	NULL	NULL	YES	BTREE		
 t1	0	db_row_hash_2	1	db_row_hash_2	A	NULL	NULL	NULL	YES	BTREE		
+t1	0	e	1	e	A	NULL	NULL	NULL	YES	BTREE		
 t1	0	a	1	a	A	NULL	NULL	NULL	YES	BTREE		
+t1	0	d	1	d	A	NULL	NULL	NULL	YES	HASH		
 drop table t1;
 #now the table with key on multiple columns; the ultimate test;
 create table t1(a blob, b int , c varchar(2000) , d text  , e varchar(3000) , f longblob , g int , h text ,
@@ -1130,17 +1130,17 @@ t1	CREATE TABLE `t1` (
   `c` blob DEFAULT NULL,
   `d` blob DEFAULT NULL,
   `e` int(11) DEFAULT NULL,
+  UNIQUE KEY `e` (`e`),
   UNIQUE KEY `a` (`a`,`c`) USING HASH,
-  UNIQUE KEY `b` (`b`,`d`) USING HASH,
-  UNIQUE KEY `e` (`e`)
+  UNIQUE KEY `b` (`b`,`d`) USING HASH
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 show keys from t1;
 Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
+t1	0	e	1	e	A	NULL	NULL	NULL	YES	BTREE		
 t1	0	a	1	a	A	NULL	NULL	NULL	YES	HASH		
 t1	0	a	2	c	A	NULL	NULL	NULL	YES	HASH		
 t1	0	b	1	b	A	NULL	NULL	NULL	YES	HASH		
 t1	0	b	2	d	A	NULL	NULL	NULL	YES	HASH		
-t1	0	e	1	e	A	0	NULL	NULL	YES	BTREE		
 drop table t1;
 #visibility of db_row_hash 
 create table t1 (a blob unique , b blob unique);
diff --git a/mysql-test/main/long_unique_bugs.result b/mysql-test/main/long_unique_bugs.result
index 87a57fb4614..48e74bdd564 100644
--- a/mysql-test/main/long_unique_bugs.result
+++ b/mysql-test/main/long_unique_bugs.result
@@ -239,3 +239,49 @@ CREATE TABLE t1 (a INT, UNIQUE USING HASH (a)) PARTITION BY HASH (a) PARTITIONS
 INSERT INTO t1 VALUES (2);
 REPLACE INTO t1 VALUES (2);
 DROP TABLE t1;
+CREATE TABLE t1 (pk INT, a CHAR(4), b BLOB NOT NULL, PRIMARY KEY(pk));
+INSERT INTO t1 VALUES (1,'foo','bar');
+ALTER TABLE t1 ADD KEY (b(64));
+ALTER TABLE t1 ADD UNIQUE (b(165));
+ALTER TABLE t1 ADD KEY (b(1000));
+ALTER TABLE t1 ADD KEY (b(500));
+ALTER TABLE t1 ADD UNIQUE (a,b);
+ALTER TABLE t1 ADD UNIQUE (b(95));
+ALTER TABLE t1 ADD KEY (b(30));
+ALTER TABLE t1 ADD UNIQUE (b(20));
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `pk` int(11) NOT NULL,
+  `a` char(4) DEFAULT NULL,
+  `b` blob NOT NULL,
+  PRIMARY KEY (`pk`),
+  UNIQUE KEY `b_2` (`b`(165)),
+  UNIQUE KEY `b_5` (`b`(95)),
+  UNIQUE KEY `b_7` (`b`(20)),
+  UNIQUE KEY `a` (`a`,`b`) USING HASH,
+  KEY `b` (`b`(64)),
+  KEY `b_3` (`b`(1000)),
+  KEY `b_4` (`b`(500)),
+  KEY `b_6` (`b`(30))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+ALTER TABLE t1 ADD UNIQUE (b);
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `pk` int(11) NOT NULL,
+  `a` char(4) DEFAULT NULL,
+  `b` blob NOT NULL,
+  PRIMARY KEY (`pk`),
+  UNIQUE KEY `b_2` (`b`(165)),
+  UNIQUE KEY `b_5` (`b`(95)),
+  UNIQUE KEY `b_7` (`b`(20)),
+  UNIQUE KEY `a` (`a`,`b`) USING HASH,
+  UNIQUE KEY `b_8` (`b`) USING HASH,
+  KEY `b` (`b`(64)),
+  KEY `b_3` (`b`(1000)),
+  KEY `b_4` (`b`(500)),
+  KEY `b_6` (`b`(30))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+ALTER TABLE t1 FORCE;
+DROP TABLE t1;
diff --git a/mysql-test/main/long_unique_bugs.test b/mysql-test/main/long_unique_bugs.test
index ed0daee426f..11b1c4f09b6 100644
--- a/mysql-test/main/long_unique_bugs.test
+++ b/mysql-test/main/long_unique_bugs.test
@@ -1,4 +1,5 @@
 --source include/have_innodb.inc
+--source include/have_partition.inc
 
 #
 # MDEV-18707 Server crash in my_hash_sort_bin, ASAN heap-use-after-free in Field::is_null, server hang, corrupted double-linked list
@@ -269,8 +270,27 @@ drop table t1;
 #
 # MDEV-18904 Assertion `m_part_spec.start_part >= m_part_spec.end_part' failed in ha_partition::index_read_idx_map
 #
---source include/have_partition.inc
 CREATE TABLE t1 (a INT, UNIQUE USING HASH (a)) PARTITION BY HASH (a) PARTITIONS 2;
 INSERT INTO t1 VALUES (2);
 REPLACE INTO t1 VALUES (2);
 DROP TABLE t1;
+
+#
+# MDEV-19049 Server crashes in check_duplicate_long_entry_key, ASAN stack-buffer-overflow in Field_blob::get_key_image
+#
+CREATE TABLE t1 (pk INT, a CHAR(4), b BLOB NOT NULL, PRIMARY KEY(pk));
+INSERT INTO t1 VALUES (1,'foo','bar');
+
+ALTER TABLE t1 ADD KEY (b(64));
+ALTER TABLE t1 ADD UNIQUE (b(165));
+ALTER TABLE t1 ADD KEY (b(1000));
+ALTER TABLE t1 ADD KEY (b(500));
+ALTER TABLE t1 ADD UNIQUE (a,b);
+ALTER TABLE t1 ADD UNIQUE (b(95));
+ALTER TABLE t1 ADD KEY (b(30));
+ALTER TABLE t1 ADD UNIQUE (b(20));
+show create table t1;
+ALTER TABLE t1 ADD UNIQUE (b);
+show create table t1;
+ALTER TABLE t1 FORCE;
+DROP TABLE t1;
diff --git a/mysql-test/main/long_unique_innodb.result b/mysql-test/main/long_unique_innodb.result
index cb8c3ea4858..135bb0808cc 100644
--- a/mysql-test/main/long_unique_innodb.result
+++ b/mysql-test/main/long_unique_innodb.result
@@ -9,8 +9,8 @@ Table	Create Table
 t1	CREATE TABLE `t1` (
   `a` blob DEFAULT NULL,
   `c` int(11) DEFAULT NULL,
-  UNIQUE KEY `a` (`a`) USING HASH,
-  UNIQUE KEY `c` (`c`)
+  UNIQUE KEY `c` (`c`),
+  UNIQUE KEY `a` (`a`) USING HASH
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1
 drop table t1;
 #test for concurrent insert of long unique in innodb
diff --git a/mysql-test/main/long_unique_update.result b/mysql-test/main/long_unique_update.result
index 60a4fb46558..b508583f47c 100644
--- a/mysql-test/main/long_unique_update.result
+++ b/mysql-test/main/long_unique_update.result
@@ -71,8 +71,8 @@ create table t1 (a int primary key, b blob unique , c int unique );
 show keys from t1;
 Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
 t1	0	PRIMARY	1	a	A	0	NULL	NULL		BTREE		
-t1	0	b	1	b	A	NULL	NULL	NULL	YES	HASH		
 t1	0	c	1	c	A	NULL	NULL	NULL	YES	BTREE		
+t1	0	b	1	b	A	NULL	NULL	NULL	YES	HASH		
 insert into t1 values(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),(6,6,6),(7,7,7);
 select * from t1 limit 3;
 a	b	c
@@ -220,18 +220,18 @@ t1	CREATE TABLE `t1` (
   `f` int(11) DEFAULT NULL,
   `g` text DEFAULT NULL,
   PRIMARY KEY (`a`),
-  UNIQUE KEY `b` (`b`,`c`) USING HASH,
   UNIQUE KEY `b_2` (`b`,`f`),
+  UNIQUE KEY `b` (`b`,`c`) USING HASH,
   UNIQUE KEY `e` (`e`,`g`) USING HASH,
   UNIQUE KEY `a` (`a`,`b`,`c`,`d`,`e`,`f`,`g`) USING HASH
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 show keys from t1;
 Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment	Index_comment
 t1	0	PRIMARY	1	a	A	0	NULL	NULL		BTREE		
-t1	0	b	1	b	A	NULL	NULL	NULL	YES	HASH		
-t1	0	b	2	c	A	NULL	NULL	NULL	YES	HASH		
 t1	0	b_2	1	b	A	NULL	NULL	NULL	YES	BTREE		
 t1	0	b_2	2	f	A	NULL	NULL	NULL	YES	BTREE		
+t1	0	b	1	b	A	NULL	NULL	NULL	YES	HASH		
+t1	0	b	2	c	A	NULL	NULL	NULL	YES	HASH		
 t1	0	e	1	e	A	NULL	NULL	NULL	YES	HASH		
 t1	0	e	2	g	A	NULL	NULL	NULL	YES	HASH		
 t1	0	a	1	a	A	NULL	NULL	NULL		HASH		
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index ad62ecc1103..c755a74e174 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2773,6 +2773,7 @@ bool quick_rm_table(THD *thd, handlerton *base, const LEX_CSTRING *db,
   - UNIQUE keys where all column are NOT NULL
   - UNIQUE keys that don't contain partial segments
   - Other UNIQUE keys
+  - LONG UNIQUE keys
   - Normal keys
   - Fulltext keys
 
@@ -2796,6 +2797,14 @@ static int sort_keys(KEY *a, KEY *b)
   {
     if (!(b_flags & HA_NOSAME))
       return -1;
+    /*
+      Long Unique keys should always be last unique key.
+      Before this patch they used to change order wrt to partial keys (MDEV-19049)
+    */
+    if (a->algorithm == HA_KEY_ALG_LONG_HASH)
+      return 1;
+    if (b->algorithm == HA_KEY_ALG_LONG_HASH)
+      return -1;
     if ((a_flags ^ b_flags) & HA_NULL_PART_KEY)
     {
       /* Sort NOT NULL keys before other keys */


More information about the commits mailing list