Bug 803802

Summary: don't warn about harmless memmove read-beyond-end-of-buffer
Product: [Fedora] Fedora Reporter: Jim Meyering <meyering>
Component: valgrindAssignee: Mark Wielaard <mjw>
Status: CLOSED ERRATA QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 17CC: dodji, jakub, mjw, tmraz
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2012-12-20 15:51:14 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description Jim Meyering 2012-03-15 16:51:24 UTC
Description of problem:

On F17/x86_64, I ran these commands:

    s=$(printf '\304\215y\304\215')
    echo "x $s" > in
    LC_ALL=cs_CZ.UTF-8 valgrind grep --color=always -Ei "$s" in

and valgrind warned about an 8-byte read starting just 4 bytes from the
end of a regexec.c-internal heap buffer.  That means memmove has read
four bytes beyond the end of that buffer:

   Invalid read of size 8
      at 0x3FD448E38D: _wordcopy_fwd_dest_aligned (wordcopy.c:205)
      by 0x3FD4487F93: __GI_memmove (memmove.c:76)
      by 0x3FD44C4525: re_string_reconstruct (regex_internal.c:675)
      by 0x3FD44D3D87: re_search_internal (regexec.c:829)
      by 0x3FD44D5474: re_search_stub (regexec.c:463)
      by 0x3FD44D5D17: re_search (regexec.c:326)
      by 0x404287: ??? (in /usr/bin/grep)
      by 0x405BF2: ??? (in /usr/bin/grep)
      by 0x4062AF: ??? (in /usr/bin/grep)
      by 0x406409: ??? (in /usr/bin/grep)
      by 0x406BE8: ??? (in /usr/bin/grep)
      by 0x4038DC: ??? (in /usr/bin/grep)
    Address 0x4c3bcb8 is 24 bytes inside a block of size 28 alloc'd
      at 0x4A0884D: malloc (vg_replace_malloc.c:263)
      by 0x4A089CF: realloc (vg_replace_malloc.c:632)
      by 0x3FD44D3A37: re_search_internal (regex_internal.c:143)
      by 0x3FD44D5474: re_search_stub (regexec.c:463)
      by 0x3FD44D5D17: re_search (regexec.c:326)
      by 0x404287: ??? (in /usr/bin/grep)
      by 0x405BF2: ??? (in /usr/bin/grep)
      by 0x4062AF: ??? (in /usr/bin/grep)
      by 0x406409: ??? (in /usr/bin/grep)
      by 0x406BE8: ??? (in /usr/bin/grep)
      by 0x4038DC: ??? (in /usr/bin/grep)

And if you dig into regexec.c (already rather deep), and from there
into glibc's wordcopy.c and memmove.c (deep enough to make even Roland
cringe), you see that this is deliberate.  For an memmove use like the
one in regexec.c, char *buf = malloc(28); ... memmove (buf, buf+4, 24);
where the destination pointer, "buf", is 8-byte aligned, but the source
pointer is not, the underlying code reads 32 bytes (four 8-byte op_t's) in
order to write the three 8-byte-aligned op_t's.  Since it reads beyond end
of buffer only when the source pointer is not aligned to an op_t boundary,
I've convinced myself that there is no way reading those extra bytes
(up to 7) could cross a page boundary.

Now that I'm convinced this is not a bug, the question is whether we
can avoid the false positive.  I.e., can valgrind be taught that when a
memmove call appears to read a few bytes beyond end of the source buffer,
that it is ok, as long the overrun is consistent with the alignment of
the source pointer?

For the record, the memmove use is here:

Breakpoint 1, re_string_reconstruct (pstr=pstr <at> entry=0x7fffffffdd20,
    idx=idx <at> entry=1, eflags=eflags <at> entry=0) at regex_internal.c:675
675                     memmove (pstr->wcs, pstr->wcs + offset,
(gdb) p pstr->wcs
$1 = (wint_t *) 0x8222a0

And the offending read happened here:

#0  _wordcopy_fwd_dest_aligned (dstp=<optimized out>, srcp=<optimized out>,
    len=3) at wordcopy.c:205
205           a3 = ((op_t *) srcp)[3];


Version-Release number of selected component (if applicable): valgrind-3.7.0-2.fc17.x86_64

How reproducible: always

Steps to Reproduce:
1. see above
2.
3.

Actual results:
as above

Expected results:
no warning about the harmless memmove

Additional info:
Initially posted here:
http://thread.gmane.org/gmane.comp.gnu.grep.bugs/4412

Comment 1 Jim Meyering 2012-03-15 16:52:30 UTC
As Paul Eggert noted in the above discussion, a similar bug
appears to have been fixed in Fedora 15:

https://bugzilla.redhat.com/show_bug.cgi?id=705790

Comment 2 Mark Wielaard 2012-10-05 18:34:26 UTC
This has been fixed in 3.8.1 which is currently in rawhide. I am keeping this instance of the bug open for a backport of the package to fedora 17.

See also https://bugzilla.redhat.com/show_bug.cgi?id=757700

Comment 3 Jim Meyering 2012-10-05 19:09:20 UTC
great!  Thanks, Mark.

Comment 4 Fedora Update System 2012-10-15 21:59:39 UTC
valgrind-3.8.1-3.fc17 has been submitted as an update for Fedora 17.
https://admin.fedoraproject.org/updates/valgrind-3.8.1-3.fc17

Comment 5 Fedora Update System 2012-10-17 00:28:52 UTC
Package valgrind-3.8.1-4.fc17:
* should fix your issue,
* was pushed to the Fedora 17 testing repository,
* should be available at your local mirror within two days.
Update it with:
# su -c 'yum update --enablerepo=updates-testing valgrind-3.8.1-4.fc17'
as soon as you are able to.
Please go to the following url:
https://admin.fedoraproject.org/updates/FEDORA-2012-16272/valgrind-3.8.1-4.fc17
then log in and leave karma (feedback).

Comment 6 Fedora Update System 2012-12-20 15:51:16 UTC
valgrind-3.8.1-4.fc17 has been pushed to the Fedora 17 stable repository.  If problems still persist, please make note of it in this bug report.