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

crash in libldap_r with multithreading (ITS#2150)



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;
}