]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
nftables: don't crash in 'list ruleset' if policy is not set
authorSergei Trofimovich <slyfox@gentoo.org>
Mon, 16 Sep 2019 07:33:20 +0000 (08:33 +0100)
committerFlorian Westphal <fw@strlen.de>
Mon, 16 Sep 2019 07:52:14 +0000 (09:52 +0200)
Minimal reproducer:

```
  $ cat nft.ruleset
    # filters
    table inet filter {
        chain prerouting {
            type filter hook prerouting priority -50
        }
    }

    # dump new state
    list ruleset

  $ nft -c -f ./nft.ruleset
    table inet filter {
    chain prerouting {
    Segmentation fault (core dumped)
```

The crash happens in `chain_print_declaration()`:

```
    if (chain->flags & CHAIN_F_BASECHAIN) {
        mpz_export_data(&policy, chain->policy->value,
                        BYTEORDER_HOST_ENDIAN, sizeof(int));
```

Here `chain->policy` is `NULL` (as textual rule does not mention it).

The change is not to print the policy if it's not set
(similar to `chain_evaluate()` handling).

CC: Florian Westphal <fw@strlen.de>
CC: Pablo Neira Ayuso <pablo@netfilter.org>
CC: netfilter-devel@vger.kernel.org
Bug: https://bugzilla.netfilter.org/show_bug.cgi?id=1365
Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
Acked-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
src/rule.c
tests/shell/testcases/nft-f/0021list_ruleset_0 [new file with mode: 0755]
tests/shell/testcases/nft-f/dumps/0021list_ruleset_0.nft [new file with mode: 0644]

index 5bb1c1d307895af3a73f23f9880d4bb719f71af2..0cc1fa5959180bc34a8416cdc63f31c614d812a1 100644 (file)
@@ -1107,17 +1107,21 @@ static void chain_print_declaration(const struct chain *chain,
                nft_print(octx, " # handle %" PRIu64, chain->handle.handle.id);
        nft_print(octx, "\n");
        if (chain->flags & CHAIN_F_BASECHAIN) {
-               mpz_export_data(&policy, chain->policy->value,
-                               BYTEORDER_HOST_ENDIAN, sizeof(int));
                nft_print(octx, "\t\ttype %s hook %s", chain->type,
                          hooknum2str(chain->handle.family, chain->hooknum));
                if (chain->dev != NULL)
                        nft_print(octx, " device \"%s\"", chain->dev);
-               nft_print(octx, " priority %s; policy %s;\n",
+               nft_print(octx, " priority %s;",
                          prio2str(octx, priobuf, sizeof(priobuf),
                                   chain->handle.family, chain->hooknum,
-                                  chain->priority.expr),
-                         chain_policy2str(policy));
+                                  chain->priority.expr));
+               if (chain->policy) {
+                       mpz_export_data(&policy, chain->policy->value,
+                                       BYTEORDER_HOST_ENDIAN, sizeof(int));
+                       nft_print(octx, " policy %s;",
+                                 chain_policy2str(policy));
+               }
+               nft_print(octx, "\n");
        }
 }
 
diff --git a/tests/shell/testcases/nft-f/0021list_ruleset_0 b/tests/shell/testcases/nft-f/0021list_ruleset_0
new file mode 100755 (executable)
index 0000000..37729b4
--- /dev/null
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+# Tests use of variables in jump statements
+
+set -e
+
+RULESET="table filter {
+ chain prerouting {
+  type filter hook prerouting priority -50
+ }
+}
+list  ruleset
+"
+
+exec $NFT -f - <<< "$RULESET"
diff --git a/tests/shell/testcases/nft-f/dumps/0021list_ruleset_0.nft b/tests/shell/testcases/nft-f/dumps/0021list_ruleset_0.nft
new file mode 100644 (file)
index 0000000..b2cd401
--- /dev/null
@@ -0,0 +1,5 @@
+table ip filter {
+       chain prerouting {
+               type filter hook prerouting priority -50; policy accept;
+       }
+}