]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix x86 strncat optimized implementation for large sizes
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Tue, 3 Jan 2017 14:19:12 +0000 (12:19 -0200)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Tue, 3 Jan 2017 16:24:53 +0000 (14:24 -0200)
Similar to BZ#19387, BZ#21014, and BZ#20971, both x86 sse2 strncat
optimized assembly implementations do not handle the size overflow
correctly.

The x86_64 one is in fact an issue with strcpy-sse2-unaligned, but
that is triggered also with strncat optimized implementation.

This patch uses a similar strategy used on 3daef2c8ee4df2, where
saturared math is used for overflow case.

Checked on x86_64-linux-gnu and i686-linux-gnu.  It fixes BZ #19390.

[BZ #19390]
* string/test-strncat.c (test_main): Add tests with SIZE_MAX as
maximum string size.
* sysdeps/i386/i686/multiarch/strcat-sse2.S (STRCAT): Avoid overflow
in pointer addition.
* sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S (STRCPY):
Likewise.

ChangeLog
string/test-strncat.c
sysdeps/i386/i686/multiarch/strcat-sse2.S
sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S

index 8af3a199519fa2af26bdb48d639a12edc5dfa331..1bb6eaa5367b33f391789e683a1d8af3e1425095 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2017-01-03  Adhemerval Zanella  <adhemerval.zanella@linaro.org>
+
+       [BZ #19390]
+       * string/test-strncat.c (test_main): Add tests with SIZE_MAX as
+       maximum string size.
+       * sysdeps/i386/i686/multiarch/strcat-sse2.S (STRCAT): Avoid overflow
+       in pointer addition.
+       * sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S (STRCPY):
+       Likewise.
+
 2017-01-03  Joseph Myers  <joseph@codesourcery.com>
 
        * elf/Makefile ($(objpfx)tst-ldconfig-X.out): Correct arguments
index 55d6cc57628216984fea3003aeb6fe30afb2eeff..26a6b5b91dfe68fbd96d91a606788d7705a4758b 100644 (file)
@@ -284,12 +284,23 @@ test_main (void)
       do_test (0, 0, 8, 8, n, SMALL_CHAR);
       do_test (0, 8, 8, 8, n, SMALL_CHAR);
 
+      do_test (0, 2, 2, 2, SIZE_MAX, SMALL_CHAR);
+      do_test (0, 0, 4, 4, SIZE_MAX, SMALL_CHAR);
+      do_test (4, 0, 4, 4, SIZE_MAX, BIG_CHAR);
+      do_test (0, 0, 8, 8, SIZE_MAX, SMALL_CHAR);
+      do_test (0, 8, 8, 8, SIZE_MAX, SMALL_CHAR);
+
       for (i = 1; i < 8; ++i)
        {
          do_test (0, 0, 8 << i, 8 << i, n, SMALL_CHAR);
          do_test (8 - i, 2 * i, 8 << i, 8 << i, n, SMALL_CHAR);
          do_test (0, 0, 8 << i, 2 << i, n, SMALL_CHAR);
          do_test (8 - i, 2 * i, 8 << i, 2 << i, n, SMALL_CHAR);
+
+         do_test (0, 0, 8 << i, 8 << i, SIZE_MAX, SMALL_CHAR);
+         do_test (8 - i, 2 * i, 8 << i, 8 << i, SIZE_MAX, SMALL_CHAR);
+         do_test (0, 0, 8 << i, 2 << i, SIZE_MAX, SMALL_CHAR);
+         do_test (8 - i, 2 * i, 8 << i, 2 << i, SIZE_MAX, SMALL_CHAR);
        }
 
       for (i = 1; i < 8; ++i)
@@ -297,6 +308,10 @@ test_main (void)
          do_test (i, 2 * i, 8 << i, 1, n, SMALL_CHAR);
          do_test (2 * i, i, 8 << i, 1, n, BIG_CHAR);
          do_test (i, i, 8 << i, 10, n, SMALL_CHAR);
+
+         do_test (i, 2 * i, 8 << i, 1, SIZE_MAX, SMALL_CHAR);
+         do_test (2 * i, i, 8 << i, 1, SIZE_MAX, BIG_CHAR);
+         do_test (i, i, 8 << i, 10, SIZE_MAX, SMALL_CHAR);
        }
     }
 
index 145ae66894cab8721f5ad3328d183d3660067477..6359c7330c282f8bb4011a5b5905de9bf1bc22aa 100644 (file)
@@ -227,6 +227,8 @@ L(StartStrcpyPart):
        pxor    %xmm0, %xmm0
 # ifdef USE_AS_STRNCAT
        add     %ecx, %ebx
+       sbb     %edx, %edx
+       or      %edx, %ebx
 # endif
        sub     %ecx, %eax
        jmp     L(Unalign16Both)
index c038043693b19292a9debd95d868085758eb16f3..6a5ab7ab26c63f0dff8eb3bc04b603b4afac2a06 100644 (file)
@@ -99,6 +99,8 @@ L(Unalign16Both):
        sub     %rcx, %rdi
 # ifdef USE_AS_STRNCPY
        add     %rcx, %r8
+       sbb     %rcx, %rcx
+       or      %rcx, %r8
 # endif
        mov     $16, %rcx
        movdqa  (%rsi, %rcx), %xmm1