Bug 2214374

Summary: __memmove_chk seen as __memcpy_chk
Product: Red Hat Enterprise Linux 9 Reporter: Mark Wielaard <mjw>
Component: valgrindAssignee: Mark Wielaard <mjw>
valgrind sub component: system-version QA Contact: Jesus Checa <jchecahi>
Status: VERIFIED --- Docs Contact:
Severity: unspecified    
Priority: unspecified CC: fweimer, jakub, ohudlick
Version: 9.3Keywords: Triaged
Target Milestone: rc   
Target Release: 9.3   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: valgrind-3.21.0-7.el9 Doc Type: No Doc Update
Doc Text:
Story Points: ---
Clone Of:
: 2214375 (view as bug list) Environment:
Last Closed: Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 2214375    
Deadline: 2023-07-03   

Description Mark Wielaard 2023-06-12 18:58:12 UTC
One false positive fixed in 3.21.0 (in Fedora/RHEL) was the false positive of memmove seen as memcpy with overlapping source and destination buffers (this is a real issue for memcpy, but not for memmove). We missed the case of the false positive of __memmove_chk seen as __memcpy_chk (which are used with _FORTIFY_SOURCE=2).

This is somewhat tricky to trigger because it depends on how valgrind does symbol resolution and whether memmove and memcpy (or their _chk variants) are implemented through ifuncs using the same code (address).

The following shows the issue though:

$ cat c.c 
#include <stdio.h>
#include <string.h>

volatile char *s;

char *
__memcpy_chk(char *d, const char *s, size_t n, size_t dn);

char *
__memmove_chk(char *d, const char *s, size_t n, size_t dn);

int main(int argc,const char *argv[])
{	
	char buffer[100];
	__memcpy_chk(buffer, &buffer[20], 9, 100);
	__memmove_chk(buffer, &buffer[1], 99, 100);
	return 0;
}
$ gcc -g -o c c.c
[ignore the valid warnings]
$ valgrind -q ./c
==1062238== Source and destination overlap in memcpy_chk(0x1ffefff8a0, 0x1ffefff8a1, 99)
==1062238==    at 0x484C862: __memcpy_chk (vg_replace_strmem.c:1743)
==1062238==    by 0x401180: main (c.c:16)
==1062238== 

Note that line 16 is the __memmove_chk call (not the __memcpy_chk one).
This shouldn't produce an overlap warning (because memmove is allowed to work on overlapping source and destination buffers).

The workaround is just removing 2 lines as outlined in the upstream bug report. The workaround is already in Fedora.