]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: server: Duplicate healthcheck's alpn inherited from default server
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 1 Sep 2025 13:04:18 +0000 (15:04 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 1 Sep 2025 13:45:05 +0000 (15:45 +0200)
When "check-alpn" parameter is inherited from the default server, the value
is not duplicated, the pointer of the default server is used. However, when
this parameter is overridden, the old value is released. So the "check-alpn"
value of the default server is released. So it is possible to have a UAF if
if another server inherit from the same the default server.

To fix the issue, the "check-alpn" parameter must be handled the same way
the "alpn" is. The default value is duplicated. So it could be safely
released if it is forced on the server line.

This patch should fix the issue #3096. It must be backported to all stable
versions.

src/check.c
src/server.c

index 3d03d6aa83edfa7f2dc0b9858d56b27440de054c..c994108ac499a8c03efe214a85ea83fbeee533fb 100644 (file)
@@ -1574,7 +1574,7 @@ void free_check(struct check *check)
        }
 
        ha_free(&check->pool_conn_name);
-
+       ha_free(&check->alpn_str);
        task_destroy(check->task);
 
        check_release_buf(check, &check->bi);
index d4ae2e8958e570b72a5f59b714aa01d9f947be2a..ccaa1665a39bb5ed9ac8edd0eec05fe7d0c826cc 100644 (file)
@@ -2901,8 +2901,15 @@ void srv_settings_cpy(struct server *srv, const struct server *src, int srv_tmpl
        srv->check.use_ssl            = src->check.use_ssl;
        srv->check.port               = src->check.port;
        srv->check.sni                = src->check.sni;
-       srv->check.alpn_str           = src->check.alpn_str;
-       srv->check.alpn_len           = src->check.alpn_len;
+       if (src->check.alpn_str) {
+               srv->check.alpn_str = malloc(src->check.alpn_len);
+               if (srv->check.alpn_str) {
+                       memcpy(srv->check.alpn_str, src->check.alpn_str,
+                              src->check.alpn_len);
+                       srv->check.alpn_len = src->check.alpn_len;
+               }
+       }
+
        if (!(srv->flags & SRV_F_RHTTP))
                srv->check.reuse_pool = src->check.reuse_pool;
        if (src->check.pool_conn_name)