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

Correct fix for cyrus.c free problem



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