Bug 651638 - Bad x86-64 strncasecmp on Intel Core i7
Summary: Bad x86-64 strncasecmp on Intel Core i7
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Fedora
Classification: Fedora
Component: glibc
Version: 14
Hardware: x86_64
OS: Linux
low
high
Target Milestone: ---
Assignee: Andreas Schwab
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2010-11-09 23:47 UTC by H.J. Lu
Modified: 2016-11-24 16:03 UTC (History)
9 users (show)

See Also:
Fixed In Version: glibc-2.12.90-19
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2010-11-19 00:06:09 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)
A patch (2.60 KB, patch)
2010-11-10 03:30 UTC, H.J. Lu
no flags Details | Diff

Description H.J. Lu 2010-11-09 23:47:33 UTC
(gdb) p cp + 1
$78 = 0x749ffa "gottpoff"
(gdb) p gotrel[j].str
$79 = 0x505cbe "GOTPLT"
(gdb) p len
$80 = 6
(gdb) call strncasecmp (cp + 1, gotrel[j].str, gotrel[j].len)
$81 = 0
(gdb)

Comment 1 H.J. Lu 2010-11-09 23:52:08 UTC
(gdb) call __strncasecmp_ssse3 (cp + 1, gotrel[j].str, gotrel[j].len)
$82 = 4
(gdb) call __strncasecmp_sse2 (cp + 1, gotrel[j].str, gotrel[j].len)
$83 = 4
(gdb) call __strncasecmp_sse42 (cp + 1, gotrel[j].str, gotrel[j].len)
$84 = 0
(gdb)

Comment 2 H.J. Lu 2010-11-10 00:05:45 UTC
[hjl@gnu-35 junk-1]$ cat test.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static char cp [4096+16] __attribute__ ((aligned(4096)));
static char gotrel[4096] __attribute__ ((aligned(4096)));

int
main ()
{
  char *p = cp + 0xffa;
  char *g = gotrel + 0xcbe;
  strcpy (p, "gottpoff");
  strcpy (g, "GOTPLT");
  printf ("%p: %s\n", p, p);
  printf ("%p: %s\n", g, g);
  if (strncasecmp (p, g, 6) <= 0)
    abort ();
  return 0;
}
[hjl@gnu-35 junk-1]$ make
cc     test.c   -o test
./test
0x602ffa: gottpoff
0x604cbe: GOTPLT
make: *** [all] Aborted
[hjl@gnu-35 junk-1]$

Comment 3 H.J. Lu 2010-11-10 03:30:12 UTC
Created attachment 459306 [details]
A patch

