Bug #56138 valgrind errors about overlapping memory when double-assigning same variable
Submitted: 20 Aug 2010 8:25 Modified: 15 Dec 2010 0:59
Reporter: Shane Bester (Platinum Quality Contributor) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: General Severity:S2 (Serious)
Version:5.6.1, 5.1.52, 5.5.8 OS:Any
Assigned to: Guilhem Bichot CPU Architecture:Any
Tags: valgrind

[20 Aug 2010 8:25] Shane Bester
Description:
Version: '5.6.1-m4'  socket: '/tmp/mysql.sock'  port: 3306  Source distribution
 Thread 17:                                                                    
 Source and destination overlap in memcpy(0x13b5b6e0, 0x13b5b6e0, 64)          
at: memcpy (mc_replace_strmem.c:482)                                           
by: update_hash (item_func.cc:4259)                                            
by: Item_func_set_user_var::update() (item_func.cc:4283)                       
by: Item_func_set_user_var::val_str (item_func.cc:4592)                        
by: Item::send (item.cc:5831)                                                  
by: Item_func_set_user_var::send (item_func.cc:4677)                           
by: Protocol::send_result_set_row (protocol.cc:866)                            
by: select_send::send_data (sql_class.cc:1764)                                 
by: end_send_group (sql_select.cc:12592)                                       
by: do_select (sql_select.cc:11314)                                            
by: JOIN::exec() (sql_select.cc:2336)                                          
by: mysql_select (sql_select.cc:2530)                                          
by: handle_select (sql_select.cc:290)                                          
by: execute_sqlcom_select (sql_parse.cc:4797)                                  
by: mysql_execute_command (sql_parse.cc:2298)                                  
by: mysql_parse (sql_parse.cc:5826)                                            
by: dispatch_command (sql_parse.cc:1128)                                       
by: do_command (sql_parse.cc:800)                                              
by: do_handle_one_connection (sql_connect.cc:1191)                             
by: handle_one_connection                                                      
by: start_thread                                                               
by: clone                                                                      

How to repeat:
#run mysqld in valgrind.  execute this;

select @v:=@v:=sum(1) from dual;

Suggested fix:
don't bother copying identical pointers to each other.
[21 Aug 2010 12:51] Sveta Smirnova
Thank you for the report.

