1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +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:
Alexander Barkov
2019-04-30 10:53:59 +04:00
parent 021c7216c0
commit 5fb6444a37
3 changed files with 74 additions and 0 deletions

View File

@ -909,6 +909,27 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length)
(void) from->realloc(from_length);
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))
return from; // Actually an error
if ((to->str_length=MY_MIN(from->str_length,from_length)))