https://redmine.lighttpd.net/https://redmine.lighttpd.net/favicon.ico?13667327412017-12-20T16:00:08Zlighty labsLighttpd - Bug #2849: Linux OOM kills lighttpd when using mod_authn_ldaphttps://redmine.lighttpd.net/issues/2849?journal_id=112212017-12-20T16:00:08Zcodehero
<ul></ul><p>Further information:</p>
<p>For tests 1-3, LDAP server was running on local system</p>
<p>4. Stress test on another ARM system, LDAP server remote: no leak<br />5. Stress test on an x86_64 system, LDAP server remote: no leak<br />6. Stress test on another ARM system, LDAP server local: leak</p>
<p>I will try to get a test going on x86_64 system with a local ldap server to see if the leak manifests itself there.</p> Lighttpd - Bug #2849: Linux OOM kills lighttpd when using mod_authn_ldaphttps://redmine.lighttpd.net/issues/2849?journal_id=112222017-12-20T16:13:12Zcodehero
<ul></ul><p>The following line is the culprit when LDAP server is on the same host as lighttpd:</p>
<p>auth.backend.ldap.hostname = "127.0.0.1"</p>
<p>changing this to</p>
<p>auth.backend.ldap.hostname = "192.168.1.1" (or the IP of the eth0 interface)</p>
<p>eliminates the memory leak.</p> Lighttpd - Bug #2849: Linux OOM kills lighttpd when using mod_authn_ldaphttps://redmine.lighttpd.net/issues/2849?journal_id=112232017-12-20T21:52:15Zcodehero
<ul><li><strong>File</strong> <a href="/attachments/1844">lighttpd_out_ldap_memleak.log</a> <a class="icon-only icon-download" title="Download" href="/attachments/download/1844/lighttpd_out_ldap_memleak.log">lighttpd_out_ldap_memleak.log</a> added</li></ul><p><em><strong>Yes, there is a real "memory leak" in lighttpd.</strong></em></p>
<p>I was able to recreate the leaking behaviour on an x86_64 desktop.<br />Attached is a valgrind log clearly showing unreachable bytes.</p>
<p>Further inspection of the mod_authn_ldap.c shows the incorrect function for freeing variables of type LDAP*</p>
<p>ldap_destroy() must be used instead of ldap_memfree() to free types of LDAP*</p>
<p>eg</p>
<p>The way to trigger the leak is to just repeatedly try to login with bad credentials.<br />Please patch immediately on your end as this is a vulnerability on internal systems.</p>
<p>(I doubt anyone would use ldap on an internet facing system, I could be wrong)</p> Lighttpd - Bug #2849: Linux OOM kills lighttpd when using mod_authn_ldaphttps://redmine.lighttpd.net/issues/2849?journal_id=112242017-12-21T06:35:41Zgstrauss
<ul><li><strong>Status</strong> changed from <i>New</i> to <i>Patch Pending</i></li><li><strong>Target version</strong> changed from <i>1.4.x</i> to <i>1.4.49</i></li></ul><p>Thank you for the trace. Something is definitely amiss.<br />'man ldap_destroy' instructs<br /><pre>
When ldap_unbind() is called on a session handle with siblings, all the
siblings become invalid.
Siblings must be destroyed using ldap_destroy(). Session handle
resources associated with the original (LDAP *) will be freed when the
last session handle is destroyed or when ldap_unbind() is called, if no
other session handles currently exist.
</pre><br />and ldap_unbind_ext_s() is used on the handle when ldap_bind() succeeds, but not when the ldap_sasl_bind_s() fails.</p>
<p><strong>Untested</strong>, but here is the 5 min patch to call ldap_destroy() (instead of ldap_memfree()) after a successful ldap_initialize(), even if the ldap_sasl_bind_s() fails.<br /><pre>
diff --git a/src/mod_authn_ldap.c b/src/mod_authn_ldap.c
index c2e793d1..3e75cf10 100644
--- a/src/mod_authn_ldap.c
+++ b/src/mod_authn_ldap.c
@@ -398,7 +398,7 @@ static LDAP * mod_authn_ldap_host_init(server *srv, plugin_c
onfig *s) {
ret = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &ret);
if (LDAP_OPT_SUCCESS != ret) {
mod_authn_ldap_err(srv, __FILE__, __LINE__, "ldap_set_options()", ret);
- ldap_memfree(ld);
+ ldap_destroy(ld);
return NULL;
}
@@ -412,7 +412,7 @@ static LDAP * mod_authn_ldap_host_init(server *srv, plugin_c
onfig *s) {
mod_authn_ldap_err(srv, __FILE__, __LINE__,
"ldap_set_option(LDAP_OPT_X_TLS_CACERTFILE)"
,
ret);
- ldap_memfree(ld);
+ ldap_destroy(ld);
return NULL;
}
}
@@ -420,7 +420,7 @@ static LDAP * mod_authn_ldap_host_init(server *srv, plugin_c
onfig *s) {
ret = ldap_start_tls_s(ld, NULL, NULL);
if (LDAP_OPT_SUCCESS != ret) {
mod_authn_ldap_err(srv,__FILE__,__LINE__,"ldap_start_tls_s()",ret);
- ldap_memfree(ld);
+ ldap_destroy(ld);
return NULL;
}
}
@@ -490,7 +490,7 @@ static LDAPMessage * mod_authn_ldap_search(server *srv, plugin_config *s, char *
s->auth_ldap_bindpw->ptr)
: mod_authn_ldap_bind(srv, s->ldap, NULL, NULL);
if (LDAP_SUCCESS != ret) {
- ldap_memfree(s->ldap);
+ ldap_destroy(s->ldap);
s->ldap = NULL;
return NULL;
}
@@ -635,7 +635,7 @@ static handler_t mod_authn_ldap_basic(server *srv, connection *con, void *p_d, c
}
if (LDAP_SUCCESS != mod_authn_ldap_bind(srv, ld, dn, pw)) {
- ldap_memfree(ld);
+ ldap_destroy(ld);
if (dn != p->ldap_filter->ptr) ldap_memfree(dn);
return HANDLER_ERROR;
}
diff --git a/src/mod_vhostdb_ldap.c b/src/mod_vhostdb_ldap.c
index 459d7d60..4f7e2a5f 100644
--- a/src/mod_vhostdb_ldap.c
+++ b/src/mod_vhostdb_ldap.c
@@ -251,7 +251,7 @@ static LDAP * mod_authn_ldap_host_init(server *srv, vhostdb_config *s) {
ret = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &ret);
if (LDAP_OPT_SUCCESS != ret) {
mod_authn_ldap_err(srv, __FILE__, __LINE__, "ldap_set_options()", ret);
- ldap_memfree(ld);
+ ldap_destroy(ld);
return NULL;
}
@@ -264,7 +264,7 @@ static LDAP * mod_authn_ldap_host_init(server *srv, vhostdb_config *s) {
mod_authn_ldap_err(srv, __FILE__, __LINE__,
"ldap_set_option(LDAP_OPT_X_TLS_CACERTFILE)",
ret);
- ldap_memfree(ld);
+ ldap_destroy(ld);
return NULL;
}
}
@@ -272,7 +272,7 @@ static LDAP * mod_authn_ldap_host_init(server *srv, vhostdb_config *s) {
ret = ldap_start_tls_s(ld, NULL, NULL);
if (LDAP_OPT_SUCCESS != ret) {
mod_authn_ldap_err(srv,__FILE__,__LINE__,"ldap_start_tls_s()",ret);
- ldap_memfree(ld);
+ ldap_destroy(ld);
return NULL;
}
}
@@ -338,7 +338,7 @@ static LDAPMessage * mod_authn_ldap_search(server *srv, vhostdb_config *s, char
ret = mod_authn_ldap_bind(srv, s->ldap, s->binddn, s->bindpw);
if (LDAP_SUCCESS != ret) {
- ldap_memfree(s->ldap);
+ ldap_destroy(s->ldap);
s->ldap = NULL;
return NULL;
}
</pre></p> Lighttpd - Bug #2849: Linux OOM kills lighttpd when using mod_authn_ldaphttps://redmine.lighttpd.net/issues/2849?journal_id=112262017-12-21T09:29:16Zcodehero
<ul></ul><p>I implemented almost exactly the same patch yesterday (sans mod_vhostdb_ldap.c changes) and experienced no crashes or memory leaks on both my x86_64 and my target system.</p> Lighttpd - Bug #2849: Linux OOM kills lighttpd when using mod_authn_ldaphttps://redmine.lighttpd.net/issues/2849?journal_id=112302017-12-21T22:50:46Zgstrauss
<ul><li><strong>Status</strong> changed from <i>Patch Pending</i> to <i>Fixed</i></li><li><strong>% Done</strong> changed from <i>0</i> to <i>100</i></li></ul><p>Applied in changeset <a class="changeset" title="[mod_authn_ldap] fix mem leak when ldap auth fails (fixes #2849) thx, codehero x-ref: "Linux ..." href="https://redmine.lighttpd.net/projects/lighttpd/repository/14/revisions/37f9b60d5e09d000e836a905559326775c81831f">37f9b60d5e09d000e836a905559326775c81831f</a>.</p> Lighttpd - Bug #2849: Linux OOM kills lighttpd when using mod_authn_ldaphttps://redmine.lighttpd.net/issues/2849?journal_id=118132019-07-15T11:45:13Zef
<ul></ul><p>I think <code>ldap_destroy()</code> is not the best solution, <code>ldap_unbind()</code> woud be preferable.<br />Using <code>ldap_destroy()</code> silently adds a dependency on OpenLDAP>=2.4 and will mysteriously fail on earlier versions.<br />In a mail (<a class="external" href="https://www.openldap.org/lists/openldap-technical/201202/msg00452.html">https://www.openldap.org/lists/openldap-technical/201202/msg00452.html</a>) on openldap-technical (probably predating the introduction of <code>ldap_dup()</code>/<code>ldap_destroy()</code>), Hallvard B Furuseth wrote<br /><pre>
Note that ldap_unbind() is misnamed, it should have been
called ldap_destroy(). It does send an unbind, but the more important
part is that it destroys the LDAP*.
</pre></p> Lighttpd - Bug #2849: Linux OOM kills lighttpd when using mod_authn_ldaphttps://redmine.lighttpd.net/issues/2849?journal_id=118142019-07-15T14:07:19Zgstrauss
<ul></ul><p><a class="user active user-mention" href="https://redmine.lighttpd.net/users/9903">@ef</a> It does not appear that you know what you're talking about. Kindly refrain from sharing uninformed opinions.</p>
<p>Read the man page for ldap_destroy(). Don't continuing posting to this ticket. This conversation is over.</p>
<p><a class="external" href="https://github.com/openldap/openldap/commit/0f30db1c46cf576230cd9397f0d5ad2892da7325">https://github.com/openldap/openldap/commit/0f30db1c46cf576230cd9397f0d5ad2892da7325</a></p>