Bug 816244 - tsearch conditional jump or move depends on uninitialized value
tsearch conditional jump or move depends on uninitialized value
Status: CLOSED ERRATA
Product: Red Hat Enterprise Linux 6
Classification: Red Hat
Component: valgrind (Show other bugs)
6.3
s390x Unspecified
medium Severity medium
: rc
: ---
Assigned To: Mark Wielaard
qe-baseos-tools
:
: 750272 (view as bug list)
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2012-04-25 11:39 EDT by Jeff Law
Modified: 2013-02-21 03:50 EST (History)
9 users (show)

See Also:
Fixed In Version: 3.8.1-3.1.el6
Doc Type: Bug Fix
Doc Text:
On s390 valgrind could report an "Conditional jump or move depends on uninitialised value(s)" warning for the tsearch function in glibc. This version includes a standard suppression for this warning so it is no longer reported.
Story Points: ---
Clone Of: 816168
Environment:
Last Closed: 2013-02-21 03:50:58 EST
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)


External Trackers
Tracker ID Priority Status Summary Last Updated
KDE Software Compilation 308427 None None None 2012-10-15 08:05:16 EDT

  None (edit)
Description Jeff Law 2012-04-25 11:39:43 EDT
+++ This bug was initially created as a clone of Bug #816168 +++

This bug tracking the conditional jump or move depends on uninitialized value issue.


Created attachment 580143 [details]
reproduce test

Description of problem:
glibc leak memory when following openldap referrals on s390x.
I consult this problem with jvcelak and he think that problem is in glibc.

Actual output of relevant part reproduce test:
==5511== Memcheck, a memory error detector
==5511== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==5511== Using Valgrind-3.6.0 and LibVEX; rerun with -h for copyright info
==5511== Command: ldapsearch -x -b dc=redhat -C
==5511==
==5511== Conditional jump or move depends on uninitialised value(s)
==5511==    at 0x4466B9C: tsearch (tsearch.c:177)
==5511==    by 0x448105F: __nss_lookup_function (nsswitch.c:301)
==5511==    by 0x444CB8B: gaih_inet (getaddrinfo.c:829)
==5511==    by 0x4450359: getaddrinfo (getaddrinfo.c:2358)
==5511==    by 0x40694DB: ldap_connect_to_host (os-ip.c:600)
==5511==    by 0x4050F33: ldap_int_open_connection (open.c:348)
==5511==    by 0x406682D: ldap_new_connection (request.c:425)
==5511==    by 0x4050E65: ldap_open_defconn (open.c:41)
==5511==    by 0x40677E5: ldap_send_initial_request (request.c:106)
==5511==    by 0x405BD87: ldap_sasl_bind (sasl.c:148)
==5511==    by 0x8000B571: tool_bind (common.c:1439)
==5511==    by 0x80007D2B: main (ldapsearch.c:902)
==5511==
# extended LDIF
#
# LDAPv3
# base <dc=redhat> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# redhat
dn: dc=redhat
objectClass: dcObject
objectClass: organization
o: Red Hat
dc: redhat

# Manager, redhat
dn: cn=Manager,dc=redhat
objectClass: organizationalRole
cn: Manager

# foo, redhat
dn: cn=foo,dc=redhat
objectClass: organizationalRole
cn: foo

# search reference
ref: ldap://localhost/dc=fedora??sub

# fedora
dn: dc=fedora
objectClass: dcObject
objectClass: organization
o: Fedora
dc: fedora

# Manager, fedora
dn: cn=Manager,dc=fedora
objectClass: organizationalRole
cn: Manager

# bar, fedora
dn: cn=bar,dc=fedora
objectClass: organizationalRole
cn: bar

# search result
search: 2
result: 0 Success

