Bug #88130 Invalid read of size at memcpy@GLIBC_2.2.5(vg_replace_strmem.c:1021)
Submitted: 18 Oct 2017 3:44 Modified: 18 Oct 2017 17:20
Reporter: yghmgl yang Email Updates:
Status: Duplicate Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version:5.6.37 OS:CentOS
Assigned to: CPU Architecture:Any
Tags: debug valgrind-build

[18 Oct 2017 3:44] yghmgl yang
Description:
==93205== Invalid read of size 1
==93205==    at 0x4C2DFA0: memcpy@GLIBC_2.2.5 (vg_replace_strmem.c:1021)
==93205==    by 0x84B029: String::copy(String const&) (sql_string.cc:184)
==93205==    by 0x6E9D8A: Item_char_typecast::val_str(String*) (item_strfunc.cc:3991)
==93205==    by 0x65B6B1: Item::val_str_ascii(String*) (item.cc:236)
==93205==    by 0x7144E1: Item_func_inet_aton::val_int() (item_inetfunc.cc:42)
==93205==    by 0x6B5F4D: Item_int_func::val_str(String*) (item_func.cc:765)
==93205==    by 0x6E7F30: Item_func_conv_charset::val_str(String*) (item_strfunc.cc:3558)
==93205==    by 0x6DC67A: Item_str_func::val_int() (item_strfunc.cc:143)
==93205==    by 0x9B5C61: mysql_do(THD*, List<Item>&) (sql_do.cc:34)
==93205==    by 0x7EB0D5: mysql_execute_command(THD*) (sql_parse.cc:2718)
==93205==    by 0x7F528B: mysql_parse(THD*, char*, unsigned int, Parser_state*) (sql_parse.cc:6489)
==93205==    by 0x7E8005: dispatch_command(enum_server_command, THD*, char*, unsigned int) (sql_parse.cc:1377)
==93205==    by 0x7E7037: do_command(THD*) (sql_parse.cc:1040)
==93205==    by 0x20973B67: threadpool_process_request(THD*) (threadpool_common.cc:321)
==93205==    by 0x20976A37: handle_event(connection_t*) (threadpool_unix.cc:1611)
==93205==    by 0x20976C94: worker_main(void*) (threadpool_unix.cc:1664)
==93205==    by 0xB99FDC: pfs_spawn_thread (pfs.cc:1860)
==93205==    by 0x5043DC4: start_thread (in /usr/lib64/libpthread-2.17.so)
==93205==    by 0x61AC21C: clone (in /usr/lib64/libc-2.17.so)
==93205==  Address 0x36551b40 is 0 bytes inside a block of size 24 free'd   
==93205==    at 0x4C2AD1D: free (vg_replace_malloc.c:530)
==93205==    by 0xAD134F: my_free (my_malloc.c:140)
==93205==    by 0x636835: String::free() (sql_string.h:313)
==93205==    by 0x84ABD9: String::real_alloc(unsigned int) (sql_string.cc:45)   
==93205==    by 0x677074: String::alloc(unsigned int) (sql_string.h:322)
==93205==    by 0x6E9D70: Item_char_typecast::val_str(String*) (item_strfunc.cc:3990)
==93205==    by 0x65B6B1: Item::val_str_ascii(String*) (item.cc:236)
==93205==    by 0x7144E1: Item_func_inet_aton::val_int() (item_inetfunc.cc:42)
==93205==    by 0x6B5F4D: Item_int_func::val_str(String*) (item_func.cc:765)
==93205==    by 0x6E7F30: Item_func_conv_charset::val_str(String*) (item_strfunc.cc:3558)
==93205==    by 0x6DC67A: Item_str_func::val_int() (item_strfunc.cc:143)
==93205==    by 0x9B5C61: mysql_do(THD*, List<Item>&) (sql_do.cc:34)
==93205==    by 0x7EB0D5: mysql_execute_command(THD*) (sql_parse.cc:2718)
==93205==    by 0x7F528B: mysql_parse(THD*, char*, unsigned int, Parser_state*) (sql_parse.cc:6489)
==93205==    by 0x7E8005: dispatch_command(enum_server_command, THD*, char*, unsigned int) (sql_parse.cc:1377)
==93205==    by 0x7E7037: do_command(THD*) (sql_parse.cc:1040)
==93205==    by 0x20973B67: threadpool_process_request(THD*) (threadpool_common.cc:321)
==93205==    by 0x20976A37: handle_event(connection_t*) (threadpool_unix.cc:1611)
==93205==    by 0x20976C94: worker_main(void*) (threadpool_unix.cc:1664)
==93205==    by 0xB99FDC: pfs_spawn_thread (pfs.cc:1860)
==93205==    by 0x5043DC4: start_thread (in /usr/lib64/libpthread-2.17.so)
==93205==    by 0x61AC21C: clone (in /usr/lib64/libc-2.17.so)
==93205==  Block was alloc'd at
==93205==    at 0x4C29C23: malloc (vg_replace_malloc.c:299)
==93205==    by 0xAD0F05: my_malloc (my_malloc.c:38)
==93205==    by 0x84ABE9: String::real_alloc(unsigned int) (sql_string.cc:46)
==93205==    by 0x677074: String::alloc(unsigned int) (sql_string.h:322)
==93205==    by 0x84AE12: String::set_int(long long, bool, charset_info_st const*) (sql_string.cc:133)
==93205==    by 0x6B6741: Item_func_numhybrid::val_str(String*) (item_func.cc:903)
==93205==    by 0x6E14AF: Item_func_left::val_str(String*) (item_strfunc.cc:1595)
==93205==    by 0x6E9A46: Item_char_typecast::val_str(String*) (item_strfunc.cc:3938)
==93205==    by 0x65B6B1: Item::val_str_ascii(String*) (item.cc:236)
==93205==    by 0x7144E1: Item_func_inet_aton::val_int() (item_inetfunc.cc:42)
==93205==    by 0x6B5F4D: Item_int_func::val_str(String*) (item_func.cc:765)
==93205==    by 0x6E7F30: Item_func_conv_charset::val_str(String*) (item_strfunc.cc:3558)
==93205==    by 0x6DC67A: Item_str_func::val_int() (item_strfunc.cc:143)
==93205==    by 0x9B5C61: mysql_do(THD*, List<Item>&) (sql_do.cc:34)
==93205==    by 0x7EB0D5: mysql_execute_command(THD*) (sql_parse.cc:2718)
==93205==    by 0x7F528B: mysql_parse(THD*, char*, unsigned int, Parser_state*) (sql_parse.cc:6489)
==93205==    by 0x7E8005: dispatch_command(enum_server_command, THD*, char*, unsigned int) (sql_parse.cc:1377)
==93205==    by 0x7E7037: do_command(THD*) (sql_parse.cc:1040)
==93205==    by 0x20973B67: threadpool_process_request(THD*) (threadpool_common.cc:321)
==93205==    by 0x20976A37: handle_event(connection_t*) (threadpool_unix.cc:1611)
==93205==    by 0x20976C94: worker_main(void*) (threadpool_unix.cc:1664)
==93205==    by 0xB99FDC: pfs_spawn_thread (pfs.cc:1860)
==93205==    by 0x5043DC4: start_thread (in /usr/lib64/libpthread-2.17.so)
==93205==    by 0x61AC21C: clone (in /usr/lib64/libc-2.17.so)

How to repeat:
pquery is random execute sql statement, so it hard to find which statement cause this issue,but it happened every day in my daily test.

Suggested fix:
Maybe this is not a bug,According to the stack information

bool String::real_alloc(uint32 length)
{
  uint32 arg_length= ALIGN_SIZE(length + 1);
  DBUG_ASSERT(arg_length > length);
  if (arg_length <= length)
    return TRUE;                                 /* Overflow */
  str_length=0;
  if (Alloced_length < arg_length)
  {
    free();   ==>  free the memory and valgrind mark the memory freed
    if (!(Ptr=(char*) my_malloc(arg_length,MYF(MY_WME))))  ==> malloc the memory, maybe the Ptr is the same memory block with freed memory, but the memory was marked by valgrind.
      return TRUE;
    Alloced_length=arg_length;
    alloced=1;
  }
  Ptr[0]=0;
  return FALSE;
}
[18 Oct 2017 17:20] MySQL Verification Team
Without a testcase, I have to make a guess this is a duplicate of fixed bug which I'll note in private comment: