]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: http rule: http capture 'id' rule points to a non existing id
authorBaptiste Assmann <bedis9@gmail.com>
Tue, 3 Nov 2015 22:31:35 +0000 (23:31 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 4 Nov 2015 07:47:55 +0000 (08:47 +0100)
It is possible to create a http capture rule which points to a capture slot
id which does not exist.

Current patch prevent this when parsing configuration and prevent running
configuration which contains such rules.

This configuration is now invalid:

  frontend f
   bind :8080
   http-request capture req.hdr(User-Agent) id 0
   default_backend b

this one as well:

  frontend f
   bind :8080
   declare capture request len 32 # implicit id is 0 here
   http-request capture req.hdr(User-Agent) id 1
   default_backend b

It applies of course to both http-request and http-response rules.

doc/configuration.txt
include/proto/proto_http.h
src/cfgparse.c

index c3966d709bb6fe67b35a7ea12cc4dee9dc4c708e..997d838b110a3e81424b062d744dd34357e48a4d 100644 (file)
@@ -3655,6 +3655,8 @@ http-request { allow | deny | tarpit | auth [realm <realm>] | redirect <rule> |
       the captured string in a previously declared capture slot. This is useful
       to run captures in backends. The slot id can be declared by a previous
       directive "http-request capture" or with the "declare capture" keyword.
+      If the slot <id> doesn't exist, then HAProxy fails parsing the
+      configuration to prevent unexpected behavior at run time.
 
     - { track-sc0 | track-sc1 | track-sc2 } <key> [table <table>] :
       enables tracking of sticky counters from current request. These rules
@@ -4003,6 +4005,8 @@ http-response { allow | deny | add-header <name> <fmt> | set-nice <nice> |
       This is useful to run captures in backends. The slot id can be declared by
       a previous directive "http-response capture" or with the "declare capture"
       keyword.
+      If the slot <id> doesn't exist, then HAProxy fails parsing the
+      configuration to prevent unexpected behavior at run time.
 
     - "redirect" : this performs an HTTP redirection based on a redirect rule.
       This supports a format string similarly to "http-request redirect" rules,
index 0446b45d6d1a12ed1b878a0194b4c393e20106a7..a1b0cb3705a758800037790c749a7642aaf35a37 100644 (file)
@@ -147,6 +147,11 @@ int val_hdr(struct arg *arg, char **err_msg);
 int smp_prefetch_http(struct proxy *px, struct stream *s, unsigned int opt,
                   const struct arg *args, struct sample *smp, int req_vol);
 
+enum act_return http_action_req_capture_by_id(struct act_rule *rule, struct proxy *px,
+                                              struct session *sess, struct stream *s, int flags);
+enum act_return http_action_res_capture_by_id(struct act_rule *rule, struct proxy *px,
+                                              struct session *sess, struct stream *s, int flags);
+
 /* Note: these functions *do* modify the sample. Even in case of success, at
  * least the type and uint value are modified.
  */
index f4bc5033ef00cc55c409876a30edff59c8ddbc34..44070a541e9c543af83beb15c9bff63280009cc2 100644 (file)
@@ -7751,6 +7751,32 @@ int check_config_validity()
                        }
                }
 
+               /* parse http-request capture rules to ensure id really exists */
+               list_for_each_entry(hrqrule, &curproxy->http_req_rules, list) {
+                       if (hrqrule->action  != ACT_CUSTOM ||
+                           hrqrule->action_ptr != http_action_req_capture_by_id)
+                               continue;
+
+                       if (hrqrule->arg.capid.idx >= curproxy->nb_req_cap) {
+                               Alert("Proxy '%s': unable to find capture id '%d' referenced by http-request capture rule.\n",
+                                     curproxy->id, hrqrule->arg.capid.idx);
+                               cfgerr++;
+                       }
+               }
+
+               /* parse http-response capture rules to ensure id really exists */
+               list_for_each_entry(hrqrule, &curproxy->http_res_rules, list) {
+                       if (hrqrule->action  != ACT_CUSTOM ||
+                           hrqrule->action_ptr != http_action_res_capture_by_id)
+                               continue;
+
+                       if (hrqrule->arg.capid.idx >= curproxy->nb_rsp_cap) {
+                               Alert("Proxy '%s': unable to find capture id '%d' referenced by http-response capture rule.\n",
+                                     curproxy->id, hrqrule->arg.capid.idx);
+                               cfgerr++;
+                       }
+               }
+
                /* find the target table for 'http-request' layer 7 rules */
                list_for_each_entry(hrqrule, &curproxy->http_req_rules, list) {
                        struct proxy *target;