]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
evaluate: fix segfault when adding elements to invalid set
authorPeter Tirsek <peter@tirsek.com>
Sun, 26 Jun 2022 05:47:07 +0000 (00:47 -0500)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 27 Jun 2022 10:12:23 +0000 (12:12 +0200)
Adding elements to a set or map with an invalid definition causes nft to
segfault. The following nftables.conf triggers the crash:

    flush ruleset
    create table inet filter
    set inet filter foo {}
    add element inet filter foo { foobar }

Simply parsing and checking the config will trigger it:

    $ nft -c -f nftables.conf.crash
    Segmentation fault

The error in the set/map definition is correctly caught and queued, but
because the set is invalid and does not contain a key type, adding to it
causes a NULL pointer dereference of set->key within setelem_evaluate().

I don't think it's necessary to queue another error since the underlying
problem is correctly detected and reported when parsing the definition
of the set. Simply checking the validity of set->key before using it
seems to fix it, causing the error in the definition of the set to be
reported properly. The element type error isn't caught, but that seems
reasonable since the key type is invalid or unknown anyway:

    $ ./nft -c -f ~/nftables.conf.crash
    /home/pti/nftables.conf.crash:3:21-21: Error: set definition does not specify key
    set inet filter foo {}
                        ^

[ Add tests to cover this case --pablo ]

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1597
Signed-off-by: Peter Tirsek <peter@tirsek.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/evaluate.c
tests/shell/testcases/sets/errors_0

index 82bf1311fa5304284e10bc376b734b2d07164ff7..073bf8717236bba7fca5106aa12d89f30490f721 100644 (file)
@@ -3996,6 +3996,9 @@ static int setelem_evaluate(struct eval_ctx *ctx, struct cmd *cmd)
                return set_not_found(ctx, &ctx->cmd->handle.set.location,
                                     ctx->cmd->handle.set.name);
 
+       if (set->key == NULL)
+               return -1;
+
        set->existing_set = set;
        ctx->set = set;
        expr_set_context(&ctx->ectx, set->key->dtype, set->key->len);
index a676ac7331c8b943decf21d440eddd2c03f56879..569f4ab830cd58d45a9123bae5f6108c1f676493 100755 (executable)
@@ -27,4 +27,15 @@ delete element x y { 1.1.1.1/24 }
 add element x y { 1.1.1.1/24 }
 delete element x y { 2.2.2.2/24 }"
 
+$NFT -f - <<< $RULESET
+if [ $? -eq 0 ]
+then
+       exit 1
+fi
+
+RULESET="flush ruleset
+create table inet filter
+set inet filter foo {}
+add element inet filter foo { foobar }"
+
 $NFT -f - <<< $RULESET || exit 0