Skip to content

Commit f538a64

Browse files
committed
MDEV-15005 ASAN: stack-buffer-overflow in my_strnncollsp_simple
cmp_item_sort_string::store_value() did not cache the string returned from item->val_str(), whose result can point to various private members such as Item_char_typecast::tmp_value. - cmp_item_sort_string::store_value() remembered the pointer returned from item->val_str() poiting to tmp_value into cmp_item_string::value_res. - Later, cmp_item_real::store_value() was called, which called Item_str_func::val_real(), which called Item_char_typecast::val_str(&tmp) using a local stack variable "String tmp". Item_char_typecast::tmp_value was overwritten and become a link to "tmp": tmp_value.Ptr freed its own buffer and set to point to the buffer owned by "tmp". - On return from Item_str_func::val_real(), "String tmp" was destructed, but "tmp_value" still pointed to the buffer owned by "tmp", So tmp_value.Ptr became invalid. - Then cmp_item_sort_string() passed cmp_item_string::value_res to sortcmp(). At this point, value_res still pointed to an invalid value of Item_char_typecast::tmp_value. Fix: changing cmp_item_sort_string::store_value() to force copying to cmp_item_string::value if item->val_str(&value) returned a different pointer (instead of &value).
1 parent 31e2ab5 commit f538a64

File tree

5 files changed

+52
-0
lines changed

5 files changed

+52
-0
lines changed

mysql-test/r/ctype_latin1.result

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8208,5 +8208,18 @@ Warnings:
82088208
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d` from `test`.`t1` where ((coalesce(`test`.`t1`.`c`,0) = '3 ') and (coalesce(`test`.`t1`.`d`,0) = '3 '))
82098209
DROP TABLE t1;
82108210
#
8211+
# MDEV-15005 ASAN: stack-buffer-overflow in my_strnncollsp_simple
8212+
#
8213+
SET NAMES latin1;
8214+
SELECT CONVERT(1, CHAR) IN ('100', 10, '101');
8215+
CONVERT(1, CHAR) IN ('100', 10, '101')
8216+
0
8217+
SELECT CONVERT(1, CHAR) IN ('100', 10, '1');
8218+
CONVERT(1, CHAR) IN ('100', 10, '1')
8219+
1
8220+
SELECT CONVERT(1, CHAR) IN ('100', '10', '1');
8221+
CONVERT(1, CHAR) IN ('100', '10', '1')
8222+
1
8223+
#
82118224
# End of 10.1 tests
82128225
#

mysql-test/r/ctype_utf8.result

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10535,5 +10535,18 @@ CAST(_utf8 0xC499 AS CHAR CHARACTER SET latin1)
1053510535
Warnings:
1053610536
Warning 1977 Cannot convert 'utf8' character 0xC499 to 'latin1'
1053710537
#
10538+
# MDEV-15005 ASAN: stack-buffer-overflow in my_strnncollsp_simple
10539+
#
10540+
SET NAMES utf8;
10541+
SELECT CONVERT(1, CHAR) IN ('100', 10, '101');
10542+
CONVERT(1, CHAR) IN ('100', 10, '101')
10543+
0
10544+
SELECT CONVERT(1, CHAR) IN ('100', 10, '1');
10545+
CONVERT(1, CHAR) IN ('100', 10, '1')
10546+
1
10547+
SELECT CONVERT(1, CHAR) IN ('100', '10', '1');
10548+
CONVERT(1, CHAR) IN ('100', '10', '1')
10549+
1
10550+
#
1053810551
# End of 10.1 tests
1053910552
#

mysql-test/t/ctype_latin1.test

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,15 @@ EXPLAIN EXTENDED
389389
SELECT * FROM t1 WHERE COALESCE(c,0)='3 ' AND COALESCE(d,0)=COALESCE(c,0);
390390
DROP TABLE t1;
391391

392+
--echo #
393+
--echo # MDEV-15005 ASAN: stack-buffer-overflow in my_strnncollsp_simple
394+
--echo #
395+
396+
SET NAMES latin1;
397+
SELECT CONVERT(1, CHAR) IN ('100', 10, '101');
398+
SELECT CONVERT(1, CHAR) IN ('100', 10, '1');
399+
SELECT CONVERT(1, CHAR) IN ('100', '10', '1');
400+
392401
--echo #
393402
--echo # End of 10.1 tests
394403
--echo #

mysql-test/t/ctype_utf8.test

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2024,6 +2024,16 @@ SELECT CONVERT(_utf8 0xC499 USING latin1);
20242024
SELECT CAST(_utf8 0xC499 AS CHAR CHARACTER SET latin1);
20252025

20262026

2027+
--echo #
2028+
--echo # MDEV-15005 ASAN: stack-buffer-overflow in my_strnncollsp_simple
2029+
--echo #
2030+
2031+
SET NAMES utf8;
2032+
SELECT CONVERT(1, CHAR) IN ('100', 10, '101');
2033+
SELECT CONVERT(1, CHAR) IN ('100', 10, '1');
2034+
SELECT CONVERT(1, CHAR) IN ('100', '10', '1');
2035+
2036+
20272037
--echo #
20282038
--echo # End of 10.1 tests
20292039
--echo #

sql/item_cmpfunc.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1312,6 +1312,13 @@ class cmp_item_sort_string :public cmp_item_string
13121312
{
13131313
value_res= item->val_str(&value);
13141314
m_null_value= item->null_value;
1315+
// Make sure to cache the result String inside "value"
1316+
if (value_res && value_res != &value)
1317+
{
1318+
if (value.copy(*value_res))
1319+
value.set("", 0, item->collation.collation);
1320+
value_res= &value;
1321+
}
13151322
}
13161323
int cmp(Item *arg)
13171324
{

0 commit comments

Comments
 (0)