Bug 454040 - s390x: False-positive memcheck:cond in memmem on arch13 systems
Summary: s390x: False-positive memcheck:cond in memmem on arch13 systems
Status: RESOLVED FIXED
Alias: None
Product: valgrind
Classification: Developer tools
Component: memcheck (show other bugs)
Version: unspecified
Platform: Other Linux
: NOR normal
Target Milestone: ---
Assignee: Andreas Arnez
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-05-19 12:22 UTC by Andreas Arnez
Modified: 2022-07-07 12:27 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments
Add intercept for memmem on s390x (1.94 KB, patch)
2022-05-19 12:34 UTC, Andreas Arnez
Details
Add memcheck memmem vgtest (3.99 KB, text/plain)
2022-05-19 22:23 UTC, Mark Wielaard
Details
Patch for adding a memmem intercept, version 2 (1.91 KB, patch)
2022-05-20 14:23 UTC, Andreas Arnez
Details
memcheck memmem tests (5.06 KB, text/plain)
2022-05-25 14:38 UTC, Mark Wielaard
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andreas Arnez 2022-05-19 12:22:01 UTC
On a system that supports the vector enhancements facility 2 (arch13 or higher), glibc runs an optimized version of memmem that uses the "vector string search" instruction. That implementation contains a conditional jump that may depend on undefined values; however, the end result of the function is still independent from these undefined values. Since memcheck can't see that, it may report a false positive, as reproduced like this:

  $ valgrind perl -e "use lib '.'; require BarXXXXXXXXXXXXXXX;"
  ...
  ==3271940== Conditional jump or move depends on uninitialised value(s)
  ==3271940==    at 0x4CAABB6: __memmem_arch13 (memmem-arch13.S:65)
  ==3271940==    by 0x49B64FF: Perl_pp_require (in /usr/lib64/libperl.so.5.32.1)
  ==3271940==    by 0x49654C1: Perl_runops_standard (in /usr/lib64/libperl.so.5.32.1)
  ==3271940==    by 0x48DC3F5: perl_run (in /usr/lib64/libperl.so.5.32.1)
  ==3271940==    by 0x108E37: main (in /usr/bin/perl)
Comment 1 Andreas Arnez 2022-05-19 12:34:12 UTC
Created attachment 148994 [details]
Add intercept for memmem on s390x

Add an intercept for memmem on s390x platforms. This fixes the problem in my testing.
Comment 2 Mark Wielaard 2022-05-19 22:20:08 UTC
Looks good and fixes the issue for me.

+      /* If the needle is the empty string, match immediately. */ \
+      if (nlen == 0) return CONST_CAST(void *,h); \
+      \
+      HChar n0 = n[0]; \
+      \
+      for (; hlen >= nlen; hlen--, h++) { \
+         const HChar hh = *h; \
+         if (hh != n0) continue; \
+         \
+         UWord i; \
+         for (i = 0; i < nlen; i++) { \
+            if (n[i] != h[i]) \
+               break; \
+         } \
+         if (i == nlen) \
+           return CONST_CAST(HChar *,h); \

I think the for loop could/should be from i = 1. needle being zero sized (nlen == 0) and n[0] == h[0] (hh != n0) has already been checked above.
Comment 3 Mark Wielaard 2022-05-19 22:23:57 UTC
Created attachment 149008 [details]
Add memcheck memmem vgtest

I wrote a testcase that fails before the patch (on s390x) and succeeds afterwards. It would be nice to add it so we check the same isn't an issue on other arches and to test our own memmem intercept.
Comment 4 Andreas Arnez 2022-05-20 14:18:45 UTC
(In reply to Mark Wielaard from comment #2)
> Looks good and fixes the issue for me.
> I think the for loop could/should be from i = 1. needle being zero sized
> (nlen == 0) and n[0] == h[0] (hh != n0) has already been checked above.
Thanks, you're right. Also, the hh variable is only accessed once and doesn't improve readability. I'll attach an updated patch.

(In reply to Mark Wielaard from comment #3)
> Created attachment 149008 [details]
> Add memcheck memmem vgtest
> 
> I wrote a testcase that fails before the patch (on s390x) and succeeds
> afterwards. It would be nice to add it so we check the same isn't an issue
> on other arches and to test our own memmem intercept.
Great! Do we also want to check cases where memcheck is expected to complain about the use of uninitialized values in memmem?
Comment 5 Andreas Arnez 2022-05-20 14:23:46 UTC
Created attachment 149025 [details]
Patch for adding a memmem intercept, version 2

This addresses Mark's comment and removes the 'hh' variable.
Comment 6 Mark Wielaard 2022-05-25 14:38:56 UTC
Created attachment 149209 [details]
memcheck memmem tests

> > I wrote a testcase that fails before the patch (on s390x) and succeeds
> > afterwards. It would be nice to add it so we check the same isn't an issue
> > on other arches and to test our own memmem intercept.
> Great! Do we also want to check cases where memcheck is expected to complain
> about the use of uninitialized values in memmem?

Good idea. But that turned out trickier than expected. Since there are multiple different memmem implementations some of which call overridden memchr and now we have an actual memmem override for s390x matching on the backtrace is hard. So the two uninit needle and uninit haystack testcases just filter on the main file line numbers.
Comment 7 Mark Wielaard 2022-05-25 14:39:37 UTC
(In reply to Andreas Arnez from comment #5)
> Created attachment 149025 [details]
> Patch for adding a memmem intercept, version 2
> 
> This addresses Mark's comment and removes the 'hh' variable.

Looks good to me and works with the new testcase I just attached.
Comment 8 Mark Wielaard 2022-06-18 13:22:38 UTC
I believe this is good to go. I have been testing it, including the new testcase on various fedora systems.

Andreas, could you push the fix. Let me know if you want me to add the testcase separately.
Comment 9 Andreas Arnez 2022-07-07 12:27:10 UTC
(In reply to Mark Wielaard from comment #8)
> Andreas, could you push the fix. Let me know if you want me to add the
> testcase separately.
Thanks, I pushed the fix now, including your testcase.