From: Aurelien DARRAGON Date: Mon, 17 Jun 2024 16:07:22 +0000 (+0200) Subject: BUG/MEDIUM: proxy: fix email-alert invalid free X-Git-Tag: v3.1-dev2~39 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8e226682be904a6774f65e90bac0b674888cc293;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: proxy: fix email-alert invalid free In fa90a7d3 ("BUG/MINOR: proxy: fix email-alert leak on deinit()"), I tried to fix email-alert deinit() leak the simple way by leveraging existing free_email_alert() helper function which was already used for freeing email alert settings used in a default section. However, as described in GH #2608, there is a subtelty that makes free_email_alert() not suitable for use from free_proxy(). Indeed, proxy 'mailers.name' hint shares the same memory space than the pointer to the corresponding mailers section (once the proxy is resolved, name hint is replaced by the pointer to the section). However, since both values share the same space (through union), we have to take care of not freeing `mailers.name` once init_email_alert() was called on the proxy. Unfortunately, free_email_alert() isn't protected against that, causing double free() during deinit when mailers section is referenced from multiple proxy sections. Since there is no easy fix, and that the leak in itself isn't a big deal (fa90a7d3 was simply an opportunistic fix rather than a must-have given that the leak only occurs during deinit and not during runtime), let's actually revert the fix to restore legacy behavior and prevent deinit errors. Thanks to @snetat for having reported the issue on Github as well as providing relevant infos to pinpoint the bug. It should be backported everywhere fa90a7d3 was backported. [ada: for versions prior to 3.0, simply revert the offending commit using 'git revert' as proxy_free_common() first appears in 3.0] --- diff --git a/src/proxy.c b/src/proxy.c index 3acfdf6f84..83d7436e31 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -253,8 +253,6 @@ static inline void proxy_free_common(struct proxy *px) LIST_DEL_INIT(&lf->list); chunk_destroy(&px->log_tag); - - free_email_alert(px); } void free_proxy(struct proxy *p) @@ -1483,6 +1481,7 @@ void proxy_free_defaults(struct proxy *defproxy) proxy_release_conf_errors(defproxy); deinit_proxy_tcpcheck(defproxy); + free_email_alert(defproxy); /* FIXME: we cannot free uri_auth because it might already be used by * another proxy (legacy code for stats URI ...). Refcount anyone ?