Bug #57510 comparing uninitialised values in ctype-bin.c
Submitted: 18 Oct 2010 7:40 Modified: 2 Mar 2012 18:17
Reporter: Shane Bester (Platinum Quality Contributor) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S2 (Serious)
Version:5.1.53, 5.5.7 OS:Linux (FC13 x64, Ubuntu 10.04 32-bit)
Assigned to: CPU Architecture:Any
Tags: regression

[18 Oct 2010 7:40] Shane Bester
Description:
5.1.53 valgrind outputs:
Conditional jump or move depends on uninitialised value(s)
at: bcmp (mc_replace_strmem.c:541)
by: my_strnncoll_binary (ctype-bin.c:84)
by: my_strnncollsp_binary (ctype-bin.c:125)
by: srtcmp_in (item_cmpfunc.cc:3805)
by: my_qsort2 (mf_qsort.c:130)
by: in_vector::sort (item_cmpfunc.h:785)
by: Item_func_in::fix_length_and_dec (item_cmpfunc.cc:4009)
by: Item_func::fix_fields (item_func.cc:198)
by: Item_func_in::fix_fields (item_cmpfunc.cc:3785)
by: setup_fields (sql_base.cc:7551)
by: JOIN::prepare (sql_select.cc:514)
by: mysql_select (sql_select.cc:2513)
by: handle_select (sql_select.cc:269)
by: execute_sqlcom_select (sql_parse.cc:5127)
by: mysql_execute_command (sql_parse.cc:2292)
by: mysql_parse (sql_parse.cc:6051)
by: dispatch_command (sql_parse.cc:1260)
by: do_command (sql_parse.cc:888)
by: handle_one_connection (sql_connect.cc:1136)
by: start_thread (pthread_create.c:301)

How to repeat:
run mysqld in valgrind like this:

valgrind -v --leak-check=full --show-reachable=yes --db-attach=yes --tool=memcheck --num-callers=50 ./bin/mysqld --no-defaults --basedir=. --datadir=./data --skip-gr --skip-na

Then:
select ("aaaaaaaaaaa" not in ("",
geomfromtext("polygon(46375 -5621,3986 -47555)"),
geomfromtext("polygon(-78653 -98998,-73561 100001)")));

Suggested fix:
initialize things. these annoying failures are hit frequently in random testing
[18 Oct 2010 9:23] Valeriy Kravchuk
Verified with current mysql-5.5 from bzr on 32-bit Ubuntu 10.04:

