From: Aurelien DARRAGON Date: Tue, 11 Jul 2023 07:31:06 +0000 (+0200) Subject: BUG/MINOR: sink/log: properly deinit srv in sink_new_from_logsrv() X-Git-Tag: v2.9-dev2~62 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c38cf3cf98d30d6d069c36d3d475511d892201b9;p=thirdparty%2Fhaproxy.git BUG/MINOR: sink/log: properly deinit srv in sink_new_from_logsrv() When errors are encountered in sink_new_from_logsrv() function, incompetely allocated ressources are freed to prevent memory leaks. For instance: logsrv implicit server is manually cleaned up on error prior to returning from the function. However, since 198e92a8e5 ("MINOR: server: add a global list of all known servers") every server created using new_server() is registered to the global list, but unfortunately the manual srv cleanup in sink_new_from_logsrv() doesn't remove the srv from the global list, so the freed server will still be referenced there, which can result in invalid reads later. Moreover, server API has evolved since, and now the srv_drop() function is available for that purpose, so let's use it, but make sure that srv is freed before the proxy because on older versions srv_drop() expects the srv to be linked to a valid proxy pointer. This must be backported up to 2.4. [For 2.4 version, free_server() must be used instead of srv_drop()] --- diff --git a/src/sink.c b/src/sink.c index 87aa9de9a3..8e8e7e6d4b 100644 --- a/src/sink.c +++ b/src/sink.c @@ -1146,6 +1146,9 @@ struct sink *sink_new_from_logsrv(struct logsrv *logsrv) return sink; error: + if (srv) + srv_drop(srv); + if (p) { if (p->id) free(p->id); @@ -1155,16 +1158,6 @@ error: free(p); } - if (srv) { - if (srv->id) - free(srv->id); - if (srv->conf.file) - free((void *)srv->conf.file); - if (srv->per_thr) - free(srv->per_thr); - free(srv); - } - if (sft) free(sft);