Commit 1c1dd1f2 authored by unknown's avatar unknown

Fix for bug #32241: memory corruption due to large index map in 'Range

checked for each record'

The problem was in incorrectly calculated length of the buffer used to
store a hexadecimal representation of an index map in
select_describe(). This could result in buffer overrun and stack
corruption under some circumstances.

Fixed by correcting the calculation.


mysql-test/r/explain.result:
  Added a test case for bug #32241.
mysql-test/t/explain.test:
  Added a test case for bug #32241.
sql/sql_select.cc:
  Corrected the buffer length calculation. Count one hex digit as 4 bits,
  not 8.
parent f6686659
...@@ -87,3 +87,23 @@ Warnings: ...@@ -87,3 +87,23 @@ Warnings:
Note 1003 select '1' AS `f1`,'1' AS `f2` from `test`.`t1` having 1 Note 1003 select '1' AS `f1`,'1' AS `f2` from `test`.`t1` having 1
drop view v1; drop view v1;
drop table t1; drop table t1;
CREATE TABLE t1(c INT);
INSERT INTO t1 VALUES (),();
CREATE TABLE t2 (b INT,
KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
KEY(b),KEY(b),KEY(b),KEY(b),KEY(b));
INSERT INTO t2 VALUES (),(),();
EXPLAIN SELECT 1 FROM
(SELECT 1 FROM t2,t1 WHERE b < c GROUP BY 1 LIMIT 1) AS d2;
id select_type table type possible_keys key key_len ref rows Extra
X X X X X X X X X const row not found
X X X X X X X X X
X X X X X X X X X Range checked for each record (index map: 0xFFFFFFFFFF)
DROP TABLE t2;
DROP TABLE t1;
...@@ -66,4 +66,32 @@ explain extended select * from t1 having 1; ...@@ -66,4 +66,32 @@ explain extended select * from t1 having 1;
drop view v1; drop view v1;
drop table t1; drop table t1;
#
# Bug #32241: memory corruption due to large index map in 'Range checked for
# each record'
#
CREATE TABLE t1(c INT);
INSERT INTO t1 VALUES (),();
CREATE TABLE t2 (b INT,
KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
KEY(b),KEY(b),KEY(b),KEY(b),KEY(b),
KEY(b),KEY(b),KEY(b),KEY(b),KEY(b));
INSERT INTO t2 VALUES (),(),();
# We only need to make sure that there is no buffer overrun and the index map
# is displayed correctly
--replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X
EXPLAIN SELECT 1 FROM
(SELECT 1 FROM t2,t1 WHERE b < c GROUP BY 1 LIMIT 1) AS d2;
DROP TABLE t2;
DROP TABLE t1;
# End of 5.0 tests. # End of 5.0 tests.
...@@ -15282,7 +15282,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, ...@@ -15282,7 +15282,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
{ {
if (tab->use_quick == 2) if (tab->use_quick == 2)
{ {
char buf[MAX_KEY/8+1]; /* 4 bits per 1 hex digit + terminating '\0' */
char buf[MAX_KEY / 4 + 1];
extra.append(STRING_WITH_LEN("; Range checked for each " extra.append(STRING_WITH_LEN("; Range checked for each "
"record (index map: 0x")); "record (index map: 0x"));
extra.append(tab->keys.print(buf)); extra.append(tab->keys.print(buf));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment