Bug #51850 crash/memory overlap when using load data infile and set col equal to itself!
Submitted: 9 Mar 2010 4:57 Modified: 4 Nov 2010 2:04
Reporter: Shane Bester (Platinum Quality Contributor) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: DML Severity:S1 (Critical)
Version:5.0.89, 5.1.44, 5.1.45-bzr, 5.6.99 OS:Linux (fc6 x86)
Assigned to: Georgi Kodinov CPU Architecture:Any
Tags: LOAD DATA, valgrind
Triage: Triaged: D1 (Critical)

[9 Mar 2010 4:57] Shane Bester
Description:
5.1.44 stack trace of valgrind error report:

Source and destination overlap in memcpy(0x5e23bd2, 0x5e23bd2, 4)
at: memcpy (mc_replace_strmem.c:482)
by: field_conv(Field*, Field*) (field_conv.cc:783)
by: Item_field::save_in_field(Field*, bool) (item.cc:5042)
by: fill_record_n_invoke_before_triggers (sql_base.cc:8156)
by: mysql_load (sql_load.cc:995)
by: mysql_execute_command(THD*) (sql_parse.cc:3459)
by: mysql_parse (sql_parse.cc:5971)
by: dispatch_command (sql_parse.cc:1233)
by: do_command(THD*) (sql_parse.cc:874)
by: handle_one_connection (sql_connect.cc:1127)
by: start_thread (in /lib64/libpthread-2.5.so)
by: clone (in /lib64/libc-2.5.so)

How to repeat:
testcase will come soon
[9 Mar 2010 5:39] Shane Bester
run mysqld under valgrind with this testcase.

set sql_mode='';
drop table if exists t1;
create table t1(col0 timestamp)engine=myisam;
select 'test' into outfile 't1.txt';
load data infile 't1.txt'ignore into table `t1`
set `col0`=`col0`;
[9 Mar 2010 7:05] Valeriy Kravchuk
Verified just as described with recent 5.1.45 from bzr on SuSE:

...
==6583== Thread 11:
==6583== Source and destination overlap in memcpy(0x6886af9, 0x6886af9, 4)
==6583==    at 0x401EC9F: memcpy (mc_replace_strmem.c:482)
==6583==    by 0x840A2CA: field_conv(Field*, Field*) (field_conv.cc:783)
==6583==    by 0x81D4014: Item_field::save_in_field(Field*, bool) (item.cc:5042)
==6583==    by 0x82FBDCD: fill_record(THD*, List<Item>&, List<Item>&, bool) (sql_base.cc:8156)
==6583==    by 0x82FBEDD: fill_record_n_invoke_before_triggers(THD*, List<Item>&, List<Item>&, bool, Table_triggers_list*, trg_event_type) (sql_base.cc:8199)
==6583==    by 0x8406720: read_sep_field(THD*, st_copy_info&, TABLE_LIST*, List<Item>&, List<Item>&, List<Item>&, READ_INFO&, String&, unsigned long, bool) (sql_load.cc:995)
==6583==    by 0x8404E08: mysql_load(THD*, sql_exchange*, TABLE_LIST*, List<Item>&, List<Item>&, List<Item>&, enum_duplicates, bool, bool) (sql_load.cc:437)
==6583==    by 0x82A83CC: mysql_execute_command(THD*) (sql_parse.cc:3457)
==6583==    by 0x82AF253: mysql_parse(THD*, char const*, unsigned int, char const**) (sql_parse.cc:5971)
==6583==    by 0x82A2F32: dispatch_command(enum_server_command, THD*, char*, unsigned int) (sql_parse.cc:1233)
==6583==    by 0x82A21C1: do_command(THD*) (sql_parse.cc:874)
==6583==    by 0x82A05F7: handle_one_connection (sql_connect.cc:1127)
[9 Mar 2010 7:30] Shane Bester
crash can happen if the column is longblog!

set sql_mode='';
drop table if exists t1;
create table t1(col0 longblob)engine=myisam;
select 'test' into outfile 't1.txt';
load data infile 't1.txt'ignore into table `t1`
set `col0`=`col0`;

