mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-18738 ASAN heap-use-after-free in copy_if_not_alloced / copy_fields
copy_if_not_alloced() did not handle situations when "from" is a constant string pointing to a substring of "to", so this code part freed "to" but then tried to copy its old (already freed) content to a new buffer: if (to->realloc(from_length)) return from; if ((to->str_length=MY_MIN(from->str_length,from_length))) memcpy(to->Ptr,from->Ptr,to->str_length); Adding a new code piece that catches such constant substrings and propery reallocs "to" to preserve its important part referenced by "from".
This commit is contained in:
@ -4757,5 +4757,32 @@ YQ== 61
|
|||||||
Yq== 62
|
Yq== 62
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
|
# MDEV-18738 ASAN heap-use-after-free in copy_if_not_alloced / copy_fields
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
SELECT REPLACE( CAST( CURDATE() AS BINARY ), CURDATE(), REPEAT('a',32) ) AS f FROM t1 GROUP BY f;
|
||||||
|
f
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
SELECT REPLACE( LEFT( CURDATE(), 4), LEFT(CURDATE(),4), REPEAT('a',32) ) AS f FROM t1 GROUP BY f;
|
||||||
|
f
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
SELECT REPLACE(RIGHT(CURDATE(), 4), RIGHT(CURDATE(),4), REPEAT('a',32)) AS f FROM t1 GROUP BY f;
|
||||||
|
f
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
SELECT REPLACE(SUBSTR(CURDATE(),2,3), SUBSTR(CURDATE(),2,3), REPEAT('a',32)) AS f FROM t1 GROUP BY f;
|
||||||
|
f
|
||||||
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
# End of 10.1 tests
|
# End of 10.1 tests
|
||||||
#
|
#
|
||||||
|
@ -1877,6 +1877,32 @@ SELECT f1,HEX(f2) FROM t1 WHERE f1='YQ==' AND (f2= from_base64(
|
|||||||
SELECT f1,HEX(f2) FROM t1 WHERE f1='YQ==' AND (f2= from_base64("Yq==") OR f2= from_base64("YQ=="));
|
SELECT f1,HEX(f2) FROM t1 WHERE f1='YQ==' AND (f2= from_base64("Yq==") OR f2= from_base64("YQ=="));
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-18738 ASAN heap-use-after-free in copy_if_not_alloced / copy_fields
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
SELECT REPLACE( CAST( CURDATE() AS BINARY ), CURDATE(), REPEAT('a',32) ) AS f FROM t1 GROUP BY f;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
SELECT REPLACE( LEFT( CURDATE(), 4), LEFT(CURDATE(),4), REPEAT('a',32) ) AS f FROM t1 GROUP BY f;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
SELECT REPLACE(RIGHT(CURDATE(), 4), RIGHT(CURDATE(),4), REPEAT('a',32)) AS f FROM t1 GROUP BY f;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1),(2);
|
||||||
|
SELECT REPLACE(SUBSTR(CURDATE(),2,3), SUBSTR(CURDATE(),2,3), REPEAT('a',32)) AS f FROM t1 GROUP BY f;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.1 tests
|
--echo # End of 10.1 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -909,6 +909,27 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length)
|
|||||||
(void) from->realloc(from_length);
|
(void) from->realloc(from_length);
|
||||||
return from;
|
return from;
|
||||||
}
|
}
|
||||||
|
if (from->uses_buffer_owned_by(to))
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(!from->alloced);
|
||||||
|
DBUG_ASSERT(to->alloced);
|
||||||
|
/*
|
||||||
|
"from" is a constant string pointing to a fragment of alloced string "to":
|
||||||
|
to= xxxFFFyyy
|
||||||
|
- FFF is the part of "to" pointed by "from"
|
||||||
|
- xxx is the part of "to" before "from"
|
||||||
|
- yyy is the part of "to" after "from"
|
||||||
|
*/
|
||||||
|
uint32 xxx_length= (uint32) (from->ptr() - to->ptr());
|
||||||
|
uint32 yyy_length= (uint32) (to->end() - from->end());
|
||||||
|
DBUG_ASSERT(to->length() >= yyy_length);
|
||||||
|
to->length(to->length() - yyy_length); // Remove the "yyy" part
|
||||||
|
DBUG_ASSERT(to->length() >= xxx_length);
|
||||||
|
to->replace(0, xxx_length, "", 0); // Remove the "xxx" part
|
||||||
|
to->realloc(from_length);
|
||||||
|
to->str_charset= from->str_charset;
|
||||||
|
return to;
|
||||||
|
}
|
||||||
if (to->realloc(from_length))
|
if (to->realloc(from_length))
|
||||||
return from; // Actually an error
|
return from; // Actually an error
|
||||||
if ((to->str_length=MY_MIN(from->str_length,from_length)))
|
if ((to->str_length=MY_MIN(from->str_length,from_length)))
|
||||||
|
Reference in New Issue
Block a user