# numResponses: 8
# numEntries: 6
# numReferences: 1
==5511==
==5511== HEAP SUMMARY:
==5511==     in use at exit: 14 bytes in 1 blocks
==5511==   total heap usage: 249 allocs, 248 frees, 72,117 bytes allocated
==5511==
==5511== 14 bytes in 1 blocks are still reachable in loss record 1 of 1
==5511==    at 0x402C3CC: malloc (vg_replace_malloc.c:236)
==5511==    by 0x80007AC5: main (ldapsearch.c:814)
==5511==
==5511== LEAK SUMMARY:
==5511==    definitely lost: 0 bytes in 0 blocks
==5511==    indirectly lost: 0 bytes in 0 blocks
==5511==      possibly lost: 0 bytes in 0 blocks
==5511==    still reachable: 14 bytes in 1 blocks
==5511==         suppressed: 0 bytes in 0 blocks
==5511==
==5511== For counts of detected and suppressed errors, rerun with: -v
==5511== Use --track-origins=yes to see where uninitialised values come from
==5511== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)
:: [   PASS   ] :: Running 'valgrind --leak-check=full --show-reachable=yes ldapsearch -x -b "dc=redhat" -C 2>&1'

Version-Release number of selected component (if applicable):
glibc-2.12-1.80.el6.s390x

How reproducible:
always

Steps to Reproduce:
1. you can install debuginfo-install openldap if you want
2. run runtest.sh from attachement
  
Actual results:
At valgrind output
still reachable: 14 bytes in 1 blocks

Expected results:
no leak

--- Additional comment from jvcelak@redhat.com on 2012-04-25 10:23:34 EDT ---

It seems that the leak presents even without following the referral.

Btw, getaddrinfo() has matching freeaddrinfo().

--- Additional comment from law@redhat.com on 2012-04-25 11:38:40 EDT ---

The memory leak is in ldap itself.  If you look at the valgrind summary information it tells you where the memory was allocated:

==5511== 14 bytes in 1 blocks are still reachable in loss record 1 of 1
==5511==    at 0x402C3CC: malloc (vg_replace_malloc.c:236)
==5511==    by 0x80007AC5: main (ldapsearch.c:814)

If we look at ldapsearch.c from openldap-2.4.23 (rhel 6.3) we find the following at line 814:

        def_urlpre = malloc( sizeof("file:////") + strlen(def_tmpdir) );

And if you read the code, def_urlpre is never free'd.


There is an issue here that needs further investigation, specifically the valgrind warning:

==5511== Conditional jump or move depends on uninitialised value(s)

This could be a problem in glibc, openldap or even a false positive. 

I'm going to reassign the memory leak back to openldap since it's clearly an openldap issue.  I'm going to create a clone to track the jump/move depends on uninitialized value problem which I'll assign to glibc for further analysis.
Comment 2 Jeff Law 2012-04-25 11:52:49 EDT
This might be a false positive:

http://0-code.google.com.library.metmuseum.org/p/drmemory/issues/detail?id=162
Comment 3 Jeff Law 2012-04-25 16:22:45 EDT
I've double checked and indeed this is a false positive.  

The line in question:


Breakpoint 8, maybe_split_for_insert (key=0x3ffffb02f80, 
    vrootp=<value optimized out>, compar=0x4b664b5518 <known_compare>)
    at tsearch.c:177
177           if (parentp != NULL && (*parentp)->red)

(gdb) ptype *parentp
type = struct node_t {
    const void *key;
    struct node_t *left;
    struct node_t *right;
    unsigned int red : 1;
} *

On the s390x (and possibly other architectures), we load (*parentp)->red as a word, then test the word is zero/nonzero.

The memory is set here:

