summaryrefslogtreecommitdiff
path: root/sql/item_func.h
diff options
context:
space:
mode:
authorChaithra Gopalareddy <chaithra.gopalareddy@oracle.com>2013-05-23 15:00:31 +0530
committerChaithra Gopalareddy <chaithra.gopalareddy@oracle.com>2013-05-23 15:00:31 +0530
commit4bd94e7d1c89118fa3d3c3648d32c370be032ce4 (patch)
treebb7ece840c87273a3fbd9dd8a7f114f80aca8536 /sql/item_func.h
parent0c903fb5c9361ca24bbcd98d420ad936fab21a80 (diff)
downloadmariadb-git-4bd94e7d1c89118fa3d3c3648d32c370be032ce4.tar.gz
Bug #16119355: PREPARED STATEMENT: READ OF FREED MEMORY WITH
STRING CONVERSION FUNCTIONS Problem: While executing the prepared statement, user variable is set to memory which would be freed at the end of execution. If the statement is executed again, valgrind throws error when accessing this pointer. Analysis: 1. First time when Item_func_set_user_var::check is called, memory is allocated for "value" to store the result. (In the call to copy_if_not_alloced). 2. While sending the result, Item_func_set_user_var::check is called again. But, this time, its called with "use_result_field" set to true. As a result, we call result_field->val_str(&value). 3. Here memory allocated for "value" gets freed. And "value" gets set to "result_field", with "str_length" being that of result_field's. 4. In the call to JOIN::cleanup, result_field's memory gets freed as this is allocated in a chunk as part of the temporary table which is needed to execute the query. 5. Next time, when execute of the same statement is called, "value" will be set to memory which is already freed. Valgrind error occurs as "str_length" is positive (set at Step 3) Note that user variables list is stored as part of the Lex object in set_var_list. Hence the persistance across executions. Solution: Patch for Bug#11764371 fixed in mysql-5.6+ fixes this problem as well.So backporting the same. In the solution for Bug#11764371, we create another object of user_var and repoint it to temp_table's field. As a result while deleting the alloced buffer in Step 3, since the cloned object does not own the buffer, deletion will not happen. So at step 5 when we execute the statement second time, the original object will be used and since deletion did not happen valgrind will not complain about dangling pointer. sql/item_func.h: Add constructors. sql/sql_select.cc: Change user variable assignment functions to read from fields after tables have been unlocked.
Diffstat (limited to 'sql/item_func.h')
-rw-r--r--sql/item_func.h7
1 files changed, 7 insertions, 0 deletions
diff --git a/sql/item_func.h b/sql/item_func.h
index 22fb38e176d..c3ef3d12d71 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1391,6 +1391,13 @@ public:
:Item_func(b), cached_result_type(INT_RESULT),
entry(NULL), entry_thread_id(0), name(a)
{}
+ Item_func_set_user_var(THD *thd, Item_func_set_user_var *item)
+ :Item_func(thd, item), cached_result_type(item->cached_result_type),
+ entry(item->entry), entry_thread_id(item->entry_thread_id),
+ value(item->value), decimal_buff(item->decimal_buff),
+ null_item(item->null_item), save_result(item->save_result),
+ name(item->name)
+ {}
enum Functype functype() const { return SUSERVAR_FUNC; }
double val_real();