+++ 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 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 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.
This might be a false positive: http://0-code.google.com.library.metmuseum.org/p/drmemory/issues/detail?id=162
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.
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.
*** Bug 750272 has been marked as a duplicate of this bug. ***
How does one setup ldapsearch so that one can run this testcase? Is this s390 specific or does it also happen on other arches?
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
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.
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.
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
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