Bug #58376 invalid memory read with trim, format, convert
Submitted: 22 Nov 2010 10:31 Modified: 13 Jan 2011 14:36
Reporter: Shane Bester (Platinum Quality Contributor) Email Updates:
Status: Duplicate Impact on me:
None 
Category:MySQL Server: Charsets Severity:S1 (Critical)
Version:5.1.53, 5.6.1 OS:Any
Assigned to: CPU Architecture:Any
Tags: application verifier, valgrind

[22 Nov 2010 10:31] Shane Bester
Description:
5.6.1-debug valgrind output:

Invalid read of size 1
at : memmove (mc_replace_strmem.c:629)
by : String::copy(String const&) (sql_string.cc:136)
by : Item_char_typecast::val_str(String*) (item_timefunc.cc:2572)
by : Item_str_func::val_int() (item_strfunc.cc:161)
by : mysql_do(THD*, List<Item>&) (sql_do.cc:34)
by : mysql_execute_command(THD*) (sql_parse.cc:2115)
by : mysql_parse(THD*, char*, unsigned int, Parser_state*) (sql_parse.cc:5537)
by : dispatch_command (sql_parse.cc:1056)
by : do_command(THD*) (sql_parse.cc:796)
by : do_handle_one_connection(THD*) (sql_connect.cc:745)
by : handle_one_connection (sql_connect.cc:684)
by : start_thread (pthread_create.c:301)
 Address 0x1409e970 is 0 bytes inside a block of size 40 free'd
at : free (vg_replace_malloc.c:325)
by : my_free (my_malloc.c:128)
by : String::free() (sql_string.h:214)
by : String::real_alloc(unsigned int) (sql_string.cc:43)
by : String::alloc(unsigned int) (sql_string.h:223)
by : Item_char_typecast::val_str(String*) (item_timefunc.cc:2571)
by : Item_str_func::val_int() (item_strfunc.cc:161)
by : mysql_do(THD*, List<Item>&) (sql_do.cc:34)
by : mysql_execute_command(THD*) (sql_parse.cc:2115)
by : mysql_parse(THD*, char*, unsigned int, Parser_state*) (sql_parse.cc:5537)
by : dispatch_command (sql_parse.cc:1056)
by : do_command(THD*) (sql_parse.cc:796)
by : do_handle_one_connection(THD*) (sql_connect.cc:745)
by : handle_one_connection (sql_connect.cc:684)
by : start_thread (pthread_create.c:301)

How to repeat:
run valgrind build of mysqld in valgrind

do convert(trim('' not in ('') from format(1,'1111-11-11')),binary(49));
[22 Nov 2010 11:08] Valeriy Kravchuk
Verified on Ubuntu:

101122 13:07:45 [Note] libexec/mysqld: ready for connections.
Version: '5.6.1-m5-debug'  socket: '/tmp/mysql.sock'  port: 3306  Source distribution
==16711== Thread 17:
==16711== Invalid read of size 1
==16711==    at 0x40274E8: memmove (mc_replace_strmem.c:629)
==16711==    by 0x827FF6F: String::copy(String const&) (sql_string.cc:136)
==16711==    by 0x821C767: Item_char_typecast::val_str(String*) (item_timefunc.cc:2572)
==16711==    by 0x82072E7: Item_str_func::val_int() (item_strfunc.cc:161)
==16711==    by 0x836A443: mysql_do(THD*, List<Item>&) (sql_do.cc:34)
==16711==    by 0x8296838: mysql_execute_command(THD*) (sql_parse.cc:2115)
==16711==    by 0x82A0055: mysql_parse(THD*, char*, unsigned int, Parser_state*) (sql_parse.cc:5537)
==16711==    by 0x82941E8: dispatch_command(enum_server_command, THD*, char*, unsigned int) (sql_parse.cc:1056)
==16711==    by 0x829388B: do_command(THD*) (sql_parse.cc:796)
==16711==    by 0x8291BED: do_handle_one_connection(THD*) (sql_connect.cc:745)
==16711==    by 0x8291A4D: handle_one_connection (sql_connect.cc:684)
==16711==    by 0x404196D: start_thread (pthread_create.c:300)
==16711==  Address 0x7e185a9 is 1 bytes inside a block of size 48 free'd
==16711==    at 0x4024B3A: free (vg_replace_malloc.c:366)
==16711==    by 0x860D696: my_free (my_malloc.c:128)
==16711==    by 0x819FCB4: String::free() (sql_string.h:214)
==16711==    by 0x827FB58: String::real_alloc(unsigned int) (sql_string.cc:43)
==16711==    by 0x81C6505: String::alloc(unsigned int) (sql_string.h:223)
==16711==    by 0x821C74F: Item_char_typecast::val_str(String*) (item_timefunc.cc:2571)
==16711==    by 0x82072E7: Item_str_func::val_int() (item_strfunc.cc:161)
==16711==    by 0x836A443: mysql_do(THD*, List<Item>&) (sql_do.cc:34)
==16711==    by 0x8296838: mysql_execute_command(THD*) (sql_parse.cc:2115)
==16711==    by 0x82A0055: mysql_parse(THD*, char*, unsigned int, Parser_state*) (sql_parse.cc:5537)
==16711==    by 0x82941E8: dispatch_command(enum_server_command, THD*, char*, unsigned int) (sql_parse.cc:1056)
==16711==    by 0x829388B: do_command(THD*) (sql_parse.cc:796)
==16711==
[29 Nov 2010 1:39] Roel Van de Paar
Found on 5.1.53 x64 on Windows x64 also using application verifier:

 # Child-SP          RetAddr           Call Site
