]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
evaluate: check for NULL datatype in rhs in lookup expr
authorArturo Borrero <arturo.borrero.glez@gmail.com>
Wed, 11 May 2016 11:30:02 +0000 (13:30 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 13 May 2016 09:34:42 +0000 (11:34 +0200)
If we are evaluating an EXPR_SET_REF, check if right->dtype is not NULL.
We can hit SEGFAULT if for whatever reason the referenced object does not
exist.

Using this testfile (note the invalid set syntax):

% cat test.nft
flush ruleset
add table t
add chain t c
add set t s {type ipv4_addr\;}
add rule t c ip saddr @s

Without this patch:

% nft -f test.nft
Segmentation fault

With this patch:

% nft -f test.nft
t.nft:4:28-28: Error: syntax error, unexpected junk, expecting newline or semicolon
add set t s {type ipv4_addr\;}
                           ^
t.nft:4:13-29: Error: set definition does not specify key data type
add set t s {type ipv4_addr\;}
            ^^^^^^^^^^^^^^^^^
t.nft:5:23-24: Error: the referenced set does not exist
add rule t c ip saddr @s
             ~~~~~~~~ ^^

Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/evaluate.c

index fcd4ecdafc6ad656d40bcfbf3eaecd652e71e674..3afb8eade7372ace7ac13b057755f5e62a99a906 100644 (file)
@@ -1381,16 +1381,32 @@ static int expr_evaluate_relational(struct eval_ctx *ctx, struct expr **expr)
 
        switch (rel->op) {
        case OP_LOOKUP:
-               /* A literal set expression implicitly declares the set */
-               if (right->ops->type == EXPR_SET)
+               switch (right->ops->type) {
+               case EXPR_SET:
+                       /* A literal set expression implicitly declares
+                        * the set
+                        */
                        right = rel->right =
-                               implicit_set_declaration(ctx, left->dtype, left->len, right);
-               else if (!datatype_equal(left->dtype, right->dtype))
-                       return expr_binary_error(ctx->msgs, right, left,
-                                                "datatype mismatch, expected %s, "
-                                                "set has type %s",
-                                                left->dtype->desc,
-                                                right->dtype->desc);
+                               implicit_set_declaration(ctx, left->dtype,
+                                                        left->len, right);
+                       break;
+               case EXPR_SET_REF:
+                       if (right->dtype == NULL)
+                               return expr_binary_error(ctx->msgs, right,
+                                                        left, "the referenced"
+                                                        " set does not "
+                                                        "exist");
+                       if (!datatype_equal(left->dtype, right->dtype))
+                               return expr_binary_error(ctx->msgs, right,
+                                                        left, "datatype "
+                                                        "mismatch, expected "
+                                                        "%s, set has type %s",
+                                                        left->dtype->desc,
+                                                        right->dtype->desc);
+                       break;
+               default:
+                       BUG("Unknown expression %s\n", right->ops->name);
+               }
 
                /* Data for range lookups needs to be in big endian order */
                if (right->set->flags & SET_F_INTERVAL &&