Created attachment 7093 [details] patch for glibc/string/test-memcmp.c Hello, The bug occurrs when "memcmp(s1, s2, 72)" calls __memcmp_ssse3, and when (s1 + 72) coinsides with a page boundary. The instruction mov -9(%rdi), %eax in __memcmp_ssse3 () at ../sysdeps/x86_64/multiarch/memcmp-ssse3.S:1467 causes a segmentation fault. Example: the page is at the address range 0x2000 - 0x3000, s1=(0x3000 - 72), and the next page is mprotected with PROT_NONE. $rdi=0x3008, and the "mov" instruction tries to read 4 bytes starting at 0x3008-9, crossing the boundary. The test case fails for the number of array sizes (72 is just one of them). Other sizes are 48, 65-75, etc. The reported glibc version is 2.18, but the same issue occurs in 2.15. How to reproduce: (1) Modify glibc/string/test-memcmp.c (the patch is attached) (2) Run "env LANGUAGE=C LC_ALL=C make check" test-memcmp-ifunc will fail with segfault. In string/test-memcmp-ifunc.out: ..... check2: length=48, simple_memcmp check2: length=48, __memcmp_sse4_1 check2: length=48, __memcmp_ssse3 Thank you. Roni.
Google ref b/9530601
This patch fixes the issue. Tested on my machines. diff --git a/sysdeps/x86_64/multiarch/memcmp-ssse3.S b/sysdeps/x86_64/multiarch/memcmp-ssse3.S index bdd2ed2..e319df9 100644 --- a/sysdeps/x86_64/multiarch/memcmp-ssse3.S +++ b/sysdeps/x86_64/multiarch/memcmp-ssse3.S @@ -1463,10 +1463,8 @@ L(next_24_bytes): test $0x40, %dh jnz L(Byte22) - mov -9(%rdi), %eax - and $0xff, %eax - mov -9(%rsi), %edx - and $0xff, %edx + movzbl -9(%rdi), %eax + movzbl -9(%rsi), %edx sub %edx, %eax ret # else
On Tue, Jun 25, 2013 at 12:51:02PM +0000, liubov.dmitrieva at gmail dot com wrote: > http://sourceware.org/bugzilla/show_bug.cgi?id=15674 > > --- Comment #2 from Liubov Dmitrieva <liubov.dmitrieva at gmail dot com> --- > This patch fixes the issue. Tested on my machines. > > diff --git a/sysdeps/x86_64/multiarch/memcmp-ssse3.S > b/sysdeps/x86_64/multiarch/memcmp-ssse3.S > index bdd2ed2..e319df9 100644 > --- a/sysdeps/x86_64/multiarch/memcmp-ssse3.S > +++ b/sysdeps/x86_64/multiarch/memcmp-ssse3.S > @@ -1463,10 +1463,8 @@ L(next_24_bytes): > test $0x40, %dh > jnz L(Byte22) > > - mov -9(%rdi), %eax > - and $0xff, %eax > - mov -9(%rsi), %edx > - and $0xff, %edx > + movzbl -9(%rdi), %eax > + movzbl -9(%rsi), %edx > sub %edx, %eax > ret > # else > Could you send this to libc-alpha. Where was problem? This code looks at first glance equivalent.
(In reply to Ondrej Bilka from comment #3) > On Tue, Jun 25, 2013 at 12:51:02PM +0000, liubov.dmitrieva at gmail dot com > wrote: > > http://sourceware.org/bugzilla/show_bug.cgi?id=15674 > > > > --- Comment #2 from Liubov Dmitrieva <liubov.dmitrieva at gmail dot com> --- > > This patch fixes the issue. Tested on my machines. > > > > diff --git a/sysdeps/x86_64/multiarch/memcmp-ssse3.S > > b/sysdeps/x86_64/multiarch/memcmp-ssse3.S > > index bdd2ed2..e319df9 100644 > > --- a/sysdeps/x86_64/multiarch/memcmp-ssse3.S > > +++ b/sysdeps/x86_64/multiarch/memcmp-ssse3.S > > @@ -1463,10 +1463,8 @@ L(next_24_bytes): > > test $0x40, %dh > > jnz L(Byte22) > > > > - mov -9(%rdi), %eax > > - and $0xff, %eax > > - mov -9(%rsi), %edx > > - and $0xff, %edx > > + movzbl -9(%rdi), %eax > > + movzbl -9(%rsi), %edx > > sub %edx, %eax > > ret > > # else > > > Could you send this to libc-alpha. Where was problem? This code looks at > first > glance equivalent. Ok. I will send. Movzbl reads only one byte and doesn't cross the boundary. Mov reads 4 bytes. For MOVZBL, the low 8 bits of the destination are replaced by the source operand. the top 24 bits are set to 0. The source operand is unaffected.
I suggest you add a comment that you only do single byte reads to not cross page boundaries.
Fixed by http://sourceware.org/git/?p=glibc.git;a=commit;h=11b8a0e1d7b6175470ffc9077e94104c896093b7
Fixed.
Introduced in glibc 2.15, fixed in glibc 2.18.