Skip to content
  • Chaithra Gopalareddy's avatar
    977a27c6
    Bug#11764651-57510:Comparing uninitialized values in CTYPE-BIN.c · 977a27c6
    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().
    977a27c6
    Bug#11764651-57510:Comparing uninitialized values in CTYPE-BIN.c
    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().
Loading