Bug 651638 - Bad x86-64 strncasecmp on Intel Core i7
Bad x86-64 strncasecmp on Intel Core i7
Status: CLOSED ERRATA
Product: Fedora
Classification: Fedora
Component: glibc (Show other bugs)
14
x86_64 Linux
low Severity high
: ---
: ---
Assigned To: Andreas Schwab
Fedora Extras Quality Assurance
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2010-11-09 18:47 EST by H.J. Lu
Modified: 2010-11-18 19:06 EST (History)
8 users (show)

See Also:
Fixed In Version: glibc-2.12.90-19
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2010-11-18 19:06:09 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:


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

  None (edit)
Description H.J. Lu 2010-11-09 18:47:33 EST
(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 18:52:08 EST
(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-09 19:05:45 EST
[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-09 22:30:12 EST
Created attachment 459306 [details]
A patch
Comment 4 H.J. Lu 2010-11-09 23:17:56 EST
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 11:24:28 EST
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 17:33:27 EST
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 04:51:41 EST
Yep, broken on a Xeon E5620 (Westmere). I'll try the fixed RPMs.
Comment 8 Simon 2010-11-11 04:55:14 EST
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 04:58:06 EST
Will this be released as an F14 update RPM? (I really think it should!).
Comment 10 Simon 2010-11-11 08:19:18 EST
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 09:56:44 EST
(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 10:37:38 EST
[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 10:41:47 EST
(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 11:00:10 EST
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 11:01:06 EST
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 11:05:42 EST
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 11:32:36 EST
(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 12:13:28 EST
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 08:23:49 EST
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 17:06:06 EST
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 07:55:54 EST
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-18 19:05:56 EST
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.