Greetings, Attached is the correct fix for the cyrus.c free problem. The patch reverts the incorrect attempted fixes in 1.70/1.71 and fixes the problem correctly by moving the 'res' int outside the loop so that it can be checked against. The free should only be done if the interact call (from the prior loop) returns successfully. The free should not depend on the current value of saslrc since it is reset at the top of the loop by sasl_client_start. The problem was caused when prompts was set/allocated by sasl_client_start but prompts->result was not initialized (It is expected that the application will allocate/deallocate prompts->result according to SASL documentation). This meant that libldap attempts to free a pointer which had not been allocated, causing a segfault. Stephen
diff -uNr ldap-old/libraries/libldap/cyrus.c ldap/libraries/libldap/cyrus.c --- ldap-old/libraries/libldap/cyrus.c 2003-02-07 03:58:21.000000000 -0500 +++ ldap/libraries/libldap/cyrus.c 2003-02-20 08:57:01.000000000 -0500 @@ -525,7 +525,7 @@ char *data; const char *mech = NULL; const char *pmech = NULL; - int saslrc, rc; + int saslrc, rc, res = LDAP_OTHER; sasl_ssf_t *ssf = NULL; sasl_conn_t *ctx; sasl_interact_t *prompts = NULL; @@ -599,22 +599,18 @@ } } - if( saslrc == SASL_INTERACT ) { - int res; - #if SASL_VERSION_MAJOR >= 2 - /* XXX the application should free interact results. - * FIXME: this should happen only - * if saslrc == SASL_INTERACT - * - * I assume that prompts->result is not needed - * by the subsequent call to (interact)() */ - if ( prompts != NULL && prompts->result != NULL ) { - LDAP_FREE( (void *)prompts->result ); - prompts->result = NULL; - } + /* The application should free interact results, + * but only if it successfully alloced/set interact + * results, which is only definitely true if the + * result of the interact call returned LDAP_SUCCESS */ + if ( res == LDAP_SUCCESS && prompts != NULL && prompts->result != NULL ) { + LDAP_FREE( (void *)prompts->result ); + prompts->result = NULL; + } #endif + if( saslrc == SASL_INTERACT ) { if( !interact ) break; res = (interact)( ld, flags, defaults, prompts ); if( res != LDAP_SUCCESS ) {
Attachment:
pgpmzGhgfhcHq.pgp
Description: PGP signature