]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MAJOR: ensure that hdr_idx is always reserved when L7 fetches are used
authorWilly Tarreau <w@1wt.eu>
Fri, 5 Oct 2012 20:41:26 +0000 (22:41 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 5 Oct 2012 20:46:09 +0000 (22:46 +0200)
Baptiste Assmann reported a bug causing a crash on recent versions when
sticking rules were set on layer 7 in a TCP proxy. The bug is easier to
reproduce with the "defer-accept" option on the "bind" line in order to
have some contents to parse when the connection is accepted. The issue
is that the acl_prefetch_http() function called from HTTP fetches relies
on hdr_idx to be preinitialized, which is not the case if there is no L7
ACL.

The solution consists in adding a new SMP_CAP_L7 flag to fetches to indicate
that they are expected to work on L7 data, so that the proxy knows that the
hdr_idx has to be initialized. This is already how ACL and HTTP mode are
handled.

The bug was present since 1.5-dev9.

include/types/sample.h
src/cfgparse.c
src/proto_http.c

index bc1aad29a9ae793ca994a85fdc540649f7232e5f..6c19ade139101244100f6fb16791747ee0da7812 100644 (file)
@@ -50,6 +50,7 @@ enum {
 enum {
        SMP_CAP_REQ = 1 << 0, /* fetch supported on request */
        SMP_CAP_RES = 1 << 1, /* fetch supported on response */
+       SMP_CAP_L7  = 1 << 2, /* fetch may require access to L7 */
 };
 
 /* Sample fetch options are passed to sample fetch functions to add precision
index 9d47dae20f66bafdf70c6f6c0a04b04a1a684399..7da0d9756f545d8abfd2eee10d60c9929d8bf6d1 100644 (file)
@@ -2945,6 +2945,10 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
                        }
                }
 
+               /* check if we need to allocate an hdr_idx struct for HTTP parsing */
+               if (expr->fetch->cap & SMP_CAP_L7)
+                       curproxy->acl_requires |= ACL_USE_L7_ANY;
+
                if (strcmp(args[myidx], "table") == 0) {
                        myidx++;
                        name = args[myidx++];
index dfd8f3f7a1acf9c7ff25b799e9950b5a203d7bee..a45cd0f1a269c39b3f7f81fb560eb5f2f8654853 100644 (file)
@@ -8780,15 +8780,15 @@ static struct acl_kw_list acl_kws = {{ },{
 /************************************************************************/
 /* Note: must not be declared <const> as its list will be overwritten */
 static struct sample_fetch_kw_list sample_fetch_keywords = {{ },{
-       { "hdr",        smp_fetch_hdr,            ARG2(1,STR,SINT), val_hdr, SMP_T_CSTR, SMP_CAP_REQ },
-       { "base",       smp_fetch_base,           0,           NULL, SMP_T_CSTR, SMP_CAP_REQ },
-       { "path",       smp_fetch_path,           0,           NULL, SMP_T_CSTR, SMP_CAP_REQ },
-       { "url",        smp_fetch_url,            0,           NULL, SMP_T_CSTR, SMP_CAP_REQ },
-       { "url_ip",     smp_fetch_url_ip,         0,           NULL, SMP_T_IPV4, SMP_CAP_REQ },
-       { "url_port",   smp_fetch_url_port,       0,           NULL, SMP_T_UINT, SMP_CAP_REQ },
-       { "url_param",  smp_fetch_url_param,      ARG2(1,STR,STR), NULL, SMP_T_CSTR, SMP_CAP_REQ },
-       { "cookie",     smp_fetch_cookie,         ARG1(1,STR), NULL, SMP_T_CSTR, SMP_CAP_REQ|SMP_CAP_RES },
-       { "set-cookie", smp_fetch_cookie,         ARG1(1,STR), NULL, SMP_T_CSTR, SMP_CAP_RES }, /* deprecated */
+       { "hdr",        smp_fetch_hdr,            ARG2(1,STR,SINT), val_hdr, SMP_T_CSTR, SMP_CAP_L7|SMP_CAP_REQ },
+       { "base",       smp_fetch_base,           0,                NULL,    SMP_T_CSTR, SMP_CAP_L7|SMP_CAP_REQ },
+       { "path",       smp_fetch_path,           0,                NULL,    SMP_T_CSTR, SMP_CAP_L7|SMP_CAP_REQ },
+       { "url",        smp_fetch_url,            0,                NULL,    SMP_T_CSTR, SMP_CAP_L7|SMP_CAP_REQ },
+       { "url_ip",     smp_fetch_url_ip,         0,                NULL,    SMP_T_IPV4, SMP_CAP_L7|SMP_CAP_REQ },
+       { "url_port",   smp_fetch_url_port,       0,                NULL,    SMP_T_UINT, SMP_CAP_L7|SMP_CAP_REQ },
+       { "url_param",  smp_fetch_url_param,      ARG2(1,STR,STR),  NULL,    SMP_T_CSTR, SMP_CAP_L7|SMP_CAP_REQ },
+       { "cookie",     smp_fetch_cookie,         ARG1(1,STR),      NULL,    SMP_T_CSTR, SMP_CAP_L7|SMP_CAP_REQ|SMP_CAP_RES },
+       { "set-cookie", smp_fetch_cookie,         ARG1(1,STR),      NULL,    SMP_T_CSTR, SMP_CAP_L7|SMP_CAP_RES }, /* deprecated */
        { NULL, NULL, 0, 0, 0 },
 }};