+++ This bug was initially created as a clone of Bug #1582598 +++
Description of problem:
python-ldap has a reference counting bug that causes a reproducible segfault in FreeIPA.
It's is only triggered when an LDAP server returns multiple attribute entries with the same name. An LDAP result contains a sequence of attributes, each item has an attribute name entry and a sequence of values. python-ldap code has extra code to handle a sequence with more than one attribute with the same name. However the code for this special case was both buggy and never triggered in any test case.
When python-ldap iterates over the attributes, it checks if an attribute name is already in the result dict. That was never the case before. In this special case, ipaAllowedToPerform;write_keys was already in the dict. The code retrieves the result list with PyDict_GetItem and later decreases the reference counter of the list. But that is wrong. PyDict_GetItem returns a borrowed reference, not a new reference. The ref count of the list dropped to zero and a broken object was returned to Python space. Later on when the object was accessed and the memory location was modified in the mean time, the interpreter crashed with a segfault.
Version-Release number of selected component (if applicable):
all versions before 3.1.0
always with FreeIPA
Steps to Reproduce:
1. ipa host-allow-create-keytab $(hostname) --users=admin
2. repeat "ipa host-show $(hostname) --all" multiple times
segfault in HTTPD error log
--- Additional comment from Christian Heimes on 2018-05-25 13:17:42 EDT ---
Fixed in release 3.1.0 by commit https://github.com/python-ldap/python-ldap/commit/77e934e88766002e77462d541b6e9c9599c7d410
--- Additional comment from Christian Heimes on 2018-05-25 13:24:57 EDT ---
Neither F27 nor RHEL are affected. The bug was introduced when python-ldap was ported to Python 3, see commit https://github.com/python-ldap/python-ldap/commit/fa35757fa2a425784676a91909b8f721cf13c095#diff-7edf3a425345c27675d056757a6a04c3R103
PyMapping_GetItemString() returns a new reference, PyDict_GetItem() a borrowed reference.
python-ldap is fine *but* python-pyldap contains the buggy code. The ref counting bug and segfaults affects FreeIPA on F27, because it uses python3-pyldap package as LDAP client library.
So we just backport this? https://github.com/python-ldap/python-ldap/commit/77e934e88766002e77462d541b6e9c9599c7d410
Yes, "if (valuelist != NULL) Py_INCREF(valuelist);" fixed the ref counting bug and segfault.
Does the build from https://src.fedoraproject.org/rpms/python-pyldap/pull-request/3 aka https://koji.fedoraproject.org/koji/taskinfo?taskID=27231248 fix the problem?
Yes, the patched version fixes the problem.
I can confirm that my reproducer script crashes with python3-pyldap-2.4.37-3.fc27.x86_64 and succeeds with python3-pyldap-2.4.37-4.fc27.x86_64.rpm.
python-pyldap-2.4.37-4.fc27 has been submitted as an update to Fedora 27. https://bodhi.fedoraproject.org/updates/FEDORA-2018-abe52b6663
python-pyldap-2.4.37-4.fc27 has been pushed to the Fedora 27 testing repository. If problems still persist, please make note of it in this bug report.
See https://fedoraproject.org/wiki/QA:Updates_Testing for
instructions on how to install test updates.
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2018-abe52b6663
python-pyldap-2.4.37-4.fc27 has been pushed to the Fedora 27 stable repository. If problems still persist, please make note of it in this bug report.