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

(ITS#6280) Race condition in TLS/SSL init code

Full_Name: Jeff Lewis
Version: 2.4.17
OS: SuSE Linux, ES9 & 10
Submission from: (NULL) (

There appears to be a race condition in SSL/TLS setup in the LDAP client library
bind fucntions.  We have workarounds for the problem in 2.3 and 2.4 which we
plan to use until we can get a proper fix so there is no time pressure on you
from my end.  Since we have a viable workaround, we're happy leaving the choice
to address the issue or not to you.

In OpenLDAP release 2.4.17, there is a race condition of some sort when SSL or
TLS is used.  When two or more threads collide in the SSL/TLS setup code, one or
both threads fail to connect.  I believe this to be some sort of a one-time
initialization problem because it is the first few bind attempts that seem to
fail and once one bind succeeds, the rest seem to succeed.

We observe this with simple binds using ldap_sasl_bind_s, ldap_simple_bind_s, or
ldap_bind_s.  We observe it on connections protected with SSL.  We also observe
it on connections protected with TLS.  We do not observe any problems involving
normal, unprotected LDAP connections.  It would appear that SSL or TLS has to be
in play.

I've got two workarounds:

1. If I serialize the binds with a mutex, the problem disappears.  This is not
something we'd want to do in our product because of the large number of binds we
have to do in a short period of time.

2. If, before the first bind attempt, I invoke ldap_set_option passing a NULL
LDAP pointer, LDAP_OPT_X_TLS_NEWCTX and a value of 0, I do not experience the
problem.  We're quite happy with this as a workaround.  This supports my belief
that the race is somewhere in the TLS initialization code.

In 2.3.39 (our current OpenLDAP client), the problem is more severe.  When
multiple threads collide in the TLS setup logic, the problem causes TLS to
become completely unusable and no connection can be established to the server. 
We've repaired this problem in libraries/libldap/tls.c by calling
ldap_pvt_tls_init through pthread_once and we're quite happy to live with this
until we can get a 2.4 OpenLDAP imported.