]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MAJOR: config: verify that targets of track-sc and stick rules are present
authorWilly Tarreau <w@1wt.eu>
Tue, 5 Feb 2019 10:38:38 +0000 (11:38 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 5 Feb 2019 10:54:49 +0000 (11:54 +0100)
Stick and track-sc rules may optionally designate a table in a different
proxy. In this case, a number of verifications are made such as validating
that this proxy actually exists. However, in multi-process mode, the target
table might indeed exist but not be bound to the set of processes the rules
will execute on. This will definitely result in a random behaviour especially
if these tables do require peer synchronization, because some tasks will be
started to try to synchronize form uninitialized areas.

The typical issue looks like this :

    peers my-peers
         peer foo ...

    listen proxy
         bind-process 1
         stick on src table ip
         ...

    backend ip
         bind-process 2
         stick-table type ip size 1k peers my-peers

While it appears obvious that the example above will not work, there are
less obvious situations, such as having bind-process in a defaults section
and having a larger set of processes for the referencing proxy than the
referenced one.

The present patch adds checks for such situations by verifying that all
processes from the referencing proxy are present on the other one in all
track-sc* and stick-* rules, and in sample fetch / converters referencing
another table so that sc_inc_gpc0() and similar are safe as well.

This fix must be backported to all maintained versions. It may potentially
disrupt configurations which already randomly crash. There hardly is any
intermediary solution though, such configurations need to be fixed.

src/action.c
src/cfgparse.c
src/sample.c

index 54d27a0f41c82b0e5c8f25ac6554c16ec2f4f9df..7574fba03dc1ba44535dba83c17770f8591d25e1 100644 (file)
@@ -51,6 +51,11 @@ int check_trk_action(struct act_rule *rule, struct proxy *px, char **err)
                          trk_idx(rule->action));
                return 0;
        }
+       else if (px->bind_proc & ~target->bind_proc) {
+               memprintf(err, "stick-table '%s' referenced by 'track-sc%d' rule not present on all processes covered by proxy '%s'",
+                         target->id, trk_idx(rule->action), px->id);
+               return 0;
+       }
        else {
                free(rule->arg.trk_ctr.table.n);
                rule->arg.trk_ctr.table.t = &target->table;
index 3e8a7f5c3a0788550a1d1fe2d7aef1d0e52aef12..a51771d44f3adeb54893c4fcfc117a8755172b25 100644 (file)
@@ -2649,6 +2649,11 @@ int check_config_validity()
                                         curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
                                cfgerr++;
                        }
+                       else if (curproxy->bind_proc & ~target->bind_proc) {
+                               ha_alert("Proxy '%s': stick-table '%s' referenced 'stick-store' rule not present on all processes covered by proxy '%s'.\n",
+                                        curproxy->id, target->id, curproxy->id);
+                               return 0;
+                       }
                        else {
                                free((void *)mrule->table.name);
                                mrule->table.t = &(target->table);
@@ -2682,6 +2687,11 @@ int check_config_validity()
                                         curproxy->id, mrule->table.name ? mrule->table.name : curproxy->id);
                                cfgerr++;
                        }
+                       else if (curproxy->bind_proc & ~target->bind_proc) {
+                               ha_alert("Proxy '%s': stick-table '%s' referenced 'stick-store' rule not present on all processes covered by proxy '%s'.\n",
+                                        curproxy->id, target->id, curproxy->id);
+                               return 0;
+                       }
                        else {
                                free((void *)mrule->table.name);
                                mrule->table.t = &(target->table);
index 88217501d4c7e24f97aacac9bece53de050a0114..963cb597d2512b253d478154b10d4dd35eb09d54 100644 (file)
@@ -1264,6 +1264,12 @@ int smp_resolve_args(struct proxy *p)
                                break;
                        }
 
+                       if (p->bind_proc & ~px->bind_proc) {
+                               ha_alert("parsing [%s:%d] : stick-table '%s' not present on all processes covered by proxy '%s'.\n",
+                                        cur->file, cur->line, px->id, p->id);
+                               return 0;
+                       }
+
                        free(arg->data.str.area);
                        arg->data.str.area = NULL;
                        arg->unresolved = 0;