[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
Re: (ITS#6018) TLS memory leak
I see at least two issues in your code. See below for specific comments.
ling qing wrote:
> The sample code is as follows.
> Make command:
> g++ testmem.C lib/libldap-2.4.so.2 lib/libsasl2.so.2 lib/liblber-2.4.so.2
> -Iinclude/ -Llib/ -DLDAP_DEPRECATED -g -lpthread
> If mode is normal, it's ok. If mode is TLS, there is memory leak even if you
> don't input bind dn. If mode is SSL, memory leak only happens when you input
> bind dn and password.
> The openLDAP lib is the latest release version 2.4.15.
>
> I am sure that this is a bug of openLDAP.
>
> #include "ldap.h"
> #include <string>
> #include <unistd.h>
>
> using namespace std;
>
> typedef enum LDAP_TRANS_METHOD {LDAP_TRANS_NORMAL, LDAP_TRANS_TLS,
> LDAP_TRANS_SSL};
>
> LDAP_TRANS_METHOD transMethod = LDAP_TRANS_NORMAL;
> const char * host = NULL;
> const char * binddn = NULL;
> const char * bindpwd = NULL;
> int connectnum = 0;
>
> void * connectLDAP(void * param)
> {
> LDAP * ld;
>
> int rc;
> string url;
> if( transMethod == LDAP_TRANS_SSL )
> url = "ldaps://";
> else
> url = "ldap://";
> if( host == NULL )
> return NULL;
> url.append(host);
>
> struct timeval tvout;
> tvout.tv_sec = 10;
> tvout.tv_usec = 0;
>
> if( ldap_set_option( NULL, LDAP_OPT_NETWORK_TIMEOUT, &tvout ) !=
> LDAP_OPT_SUCCESS )
> {
> printf("ldap_set_option LDAP_OPT_NETWORK_TIMEOUT failed\n");
> return NULL;
> }
>
> rc = ldap_initialize(&ld, url.c_str());
> if( rc != LDAP_SUCCESS || ld == NULL )
> {
> printf("ldap_initialize failed!\n");
> return NULL;
> }
>
> if( transMethod == LDAP_TRANS_TLS || transMethod == LDAP_TRANS_SSL )
> {
> int protocol = 3;
> if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &protocol ) !=
> LDAP_OPT_SUCCESS )
> {
> printf("ldap_set_option LDAP_OPT_PROTOCOL_VERSION failed\n");
> return NULL;
> }
> int cert = 0;
> if( ldap_set_option( NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &cert ) !=
> LDAP_OPT_SUCCESS )
You're not supposed to call ldap_set_option() with NULL handler from
within a threaded program, as libldap is thread-safe only when a
specific handler is only used from within a single thread. I'm not
discussing the case of this specific option, nor of its side-effects, if
any, as I didn't investigate it and I'm not specifically familiar with
that portion of code.
> {
> printf("ldap_set_option LDAP_OPT_X_TLS_REQUIRE_CERT failed\n");
> return NULL;
> }
> }
>
> if( transMethod == LDAP_TRANS_TLS )
> {
> rc = ldap_start_tls_s( ld, NULL, NULL );
> if( rc != LDAP_SUCCESS )
> {
> printf("ldap_start_tls_s failed\n");
> return NULL;
> }
> }
>
> if( binddn != NULL && bindpwd != NULL )
> {
> rc = ldap_bind_s(ld, binddn, bindpwd, LDAP_AUTH_SIMPLE);
> if ( LDAP_SUCCESS != rc )
> {
> printf("ldap_bind_s failed\n");
> return NULL;
> }
> }
This code is filled with "return NULL;" without cleaning up memory if
anything goes wrong. Are you sure everything is always going fine for
all your threads during your tests?
>
> ldap_unbind_s(ld);
> connectnum++;
> printf("%d connect ok\n", connectnum);
> return NULL;
> }
>
> int main(int argc, char ** argv)
> {
> if(argc < 2)
> {
> printf("Usage: testmem <host> [mode] [bind dn] [bind pwd]\n");
> printf("mode: default: NORMAL; SSL;TLS\n");
> return 0;
> }
> string mode="NORMAL";
> if( argc > 2 )
> mode = argv[2];
>
> if( mode == "SSL" )
> transMethod = LDAP_TRANS_SSL;
> if( mode == "TLS" )
> transMethod = LDAP_TRANS_TLS;
> host = argv[1];
>
> if( argc > 4 )
> {
> binddn = argv[3];
> bindpwd = argv[4];
> }
>
> do
> {
> pthread_t instance_thread ;
> pthread_attr_t attr;
> pthread_attr_init(&attr);
> pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
> int rc = pthread_create(&instance_thread, &attr, connectLDAP, NULL) ;
> pthread_attr_destroy(&attr);
> if (rc)
> {
> printf("Fail to create policy server instance thread\n") ;
> break;
> }
> sleep(1);
> }while(1);
> return 0;
> }
>
Ing. Pierangelo Masarati
OpenLDAP Core Team
SysNet s.r.l.
via Dossi, 8 - 27100 Pavia - ITALIA
http://www.sys-net.it
-----------------------------------
Office: +39 02 23998309
Mobile: +39 333 4963172
Fax: +39 0382 476497
Email: ando@sys-net.it
-----------------------------------