]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MAJOR: vars: Fix bogus free() during deinit() for http-request rules
authorTim Duesterhus <tim@bastelstu.be>
Sun, 14 Jun 2020 15:27:36 +0000 (17:27 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 15 Jun 2020 16:51:11 +0000 (18:51 +0200)
We cannot simply `release_sample_expr(rule->arg.vars.expr)` for a
`struct act_rule`, because `rule->arg` is a union that might not
contain valid `vars`. This leads to a crash on a configuration using
`http-request redirect` and possibly others:

    frontend http
     mode http
     bind 127.0.0.1:80
     http-request redirect scheme https

Instead a `struct act_rule` has a `release_ptr` that must be used
to properly free any additional storage allocated.

This patch fixes a regression in commit ff78fcdd7f15c8626c7e70add7a935221ee2920c.
It must be backported to whereever that patch is backported.

It has be verified that the configuration above no longer crashes.
It has also been verified that the configuration in ff78fcdd7f15c8626c7e70add7a935221ee2920c
does not leak.

src/haproxy.c
src/vars.c

index 6a8c13e6ddbdabd9f5e5abc0506515e5eced409a..215c68a3032f76b9661fe702de5cbdd7a68b61b2 100644 (file)
@@ -2555,7 +2555,6 @@ static void deinit_act_rules(struct list *rules)
        list_for_each_entry_safe(rule, ruleb, rules, list) {
                LIST_DEL(&rule->list);
                deinit_acl_cond(rule->cond);
-               release_sample_expr(rule->arg.vars.expr);
                if (rule->release_ptr)
                        rule->release_ptr(rule);
                free(rule);
index b154c529d30e0750c33604630364fa7fbe4997a5..fd95eed5d7e0de536323f775a486c416494d8f4f 100644 (file)
@@ -689,6 +689,11 @@ static enum act_return action_clear(struct act_rule *rule, struct proxy *px,
        return ACT_RET_CONT;
 }
 
+static void release_store_rule(struct act_rule *rule)
+{
+       release_sample_expr(rule->arg.vars.expr);
+}
+
 /* This two function checks the variable name and replace the
  * configuration string name by the global string name. its
  * the same string, but the global pointer can be easy to
@@ -758,6 +763,7 @@ static enum act_parse_ret parse_store(const char **args, int *arg, struct proxy
        if (!set_var) {
                rule->action     = ACT_CUSTOM;
                rule->action_ptr = action_clear;
+               rule->release_ptr = release_store_rule;
                return ACT_RET_PRS_OK;
        }
 
@@ -791,6 +797,7 @@ static enum act_parse_ret parse_store(const char **args, int *arg, struct proxy
 
        rule->action     = ACT_CUSTOM;
        rule->action_ptr = action_store;
+       rule->release_ptr = release_store_rule;
        return ACT_RET_PRS_OK;
 }