From: Willy Tarreau Date: Fri, 15 May 2026 14:55:07 +0000 (+0200) Subject: BUG/MINOR: server: better handling of OOM in srv_set_fqdn() X-Git-Tag: v3.4-dev13~71 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6c663a93746532086f7913d3968ce16c4542b4fb;p=thirdparty%2Fhaproxy.git BUG/MINOR: server: better handling of OOM in srv_set_fqdn() This function may face an OOM on strdup() in the middle of the hostname or hostname_dn replacement, leaving NULLs in either or both of the server's fields, which is definitely not good for other call places. Let's perform a safe replacement instead: we first allocate the new values, and only if they are successful, then we release the previous ones and replace them. It is not necessary to backport this unless the issue is reported (it was found via code review). --- diff --git a/src/server.c b/src/server.c index ebc8ec210..ff2ebcfb5 100644 --- a/src/server.c +++ b/src/server.c @@ -5226,6 +5226,8 @@ int srv_set_fqdn(struct server *srv, const char *hostname, int resolv_locked) struct resolv_resolution *resolution; char *hostname_dn; int hostname_len, hostname_dn_len; + char *hostname_dup = NULL; + char *hostname_dn_dup = NULL; /* Note that the server lock is already held. */ if (!srv->resolvers) @@ -5256,13 +5258,18 @@ int srv_set_fqdn(struct server *srv, const char *hostname, int resolv_locked) resolv_unlink_resolution(srv->resolv_requester); + hostname_dup = strdup(hostname); + hostname_dn_dup = strdup(hostname_dn); + if (!hostname_dup || !hostname_dn_dup) + goto err; + free(srv->hostname); free(srv->hostname_dn); - srv->hostname = strdup(hostname); - srv->hostname_dn = strdup(hostname_dn); + srv->hostname = hostname_dup; + srv->hostname_dn = hostname_dn_dup; srv->hostname_dn_len = hostname_dn_len; - if (!srv->hostname || !srv->hostname_dn) - goto err; + hostname_dup = NULL; + hostname_dn_dup = NULL; if (srv->flags & SRV_F_NO_RESOLUTION) goto end; @@ -5278,6 +5285,8 @@ int srv_set_fqdn(struct server *srv, const char *hostname, int resolv_locked) err: if (!resolv_locked) HA_SPIN_UNLOCK(DNS_LOCK, &srv->resolvers->lock); + ha_free(&hostname_dup); + ha_free(&hostname_dn_dup); return -1; }