Comment 4 H.J. Lu 2010-11-10 04:17:56 UTC
Please rebuild glibc on a machine without SSE4
support. My glibc build failed on Fedora 14/Intel
Core i7 :-(. That is how I noticed the problem.

Comment 5 H.J. Lu 2010-11-10 16:24:28 UTC
I uploaded the fixed glibc rpms at

http://www.kernel.org/pub/linux/libs/glibc/hjl/F14/

Comment 6 Nathan G. Grennan 2010-11-10 22:33:27 UTC
I can confirm that the test code crashes on an i7, but not on a Core2Quad. Both running Fedora 14 x86_64.

Comment 7 Simon 2010-11-11 09:51:41 UTC
Yep, broken on a Xeon E5620 (Westmere). I'll try the fixed RPMs.

Comment 8 Simon 2010-11-11 09:55:14 UTC
Confirmed fixed with glibc from http://www.kernel.org/pub/linux/libs/glibc/hjl/F14/ on a Xeon E5620.

Comment 9 Simon 2010-11-11 09:58:06 UTC
Will this be released as an F14 update RPM? (I really think it should!).

Comment 10 Simon 2010-11-11 13:19:18 UTC
I noticed with the update RPMs, that I still get valgrind warnings for:
==5702== Use of uninitialised value of size 8
==5702==    at 0x3000546094: __strcasecmp_l_ssse3 (in /lib64/libc-2.12.90.so)
==5702==    by 0x10D07D52: getanswer_r.clone.4 (in /lib64/libnss_dns-2.12.90.so)
==5702==    by 0x10D08F3B: __GI__nss_dns_gethostbyname3_r.clone.2 (in /lib64/libnss_dns-2.12.90.so)
==5702==    by 0x10D0A0CB: _nss_dns_gethostbyname_r (in /lib64/libnss_dns-2.12.90.so)
==5702==    by 0x30004FF44A: gethostbyname_r@@GLIBC_2.2.5 (in /lib64/libc-2.12.90.so)
==5702==    by 0x30004FEC62: gethostbyname (in /lib64/libc-2.12.90.so

I'm running on a SSE4_2-enabled CPU (GenuineIntel, Family 0x06, Model 0x2c), so how come it's not calling __strcasecmp_l_sse42?

Relatedly, http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86_64/multiarch/init-arch.c;h=15bc9046e3c73340a9f1c58dd6f098f83db6c273;hb=8ca52c6e3b2dc44a46c32d6a8e6a7f608915998f shows checks for various Intel CPUs, but no clause for extended_model 0x2c. Is this deliberate, or an omission?

Comment 11 H.J. Lu 2010-11-11 14:56:44 UTC
(In reply to comment #10)
> I noticed with the update RPMs, that I still get valgrind warnings for:
> ==5702== Use of uninitialised value of size 8
> ==5702==    at 0x3000546094: __strcasecmp_l_ssse3 (in /lib64/libc-2.12.90.so)
> ==5702==    by 0x10D07D52: getanswer_r.clone.4 (in
> /lib64/libnss_dns-2.12.90.so)
> ==5702==    by 0x10D08F3B: __GI__nss_dns_gethostbyname3_r.clone.2 (in
> /lib64/libnss_dns-2.12.90.so)
> ==5702==    by 0x10D0A0CB: _nss_dns_gethostbyname_r (in
> /lib64/libnss_dns-2.12.90.so)
> ==5702==    by 0x30004FF44A: gethostbyname_r@@GLIBC_2.2.5 (in
> /lib64/libc-2.12.90.so)
> ==5702==    by 0x30004FEC62: gethostbyname (in /lib64/libc-2.12.90.so
> I'm running on a SSE4_2-enabled CPU (GenuineIntel, Family 0x06, Model 0x2c), so
> how come it's not calling __strcasecmp_l_sse42?
> 
> Relatedly,
> http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86_64/multiarch/init-arch.c;h=15bc9046e3c73340a9f1c58dd6f098f83db6c273;hb=8ca52c6e3b2dc44a46c32d6a8e6a7f608915998f
> shows checks for various Intel CPUs, but no clause for extended_model 0x2c. Is
> this deliberate, or an omission?

Please show

# head -30 /proc/cpuinfo

Comment 12 Simon 2010-11-11 15:37:38 UTC
[sah29@barbican ~]$ head -30 /proc/cpuinfo 
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 44
model name      : Intel(R) Xeon(R) CPU           E5620  @ 2.40GHz
stepping        : 2
cpu MHz         : 1596.000
cache size      : 12288 KB
physical id     : 1
siblings        : 8
core id         : 0
cpu cores       : 4
apicid          : 32
initial apicid  : 32
fpu             : yes
fpu_exception   : yes
cpuid level     : 11
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm dca sse4_1 sse4_2 popcnt aes lahf_lm ida arat tpr_shadow vnmi flexpriority ept vpid
bogomips        : 4788.16
clflush size    : 64
cache_alignment : 64
address sizes   : 40 bits physical, 48 bits virtual
power management:

processor       : 1
vendor_id       : GenuineIntel
cpu family      : 6
model           : 44
model name      : Intel(R) Xeon(R) CPU           E5620  @ 2.40GHz

Comment 13 H.J. Lu 2010-11-11 15:41:47 UTC
(In reply to comment #10)
> I noticed with the update RPMs, that I still get valgrind warnings for:
> ==5702== Use of uninitialised value of size 8
> ==5702==    at 0x3000546094: __strcasecmp_l_ssse3 (in /lib64/libc-2.12.90.so)
> ==5702==    by 0x10D07D52: getanswer_r.clone.4 (in
> /lib64/libnss_dns-2.12.90.so)
> ==5702==    by 0x10D08F3B: __GI__nss_dns_gethostbyname3_r.clone.2 (in
> /lib64/libnss_dns-2.12.90.so)
> ==5702==    by 0x10D0A0CB: _nss_dns_gethostbyname_r (in
> /lib64/libnss_dns-2.12.90.so)
> ==5702==    by 0x30004FF44A: gethostbyname_r@@GLIBC_2.2.5 (in
> /lib64/libc-2.12.90.so)
> ==5702==    by 0x30004FEC62: gethostbyname (in /lib64/libc-2.12.90.so
> 
> I'm running on a SSE4_2-enabled CPU (GenuineIntel, Family 0x06, Model 0x2c), so
> how come it's not calling __strcasecmp_l_sse42?
> 

It shouldn't happen. How can I reproduce it?

Comment 14 Simon 2010-11-11 16:00:10 UTC
To confirm I'm running the right glibc:
[sah29@barbican ~]$ rpm -qi glibc:
Name        : glibc                        Relocations: (not relocatable)
Version     : 2.12.90                           Vendor: (none)
Release     : 18.0.f14                      Build Date: Wed 10 Nov 2010 04:48:20 GMT
Install Date: Thu 11 Nov 2010 09:54:02 GMT      Build Host: gnu-33.sc.intel.com
Group       : System Environment/Libraries   Source RPM: glibc-2.12.90-18.0.f14.src.rpm
Size        : 13311178                         License: LGPLv2+ and LGPLv2+ with exceptions and GPLv2+

[sah29@barbican ~]$ cat>strcasecmp.c<<EOF
> #include <stdio.h>
> #include <strings.h>
> int main(int argc, char *argv[])
> {
>   char s1[2], s2[2];
>   s1[1] = s2[1] = '\0';
>   printf(strcasecmp(s1,s2) < 0? "yes\n" : "no\n");
>   return 0;
> }
> EOF

[sah29@barbican ~]$ gcc -O3 strcasecmp.c
[sah29@barbican ~]$ valgrind ./a.out 
==27289== Memcheck, a memory error detector
==27289== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==27289== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==27289== Command: ./a.out
==27289== 
==27289== Conditional jump or move depends on uninitialised value(s)
==27289==    at 0x300054404B: __strcasecmp_l_ssse3 (in /lib64/libc-2.12.90.so)
==27289==    by 0x40053A: main (in /home/sah29/a.out)
==27289==

Comment 15 Simon 2010-11-11 16:01:06 UTC
Without the bash prompts:
#include <stdio.h>
#include <strings.h>
int main(int argc, char *argv[])
{
  char s1[2], s2[2];
  s1[1] = s2[1] = '\0';
  printf(strcasecmp(s1,s2) < 0? "yes\n" : "no\n");
  return 0;
}

Comment 16 Simon 2010-11-11 16:05:42 UTC
Or if you prefer a gethostname example:
#include <stdio.h>
#include <netdb.h>
int main(int argc, char *argv[])
{
  struct hostent *hent = 0;
  hent = gethostbyname("www.redhat.com");
  if (hent) {
    printf("h_name = %s\n",hent->h_name);
  }
  return 0;
}

Output:
[sah29@barbican ~]$ valgrind ./a.out 
==27398== Memcheck, a memory error detector
==27398== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==27398== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==27398== Command: ./a.out
==27398== 
==27398== Conditional jump or move depends on uninitialised value(s)
==27398==    at 0x30005461B1: __strncasecmp_l_ssse3 (in /lib64/libc-2.12.90.so)
==27398==    by 0x30004F6832: do_init (in /lib64/libc-2.12.90.so)
==27398==    by 0x30004F71A4: _res_hconf_init (in /lib64/libc-2.12.90.so)
==27398==    by 0x30004FF634: gethostbyname_r@@GLIBC_2.2.5 (in /lib64/libc-2.12.90.so)
==27398==    by 0x30004FEC62: gethostbyname (in /lib64/libc-2.12.90.so)
==27398==    by 0x40052D: main (in /home/sah29/a.out)

Comment 17 H.J. Lu 2010-11-11 16:32:36 UTC
(In reply to comment #14)
> To confirm I'm running the right glibc:
> [sah29@barbican ~]$ rpm -qi glibc:
> Name        : glibc                        Relocations: (not relocatable)
> Version     : 2.12.90                           Vendor: (none)
> Release     : 18.0.f14                      Build Date: Wed 10 Nov 2010
> 04:48:20 GMT
> Install Date: Thu 11 Nov 2010 09:54:02 GMT      Build Host: gnu-33.sc.intel.com
> Group       : System Environment/Libraries   Source RPM:
> glibc-2.12.90-18.0.f14.src.rpm
> Size        : 13311178                         License: LGPLv2+ and LGPLv2+
> with exceptions and GPLv2+
> 
> [sah29@barbican ~]$ cat>strcasecmp.c<<EOF
> > #include <stdio.h>
> > #include <strings.h>
> > int main(int argc, char *argv[])
> > {
> >   char s1[2], s2[2];
> >   s1[1] = s2[1] = '\0';
> >   printf(strcasecmp(s1,s2) < 0? "yes\n" : "no\n");
> >   return 0;
> > }
> > EOF
> 
> [sah29@barbican ~]$ gcc -O3 strcasecmp.c
> [sah29@barbican ~]$ valgrind ./a.out 
> ==27289== Memcheck, a memory error detector
> ==27289== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
> ==27289== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
> ==27289== Command: ./a.out
> ==27289== 
> ==27289== Conditional jump or move depends on uninitialised value(s)
> ==27289==    at 0x300054404B: __strcasecmp_l_ssse3 (in /lib64/libc-2.12.90.so)
> ==27289==    by 0x40053A: main (in /home/sah29/a.out)
> ==27289==

This is a valgrind bug. I got

[hjl@gnu-35 tmp]$ cat x.c
#include <stdio.h>
#include <strings.h>
int main(int argc, char *argv[])
{
  char s1[2], s2[2];
  s1[1] = s2[1] = '\0';
  printf(strcasecmp(s1,s2) < 0? "yes\n" : "no\n");
  return 0;
}
[hjl@gnu-35 tmp]$ gcc -O3 x.c
[hjl@gnu-35 tmp]$ valgrind ./a.out
==5304== Memcheck, a memory error detector
==5304== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==5304== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==5304== Command: ./a.out
==5304== 
==5304== Conditional jump or move depends on uninitialised value(s)
==5304==    at 0x3EC814404B: __strcasecmp_l_ssse3 (in /lib64/libc-2.12.90.so)
==5304==    by 0x40053A: main (in /tmp/a.out)
==5304== 
...
[hjl@gnu-35 tmp]$ gdb a.out 
GNU gdb (GDB) Fedora (7.2-23.fc14)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /tmp/a.out...(no debugging symbols found)...done.
(gdb) b __strcasecmp_l_ssse3
Function "__strcasecmp_l_ssse3" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 1 (__strcasecmp_l_ssse3) pending.
(gdb) r
Starting program: /tmp/a.out 
no

Program exited normally.
Missing separate debuginfos, use: debuginfo-install glibc-2.12.90-18.0.f14.x86_64
(gdb) b __strcasecmp_l_sse42
Breakpoint 2 at 0x3ec8125eb0
(gdb) r
Starting program: /tmp/a.out 

Breakpoint 2, 0x0000003ec8125eb0 in __strcasecmp_l_sse42 ()
   from /lib64/libc.so.6
(gdb) bt
#0  0x0000003ec8125eb0 in __strcasecmp_l_sse42 () from /lib64/libc.so.6
#1  0x000000000040053b in main ()
(gdb)

Comment 18 Simon 2010-11-11 17:13:28 UTC
My apologies. Looks like a valgrind deficiency that has been fixed with the latest 3.6.0 (Oct 2010) release: http://valgrind.org/docs/manual/dist.news.html.

I'll with 3.6.0...

Comment 19 Fedora Update System 2010-11-12 13:23:49 UTC
glibc-2.12.90-19 has been submitted as an update for Fedora 14.
https://admin.fedoraproject.org/updates/glibc-2.12.90-19

Comment 20 Fedora Update System 2010-11-13 22:06:06 UTC
glibc-2.12.90-19 has been pushed to the Fedora 14 testing repository.  If problems still persist, please make note of it in this bug report.
 If you want to test the update, you can install it with 
 su -c 'yum --enablerepo=updates-testing update glibc'.  You can provide feedback for this update here: https://admin.fedoraproject.org/updates/glibc-2.12.90-19

Comment 21 Anthony Name 2010-11-15 12:55:54 UTC
I posted bug 652338 which was where I was getting ejected from X sessions within 90 seconds of logging on and was getting reset back to the logon page.

I have tried glibc-2.12.90-19 and it has NOT fixed my problem.

If you want any specific data please let me know, chip concerned is a Xeon X3440 QuadCore I7.

Regards

Comment 22 Fedora Update System 2010-11-19 00:05:56 UTC
glibc-2.12.90-19 has been pushed to the Fedora 14 stable repository.  If problems still persist, please make note of it in this bug report.


Note You need to log in before you can comment on or make changes to this bug.