From d3a538c8fee9f31b29947ad73445f50902140899 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Fri, 12 Jun 2020 20:17:56 +0100 Subject: [PATCH] smtp_accept_map_per_host: call search_tidyup in fail path. Bug 2597 --- doc/doc-txt/ChangeLog | 5 +++++ src/src/daemon.c | 14 +++++++------- src/src/lookups/ldap.c | 11 ++++------- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 7284f9cfe..86686521e 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -35,6 +35,11 @@ JH/06 Bug 2594: Change the name used for certificate name checks in the smtp the head of the CNAME chain leading there (if there is one). This seems to align better with RFC 6125. +JH/07 Bug 2597: Fix a resource leak. Using a lookup in obtaining a value for + smtp_accept_max_per_host allocated resources which were not released + when the limit was exceeded. This eventually crashed the daemon. Fix + by adding a relase action in that path. + Exim version 4.94 ----------------- diff --git a/src/src/daemon.c b/src/src/daemon.c index 1816537ec..8c9abc7dc 100644 --- a/src/src/daemon.c +++ b/src/src/daemon.c @@ -278,10 +278,10 @@ to provide host-specific limits according to $sender_host address, but because this is in the daemon mainline, only fast expansions (such as inline address checks) should be used. The documentation is full of warnings. */ -if (smtp_accept_max_per_host != NULL) +if (smtp_accept_max_per_host) { uschar *expanded = expand_string(smtp_accept_max_per_host); - if (expanded == NULL) + if (!expanded) { if (!f.expand_string_forcedfail) log_write(0, LOG_MAIN|LOG_PANIC, "expansion of smtp_accept_max_per_host " @@ -293,7 +293,7 @@ if (smtp_accept_max_per_host != NULL) uschar *s = expanded; while (isdigit(*s)) max_for_this_host = max_for_this_host * 10 + *s++ - '0'; - if (*s != 0) + if (*s) log_write(0, LOG_MAIN|LOG_PANIC, "expansion of smtp_accept_max_per_host " "for %s contains non-digit: %s", whofrom->s, expanded); } @@ -303,8 +303,7 @@ if (smtp_accept_max_per_host != NULL) per host_address checks. Note that at this stage smtp_accept_count contains the count of *other* connections, not including this one. */ -if ((max_for_this_host > 0) && - (smtp_accept_count >= max_for_this_host)) +if (max_for_this_host > 0 && smtp_accept_count >= max_for_this_host) { int host_accept_count = 0; int other_host_count = 0; /* keep a count of non matches to optimise */ @@ -321,8 +320,8 @@ if ((max_for_this_host > 0) && early, either by hitting the target, or finding there are not enough connections left to make the target. */ - if ((host_accept_count >= max_for_this_host) || - ((smtp_accept_count - other_host_count) < max_for_this_host)) + if ( host_accept_count >= max_for_this_host + || smtp_accept_count - other_host_count < max_for_this_host) break; } @@ -336,6 +335,7 @@ if ((max_for_this_host > 0) && log_write(L_connection_reject, LOG_MAIN, "Connection from %s refused: too many connections " "from that IP address", whofrom->s); + search_tidyup(); goto ERROR_RETURN; } } diff --git a/src/src/lookups/ldap.c b/src/src/lookups/ldap.c index ef550a08d..3fced1cbd 100644 --- a/src/src/lookups/ldap.c +++ b/src/src/lookups/ldap.c @@ -1348,16 +1348,13 @@ Make sure that eldap_dn does not refer to reclaimed or worse, freed store */ static void eldap_tidy(void) { -LDAP_CONNECTION *lcp = NULL; eldap_dn = NULL; -while ((lcp = ldap_connections) != NULL) +for (LDAP_CONNECTION *lcp; lcp = ldap_connections; ldap_connections = lcp->next) { - DEBUG(D_lookup) debug_printf_indent("unbind LDAP connection to %s:%d\n", lcp->host, - lcp->port); - if(lcp->bound == TRUE) - ldap_unbind(lcp->ld); - ldap_connections = lcp->next; + DEBUG(D_lookup) debug_printf_indent("unbind LDAP connection to %s:%d\n", + lcp->host, lcp->port); + if(lcp->bound) ldap_unbind(lcp->ld); } } -- 2.30.2