Bug #51877 HANDLER interface causes invalid memory read
Submitted: 9 Mar 2010 16:52 Modified: 18 Jun 2010 2:10
Reporter: Georgi Kodinov Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: MyISAM storage engine Severity:S3 (Non-critical)
Version:5.0,5.1-bugteam OS:Linux (x86_64)
Assigned to: Sergey Vojtovich CPU Architecture:Any

[9 Mar 2010 16:52] Georgi Kodinov
Description:
Valgrind reports errors using the handler interface : 
==3685== Conditional jump or move depends on uninitialised value(s)
==3685==    at 0x9E472E: ha_key_cmp (my_handler.c:239)
==3685==    by 0x975298: _mi_seq_search (mi_search.c:271)
==3685==    by 0x9748E2: _mi_search (mi_search.c:89)
==3685==    by 0x973F12: mi_rnext (mi_rnext.c:79)
==3685==    by 0x9694F2: ha_myisam::index_next(unsigned char*) (ha_myisam.cc:1682)
==3685==    by 0x57B420: mysql_ha_read(THD*, TABLE_LIST*, enum_ha_read_modes, char*, List<Item>*, ha_rkey_function, Item*, unsigned long long, unsigned long long) (sql_handler.cc:566)
==3685==    by 0x678DD5: mysql_execute_command(THD*) (sql_parse.cc:4054)
==3685==    by 0x67E565: mysql_parse(THD*, char const*, unsigned int, char const**) (sql_parse.cc:5971)
==3685==    by 0x670C3B: dispatch_command(enum_server_command, THD*, char*, unsigned int) (sql_parse.cc:1233)
==3685==    by 0x66FC29: do_command(THD*) (sql_parse.cc:874)
==3685==    by 0x66DF88: handle_one_connection (sql_connect.cc:1127)
==3685==    by 0x39B2406A39: start_thread (in /lib64/libpthread-2.11.so)
==3685== Conditional jump or move depends on uninitialised value(s)
==3685==    at 0xA00800: my_strnncollsp_simple (ctype-simple.c:163)
==3685==    by 0x9E3F47: ha_compare_text (my_handler.c:31)
==3685==    by 0x9E4824: ha_key_cmp (my_handler.c:243)
==3685==    by 0x975298: _mi_seq_search (mi_search.c:271)
==3685==    by 0x9748E2: _mi_search (mi_search.c:89)
==3685==    by 0x973F12: mi_rnext (mi_rnext.c:79)
==3685==    by 0x9694F2: ha_myisam::index_next(unsigned char*) (ha_myisam.cc:1682)
==3685==    by 0x57B420: mysql_ha_read(THD*, TABLE_LIST*, enum_ha_read_modes, char*, List<Item>*, ha_rkey_function, Item*, unsigned long long, unsigned long long) (sql_handler.cc:566)
==3685==    by 0x678DD5: mysql_execute_command(THD*) (sql_parse.cc:4054)
==3685==    by 0x67E565: mysql_parse(THD*, char const*, unsigned int, char const**) (sql_parse.cc:5971)
==3685==    by 0x670C3B: dispatch_command(enum_server_command, THD*, char*, unsigned int) (sql_parse.cc:1233)
==3685==    by 0x66FC29: do_command(THD*) (sql_parse.cc:874)
==3685==    by 0x66DF88: handle_one_connection (sql_connect.cc:1127)
==3685==    by 0x39B2406A39: start_thread (in /lib64/libpthread-2.11.so)
==3685== Conditional jump or move depends on uninitialised value(s)
==3685==    at 0xA00811: my_strnncollsp_simple (ctype-simple.c:169)
==3685==    by 0x9E3F47: ha_compare_text (my_handler.c:31)
==3685==    by 0x9E4824: ha_key_cmp (my_handler.c:243)
==3685==    by 0x975298: _mi_seq_search (mi_search.c:271)
==3685==    by 0x9748E2: _mi_search (mi_search.c:89)
==3685==    by 0x973F12: mi_rnext (mi_rnext.c:79)
==3685==    by 0x9694F2: ha_myisam::index_next(unsigned char*) (ha_myisam.cc:1682)
==3685==    by 0x57B420: mysql_ha_read(THD*, TABLE_LIST*, enum_ha_read_modes, char*, List<Item>*, ha_rkey_function, Item*, unsigned long long, unsigned long long) (sql_handler.cc:566)
==3685==    by 0x678DD5: mysql_execute_command(THD*) (sql_parse.cc:4054)
==3685==    by 0x67E565: mysql_parse(THD*, char const*, unsigned int, char const**) (sql_parse.cc:5971)
==3685==    by 0x670C3B: dispatch_command(enum_server_command, THD*, char*, unsigned int) (sql_parse.cc:1233)
==3685==    by 0x66FC29: do_command(THD*) (sql_parse.cc:874)
==3685==    by 0x66DF88: handle_one_connection (sql_connect.cc:1127)
==3685==    by 0x39B2406A39: start_thread (in /lib64/libpthread-2.11.so)
==3685== Conditional jump or move depends on uninitialised value(s)
==3685==    at 0xA00833: my_strnncollsp_simple (ctype-simple.c:178)
==3685==    by 0x9E3F47: ha_compare_text (my_handler.c:31)
==3685==    by 0x9E4824: ha_key_cmp (my_handler.c:243)
==3685==    by 0x975298: _mi_seq_search (mi_search.c:271)
==3685==    by 0x9748E2: _mi_search (mi_search.c:89)
==3685==    by 0x973F12: mi_rnext (mi_rnext.c:79)
==3685==    by 0x9694F2: ha_myisam::index_next(unsigned char*) (ha_myisam.cc:1682)
==3685==    by 0x57B420: mysql_ha_read(THD*, TABLE_LIST*, enum_ha_read_modes, char*, List<Item>*, ha_rkey_function, Item*, unsigned long long, unsigned long long) (sql_handler.cc:566)
==3685==    by 0x678DD5: mysql_execute_command(THD*) (sql_parse.cc:4054)
==3685==    by 0x67E565: mysql_parse(THD*, char const*, unsigned int, char const**) (sql_parse.cc:5971)
==3685==    by 0x670C3B: dispatch_command(enum_server_command, THD*, char*, unsigned int) (sql_parse.cc:1233)
==3685==    by 0x66FC29: do_command(THD*) (sql_parse.cc:874)
==3685==    by 0x66DF88: handle_one_connection (sql_connect.cc:1127)
==3685==    by 0x39B2406A39: start_thread (in /lib64/libpthread-2.11.so)
==3685== Conditional jump or move depends on uninitialised value(s)
==3685==    at 0xA008C2: my_strnncollsp_simple (ctype-simple.c:186)
==3685==    by 0x9E3F47: ha_compare_text (my_handler.c:31)
==3685==    by 0x9E4824: ha_key_cmp (my_handler.c:243)
==3685==    by 0x975298: _mi_seq_search (mi_search.c:271)
==3685==    by 0x9748E2: _mi_search (mi_search.c:89)
==3685==    by 0x973F12: mi_rnext (mi_rnext.c:79)
==3685==    by 0x9694F2: ha_myisam::index_next(unsigned char*) (ha_myisam.cc:1682)
==3685==    by 0x57B420: mysql_ha_read(THD*, TABLE_LIST*, enum_ha_read_modes, char*, List<Item>*, ha_rkey_function, Item*, unsigned long long, unsigned long long) (sql_handler.cc:566)
==3685==    by 0x678DD5: mysql_execute_command(THD*) (sql_parse.cc:4054)
==3685==    by 0x67E565: mysql_parse(THD*, char const*, unsigned int, char const**) (sql_parse.cc:5971)
==3685==    by 0x670C3B: dispatch_command(enum_server_command, THD*, char*, unsigned int) (sql_parse.cc:1233)
==3685==    by 0x66FC29: do_command(THD*) (sql_parse.cc:874)
==3685==    by 0x66DF88: handle_one_connection (sql_connect.cc:1127)
==3685==    by 0x39B2406A39: start_thread (in /lib64/libpthread-2.11.so)

