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

Re: crash in libldap_r with multithreading (ITS#2150)



It appears you are not providing proper serialization of
ldap(3) calls as required by -lldap_r.  Please see mailing
list archives for discussions in this area.

Kurt

At 01:03 AM 2002-10-23, peter.vreman@cmg.com wrote:
>Full_Name: Peter Vreman
>Version: 2.0.21 and 2.0.27
>OS: Linux
>URL: 
>Submission from: (NULL) (212.136.56.8)
>
>
>Hello,
>
>The following program gives a SIGSEGV, becuase the memory is corrupted 
>(malloc/free gives the SIGSEGV). It looks like a racecondition, because the time
>
>before it crashes is different everytime. Running the program in valgrind or 
>using any other memory debugger does not help. Also it does not matter it the 
>number that is searched is in the LDAP database or not.
>
>Kind regards,
>Peter
>
>
>#include <stdlib.h>
>#include <stdio.h>
>#include <time.h>
>#include <pthread.h>
>#include <ldap.h>
>#include <ldap_features.h>
>
>// #define DEBUG
>
>#define msleep(x)    \
>    { \
>        struct timespec r_ts; \
>        r_ts.tv_sec=x/1000; \
>        r_ts.tv_nsec=(x%1000)*1000000; \
>        nanosleep(&r_ts,NULL); \
>    }
>
>static char* m_pc_addr[] = {
>    "0651515151",
>    "0567000038",
>    "0567000037",
>    "0651515153",
>    "0651515152",
>    "0567000039",
>    NULL
>};
>
>static void* ld_ldapthread(void* pv_arg);
>
>
>
>void ld_connect(LDAP **po_a_handler)
>{
>    int l_stat, l_msg_id;
>    LDAPMessage  *a_result;
>
>    *po_a_handler = ldap_init("127.0.0.1", LDAP_PORT);
>    if (*po_a_handler==NULL)
>    {
>        return;
>    }
>
>    if((l_msg_id = ldap_simple_bind(*po_a_handler, "cn=root,o=eircom.ie",
>"secret")) == -1)
>    {
>        printf("Bind LDAP error\n");
>        ldap_unbind_s( *po_a_handler );
>        *po_a_handler=NULL;
>        return;
>    }
>    l_stat = ldap_result(*po_a_handler,
>                         l_msg_id,
>                         0,
>                         NULL, /* indefinite wait */
>                         &a_result);
>    if(l_stat != LDAP_RES_BIND)
>    {
>        printf("LDAP connection refused\n");
>    }
>    l_stat = ldap_result2error(*po_a_handler, a_result, 0);
>
>    if( ldap_msgfree(a_result) == -1)
>    {
>        *po_a_handler=NULL;
>    }
>    if(l_stat != LDAP_SUCCESS)
>    {
>        *po_a_handler=NULL;
>    }
>}
>
>
>void ld_response(LDAP* a_ldap_handler)
>{
>    int l_stat;
>    int l_msgid;
>    int l_msgtype;
>    LDAPMessage  *a_result;
>    LDAPMessage  *a_msg;
>    BerElement *a_ber;
>    char **a_values;
>    char *a_attr;
>
>    l_stat = ldap_result(a_ldap_handler, /* ldap session handler  */
>                         LDAP_RES_ANY,   /* Extract any result    */
>                         1,              /* The complete message  */
>                         NULL,    /* indefinite wait */
>                         &a_result);     /* Where to save the result */
>    l_msgid = ldap_msgid(a_result);
>
>    l_stat = ldap_result2error(a_ldap_handler, a_result, 0);
>#ifdef DEBUG
>    printf("Parsing LDAP result msgid %d: %s\n",
>                  l_msgid,
>                  ldap_err2string(l_stat));
>#endif
>
>    if (l_stat != LDAP_SUCCESS)
>    {
>        /* Error, message is already traced above */
>        ldap_msgfree(a_result);          /* Free the memory allocated by the
>result */
>        return ;            /* Send the response back */
>    }
>
>    l_msgtype = ldap_msgtype(a_result);
>    switch(l_msgtype)
>    {
>    case LDAP_RES_SEARCH_RESULT:
>        printf("No entry found for %d\n", l_msgid);
>        break;
>
>    case LDAP_RES_SEARCH_ENTRY:
>        a_msg = ldap_first_entry(a_ldap_handler, a_result);
>        if (a_msg == NULL)
>        {
>            printf("No empty search result\n");
>            ldap_msgfree(a_result);          /* Free the memory allocated by the
>result */
>            return ;            /* Send the response back */
>        }
>        /* Scroll trought attributes to extract the needed ones */
>        for ( a_attr = ldap_first_attribute(a_ldap_handler, a_result, &a_ber );
>              a_attr != NULL;
>              a_attr = ldap_next_attribute(a_ldap_handler, a_result, a_ber))
>        {
>            a_values = ldap_get_values(a_ldap_handler, a_msg, a_attr);
>            if(a_values)
>            {
>                ldap_value_free(a_values);
>            }
>            ldap_memfree( a_attr );
>        }
>        ber_free(a_ber, 0);
>        break;
>
>    default:
>        printf("Unhandled LDAP result %d\n",l_msgtype);
>        break;
>    }
>    ldap_msgfree(a_result);
>
>    return;
>}
>
>
>void* ld_sessthread(void* pv_arg)
>{
>    char t_filter[100];
>    char t_base[100];
>    char s_nr[20];
>    int l_msgid;
>    LDAP *a_ldap_handler;
>    pthread_t l_thrd_id;
>    pthread_attr_t m_r_pthread_attr;
>    int i_addr = 0;
>
>    printf("session thread started\n");
>
>    ld_connect(&a_ldap_handler);
>    if (!a_ldap_handler)
>    {
>        return NULL;
>    }
>
>    pthread_attr_init( &m_r_pthread_attr );
>    pthread_attr_setdetachstate( &m_r_pthread_attr, PTHREAD_CREATE_DETACHED );
>    pthread_create(&l_thrd_id,
>                   &m_r_pthread_attr,
>                   &ld_ldapthread,
>                   a_ldap_handler);
>
>    while (1)
>    {
>#ifdef DEBUG
>        printf("Sending request\n");
>#endif
>
>        strcpy(s_nr,m_pc_addr[i_addr]);
>
>                i_addr++;
>                if (m_pc_addr[i_addr]==NULL)
>                {
>                    i_addr=0;
>                }
>
>        sprintf(t_base,
>                "number=%s,ou=subscribers,o=myorg",
>                s_nr);
>
>        sprintf(t_filter, "number=*"); /* in this case we should expect only one
>result */
>        /* Use syncronious search for one subscriber, it is there or not, should
>be the fastest response from LDAP */
>        l_msgid = ldap_search(a_ldap_handler,                  /* LDAP session
>handle */
>                              t_base,                          /* container to
>search */
>                              LDAP_SCOPE_BASE,                 /* search entire
>subtree */
>                              t_filter,                        /* search filter
>*/
>                              NULL,                            /* return all
>attributes */
>                              0);                              /* return both
>attributes and values */
>
>        msleep(1);
>    }
>    
>    return NULL;
>}
>
>
>static void* ld_ldapthread(void* pv_arg)
>{
>    LDAP* a_ldap_handler = (LDAP*)pv_arg;
>
>    printf("ldap thread started\n");
>
>    while (1)
>    {
>        ld_response(a_ldap_handler);
>    }
>
>    return NULL;
>}
>
>
>int main()
>{
>    pthread_t l_thrd_id;
>    pthread_attr_t m_r_pthread_attr;
>    int i;
>
>    for (i=0;i<10;i++)
>    {
>        pthread_attr_init( &m_r_pthread_attr );
>        pthread_attr_setdetachstate( &m_r_pthread_attr, PTHREAD_CREATE_DETACHED
>);
>        pthread_create(&l_thrd_id,
>                       &m_r_pthread_attr,
>                       &ld_sessthread,
>                       NULL);
>    }
>    
>
>    while (1)
>    {
>        msleep(1000000);
>    }
>    
>    return 0;
>}