Skip to content

Commit 924db8b

Browse files
varunraikocvicentiu
authored andcommitted
MDEV-12350: Heap corruption, overrun buffer, ASAN errors, server crash in my_fill_8bit / filesort
In the function make_sortkey a tmp buffer was defined and in the absence of param->tmp_buffer, tmp buffer used the sort_keys buffer. sort_keys buffer has a length defined in sort_field->length, while param->tmp_buffer is stored in param->rec_length. Make sure to use the appropriate length based on which buffer we are using otherwise we'll overflow. Also added a type cast to size_t during the calculation of the sort keys buffer size to avoid an oveflow if the buffer size exceeds 32 bits.
1 parent cfa18e4 commit 924db8b

File tree

3 files changed

+56
-2
lines changed

3 files changed

+56
-2
lines changed

mysql-test/r/group_by.result

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2558,3 +2558,28 @@ create table t2 (c1 int, c2 int);
25582558
select t1.c1 as c1, t2.c2 as c1 from t1, t2 where t1.c1 < 20 and t2.c2 > 5 group by t1.c1, t2.c2 having t1.c1 < 3;
25592559
c1 c1
25602560
drop table t1, t2;
2561+
SET @old_sort_buff_size = @@sort_buffer_size;
2562+
SET @@sort_buffer_size=256*1024;
2563+
CREATE TABLE t1 (c INT) ENGINE=MyISAM;
2564+
INSERT INTO t1 VALUES
2565+
(2011),(1977),(1982),(2027),(2023),(NULL),(NULL),(2004),(1974),(2032),
2566+
(1993),(NULL),(1995),(2034),(NULL),(2009),(1900),(NULL),(2025),(1900),
2567+
(2033),(1900),(2012),(NULL),(2009),(1992),(1974),(1974),(2012),(2028),
2568+
(2007),(2012),(1900),(1983),(1900),(2010),(1987),(1994),(1981),(2032),
2569+
(2010),(1989),(2014),(1900),(1900),(1976),(1978),(2007),(2030),(NULL),
2570+
(2002),(1997),(1900),(NULL),(2000),(2027),(1975),(2026),(1975),(2026),
2571+
(2029),(1977),(1900),(1900),(2031),(1993),(1986),(2012),(1979),(2013),
2572+
(1994),(2014),(2025),(2006),(1971),(1974),(2021),(2011),(NULL),(1991),
2573+
(2001),(1977),(2023),(2012),(1900),(1978),(1998),(NULL),(1988),(1999),
2574+
(2017),(2008),(1976),(1900),(2005),(2030),(2023),(1900),(1978),(1990),
2575+
(1978),(1987),(2030),(1900),(2034),(2006),(2015),(2001),(2019),(2024),
2576+
(2030),(1989),(1997),(2007),(2023),(1994),(1971),(2011),(2011),(2015),
2577+
(1984),(1978),(1979),(1989),(2008),(2030);
2578+
SELECT ExtractValue('<a></a>','/a') AS f1, SPACE(c) AS f2 FROM t1 GROUP BY f1, f2 WITH ROLLUP;
2579+
f1 f2
2580+
NULL
2581+
2582+
NULL
2583+
NULL NULL
2584+
SET @@sort_buffer_size = @old_sort_buff_size;
2585+
DROP TABLE t1;

mysql-test/t/group_by.test

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1741,6 +1741,32 @@ create table t2 (c1 int, c2 int);
17411741
select t1.c1 as c1, t2.c2 as c1 from t1, t2 where t1.c1 < 20 and t2.c2 > 5 group by t1.c1, t2.c2 having t1.c1 < 3;
17421742
drop table t1, t2;
17431743

1744+
#
1745+
# MDEV-12350: Heap corruption, overrun buffer, ASAN errors, server crash in my_fill_8bit / filesort
1746+
#
1747+
1748+
SET @old_sort_buff_size = @@sort_buffer_size;
1749+
SET @@sort_buffer_size=256*1024;
1750+
CREATE TABLE t1 (c INT) ENGINE=MyISAM;
1751+
INSERT INTO t1 VALUES
1752+
(2011),(1977),(1982),(2027),(2023),(NULL),(NULL),(2004),(1974),(2032),
1753+
(1993),(NULL),(1995),(2034),(NULL),(2009),(1900),(NULL),(2025),(1900),
1754+
(2033),(1900),(2012),(NULL),(2009),(1992),(1974),(1974),(2012),(2028),
1755+
(2007),(2012),(1900),(1983),(1900),(2010),(1987),(1994),(1981),(2032),
1756+
(2010),(1989),(2014),(1900),(1900),(1976),(1978),(2007),(2030),(NULL),
1757+
(2002),(1997),(1900),(NULL),(2000),(2027),(1975),(2026),(1975),(2026),
1758+
(2029),(1977),(1900),(1900),(2031),(1993),(1986),(2012),(1979),(2013),
1759+
(1994),(2014),(2025),(2006),(1971),(1974),(2021),(2011),(NULL),(1991),
1760+
(2001),(1977),(2023),(2012),(1900),(1978),(1998),(NULL),(1988),(1999),
1761+
(2017),(2008),(1976),(1900),(2005),(2030),(2023),(1900),(1978),(1990),
1762+
(1978),(1987),(2030),(1900),(2034),(2006),(2015),(2001),(2019),(2024),
1763+
(2030),(1989),(1997),(2007),(2023),(1994),(1971),(2011),(2011),(2015),
1764+
(1984),(1978),(1979),(1989),(2008),(2030);
1765+
1766+
SELECT ExtractValue('<a></a>','/a') AS f1, SPACE(c) AS f2 FROM t1 GROUP BY f1, f2 WITH ROLLUP;
1767+
SET @@sort_buffer_size = @old_sort_buff_size;
1768+
DROP TABLE t1;
1769+
17441770
#
17451771
# End of MariaDB 5.5 tests
17461772
#

sql/filesort.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,9 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
210210
{
211211
ulonglong keys= memory_available / (param.rec_length + sizeof(char*));
212212
table_sort.keys= (uint) min(num_rows, keys);
213-
sort_buff_sz= table_sort.keys*(param.rec_length+sizeof(char*));
213+
/* Cast to size_t to avoid overflow when result is greater than uint. */
214+
sort_buff_sz= ((size_t)table_sort.keys) *
215+
(param.rec_length + sizeof(char*));
214216
set_if_bigger(sort_buff_sz, param.rec_length * MERGEBUFF2);
215217

216218
DBUG_EXECUTE_IF("make_sort_keys_alloc_fail",
@@ -914,7 +916,8 @@ static void make_sortkey(register SORTPARAM *param,
914916
if (maybe_null)
915917
*to++=1;
916918
char *tmp_buffer= param->tmp_buffer ? param->tmp_buffer : (char*)to;
917-
String tmp(tmp_buffer, param->sort_length, cs);
919+
String tmp(tmp_buffer, param->tmp_buffer ? param->sort_length :
920+
sort_field->length, cs);
918921
String *res= item->str_result(&tmp);
919922
if (!res)
920923
{

0 commit comments

Comments
 (0)