]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
xtables: Fix for segfault in iptables-nft
authorPhil Sutter <phil@nwl.cc>
Fri, 17 Aug 2018 13:35:47 +0000 (15:35 +0200)
committerFlorian Westphal <fw@strlen.de>
Fri, 17 Aug 2018 14:15:23 +0000 (16:15 +0200)
Trying to set a chain's policy in an invalid table resulted in a
segfault. Reproducer was:

| # iptables -t broute -P BROUTING ACCEPT

Fix this by aborting in nft_chain_new() if nft_table_builtin_find()
returned NULL for the given table name.

For an illustrative error message, set errno to ENXIO in the above case
and add an appropriate Mesage to nft_strerror().

While being at it, improve the error message if an invalid policy was
given. Before:

| # iptables-nft -t filter -P INPUT ACCEPTdf
| iptables: Incompatible with this kernel.

After:

| # iptables-nft -t filter -P INPUT ACCEPTdf
| iptables: Bad policy name. Run `dmesg' for more information.

Third unrelated change in this patch: Drop error checking of
nft_chain_set() in do_commandx(): The function never returns negative,
so that check never yielded true.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Florian Westphal <fw@strlen.de>
iptables/nft.c
iptables/xtables.c

index 0b29caeb7c59e53cab58d718e7d8a375b57b746b..dd8469a920dcc316a05caa5a9019790f407950a8 100644 (file)
@@ -833,9 +833,13 @@ static struct nftnl_chain *nft_chain_new(struct nft_handle *h,
        struct builtin_chain *_c;
 
        _t = nft_table_builtin_find(h, table);
+       if (!_t) {
+               errno = ENXIO;
+               return NULL;
+       }
+
        /* if this built-in table does not exists, create it */
-       if (_t != NULL)
-               nft_table_builtin_add(h, _t);
+       nft_table_builtin_add(h, _t);
 
        _c = nft_chain_builtin_find(_t, chain);
        if (_c != NULL) {
@@ -871,6 +875,8 @@ int nft_chain_set(struct nft_handle *h, const char *table,
                c = nft_chain_new(h, table, chain, NF_DROP, counters);
        else if (strcmp(policy, "ACCEPT") == 0)
                c = nft_chain_new(h, table, chain, NF_ACCEPT, counters);
+       else
+               errno = EINVAL;
 
        if (c == NULL)
                return 0;
@@ -2828,6 +2834,7 @@ const char *nft_strerror(int err)
              "Bad rule (does a matching rule exist in that chain?)" },
            { nft_chain_set, ENOENT, "Bad built-in chain name" },
            { nft_chain_set, EINVAL, "Bad policy name" },
+           { nft_chain_set, ENXIO, "Bad table name" },
            { NULL, ELOOP, "Loop found in table" },
            { NULL, EPERM, "Permission denied (you must be root)" },
            { NULL, 0, "Incompatible with this kernel" },
index d9050b45c2c36c6794935edac9ccec3f510e3244..72f6596251da069ff94f9bb5fe013d3b9e41f1a7 100644 (file)
@@ -1266,9 +1266,6 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
                break;
        case CMD_SET_POLICY:
                ret = nft_chain_set(h, p.table, p.chain, p.policy, NULL);
-               if (ret < 0)
-                       xtables_error(PARAMETER_PROBLEM, "Wrong policy `%s'\n",
-                                     p.policy);
                break;
        default:
                /* We should never reach this... */