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

(ITS#5403) LDAP_OPT_X_SASL_SSF 64bit bugfix or workaround

Full_Name: Rein Tollevik
Version: 2.4.8
OS: Solaris 10
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (

Below is a patch that fixes, or more correctly works around, a 64bit bug in
servers/slapd/syncrepl.c that causes a bus error on (at least) 64bit Solaris. 
The real problem is imho that libraries/libldap/cyrus.c expects the argument
where it should write the LDAP_OPT_X_SASL_* options to be of type ber_len_t and
not the sasl_*_t type matching the option value it returns.  I.e, the pointer
variable where the returns values are written should be cast to the appropriate
sasl_*_t type, not a ber_len_t.   Writing to a 64bit ber_len_t when the argument
is a 32bit sasl_ssf_t causes an alignment error at best case, memory corruption
at worst.

I haven't looked too deeply into other cases where LDAP_OPT_X_SASL_* options are
set or retrieved with ldap_set_option() or ldap_get_option(), so I don't know
the consequence of changing cyrus.c.  That's why I don't have what I would
consider a real fix to libraries/libldap/cyrus.c rather than this workaround.

Rein Tollevik
Basefarm AS

Index: servers/slapd/syncrepl.c
RCS file: /f/CVSROOT/drift/OpenLDAP/servers/slapd/syncrepl.c,v
retrieving revision
diff -u -u -w -r1.1.1.18 syncrepl.c
--- servers/slapd/syncrepl.c	21 Feb 2008 13:55:21 -0000
+++ servers/slapd/syncrepl.c	7 Mar 2008 11:34:08 -0000
@@ -444,6 +444,10 @@
 #ifdef HAVE_TLS
 	void	*ssl;
+	ber_len_t ssf;	/* XXX The correct type would be sasl_ssf_t, but
+			 * this is what the LDAP_OPT_X_SASL_SSF return
+			 * value is cast into in libldap/cyrus.c
+			 */
 	rc = slap_client_connect( &si->si_ld, &si->si_bindconf );
 	if ( rc != LDAP_SUCCESS ) {
@@ -462,7 +466,8 @@
 		op->o_tls_ssf = ldap_pvt_tls_get_strength( ssl );
 #endif /* HAVE_TLS */
-	ldap_get_option( si->si_ld, LDAP_OPT_X_SASL_SSF, &op->o_sasl_ssf );
+	ldap_get_option( si->si_ld, LDAP_OPT_X_SASL_SSF, &ssf);
+	op->o_sasl_ssf = ssf;
 	op->o_ssf = ( op->o_sasl_ssf > op->o_tls_ssf )
 		?  op->o_sasl_ssf : op->o_tls_ssf;