Project

General

Profile

Bug #3285

memory leaks in libsldap

Added by Hans Rosenfeld about 8 years ago. Updated about 8 years ago.

Status:
Resolved
Priority:
Normal
Category:
lib - userland libraries
Start date:
2012-10-17
Due date:
% Done:

100%

Estimated time:
Difficulty:
Medium
Tags:
needs-triage
Gerrit CR:

Description

'ldap_cachemgr' can allocate whole memory if LDAP server is not available. This can be reproduced with this configuration:

# ldapclient list
NS_LDAP_FILE_VERSION= 2.0
NS_LDAP_BINDDN= cn=root,dc=ourdomain,dc=com
NS_LDAP_BINDPASSWD= {NS1}xxxxxxxxxxx
NS_LDAP_SERVERS= 10.28.73.199
NS_LDAP_SEARCH_BASEDN= dc=ourdomain,dc=com
NS_LDAP_AUTH= simple
NS_LDAP_SEARCH_REF= FALSE
NS_LDAP_CACHETTL= 0
NS_LDAP_CREDENTIAL_LEVEL= proxy anonymous
NS_LDAP_SERVICE_SEARCH_DESC= passwd:ou=users, dc=ourdomain,dc=com
NS_LDAP_SERVICE_SEARCH_DESC= group:cn=groups, dc=ourdomain,dc=com
NS_LDAP_SERVICE_SEARCH_DESC= netgroup:cn=netgroup, dc=ourdomain,dc=com

The first set of leaks is related to having several credential levels. This can be observed with ::findleaks in mdb:

# mdb -p 7888
Loading modules: [ ld.so.1 libumem.so.1 libc.so.1 libuutil.so.1 libnvpair.so.1 ]
> ::find
findleaks
findstack
> ::findleaks -vd
findleaks:                maximum buffers => 448
findleaks:                 actual buffers => 349
findleaks: 
findleaks:             potential pointers => 179760
findleaks:                     dismissals => 147542        (82.0%)
findleaks:                         misses => 26756         (14.8%)
findleaks:                           dups => 5131          ( 2.8%)
findleaks:                        follows => 331           ( 0.1%)
findleaks: 
findleaks:              peak memory usage => 62 kB
findleaks:               elapsed CPU time => 0.0 seconds
findleaks:              elapsed wall time => 0.0 seconds
findleaks: 
BYTES             LEAKED VMEM_SEG CALLER
24576                  2 fe68d000 MMAP
4096                   1 fec12000 MMAP
------------------------------------------------------------------------
           Total       2 oversized leaks, 28672 bytes

CACHE     LEAKED   BUFCTL CALLER
0808b810       8 080bdeb8 libc_hwcap1.so.1`strdup+0x26
08088c10       8 080969a0 libsldap.so.1`doSimpleBind+0x2d3
------------------------------------------------------------------------
   Total      16 buffers, 832 bytes

mmap(2) leak: [fe68d000, fe693000), 24576 bytes
mmap(2) leak: [fec12000, fec13000), 4096 bytes
umem_alloc_80 leak: 8 buffers, 80 bytes each, 640 bytes total
            ADDR          BUFADDR        TIMESTAMP           THREAD
                            CACHE          LASTLOG         CONTENTS
         80bdeb8          80baf08      55e582aa9fa                7
                          808b810          8080384                0
                 libumem.so.1`umem_cache_alloc_debug+0x144
                 libumem.so.1`umem_cache_alloc+0x153
                 libumem.so.1`umem_alloc+0xcd
                 libumem.so.1`malloc+0x2a
                 libc_hwcap1.so.1`strdup+0x26
                 libsldap.so.1`doSimpleBind+0x2ee
                 libsldap.so.1`performBind+0x63
                 libsldap.so.1`openConnection+0x27d
                 libsldap.so.1`makeConnection+0x6a0
                 libsldap.so.1`getConnection+0x4c3
                 libsldap.so.1`__s_api_getConnection+0x34
                 libsldap.so.1`__ns_ldap_getRootDSE+0xcc
                 getldap_get_rootDSE+0xe8
                 libc_hwcap1.so.1`_thrp_setup+0x9b
                 libc_hwcap1.so.1`_lwp_start

umem_alloc_24 leak: 8 buffers, 24 bytes each, 192 bytes total
            ADDR          BUFADDR        TIMESTAMP           THREAD
                            CACHE          LASTLOG         CONTENTS                                      
         80969a0          80bebc0      55e582aa699                7
                          8088c10          8080320                0
                 libumem.so.1`umem_cache_alloc_debug+0x144
                 libumem.so.1`umem_cache_alloc+0x153
                 libumem.so.1`umem_alloc+0xcd
                 libumem.so.1`malloc+0x2a
                 libumem.so.1`calloc+0x4a
                 libsldap.so.1`doSimpleBind+0x2d3
                 libsldap.so.1`performBind+0x63
                 libsldap.so.1`openConnection+0x27d
                 libsldap.so.1`makeConnection+0x6a0
                 libsldap.so.1`getConnection+0x4c3
                 libsldap.so.1`__s_api_getConnection+0x34
                 libsldap.so.1`__ns_ldap_getRootDSE+0xcc
                 getldap_get_rootDSE+0xe8
                 libc_hwcap1.so.1`_thrp_setup+0x9b
                 libc_hwcap1.so.1`_lwp_start

getConnection() will call makeConnection() repeatedly, trying the different credential levels and bindings etc until one call finally succeeds. Each failing call to makeConnection() allocates an error structure (MKERROR), which is then leaked when *errorp is overwritten in the next call to makeConnection(). By calling __ns_ldap_freeError() in makeConnection() instead of just setting *errorp=NULL the leaks can be avoided.

The second leak was harder to find. On success, makeConnection() creates a connection structure and adds it to some cache by calling addConnection(). Normally this stuff is freed by calling DropConnection() in __ns_ldap_getRootDSE() before the connection thread exits. This call to DropConnection() is missing in the error path for ldap_search_ext_s() in __ns_ldap_getRootDSE().

This means that if makeConnection() succeeds (like it seems to do without actually connecting to any server in the case of an anonymous LDAP bind), but actually talking to the LDAP server fails, the connection information structure remains in the cache forever. This also means that a reference to that information is kept and ::findleaks can't find the leak.

History

#1

Updated by Hans Rosenfeld about 8 years ago

webrev: http://grumpf.hope-2000.org/illumos-3285-webrev/

While at it I also added a few newlines to a bunch of debugging printfs that needed them.

#2

Updated by Rich Lowe about 8 years ago

  • Status changed from New to Resolved

Resolved in b3b48d8

Also available in: Atom PDF