]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MEDIUM: resolvers: reject servers sharing an SRV record with different resolvers
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 29 Sep 2026 07:39:46 +0000 (09:39 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Tue, 10 Nov 2026 14:47:52 +0000 (15:47 +0100)
All servers of a proxy using the same SRV name share the same SRV request
(srvrq), which is linked to the resolvers section of the first server
found with a "resolvers" keyword. When another server of the same proxy
uses the same SRV name with a different resolvers section, the SRV
responses are processed by the first section under its own lock, and
resolv_check_response() updates all attached servers from there, calling
srv_update_fqdn(), resolv_link_resolution() and _resolv_unlink_resolution()
on servers whose resolutions belong to the other section, without holding
this other section's lock, while its task may run on another thread. This
can corrupt this section's resolution lists. In addition, the second
section's settings (timeouts, nameservers) are silently ignored for the
SRV record.

Such a configuration is accepted without any warning:

    backend be
        server-template a 2 _http._tcp.svc.test resolvers r1 init-addr none
        server-template c 2 _http._tcp.svc.test resolvers r2 init-addr none

Since there's no valid use case for this, let's report an error when a
server uses an SRV record already used with another resolvers section in
the same proxy.

The SRV request sharing was introduced in 1.8 by commit 67957bd59
("MAJOR: dns: Refactor the DNS code"). This should be backported to all
stable branches.

src/resolvers.c

index e09560931a4f49e453814314c508a2af0b42607e..edb76a7c605c743bb190fb7429e126c1a8ec12a9 100644 (file)
@@ -2978,6 +2978,16 @@ static int resolvers_finalize_config(void)
                                                continue;
                                        }
                                }
+                               else if (srv->srvrq->resolvers != srv->resolvers) {
+                                       /* the SRV request is shared by all servers of
+                                        * the proxy using the same SRV name, and the
+                                        * servers are updated under its resolvers' lock.
+                                        */
+                                       ha_alert("%s '%s', server '%s': all servers using SRV record '%s' must use the same resolvers section ('%s' was already used).\n",
+                                                proxy_type_str(px), px->id, srv->id, srv->srvrq->name, srv->srvrq->resolvers->id);
+                                       err_code |= (ERR_ALERT|ERR_ABORT);
+                                       continue;
+                               }
 
                                srv->srvrq_check = task_new_anywhere();
                                if (!srv->srvrq_check) {