[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: Clarification regarding global ldapoptions structure in ldap



Hi Howard,
Thanks for your response. I may be missing something, but let me share my thoughts based on code.

ldap_set_option called from many threads, not only that even  ldap_int_tls_connect, ldap_pvt_tls_init_def_ctx as multiple thread can connect to LDAP server.
Based on code lookup, i feel not every members of option structure is read only.

Let's consider ldapoptions->ldo_tls_ctx which is global and can be used by many threads. Suppose there is two threads and thread A may be at point 1 and thread B may be at point 2, based on scheduling chances of getting it messed is more, which problem i am facing now. Have a look and please share in case my assumptions are wrong or i am missing something.

tls2.c
---------------------------

1. Let's see where ldo_tls_ctx get allocated.
ldap_pvt_tls_init_def_ctx( int is_server )
{
        struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT(); // Accessed global option structure
        int rc;
        LDAP_MUTEX_LOCK( &tls_def_ctx_mutex );
        rc = ldap_int_tls_init_ctx( lo, is_server );                  // Inside this function  lo->ldo_tls_ctx is allocated.
        LDAP_MUTEX_UNLOCK( &tls_def_ctx_mutex );
        return rc;
}

static int
ldap_int_tls_init_ctx( struct ldapoptions *lo, int is_server )
{
...
lo->ldo_tls_ctx = ti->ti_ctx_new( lo ); //The same global variable is allocated with memory
        if ( lo->ldo_tls_ctx == NULL ) {
                Debug( LDAP_DEBUG_ANY,
                   "TLS: could not allocate default ctx.\n",
                        0,0,0);
                rc = -1;
                goto error_exit;
        }
...
}

2. Let's see where it's getting freed. ldo_tls_ctx the same from global option context.

ldap_pvt_tls_destroy( void )
{
        struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT();   //Accessed the global structure  

        ldap_int_tls_destroy( lo );

...
}

void
ldap_int_tls_destroy( struct ldapoptions *lo )
{
        if ( lo->ldo_tls_ctx ) {
                ldap_pvt_tls_ctx_free( lo->ldo_tls_ctx );                   //Freeing the global tls context
                lo->ldo_tls_ctx = NULL;
        }
}

So if thread 1 where allocation done, and scheduling thread 2 at destroy part, thread 1 again got chance to access and fill some data , it's already freed by thread 2. If the tls context is part of global option structure and all threads will be viewing the same.


I can see a local ldo_tls_ctx exists per ld, but it's again being assigned with same global option ldo_tls_ctx.

static int
ldap_int_tls_connect( LDAP *ld, LDAPConn *conn, const char *host )
{
 ...
        Sockbuf *sb = conn->lconn_sb;
        int     err;
        tls_session     *ssl = NULL;

        if ( HAS_TLS( sb )) {
                ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl );
        } else {
                struct ldapoptions *lo;
                tls_ctx *ctx;

                ctx = ld->ld_options.ldo_tls_ctx;                            //Accessing the local ldo_tls_ctx.
               ssl = alloc_handle( ctx, 0 );

                if ( ssl == NULL ) return -1;

#ifdef LDAP_DEBUG
                ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug,
                        LBER_SBIOD_LEVEL_TRANSPORT, (void *)"tls_" );
#endif
                ber_sockbuf_add_io( sb, tls_imp->ti_sbio,
                        LBER_SBIOD_LEVEL_TRANSPORT, (void *)ssl );

                lo = LDAP_INT_GLOBAL_OPT();
                if( ctx == NULL ) {
                        ctx = lo->ldo_tls_ctx;                    //Getting the ldo_tls_ctx from context from global context which was allocated inside alloc_handle further functions.
                        ld->ld_options.ldo_tls_ctx = ctx;                     // Assigned the same global context to local variable.
                        tls_ctx_ref( ctx );
                }
...


Thanks 
Sachidananda



On Tue, Aug 6, 2019 at 9:44 PM Howard Chu <hyc@symas.com> wrote:
sachidananda sahu wrote:
> Hi All,
>
> Any one can give a thought on this ?

Your problem description makes no sense. Unless you're explicitly calling ldap_set_option in multiple threads,
the option structure is read-only.

The default libldap is not threadsafe, nor is it meant to be. You should probably be using libldap_r.
>
>
>
> On Thu, Aug 1, 2019 at 7:55 PM sachidananda sahu <sachi059@gmail.com <mailto:sachi059@gmail.com>> wrote:
>
>
>     Hi All,
>
>     I recently upgraded to openldap 2.4.47, it's working with single threaded connection but with multi threaded getting problem due to global structure of
>     ldapoptions in init.c
>
>     -------------------------
>     init.c
>     -------------------------
>
>     *struct* ldapoptions ldap_int_global_options  =
>             { LDAP_UNINITIALIZED , LDAP_DEBUG_NONE,
>                     LDAP_LDO_NULLARG ,
>                     LDAP_LDO_CONNECTIONLESS_NULLARG,
>                     LDAP_LDO_TLS_NULLARG,
>                     LDAP_LDO_SASL_NULLARG ,
>                     LDAP_LDO_GSSAPI_NULLARG,
>                     LDAP_LDO_MUTEX_NULLARG  };,
>
>
>     This global structure is accessed at multiple places (such as ldap_pvt_tls_init_def_ctx , alloc_handle, ldap_int_tls_connect , *ldap_pvt_tls_destroy , ldap_ld_free*)
>
>     in tls2.c using the macro lo = LDAP_INT_GLOBAL_OPT
>     (); 
>
>     So in case of multi threaded application multiple ldap connection will be using this global structure, for example ldo_tls_ctx of lapoptions will be used.
>     In one thread it can be creating a tls connection and in one it can be destroying the connection. As it's global so it is getting corrupted. 
>
>     Is openldap library thread safe completely ? Because this variable seems to be not for this tls context variable, is there any other way of using this
>     context . As i can see a local variable ldo_tls_ctx exist in dap ld->ldc->ldap_options->ldo_tls_ctx structure, but it's just got assigned with the same
>     address of global structure in  ldap_int_tls_connect.
>
>     So can someone share some thoughts on it ?
>
>     --
>     Regards,
>     Sachidananda Sahu
>
>
>
> --
> Regards,
> Sachidananda Sahu
> +91-9035265767


--
  -- Howard Chu
  CTO, Symas Corp.           http://www.symas.com
  Director, Highland Sun     http://highlandsun.com/hyc/
  Chief Architect, OpenLDAP  http://www.openldap.org/project/


--
Regards,
Sachidananda Sahu
+91-9035265767