]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MAJOR: counters: check for null-deref when looking up an alternate table
authorWilly Tarreau <w@1wt.eu>
Wed, 9 Apr 2014 11:25:42 +0000 (13:25 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 9 Apr 2014 11:32:11 +0000 (13:32 +0200)
Constructions such as sc0_get_gpc0(foo) allow to look up the same key as
the current key but in an alternate table. A check was missing to ensure
we already have a key, resulting in a crash if this lookup is performed
before the associated track-sc rule.

This bug was reported on the mailing list by Neil@iamafreeman and
narrowed down further by Lukas Tribus and Thierry Fournier.

This bug was introduced in 1.5-dev20 by commit "0f791d4 MEDIUM: counters:
support looking up a key in an alternate table".

src/session.c

index efc0736ec0a8b640bddaf343e48fddab343031fb..cada0ab99fe96d49372538d36d211a0658883e9f 100644 (file)
@@ -2639,6 +2639,7 @@ static struct stkctr *
 smp_fetch_sc_stkctr(struct session *l4, const struct arg *args, const char *kw)
 {
        static struct stkctr stkctr;
+       struct stksess *stksess;
        unsigned int num = kw[2] - '0';
        int arg = 0;
 
@@ -2668,13 +2669,17 @@ smp_fetch_sc_stkctr(struct session *l4, const struct arg *args, const char *kw)
         * the sc[0-9]_ form, or even higher using sc_(num) if needed.
         * args[arg] is the first optional argument.
         */
+       stksess = stkctr_entry(&l4->stkctr[num]);
+       if (!stksess)
+               return NULL;
+
        if (unlikely(args[arg].type == ARGT_TAB)) {
                /* an alternate table was specified, let's look up the same key there */
                stkctr.table = &args[arg].data.prx->table;
-               stkctr_set_entry(&stkctr, stktable_lookup(stkctr.table, stkctr_entry(&l4->stkctr[num])));
+               stkctr_set_entry(&stkctr, stktable_lookup(stkctr.table, stksess));
                return &stkctr;
        }
-       return stkctr_entry(&l4->stkctr[num]) ? &l4->stkctr[num] : NULL;
+       return &l4->stkctr[num];
 }
 
 /* set return a boolean indicating if the requested session counter is