-
Chaithra Gopalareddy authored
The first part of the problem reported in the bug, is fixed in the patch for Bug#11766212.This fix is for the second part of the problem reported. PROBLEM: The following query results in an invalid read when run with valgrind select left(geomfromtext("point(0 0)"),1) not in ( @@global.query_cache_type,1 not between -1 and "a", elt(1,'',1,1,1), geomfromtext("point(1 -1)") in ("bbbbbbbbb"),1); 5.5.8-debug valgrind output: Invalid read of size 1 at: my_strnncollsp_utf8 (ctype-utf8.c:2590) by: sortcmp (sql_string.cc:668) by: cmp_item_sort_string::cmp (item_cmpfunc.h:1019) by: Item_func_in::val_int (item_cmpfunc.cc:4130) by: Item::send (item.cc:5864) by: Protocol::send_result_set_row (protocol.cc:848) by: select_send::send_data (sql_class.cc:1789) by: JOIN::exec (sql_select.cc:1857) by: mysql_select (sql_select.cc:2568) by: handle_select (sql_select.cc:296) by: execute_sqlcom_select (sql_parse.cc:4464) by: mysql_execute_command (sql_parse.cc:2066) by: mysql_parse (sql_parse.cc:5500) by: dispatch_command (sql_parse.cc:1030) by: do_command (sql_parse.cc:770) by: do_handle_one_connection (sql_connect.cc:745) by: handle_one_connection (sql_connect.cc:684) by: start_thread (pthread_create.c:301) Problem Analysis: The above mentioned invalid read can be reproduced using a simplified query like this one: select left(geomfromtext("point(0 0)"),1) in (@@global.query_cache_type,1,""); Problem is present in cmp_item_sort_string::store_value, because it does not make its own copy of the value evaluated. Instead tries to refer to a temporary value that could be changed or deleted by other functions. Hence while reusing the evaluated value in case of Item_func_in::val_int, we get a valgrind error saying Invalid read. With respect to the above query, this is what happens: a) To be compared with @@global.query_cache_type, function left() is evaluated in "string" context. This evaluation modifies Item_func_left::tmp_value, and returns a pointer to this tmp_value. The "comparator object" (cmp_item) stores the returned pointer in cmp_item::value_res and then the comparison is done. b) To be compared with 1, left() is evaluated in "real number" context, which modifies Item_func_left::tmp_value again. Comparison is done with the real value. c) To be compared with "", left() is NOT evaluated again because cmp_item already has a pointer to the value of left() in string context (from (a)). However, this value was a pointer to Item_func_left::tmp_value, and (b) has modified this String. So we would be looking at out-of-date data. Hence while reusing the evaluated value in case of Item_func_in::val_int, we get a valgrind error saying Invalid read. Solution: The fix it to make a copy of the value retured from val_str() in cmp_item_sort_string::store_value().
Chaithra Gopalareddy authoredThe first part of the problem reported in the bug, is fixed in the patch for Bug#11766212.This fix is for the second part of the problem reported. PROBLEM: The following query results in an invalid read when run with valgrind select left(geomfromtext("point(0 0)"),1) not in ( @@global.query_cache_type,1 not between -1 and "a", elt(1,'',1,1,1), geomfromtext("point(1 -1)") in ("bbbbbbbbb"),1); 5.5.8-debug valgrind output: Invalid read of size 1 at: my_strnncollsp_utf8 (ctype-utf8.c:2590) by: sortcmp (sql_string.cc:668) by: cmp_item_sort_string::cmp (item_cmpfunc.h:1019) by: Item_func_in::val_int (item_cmpfunc.cc:4130) by: Item::send (item.cc:5864) by: Protocol::send_result_set_row (protocol.cc:848) by: select_send::send_data (sql_class.cc:1789) by: JOIN::exec (sql_select.cc:1857) by: mysql_select (sql_select.cc:2568) by: handle_select (sql_select.cc:296) by: execute_sqlcom_select (sql_parse.cc:4464) by: mysql_execute_command (sql_parse.cc:2066) by: mysql_parse (sql_parse.cc:5500) by: dispatch_command (sql_parse.cc:1030) by: do_command (sql_parse.cc:770) by: do_handle_one_connection (sql_connect.cc:745) by: handle_one_connection (sql_connect.cc:684) by: start_thread (pthread_create.c:301) Problem Analysis: The above mentioned invalid read can be reproduced using a simplified query like this one: select left(geomfromtext("point(0 0)"),1) in (@@global.query_cache_type,1,""); Problem is present in cmp_item_sort_string::store_value, because it does not make its own copy of the value evaluated. Instead tries to refer to a temporary value that could be changed or deleted by other functions. Hence while reusing the evaluated value in case of Item_func_in::val_int, we get a valgrind error saying Invalid read. With respect to the above query, this is what happens: a) To be compared with @@global.query_cache_type, function left() is evaluated in "string" context. This evaluation modifies Item_func_left::tmp_value, and returns a pointer to this tmp_value. The "comparator object" (cmp_item) stores the returned pointer in cmp_item::value_res and then the comparison is done. b) To be compared with 1, left() is evaluated in "real number" context, which modifies Item_func_left::tmp_value again. Comparison is done with the real value. c) To be compared with "", left() is NOT evaluated again because cmp_item already has a pointer to the value of left() in string context (from (a)). However, this value was a pointer to Item_func_left::tmp_value, and (b) has modified this String. So we would be looking at out-of-date data. Hence while reusing the evaluated value in case of Item_func_in::val_int, we get a valgrind error saying Invalid read. Solution: The fix it to make a copy of the value retured from val_str() in cmp_item_sort_string::store_value().
Loading