281       q = (struct node_t *) malloc (sizeof (struct node_t));
282       if (q != NULL)
283         {
284           *nextp = q;                       /* link new node to old */
285           q->key = key;                     /* initialize new node */
286           q->red = 1;
287           q->left = q->right = NULL;
=> 0x4b6649ab5e <__tsearch+430>:        oi      24(%r2),128

Valgrind (quite reasonably) still considers the memory at this location undefined as this instruction just sets a single bit at the memory location.  Thus when we load & test the full word later valgrind complains.

In an ideal world, valgrind would suppress this error.  Reassigning to valgrind so that its suppressions can be updated.
Comment 4 RHEL Product and Program Management 2012-05-03 00:56:00 EDT
Since RHEL 6.3 External Beta has begun, and this bug remains
unresolved, it has been rejected as it is not proposed as
exception or blocker.

Red Hat invites you to ask your support representative to
propose this request, if appropriate and relevant, in the
next release of Red Hat Enterprise Linux.
Comment 6 Jeff Law 2012-07-25 02:08:02 EDT
*** Bug 750272 has been marked as a duplicate of this bug. ***
Comment 8 Mark Wielaard 2012-09-24 04:13:29 EDT
How does one setup ldapsearch so that one can run this testcase?
Is this s390 specific or does it also happen on other arches?
Comment 9 Jeff Law 2012-09-24 08:57:59 EDT
I don't really recall how much about this other than it is definitely specific so s390[x].  

You might look at c#2 for bz 750272 as that might be a reasonable testcase.  Clearly I was able to trigger based on c#3 of this BZ.  I don't recall doing anything particularly special.

Jeff
Comment 10 Mark Wielaard 2012-09-25 15:38:29 EDT
OK, the simple replicator is just:
$ valgrind netstat

On s390x That will generate:

==44073== Conditional jump or move depends on uninitialised value(s)
==44073==    at 0x4935F12B9C: tsearch (in /lib64/libc-2.12.so)

Also with valgrind-3.8.1-2.1.el6.s390x

It doesn't happen on x86_64.
Comment 11 Mark Wielaard 2012-09-26 12:46:59 EDT
So adding the following suppression would work around it:

{
   s390x-tsearch-node_t-red
   Memcheck:Cond
   fun:tsearch
   obj:/lib64/libc-2.12.so
}

As a workaround just put that in a file called s390-tsearch.supp and run:

$ valgrind --suppressions=s390-tsearch.supp netstat

And there will be no more warnings.
Comment 12 Mark Wielaard 2012-09-26 12:48:25 EDT
Just for the record, this is the assembly for the test that triggers the warning:

174	
175	      /* If the parent of this node is also red, we have to do
176		 rotations.  */
177	      if (parentp != NULL && (*parentp)->red)
   0x0000004935f12a64 <+180>:	ltgr	%r8,%r8
   0x0000004935f12a68 <+184>:	je	0x4935f12af4 <__tsearch+324>
   0x0000004935f12a6c <+188>:	lg	%r2,0(%r8)
   0x0000004935f12a72 <+194>:	ltg	%r3,24(%r2)
   0x0000004935f12a78 <+200>:	jhe	0x4935f12af4 <__tsearch+324>
   0x0000004935f12b90 <+480>:	lg	%r3,0(%r10)
   0x0000004935f12b96 <+486>:	ltg	%r4,24(%r3)
=> 0x0000004935f12b9c <+492>:	jhe	0x4935f12c08 <__tsearch+600>

178		{


And this is the node_t initialization code:

281	  q = (struct node_t *) malloc (sizeof (struct node_t));
   0x0000004935f12b2a <+378>:	lghi	%r2,32
   0x0000004935f12b2e <+382>:	brasl	%r14,0x4935e28528 <malloc@plt>

282	  if (q != NULL)
   0x0000004935f12b34 <+388>:	ltgr	%r2,%r2
   0x0000004935f12b38 <+392>:	je	0x4935f12c08 <__tsearch+600>

283	    {
284	      *nextp = q;			/* link new node to old */
   0x0000004935f12b3c <+396>:	stg	%r2,0(%r11)

285	      q->key = key;			/* initialize new node */
   0x0000004935f12b42 <+402>:	lg	%r4,168(%r15)
   0x0000004935f12b48 <+408>:	stg	%r4,0(%r2)

286	      q->red = 1;
   0x0000004935f12b5e <+430>:	oi	24(%r2),128

287	      q->left = q->right = NULL;
   0x0000004935f12b4e <+414>:	lghi	%r5,0
   0x0000004935f12b52 <+418>:	stg	%r5,16(%r2)
   0x0000004935f12b58 <+424>:	stg	%r5,8(%r2)

288
Comment 16 errata-xmlrpc 2013-02-21 03:50:58 EST
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

http://rhn.redhat.com/errata/RHBA-2013-0347.html

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