]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MEDIUM: cache: forbid cache rules in defaults sections
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 12 Nov 2026 08:48:38 +0000 (09:48 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Thu, 12 Nov 2026 17:20:31 +0000 (18:20 +0100)
A "cache-use" or "cache-store" rule declared in a defaults section has
never worked: the implicit cache-store filter it creates is attached to
the defaults section itself, where the "filter" directive is not
supported. The filter is never resolved, and the rule inherited by the
proxies references a configuration pointing at an unresolved cache name
instead of a cache, which leads to crashes or silently broken caching
depending on the filter mode of the proxies.

Supporting these rules with the legacy filters would require a deep
rework of the rule-to-filter binding, hard to backport. So, until the
new filter API covers this case, the rules are simply forbidden in a
defaults section, with an explicit alert:

    [ALERT] : Proxy 'd': 'cache-use' rules are not supported in a defaults section.

This patch must be backported to all supported versions.

reg-tests/cache/defaults_rules_forbidden.vtc [new file with mode: 0644]
src/cache.c

diff --git a/reg-tests/cache/defaults_rules_forbidden.vtc b/reg-tests/cache/defaults_rules_forbidden.vtc
new file mode 100644 (file)
index 0000000..5750eae
--- /dev/null
@@ -0,0 +1,39 @@
+varnishtest "cache rules are forbidden in defaults sections"
+
+# A cache rule declared in a defaults section would create an implicit
+# cache-store filter on the defaults section itself. It would never be
+# resolved nor attached to the proxies inheriting the rule, leading to
+# crashes or silently broken caching. Such rules are rejected at check
+# time: haproxy must refuse the configuration.
+
+feature ignore_unknown_macro
+
+# A "cache-use" rule in a defaults section is rejected.
+haproxy h1 -conf-BAD {'cache-use' rules are not supported in a defaults section} {
+    defaults d
+        mode http
+        timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
+        timeout client  "${HAPROXY_TEST_TIMEOUT-5s}"
+        timeout server  "${HAPROXY_TEST_TIMEOUT-5s}"
+        http-request cache-use my_cache
+
+    frontend fe from d
+
+    cache my_cache
+        total-max-size 1
+}
+
+# A "cache-store" rule in a defaults section is rejected too.
+haproxy h2 -conf-BAD {'cache-store' rules are not supported in a defaults section} {
+    defaults d
+        mode http
+        timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
+        timeout client  "${HAPROXY_TEST_TIMEOUT-5s}"
+        timeout server  "${HAPROXY_TEST_TIMEOUT-5s}"
+        http-response cache-store my_cache
+
+    frontend fe from d
+
+    cache my_cache
+        total-max-size 1
+}
index e11b13af895f0a6dfef3af73d65d8881e863b2ed..81284897476bf0889cd423412e762b5473bd67de 100644 (file)
@@ -2385,6 +2385,12 @@ static int check_cache_rule(struct act_rule *rule, struct proxy *proxy, char **e
        struct cache_flt_conf *cconf = NULL;
        char *name = rule->arg.act.p[0];
 
+       if (proxy->cap & PR_CAP_DEF) {
+               memprintf(err, "'%s' rules are not supported in a defaults section",
+                         rule->kw ? rule->kw->kw : "cache");
+               return 0;
+       }
+
        /* check if a cache filter was already registered with this cache
         * name, if that's the case, must use it. */
        fconf = flt_find_conf(proxy, cache_store_flt_id, FLT_SIDE_RES, cache_store_find_flt, (char *)name);