How to repeat:
run the attached test case(s) under valgrind.

Suggested fix:
Make the handler interface correctly handle out-of-band updates.
[9 Mar 2010 16:57] Georgi Kodinov
bug2.test : test case with regular myisam keys

Attachment: bug2.test (application/octet-stream, text), 357 bytes.

[9 Mar 2010 17:01] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/102758

3380 Georgi Kodinov	2010-03-09
      Disable the second part of the test for bug #51357 until bug #51877 is fixed.
[17 Mar 2010 18:50] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/103627

3404 Sergey Vojtovich	2010-03-17
      BUG#51877 - HANDLER interface causes invalid memory read
      
      Invalid memory read if HANDLER ... READ NEXT is executed
      after failed (e.g. empty table) HANDLER ... READ FIRST.
      
      The problem was that we attempted to perform READ NEXT,
      whereas there is no pivot available from failed READ FIRST.
      
      With this fix READ NEXT after failed READ FIRST equals
      to READ FIRST.
      
      This bug affects MyISAM tables only.
     @ mysql-test/r/gis-rtree.result
        Restore a test case for BUG51357.
     @ mysql-test/t/gis-rtree.test
        Restore a test case for BUG51357.
     @ storage/myisam/mi_rnext.c
        "search first" failed. This means we have no pivot for
        "search next", or in other words MI_INFO::lastkey is
        likely uninitialized.
        
        Normally SQL layer would never request "search next" if
        "search first" failed. But HANDLER may do anything.
        
        As mi_rnext() without preceeding mi_rkey()/mi_rfirst()
        equals to mi_rfirst(), we must restore original state
        as if failing mi_rfirst() was not called.
