]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix i386 memmove issue (bug 22644).
authorAndrew Senkevich <andrew.n.senkevich@gmail.com>
Fri, 23 Mar 2018 15:19:45 +0000 (16:19 +0100)
committerAurelien Jarno <aurelien@aurel32.net>
Thu, 20 Dec 2018 07:14:01 +0000 (08:14 +0100)
[BZ #22644]
* sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S: Fixed
branch conditions.
* string/test-memmove.c (do_test2): New testcase.

(cherry picked from commit cd66c0e584c6d692bc8347b5e72723d02b8a8ada)

ChangeLog
NEWS
string/test-memmove.c
sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S

index 3305107bca916585c386a3595013c1e82dde03e4..63813de2d5a9a946dc444dfcb27ae28c72d08fb4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2018-03-23  Andrew Senkevich  <andrew.senkevich@intel.com>
+           Max Horn  <max@quendi.de>
+
+       [BZ #22644]
+       * sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S: Fixed
+       branch conditions.
+       * string/test-memmove.c (do_test2): New testcase.
+
 2018-09-06  Stefan Liebler  <stli@linux.ibm.com>
 
        * sysdeps/unix/sysv/linux/spawni.c (maybe_script_execute):
diff --git a/NEWS b/NEWS
index d11dfe1429578abbd3cb0f7bec9a7ed2d37a7853..77f7f1ad0e72ac63581119736ad5f88cf14c5449 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -60,6 +60,8 @@ The following bugs are resolved with this release:
   [21609] x86-64: Align the stack in __tls_get_addr
   [21624] Unsafe alloca allows local attackers to alias stack and heap (CVE-2017-1000366)
   [21654] nss: Fix invalid cast in group merging
+  [22644] string: memmove-sse2-unaligned on 32bit x86 produces garbage when
+    crossing 2GB threshold (CVE-2017-18269)
   [22715] x86-64: Properly align La_x86_64_retval to VEC_SIZE
 \f
 Version 2.24
index 43433297e543e1045b8fa7c80a9490474086f5f5..f44c05d669d7b48bba7b87882c63f1725f630922 100644 (file)
@@ -245,6 +245,60 @@ do_random_tests (void)
     }
 }
 
+static void
+do_test2 (void)
+{
+  size_t size = 0x20000000;
+  uint32_t * large_buf;
+
+  large_buf = mmap ((void*) 0x70000000, size, PROT_READ | PROT_WRITE,
+                   MAP_PRIVATE | MAP_ANON, -1, 0);
+
+  if (large_buf == MAP_FAILED)
+    error (77, errno, "Large mmap failed");
+
+  if ((uintptr_t) large_buf > 0x80000000 - 128
+      || 0x80000000 - (uintptr_t) large_buf > 0x20000000)
+    {
+      error (0, 0, "Large mmap allocated improperly");
+      ret = 77;
+      munmap ((void *) large_buf, size);
+      return;
+    }
+
+  size_t bytes_move = 0x80000000 - (uintptr_t) large_buf;
+  size_t arr_size = bytes_move / sizeof (uint32_t);
+  size_t i;
+
+  FOR_EACH_IMPL (impl, 0)
+    {
+      for (i = 0; i < arr_size; i++)
+        large_buf[i] = (uint32_t) i;
+
+      uint32_t * dst = &large_buf[33];
+
+#ifdef TEST_BCOPY
+      CALL (impl, (char *) large_buf, (char *) dst, bytes_move);
+#else
+      CALL (impl, (char *) dst, (char *) large_buf, bytes_move);
+#endif
+
+      for (i = 0; i < arr_size; i++)
+       {
+         if (dst[i] != (uint32_t) i)
+           {
+             error (0, 0,
+                    "Wrong result in function %s dst \"%p\" src \"%p\" offset \"%zd\"",
+                    impl->name, dst, large_buf, i);
+             ret = 1;
+             break;
+           }
+       }
+    }
+
+  munmap ((void *) large_buf, size);
+}
+
 int
 test_main (void)
 {
@@ -284,6 +338,9 @@ test_main (void)
     }
 
   do_random_tests ();
+
+  do_test2 ();
+
   return ret;
 }
 
index 76f34291a38a0699a8c64deb11afd31911f63aa0..bb26708d67aa47d32100d26cec5f7425f919e2e8 100644 (file)
@@ -72,7 +72,7 @@ ENTRY (MEMCPY)
        cmp     %edx, %eax
 
 # ifdef USE_AS_MEMMOVE
-       jg      L(check_forward)
+       ja      L(check_forward)
 
 L(mm_len_0_or_more_backward):
 /* Now do checks for lengths. We do [0..16], [16..32], [32..64], [64..128]
@@ -81,7 +81,7 @@ L(mm_len_0_or_more_backward):
        jbe     L(mm_len_0_16_bytes_backward)
 
        cmpl    $32, %ecx
-       jg      L(mm_len_32_or_more_backward)
+       ja      L(mm_len_32_or_more_backward)
 
 /* Copy [0..32] and return.  */
        movdqu  (%eax), %xmm0
@@ -92,7 +92,7 @@ L(mm_len_0_or_more_backward):
 
 L(mm_len_32_or_more_backward):
        cmpl    $64, %ecx
-       jg      L(mm_len_64_or_more_backward)
+       ja      L(mm_len_64_or_more_backward)
 
 /* Copy [0..64] and return.  */
        movdqu  (%eax), %xmm0
@@ -107,7 +107,7 @@ L(mm_len_32_or_more_backward):
 
 L(mm_len_64_or_more_backward):
        cmpl    $128, %ecx
-       jg      L(mm_len_128_or_more_backward)
+       ja      L(mm_len_128_or_more_backward)
 
 /* Copy [0..128] and return.  */
        movdqu  (%eax), %xmm0
@@ -132,7 +132,7 @@ L(mm_len_128_or_more_backward):
        add     %ecx, %eax
        cmp     %edx, %eax
        movl    SRC(%esp), %eax
-       jle     L(forward)
+       jbe     L(forward)
        PUSH (%esi)
        PUSH (%edi)
        PUSH (%ebx)
@@ -269,7 +269,7 @@ L(check_forward):
        add     %edx, %ecx
        cmp     %eax, %ecx
        movl    LEN(%esp), %ecx
-       jle     L(forward)
+       jbe     L(forward)
 
 /* Now do checks for lengths. We do [0..16], [0..32], [0..64], [0..128]
        separately.  */