Don't write beyond destination in __mempcpy_avx512_no_vzeroupper (bug 23196)

Message ID CAMe9rOrTccaQQL3rptbyC8kVhuHCCAr82E3U+_ZVAP=-PBVOwg@mail.gmail.com
State New, archived
Headers

Commit Message

H.J. Lu May 22, 2018, 4:33 p.m. UTC
  On Tue, May 22, 2018 at 8:38 AM, Andreas Schwab <schwab@suse.de> wrote:
> On Mai 22 2018, Florian Weimer <fweimer@redhat.com> wrote:
>
>> On 05/22/2018 05:06 PM, Andreas Schwab wrote:
>>> On Mai 22 2018, Florian Weimer<fweimer@redhat.com>  wrote:
>>>
>>>> And with the original reproducer, we wouldn't hit preloop_large, where the
>>>> bug is.
>>> Worksforme.
>>>
>>> $ string/test-mempcpy
>>
>> I don't doubt that.  Our CPUs probably have different cache sizes,
>
> Same cache size.

Here is the testcase.   Since both memcpy and memcpy share the
the same body of code, we can't use RAX to refer the beginning of
destination.  Please update your patch with this info together this
tesrcase.

Thanks.
  

Comments

Andreas Schwab May 23, 2018, 7:54 a.m. UTC | #1
I have installed the patch now, please commit your test case.

Andreas.
  

Patch

From d37944f542ff772b66634e6436865473b4f7b2fe Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Tue, 22 May 2018 09:14:37 -0700
Subject: [PATCH] Add a test case for BZ #23196

---
 string/test-memcpy.c | 47 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/string/test-memcpy.c b/string/test-memcpy.c
index 45f20a6d80..3c8066da52 100644
--- a/string/test-memcpy.c
+++ b/string/test-memcpy.c
@@ -212,6 +212,50 @@  do_random_tests (void)
     }
 }
 
+static void
+do_test1 (void)
+{
+  size_t size = 0x100000;
+  void *large_buf;
+
+  large_buf = mmap (NULL, size * 2 + page_size, PROT_READ | PROT_WRITE,
+		    MAP_PRIVATE | MAP_ANON, -1, 0);
+  if (large_buf == MAP_FAILED)
+    {
+      puts ("Failed to allocat large_buf, skipping do_test1");
+      return;
+    }
+
+  if (mprotect (large_buf + size, page_size, PROT_NONE))
+    error (EXIT_FAILURE, errno, "mprotect failed");
+
+  size_t arrary_size = size / sizeof (uint32_t);
+  uint32_t *dest = large_buf;
+  uint32_t *src = large_buf + size + page_size;
+  size_t i;
+
+  for (i = 0; i < arrary_size; i++)
+    src[i] = (uint32_t) i;
+
+  FOR_EACH_IMPL (impl, 0)
+    {
+      memset (dest, -1, size);
+      CALL (impl, (char *) dest, (char *) src, size);
+      for (i = 0; i < arrary_size; i++)
+	if (dest[i] != src[i])
+	  {
+	    error (0, 0,
+		   "Wrong result in function %s dst \"%p\" src \"%p\" offset \"%zd\"",
+		   impl->name, dest, src, i);
+	    ret = 1;
+	    break;
+	  }
+    }
+
+  munmap ((void *) dest, size);
+  munmap ((void *) src, size);
+}
+
 int
 test_main (void)
 {
@@ -253,6 +297,9 @@  test_main (void)
   do_test (0, 0, getpagesize ());
 
   do_random_tests ();
+
+  do_test1 ();
+
   return ret;
 }
 
-- 
2.17.0