[18 Mar 2010 9:48] Ingo Strüwing
Approved. No comments. (Hm. I can't resist to comment about original code. The name of the flag HA_STATE_PREV_FOUND is slightly confusing. It is set as long as *no* key has been previously found...)
[24 Mar 2010 17:58] Ramil Kalimullin
Please add a b-tree key test case as discussed.
Thanks.
[25 Mar 2010 11:49] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/104306

3404 Sergey Vojtovich	2010-03-25
      BUG#51877 - HANDLER interface causes invalid memory read
      
      Invalid memory read if HANDLER ... READ NEXT is executed
      after failed (e.g. empty table) HANDLER ... READ FIRST.
      
      The problem was that we attempted to perform READ NEXT,
      whereas there is no pivot available from failed READ FIRST.
      
      With this fix READ NEXT after failed READ FIRST equals
      to READ FIRST.
      
      This bug affects MyISAM tables only.
     @ mysql-test/r/gis-rtree.result
        Restore a test case for BUG51357.
     @ mysql-test/r/handler_myisam.result
        A test case for BUG#51877.
     @ mysql-test/t/gis-rtree.test
        Restore a test case for BUG51357.
     @ mysql-test/t/handler_myisam.test
        A test case for BUG#51877.
     @ storage/myisam/mi_rnext.c
        "search first" failed. This means we have no pivot for
        "search next", or in other words MI_INFO::lastkey is
        likely uninitialized.
        
        Normally SQL layer would never request "search next" if
        "search first" failed. But HANDLER may do anything.
        
        As mi_rnext() without preceeding mi_rkey()/mi_rfirst()
        equals to mi_rfirst(), we must restore original state
        as if failing mi_rfirst() was not called.
[26 Mar 2010 8:22] Bugs System
Pushed into 5.5.4-m3 (revid:alik@sun.com-20100326080914-2pz8ns984e0spu03) (version source revid:alexey.kopytov@sun.com-20100312095153-t4rtoqc7p96lmxvh) (merge vers: 5.5.3-m2) (pib:16)
[26 Mar 2010 8:26] Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20100326081116-m3v4l34yhr43mtsv) (version source revid:alik@sun.com-20100325072612-4sds00ix8ajo1e84) (pib:16)
[26 Mar 2010 8:30] Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20100326081944-qja07qklw1p2w7jb) (version source revid:alik@sun.com-20100325073410-4t4i9gu2u1pge7xb) (merge vers: 6.0.14-alpha) (pib:16)
[6 Apr 2010 7:57] Bugs System
Pushed into 5.1.46 (revid:sergey.glukhov@sun.com-20100405111026-7kz1p8qlzglqgfmu) (version source revid:aelkin@mysql.com-20100325161323-40o0cmhdzphdn1nk) (merge vers: 5.1.46) (pib:16)
[12 Apr 2010 22:17] Paul DuBois
Noted in 5.1.46, 5.5.5, 6.0.14 changelogs.

Invalid memory reads occurred for HANDLER ... READ NEXT after a
failed HANDLER ... READ FIRST.
[28 May 2010 6:05] Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20100524190136-egaq7e8zgkwb9aqi) (version source revid:alik@sun.com-20100422150750-vp0n37kp9ywq5ghf) (pib:16)
[28 May 2010 6:33] Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20100524190941-nuudpx60if25wsvx) (version source revid:alik@sun.com-20100422150658-fkhgnwwkyugtxrmu) (merge vers: 6.0.14-alpha) (pib:16)
[28 May 2010 7:01] Bugs System
Pushed into 5.5.5-m3 (revid:alik@sun.com-20100524185725-c8k5q7v60i5nix3t) (version source revid:alexey.kopytov@sun.com-20100402151743-xowc2u930h729jsy) (merge vers: 5.5.4-m3) (pib:16)
[30 May 2010 0:24] Paul DuBois
Already fixed.
[17 Jun 2010 12:09] Bugs System
Pushed into 5.1.47-ndb-7.0.16 (revid:martin.skold@mysql.com-20100617114014-bva0dy24yyd67697) (version source revid:vasil.dimov@oracle.com-20100331130613-8ja7n0vh36a80457) (merge vers: 5.1.46) (pib:16)
[17 Jun 2010 12:56] Bugs System
Pushed into 5.1.47-ndb-6.2.19 (revid:martin.skold@mysql.com-20100617115448-idrbic6gbki37h1c) (version source revid:martin.skold@mysql.com-20100609211156-tsac5qhw951miwtt) (merge vers: 5.1.46-ndb-6.2.19) (pib:16)
[17 Jun 2010 13:36] Bugs System
Pushed into 5.1.47-ndb-6.3.35 (revid:martin.skold@mysql.com-20100617114611-61aqbb52j752y116) (version source revid:vasil.dimov@oracle.com-20100331130613-8ja7n0vh36a80457) (merge vers: 5.1.46) (pib:16)