==26198== Thread 17:
==26198== Conditional jump or move depends on uninitialised value(s)
==26198==    at 0x402703A: bcmp (mc_replace_strmem.c:541)
==26198==    by 0x8668E83: my_strnncoll_binary (ctype-bin.c:84)
==26198==    by 0x8668EE7: my_strnncollsp_binary (ctype-bin.c:125)
==26198==    by 0x81F95CB: srtcmp_in(charset_info_st*, String const*, String const*) (item_cmpfunc.cc:3828)
==26198==    by 0x862671B: my_qsort2 (mf_qsort.c:130)
==26198==    by 0x8200077: in_vector::sort() (item_cmpfunc.h:807)
==26198==    by 0x81F9DCB: Item_func_in::fix_length_and_dec() (item_cmpfunc.cc:4032)
==26198==    by 0x81D819F: Item_func::fix_fields(THD*, Item**) (item_func.cc:219)
==26198==    by 0x81F9466: Item_func_in::fix_fields(THD*, Item**) (item_cmpfunc.cc:3808)
==26198==    by 0x82E9915: setup_fields(THD*, Item**, List<Item>&, enum_mark_columns, List<Item>*, bool) (sql_base.cc:7721)
==26198==    by 0x82FBDAB: JOIN::prepare(Item***, TABLE_LIST*, unsigned int, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, st_select_lex*, st_select_lex_unit*) (sql_select.cc:542)
==26198==    by 0x8302665: mysql_select(THD*, Item***, TABLE_LIST*, unsigned int, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) (sql_select.cc:2529)
==26198== 
==26198== Conditional jump or move depends on uninitialised value(s)
==26198==    at 0x8668E8B: my_strnncoll_binary (ctype-bin.c:85)
==26198==    by 0x8668EE7: my_strnncollsp_binary (ctype-bin.c:125)
==26198==    by 0x81F95CB: srtcmp_in(charset_info_st*, String const*, String const*) (item_cmpfunc.cc:3828)
==26198==    by 0x862671B: my_qsort2 (mf_qsort.c:130)
==26198==    by 0x8200077: in_vector::sort() (item_cmpfunc.h:807)
==26198==    by 0x81F9DCB: Item_func_in::fix_length_and_dec() (item_cmpfunc.cc:4032)
==26198==    by 0x81D819F: Item_func::fix_fields(THD*, Item**) (item_func.cc:219)
==26198==    by 0x81F9466: Item_func_in::fix_fields(THD*, Item**) (item_cmpfunc.cc:3808)
==26198==    by 0x82E9915: setup_fields(THD*, Item**, List<Item>&, enum_mark_columns, List<Item>*, bool) (sql_base.cc:7721)
==26198==    by 0x82FBDAB: JOIN::prepare(Item***, TABLE_LIST*, unsigned int, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, st_select_lex*, st_select_lex_unit*) (sql_select.cc:542)
==26198==    by 0x8302665: mysql_select(THD*, Item***, TABLE_LIST*, unsigned int, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) (sql_select.cc:2529)
==26198==    by 0x82FB6F7: handle_select(THD*, LEX*, select_result*, unsigned long) (sql_select.cc:296)
==26198== 
==26198== Conditional jump or move depends on uninitialised value(s)
==26198==    at 0x862671E: my_qsort2 (mf_qsort.c:130)
==26198==    by 0x8200077: in_vector::sort() (item_cmpfunc.h:807)
==26198==    by 0x81F9DCB: Item_func_in::fix_length_and_dec() (item_cmpfunc.cc:4032)
==26198==    by 0x81D819F: Item_func::fix_fields(THD*, Item**) (item_func.cc:219)
==26198==    by 0x81F9466: Item_func_in::fix_fields(THD*, Item**) (item_cmpfunc.cc:3808)
==26198==    by 0x82E9915: setup_fields(THD*, Item**, List<Item>&, enum_mark_columns, List<Item>*, bool) (sql_base.cc:7721)
==26198==    by 0x82FBDAB: JOIN::prepare(Item***, TABLE_LIST*, unsigned int, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, st_select_lex*, st_select_lex_unit*) (sql_select.cc:542)
==26198==    by 0x8302665: mysql_select(THD*, Item***, TABLE_LIST*, unsigned int, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) (sql_select.cc:2529)
==26198==    by 0x82FB6F7: handle_select(THD*, LEX*, select_result*, unsigned long) (sql_select.cc:296)
==26198==    by 0x829501E: execute_sqlcom_select(THD*, TABLE_LIST*) (sql_parse.cc:4565)
==26198==    by 0x828D667: mysql_execute_command(THD*) (sql_parse.cc:2175)
==26198==    by 0x8296EA4: mysql_parse(THD*, char*, unsigned int, Parser_state*) (sql_parse.cc:5594)
==26198== 
...
[18 Oct 2010 15:27] MySQL Verification Team
Another testcase shows reading of freed memory:

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)

Address 0x6a17610 is 0 bytes inside a block of size 576 free'd
at: free (vg_replace_malloc.c:325)
by: my_free (my_malloc.c:128)
by: String::free (sql_string.h:208)
by: String::~String (sql_string.h:98)
by: Item_str_func::val_real (item_strfunc.cc:151)
by: cmp_item_real::store_value (item_cmpfunc.h:1086)
by: Item_func_in::val_int (item_cmpfunc.cc:4125)
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)
[2 Mar 2012 18:17] Paul DuBois
Noted in 5.6.5 changelog.

Invalid memory reads could occur when
cmp_item_sort_string::store_value() tried to refer to a temporary
value that could be changed or deleted by other functions.