diff options
author | Alexander Barkov <bar@mariadb.com> | 2018-03-19 13:07:41 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2018-03-19 13:07:41 +0400 |
commit | f538a64817ce583fcce558303ae9d9b6aeecf838 (patch) | |
tree | e4182297d45c0434630a14833bf0af9f8bd2d70e /sql/item_cmpfunc.h | |
parent | 31e2ab513d1d0d6caad96f613cbce3ad25c19497 (diff) | |
download | mariadb-git-f538a64817ce583fcce558303ae9d9b6aeecf838.tar.gz |
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).
Diffstat (limited to 'sql/item_cmpfunc.h')
-rw-r--r-- | sql/item_cmpfunc.h | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 076e6da953c..41d5ce25fd4 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1312,6 +1312,13 @@ public: { value_res= item->val_str(&value); m_null_value= item->null_value; + // Make sure to cache the result String inside "value" + if (value_res && value_res != &value) + { + if (value.copy(*value_res)) + value.set("", 0, item->collation.collation); + value_res= &value; + } } int cmp(Item *arg) { |