From 059797ed44007fe954cf47f6f09db78e60df16fd Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 29 Oct 2021 12:24:47 +0400 Subject: [PATCH] MDEV-24901 SIGSEGV in fts_get_table_name, SIGSEGV in ib_vector_size, SIGSEGV in row_merge_fts_doc_tokenize, stack smashing strmake() puts one extra 0x00 byte at the end of the string. The code in my_strnxfrm_tis620[_nopad] did not take this into account, so in the reported scenario the 0x00 byte was put outside of a stack variable, which made ASAN crash. This problem is already fixed in in MySQL: commit 19bd66fe43c41f0bde5f36bc6b455a46693069fb Author: bin.x.su@oracle.com <> Date: Fri Apr 4 11:35:27 2014 +0800 But the fix does not seem to be correct, as it breaks when finds a zero byte in the source string. Using memcpy() instead of strmake(). - Unlike strmake(), memcpy() it does not write beyond the destination size passed. - Unlike the MySQL fix, memcpy() does not break on the first 0x00 byte found in the source string. --- mysql-test/r/ctype_tis620.result | 9 ++++++ .../suite/innodb/r/innodb_ctype_tis620.result | 32 +++++++++++++++++++ .../suite/innodb/t/innodb_ctype_tis620.test | 29 +++++++++++++++++ mysql-test/t/ctype_tis620.test | 7 ++++ strings/ctype-tis620.c | 8 ++--- 5 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_ctype_tis620.result create mode 100644 mysql-test/suite/innodb/t/innodb_ctype_tis620.test diff --git a/mysql-test/r/ctype_tis620.result b/mysql-test/r/ctype_tis620.result index ee333e751e4..d8432c4ca0c 100644 --- a/mysql-test/r/ctype_tis620.result +++ b/mysql-test/r/ctype_tis620.result @@ -4421,5 +4421,14 @@ DROP TABLE t1; # SET STORAGE_ENGINE=Default; # +# MDEV-24901 SIGSEGV in fts_get_table_name, SIGSEGV in ib_vector_size, SIGSEGV in row_merge_fts_doc_tokenize, stack smashing +# +SELECT HEX(WEIGHT_STRING(_tis620 'a\0b')); +HEX(WEIGHT_STRING(_tis620 'a\0b')) +610062 +SELECT HEX(WEIGHT_STRING(_tis620 'a\0b' COLLATE tis620_thai_nopad_ci)); +HEX(WEIGHT_STRING(_tis620 'a\0b' COLLATE tis620_thai_nopad_ci)) +610062 +# # End of 10.2 tests # diff --git a/mysql-test/suite/innodb/r/innodb_ctype_tis620.result b/mysql-test/suite/innodb/r/innodb_ctype_tis620.result new file mode 100644 index 00000000000..6b291f2d359 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_ctype_tis620.result @@ -0,0 +1,32 @@ +SET STORAGE_ENGINE=InnoDB; +# +# Start of 10.2 tests +# +# +# MDEV-24901 SIGSEGV in fts_get_table_name, SIGSEGV in ib_vector_size, SIGSEGV in row_merge_fts_doc_tokenize, stack smashing Export +# +CREATE TABLE t1(c TEXT CHARACTER SET tis620); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` text CHARACTER SET tis620 DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES('100'); +ALTER TABLE t1 ADD FULLTEXT INDEX(c), ALGORITHM=INPLACE; +Warnings: +Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID +DROP TABLE t1; +CREATE TABLE t1(c TEXT CHARACTER SET tis620 COLLATE tis620_thai_nopad_ci); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` text CHARACTER SET tis620 COLLATE tis620_thai_nopad_ci DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES('100'); +ALTER TABLE t1 ADD FULLTEXT INDEX(c), ALGORITHM=INPLACE; +Warnings: +Warning 124 InnoDB rebuilding table to add column FTS_DOC_ID +DROP TABLE t1; +# +# End of 10.2 tests +# diff --git a/mysql-test/suite/innodb/t/innodb_ctype_tis620.test b/mysql-test/suite/innodb/t/innodb_ctype_tis620.test new file mode 100644 index 00000000000..fee1b283ac3 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_ctype_tis620.test @@ -0,0 +1,29 @@ +--source include/have_innodb.inc +--source include/have_tis620.inc + +SET STORAGE_ENGINE=InnoDB; + +--echo # +--echo # Start of 10.2 tests +--echo # + +--echo # +--echo # MDEV-24901 SIGSEGV in fts_get_table_name, SIGSEGV in ib_vector_size, SIGSEGV in row_merge_fts_doc_tokenize, stack smashing Export +--echo # + +CREATE TABLE t1(c TEXT CHARACTER SET tis620); +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES('100'); +ALTER TABLE t1 ADD FULLTEXT INDEX(c), ALGORITHM=INPLACE; +DROP TABLE t1; + +CREATE TABLE t1(c TEXT CHARACTER SET tis620 COLLATE tis620_thai_nopad_ci); +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES('100'); +ALTER TABLE t1 ADD FULLTEXT INDEX(c), ALGORITHM=INPLACE; +DROP TABLE t1; + + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/mysql-test/t/ctype_tis620.test b/mysql-test/t/ctype_tis620.test index 7bc248aec2b..7f6382fe7bc 100644 --- a/mysql-test/t/ctype_tis620.test +++ b/mysql-test/t/ctype_tis620.test @@ -209,6 +209,13 @@ let $coll='tis620_nopad_bin'; let $coll_pad='tis620_bin'; --source include/ctype_pad_all_engines.inc +--echo # +--echo # MDEV-24901 SIGSEGV in fts_get_table_name, SIGSEGV in ib_vector_size, SIGSEGV in row_merge_fts_doc_tokenize, stack smashing +--echo # + +SELECT HEX(WEIGHT_STRING(_tis620 'a\0b')); +SELECT HEX(WEIGHT_STRING(_tis620 'a\0b' COLLATE tis620_thai_nopad_ci)); + --echo # --echo # End of 10.2 tests --echo # diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index 66bd1604803..4f1d12ae741 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -605,8 +605,8 @@ my_strnxfrm_tis620(CHARSET_INFO *cs, const uchar *src, size_t srclen, uint flags) { size_t len, dstlen0= dstlen; - len= (uint) (strmake((char*) dst, (char*) src, MY_MIN(dstlen, srclen)) - - (char*) dst); + len= MY_MIN(dstlen, srclen); + memcpy(dst, src, len); len= thai2sortable(dst, len); set_if_smaller(dstlen, nweights); set_if_smaller(len, dstlen); @@ -628,8 +628,8 @@ my_strnxfrm_tis620_nopad(CHARSET_INFO *cs, const uchar *src, size_t srclen, uint flags) { size_t len, dstlen0= dstlen; - len= (uint) (strmake((char*) dst, (char*) src, MY_MIN(dstlen, srclen)) - - (char*) dst); + len= MY_MIN(dstlen, srclen); + memcpy(dst, src, len); len= thai2sortable(dst, len); set_if_smaller(dstlen, nweights); set_if_smaller(len, dstlen);