diff options
author | Dmitry Shulga <dmitry.shulga@mariadb.com> | 2021-10-20 19:24:31 +0700 |
---|---|---|
committer | Dmitry Shulga <dmitry.shulga@mariadb.com> | 2021-12-16 10:14:57 +0700 |
commit | a65d01a4cf04c744f9355bec186430540ce6ba08 (patch) | |
tree | 446c7711e28b914d468346da996c46219d2343a8 /sql/sql_tvc.cc | |
parent | 7bc629a5ce9e1edf2c27ddfba2a55c4341d55b4f (diff) | |
download | mariadb-git-a65d01a4cf04c744f9355bec186430540ce6ba08.tar.gz |
MDEV-23182: Server crashes in Item::fix_fields_if_needed / table_value_constr::prepare upon 2nd execution of PSbb-10.3-MDEV-23182
Repeating execution of a query containing the clause IN with string literals
in environment where the server variable in_predicate_conversion_threshold
is set results in server abnormal termination in case the query is run
as a Prepared Statement and conversion of charsets for string values in the
query are required.
The reason for server abnormal termination is that instances of the class
Item_string created on transforming the IN clause into subquery were created
on runtime memory root that is deallocated on finishing execution of Prepared
statement. On the other hand, references to Items placed on deallocated memory
root still exist in objects of the class table_value_constr. Subsequent running
of the same prepared statement leads to dereferencing of pointers to already
deallocated memory that could lead to undefined behaviour.
To fix the issue the values being pushed into a values list for TVC are created
by cloning their original items. This way the cloned items are allocate on
the PS memroot and as consequences no dangling pointer does more exist.
Diffstat (limited to 'sql/sql_tvc.cc')
-rw-r--r-- | sql/sql_tvc.cc | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc index 96c5223ee6a..3866b7c9352 100644 --- a/sql/sql_tvc.cc +++ b/sql/sql_tvc.cc @@ -539,7 +539,10 @@ bool Item_func_in::create_value_list_for_tvc(THD *thd, if (is_list_of_rows) { - Item_row *row_list= (Item_row *)(args[i]); + Item_row *row_list= (Item_row *)(args[i]->build_clone(thd)); + + if (!row_list) + return true; for (uint j=0; j < row_list->cols(); j++) { @@ -561,7 +564,8 @@ bool Item_func_in::create_value_list_for_tvc(THD *thd, sprintf(col_name, "_col_%i", 1); args[i]->set_name(thd, col_name, strlen(col_name), thd->charset()); } - if (tvc_value->push_back(args[i]->real_item())) + Item *arg_clone= args[i]->build_clone(thd); + if (!arg_clone || tvc_value->push_back(arg_clone)) return true; } |