]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
datatype: fix crash when using basetype instead of symbolic constants
authorPablo Neira Ayuso <pablo@netfilter.org>
Fri, 28 Nov 2014 18:04:21 +0000 (19:04 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 28 Nov 2014 18:41:58 +0000 (19:41 +0100)
The following example:

 # nft add rule filter input ct state 8 accept
 Segmentation fault

leads to a crash because we have the following datatype relation:

 ct_state -> bitmask -> integer

The bitmask, which is an intermediate basetype, has no parse()
function, this leads to a crash in symbolic_constant_parse().

Patrick suggested to walk down the chain until we find a parser
function.

Reported-by: leroy christophe <christophe.leroy@c-s.fr>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/datatype.c
tests/regression/any/ct.t

index 5f976aa3e96a08b3f89394d99748fb9e13cd12fa..7c9c3d488dbeefdb906d62de9943dd4bfc39034a 100644 (file)
@@ -125,21 +125,28 @@ struct error_record *symbolic_constant_parse(const struct expr *sym,
                        break;
        }
 
-       dtype = sym->dtype;
-       if (s->identifier == NULL) {
-               *res = NULL;
-               erec = sym->dtype->basetype->parse(sym, res);
-               if (erec != NULL)
-                       return erec;
-               if (*res)
-                       return NULL;
+       if (s->identifier != NULL)
+               goto out;
 
-               return error(&sym->location, "Could not parse %s", dtype->desc);
-       }
+       dtype = sym->dtype;
+       *res = NULL;
+       do {
+               if (dtype->basetype->parse) {
+                       erec = dtype->basetype->parse(sym, res);
+                       if (erec != NULL)
+                               return erec;
+                       if (*res)
+                               return NULL;
+                       goto out;
+               }
+       } while ((dtype = dtype->basetype));
 
-       *res = constant_expr_alloc(&sym->location, dtype,
-                                  dtype->byteorder, dtype->size,
-                                  constant_data_ptr(s->value, dtype->size));
+       return error(&sym->location, "Could not parse %s", sym->dtype->desc);
+out:
+       *res = constant_expr_alloc(&sym->location, sym->dtype,
+                                  sym->dtype->byteorder, sym->dtype->size,
+                                  constant_data_ptr(s->value,
+                                  sym->dtype->size));
        return NULL;
 }
 
index 7ce898dec69f577a14e74c9467d3170a8509203e..79674ee74b2cffccc32f31729270d6ea8a924507 100644 (file)
@@ -13,6 +13,7 @@ ct state {new,established, related, untracked};ok
 - ct state != {new,established, related, untracked};ok
 ct state invalid drop;ok
 ct state established accept;ok
+ct state 8;ok;ct state new
 
 ct direction original;ok
 ct direction != original;ok