[python-ldap] [BUG, PATCH] Recursive locking problem when using TLS with reconnect

Philipp Hahn hahn at univention.de
Fri Sep 5 19:29:26 CEST 2014


Hello,

After updating python-ldap from 2.3.11 to 2.4.10 one of our tests
testing the reconnect behavior in obscure cases starts failing: the test
just hangs.
The problem also exists with 2.4.13.

I think this is related to the change in 2.4.9
"ldapobject.ReconnectLDAPObject.reconnect() now does kind of an internal
locking to pause other threads while reconnecting  is pending."

Using "gdb -p $PID -ex 'thread apply all bt'" I was able to track down a
recursive locking problem:

> #0  sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:86
...
> #7  PyEval_EvalFrameEx (.../usr/lib/python2.7/dist-packages/ldap/ldapobject.py, line 772, in reconnect ...
...
> #11 PyEval_EvalFrameEx (.../usr/lib/python2.7/dist-packages/ldap/ldapobject.py, line 823, in _apply_method_s ...
...
> #16 PyEval_EvalFrameEx (.../usr/lib/python2.7/dist-packages/ldap/ldapobject.py, line 842, in start_tls_s ...
...
> #20 PyEval_EvalFrameEx (.../usr/lib/python2.7/dist-packages/ldap/ldapobject.py, line 787, in reconnect ...
...
> #24 PyEval_EvalFrameEx (.../usr/lib/python2.7/dist-packages/ldap/ldapobject.py, line 823, in _apply_method_s ...
...
> #29 PyEval_EvalFrameEx (.../usr/lib/python2.7/dist-packages/ldap/ldapobject.py, line 876, in search_ext_s ...
...
> #33 PyEval_EvalFrameEx (.../usr/lib/pymodules/python2.7/univention/uldap.py, line 339, in search ...
...
> #37 PyEval_EvalFrameEx (.../usr/lib/pymodules/python2.7/univention/uldap.py, line 350, in searchDn ...
...

As you can see its a TLS encrypted connection, which again fails and
starts to re-connect, while it is already re-connecting. This then
dead-locks when the self._reconnect_lock is acquired a 2nd time by the
same thread.

The following patches solves the hang for me:

--- Lib/ldap/ldapobject.py.orig 2014-09-05 18:13:21.113628647 +0200
+++ Lib/ldap/ldapobject.py      2014-09-05 18:23:05.913107047 +0200
@@ -784,7 +784,7 @@
           self._restore_options()
           # StartTLS extended operation in case this was called before
           if self._start_tls:
-            self.start_tls_s()
+            SimpleLDAPObject.start_tls_s(self)
           # Repeat last simple or SASL bind
           self._apply_last_bind()
         except (ldap.SERVER_DOWN,ldap.TIMEOUT),e:


Sincerely
Philipp Hahn

PS: Is your CVS tree still the master or is there some official
GIT/Subverion repository for easier cloning?
PPS: <https://forge.univention.org/bugzilla/show_bug.cgi?id=35741>
-- 
Philipp Hahn
Open Source Software Engineer

Univention GmbH
be open.
Mary-Somerville-Str. 1
D-28359 Bremen
Tel.: +49 421 22232-0
Fax : +49 421 22232-99
hahn at univention.de

http://www.univention.de/
Geschäftsführer: Peter H. Ganten
HRB 20755 Amtsgericht Bremen
Steuer-Nr.: 71-597-02876


More information about the python-ldap mailing list