Verified as described.
[26 Aug 2010 5:44] MySQL Verification Team
hm, in another bug report guilhem mentioned that is it not a bug if the src and dest parameters are identical.  perhaps this too is not a bug..?
[10 Nov 2010 14:13] Guilhem Bichot
memcpy(to,from,len) is undefined if to==from. So this bug report is correctly a bug (unlike BUG#52089). We should fix it (using memmove()?) and any other such warning.
For the case where struct assignment is wrongly converted to memcpy() (a gcc bug, like in BUG#52089), maybe we should have some if()s:
if(from != to) *to=*from;
to work around the gcc bug (we already have that if() if HAVE_purify is defined; I suggest we have it in all builds).
[10 Nov 2010 19: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/123489

3379 Guilhem Bichot	2010-11-10
      Fix for Bug#56138 "valgrind errors about overlapping memory when double-assigning same variable",
      and related small fixes.
     @ mysql-test/t/user_var.test
        test for bug
     @ sql/field_conv.cc
        From the C standard, memcpy() has undefined behaviour if to->ptr==from->ptr
     @ sql/item_func.cc
        In the case of BUG#56138, entry->value==ptr in which case memcpy()
        has undefined results per the C standard.
     @ sql/sql_select.cc
        Work around a bug in gcc which existed at least until gcc 4.1.2
        http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19410 .
[10 Nov 2010 20:25] Guilhem Bichot
This bug exists in 5.1-bugteam too revision-id:guilhem@mysql.com-20101105131747-qh7boorqpe3z3cl2 .
Triage: could you please consider allowing a push in 5.1 or at least 5.5 (if reviewers approve the patch). Because this isn't just a Valgrind warning. The C standard says that memcpy(dest,src,len) has undefined behaviour when the source and target memory areas overlap, which is the case here. It sounds risky to keep this wrong memcpy() around (it could corrupt memory in an unrepeatable manner), when the fix (changing to memmove()) has zero risk (memmove() is like memcpy() but supports overlapping areas).
[10 Nov 2010 20:37] Guilhem Bichot
In support of fixing in earlier versions than 5.6:
(thanks Davi for finding this link) there is a quite recent change in glibc which makes memcpy() produce bad results when source and destination overlap:
http://lwn.net/Articles/414467/
and this has already started making applications (Flash) break (they break because they used memcpy() with overlap, which the C standard says is undefined, but worked so far with glibc, and will not work anymore).
We should set ourselves ready for this glibc change, by not doing memcpy() with overlap; which my patch fixes.
[10 Nov 2010 20:57] 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/123499

3379 Guilhem Bichot	2010-11-10
      Fix for Bug#56138 "valgrind errors about overlapping memory when double-assigning same variable",
      and related small fixes.
     @ mysql-test/t/user_var.test
        test for bug
     @ sql/field_conv.cc
        From the C standard, memcpy() has undefined behaviour if to->ptr==from->ptr
     @ sql/item_func.cc
        In the case of BUG#56138, entry->value==ptr in which case memcpy()
        has undefined results per the C standard.
     @ sql/sql_select.cc
        Work around a bug in old gcc
[13 Nov 2010 13:14] MySQL Verification Team
FYI, an even shorter testcase...

do @a:=@a:=1.0;

Source and destination overlap in memcpy(0xf7510c0, 0xf7510c0, 64)
at : memcpy (mc_replace_strmem.c:497)
by : update_hash (item_func.cc:4327)
by : Item_func_set_user_var::update_hash (item_func.cc:4351)
by : Item_func_set_user_var::update (item_func.cc:4627)
by : Item_func_set_user_var::val_int (item_func.cc:4652)
by : mysql_do (sql_do.cc:34)
by : mysql_execute_command (sql_parse.cc:2088)
by : mysql_parse (sql_parse.cc:5512)
by : dispatch_command (sql_parse.cc:1029)
by : do_command (sql_parse.cc:769)
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)
[22 Nov 2010 8:58] 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/124587

3514 Guilhem Bichot	2010-11-22
      Fix for Bug#56138 "valgrind errors about overlapping memory when double-assigning same variable",
      and related small fixes.
     @ mysql-test/t/user_var.test
        test for bug
     @ sql/field_conv.cc
        From the C standard, memcpy() has undefined behaviour if to->ptr==from->ptr
     @ sql/item_func.cc
        In the case of BUG#56138, entry->value==ptr in which case memcpy()
        has undefined results per the C standard.
     @ sql/sql_select.cc
        Work around a bug in old gcc
[22 Nov 2010 9:32] Guilhem Bichot
queued to 5.1-bugteam, 5.5-bugteam, trunk-bugfixing
[5 Dec 2010 12:39] Bugs System
Pushed into mysql-trunk 5.6.1 (revid:alexander.nozdrin@oracle.com-20101205122447-6x94l4fmslpbttxj) (version source revid:alexander.nozdrin@oracle.com-20101205122447-6x94l4fmslpbttxj) (merge vers: 5.6.1) (pib:23)
[15 Dec 2010 0:59] Paul DuBois
Noted in 5.1.54, 5.5.8 changelogs.

Valgrind warnings about overlapping memory when double-assigning the
same variable were corrected.
[15 Dec 2010 5:51] Bugs System
Pushed into mysql-5.1 5.1.55 (revid:sunanda.menon@oracle.com-20101215054055-vgwki317xg1wphhh) (version source revid:sunanda.menon@oracle.com-20101215054055-vgwki317xg1wphhh) (merge vers: 5.1.55) (pib:23)
[16 Dec 2010 22:28] Bugs System
Pushed into mysql-5.5 5.5.9 (revid:jonathan.perkin@oracle.com-20101216101358-fyzr1epq95a3yett) (version source revid:jonathan.perkin@oracle.com-20101216101358-fyzr1epq95a3yett) (merge vers: 5.5.9) (pib:24)