00 00000000`3482de08 00000001`40106e42 mysqld!memcpy+0x80
01 00000000`3482de10 00000001`4019e633 mysqld!String::copy+0x42
02 00000000`3482de40 00000001`40147041 mysqld!Item_char_typecast::val_str+0x1f3
03 00000000`3482ded0 00000001`401b2c69 mysqld!Item_str_func::val_int+0x51
04 00000000`3482df60 00000001`4006cf83 mysqld!mysql_do+0x59
05 00000000`3482dfa0 00000001`40071910 mysqld!mysql_execute_command+0x4f3
06 00000000`3482f390 00000001`400725e8 mysqld!mysql_parse+0x1b0
07 00000000`3482f4c0 00000001`40073077 mysqld!dispatch_command+0x798
08 00000000`3482fe20 00000001`4009a147 mysqld!do_command+0xf7
09 00000000`3482fe60 00000001`4031faa5 mysqld!handle_one_connection+0x127
0a 00000000`3482fe90 00000001`402ea477 mysqld!pthread_start+0x55
0b 00000000`3482fec0 00000001`402ea545 mysqld!_callthreadstart+0x17
0c 00000000`3482fef0 000007fe`f32f93c7 mysqld!_threadstart+0x95
0d 00000000`3482ff20 00000000`76ddf56d vfbasics!AVrfpStandardThreadFunction+0x2b
0e 00000000`3482ff60 00000000`77013021 kernel32!BaseThreadInitThunk+0xd
0f 00000000`3482ff90 00000000`00000000 ntdll!RtlUserThreadStart+0x1d

0:013> .frame 0n0;dv
00 00000000`3482de08 00000001`40106e42 mysqld!memcpy+0x80 [F:\dd\vctools\crt_bld\SELF_64_AMD64\crt\src\AMD64\memcpy.asm @ 173]
            dst = <Memory access error>
            src = <Memory access error>
          count = <Memory access error>
0:013> .frame 0n1;dv
01 00000000`3482de10 00000001`4019e633 mysqld!String::copy+0x42 [g:\mysql-5.1.53-winbuild\mysql-community-nt-5.1.53-build\sql\sql_string.cc @ 205]
           this = 0x00000000`3482df00
            str = 0x00000000`3060b6e0

Relevant code for last frame (01):

bool String::copy(const String &str)
{
  if (alloc(str.str_length))
    return TRUE;
  str_length=str.str_length;
  bmove(Ptr,str.Ptr,str_length);		// May be overlapping
  Ptr[str_length]=0;     <---------- sql_string.cc @ 205
  str_charset=str.str_charset;
  return FALSE;
}

For devs: I've got a full coredump if you like.

Marking private and security as this is in a GA release and could potentially be exploited.
[1 Dec 2010 23:20] Roel Van de Paar
Notice the memcpy <vs> memmove difference btw!
[13 Jan 2011 14:36] Alexander Barkov
Duplicate for:

http://bugs.mysql.com/bug.php?id=58005