Thread 14:
Invalid read of size 1
at: memcpy (mc_replace_strmem.c:482)
by: String::copy() (sql_string.cc:82)
by: field_conv(Field*, Field*) (field_conv.cc:799)
by: Item_field::save_in_field(Field*, bool) (item.cc:5042)
by: fill_record_n_invoke_before_triggers (sql_base.cc:8156)
by: mysql_load  (sql_load.cc:995)
by: mysql_execute_command(THD*) (sql_parse.cc:3459)
by: mysql_parse (sql_parse.cc:5971)
by: dispatch_command (sql_parse.cc:1233)
by: do_command(THD*) (sql_parse.cc:874)
by: handle_one_connection (sql_connect.cc:1127)
by: start_thread (in /lib64/libpthread-2.5.so)
by: clone (in /lib64/libc-2.5.so)
 Address 0x9d24fc3 is 3 bytes inside a block of size 8 free'd
at: free (vg_replace_malloc.c:325)
by: Field_blob::val_str(String*, String*) (sql_string.h:196)
by: field_conv(Field*, Field*) (field.h:121)
by: Item_field::save_in_field(Field*, bool) (item.cc:5042)
by: fill_record_n_invoke_before_triggers (sql_base.cc:8156)
by: mysql_load (sql_load.cc:995)
by: mysql_execute_command(THD*) (sql_parse.cc:3459)
by: mysql_parse (sql_parse.cc:5971)
by: dispatch_command(sql_parse.cc:1233)
by: do_command(THD*) (sql_parse.cc:874)
by: handle_one_connection (sql_connect.cc:1127)
by: start_thread (in /lib64/libpthread-2.5.so)
by: clone (in /lib64/libc-2.5.so)
[17 Mar 2010 10:24] Georgi Kodinov
First test case (with the timestamp column) is not producing valgrind warnings on my fc12/valgrind 3.5 box on 5.1-bugteam.
However the second test produces the following valgrind warnings:
==5814== Invalid read of size 1
==5814==    at 0x4A06A68: memcpy (mc_replace_strmem.c:497)
==5814==    by 0x6ACF47: String::realloc(unsigned int) (sql_string.cc:82)
==5814==    by 0x6AD1A2: String::copy() (sql_string.cc:193)
==5814==    by 0x835CF6: field_conv(Field*, Field*) (field_conv.cc:799)
==5814==    by 0x5E99FC: Item_field::save_in_field(Field*, bool) (item.cc:5071)
==5814==    by 0x71D8F5: fill_record(THD*, List<Item>&, List<Item>&, bool) (sql_base.cc:8173)
==5814==    by 0x71DA29: fill_record_n_invoke_before_triggers(THD*, List<Item>&, List<Item>&, bool, Table_triggers_list*, trg_event_type) (sql_base.cc:8218)
==5814==    by 0x831887: read_sep_field(THD*, st_copy_info&, TABLE_LIST*, List<Item>&, List<Item>&, List<Item>&, READ_INFO&, String&, unsigned long, bool) (sql_load.cc:995)
==5814==    by 0x82FD5C: mysql_load(THD*, sql_exchange*, TABLE_LIST*, List<Item>&, List<Item>&, List<Item>&, enum_duplicates, bool, bool) (sql_load.cc:439)
==5814==    by 0x6C7E88: mysql_execute_command(THD*) (sql_parse.cc:3459)
==5814==    by 0x6CF715: mysql_parse(THD*, char const*, unsigned int, char const**) (sql_parse.cc:5971)
==5814==    by 0x6C1DEB: dispatch_command(enum_server_command, THD*, char*, unsigned int) (sql_parse.cc:1233)
==5814==    by 0x6C0DD9: do_command(THD*) (sql_parse.cc:874)
==5814==    by 0x6BF138: handle_one_connection (sql_connect.cc:1127)
==5814==    by 0x39B2406A39: start_thread (in /lib64/libpthread-2.11.so)
==5814==  Address 0x60cf273 is 3 bytes inside a block of size 8 free'd
==5814==    at 0x4A04D72: free (vg_replace_malloc.c:325)
==5814==    by 0xB0209F: my_no_flags_free (my_malloc.c:59)
==5814==    by 0x5CCF5D: String::free() (sql_string.h:196)
==5814==    by 0x5F1DA6: String::set(char const*, unsigned int, charset_info_st*) (sql_string.h:143)
==5814==    by 0x6886A9: Field_blob::val_str(String*, String*) (field.cc:7819)
==5814==    by 0x5F2BF4: Field::val_str(String*) (field.h:125)
==5814==    by 0x835C5B: field_conv(Field*, Field*) (field_conv.cc:790)
==5814==    by 0x5E99FC: Item_field::save_in_field(Field*, bool) (item.cc:5071)
==5814==    by 0x71D8F5: fill_record(THD*, List<Item>&, List<Item>&, bool) (sql_base.cc:8173)
==5814==    by 0x71DA29: fill_record_n_invoke_before_triggers(THD*, List<Item>&, List<Item>&, bool, Table_triggers_list*, trg_event_type) (sql_base.cc:8218)
==5814==    by 0x831887: read_sep_field(THD*, st_copy_info&, TABLE_LIST*, List<Item>&, List<Item>&, List<Item>&, READ_INFO&, String&, unsigned long, bool) (sql_load.cc:995)
==5814==    by 0x82FD5C: mysql_load(THD*, sql_exchange*, TABLE_LIST*, List<Item>&, List<Item>&, List<Item>&, enum_duplicates, bool, bool) (sql_load.cc:439)
==5814==    by 0x6C7E88: mysql_execute_command(THD*) (sql_parse.cc:3459)
==5814==    by 0x6CF715: mysql_parse(THD*, char const*, unsigned int, char const**) (sql_parse.cc:5971)
==5814==    by 0x6C1DEB: dispatch_command(enum_server_command, THD*, char*, unsigned int) (sql_parse.cc:1233)
==5814==    by 0x6C0DD9: do_command(THD*) (sql_parse.cc:874)
[18 Mar 2010 15:30] 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/103711

