summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2014-11-28 19:04:21 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2014-11-28 19:41:58 +0100
commitd297735543a8c32b83e40563f01fea33e233b4ef (patch)
treec1a512da3971f64295d749a06ddf7f2561af1dfe
parent8ff7fed3b0d866268322d27511ddc73fbd8c77c8 (diff)
datatype: fix crash when using basetype instead of symbolic constants
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>
-rw-r--r--src/datatype.c33
-rw-r--r--tests/regression/any/ct.t1
2 files changed, 21 insertions, 13 deletions
diff --git a/src/datatype.c b/src/datatype.c
index 5f976aa3..7c9c3d48 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -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;
}
diff --git a/tests/regression/any/ct.t b/tests/regression/any/ct.t
index 7ce898de..79674ee7 100644
--- a/tests/regression/any/ct.t
+++ b/tests/regression/any/ct.t
@@ -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