3404 Georgi Kodinov	2010-03-18
      Bug #51850: crash/memory overlap when using load data infile and set
        col equal to itself!
      
      There's no need to copy the value of a field into itself.
      While generally harmless (except for some performance penalties)
      it may be dangerous when the copy code doesn't expect this.
      Fixed by checking if the source field is the same as the destination
      field before copying the data.
      Note that we must preserve the order of assignment of the null 
      flags (hence the null_value assignment addition).
[23 Mar 2010 15:00] 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/104097

3412 Georgi Kodinov	2010-03-18
      Bug #51850: crash/memory overlap when using load data infile and set
        col equal to itself!
      
      There's no need to copy the value of a field into itself.
      While generally harmless (except for some performance penalties)
      it may be dangerous when the copy code doesn't expect this.
      Fixed by checking if the source field is the same as the destination
      field before copying the data.
      Note that we must preserve the order of assignment of the null 
      flags (hence the null_value assignment addition).
[23 Mar 2010 15:09] 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/104099

3412 Georgi Kodinov	2010-03-23
      Bug #51850: crash/memory overlap when using load data infile and set
        col equal to itself!
      
      There's no need to copy the value of a field into itself.
      While generally harmless (except for some performance penalties)
      it may be dangerous when the copy code doesn't expect this.
      Fixed by checking if the source field is the same as the destination
      field before copying the data.
      Note that we must preserve the order of assignment of the null 
      flags (hence the null_value assignment addition).
[26 Mar 2010 8:31] 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:58] Bugs System
Pushed into 5.1.46 (revid:sergey.glukhov@sun.com-20100405111026-7kz1p8qlzglqgfmu) (version source revid:joro@sun.com-20100323150700-zbddigpapcxcyuxc) (merge vers: 5.1.46) (pib:16)
[14 Apr 2010 19:41] Paul Dubois
Noted in 5.1.46, 6.0.14 changelogs.

In LOAD DATA INFILE, using a SET clause to set a column equal to
itself caused a server crash.  

Setting report to Need Merge pending push to Celosia.
[17 Jun 2010 11:57] 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:36] 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:22] 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)
[18 Jun 2010 1:23] Paul Dubois
Setting report to Need Merge pending push to Celosia.
[4 Nov 2010 2:04] Paul Dubois
Noted in 5.5.7 changelog.