netfilter: nf_tables: remove check against removal of inactive objects
authorPablo Neira Ayuso <pablo@netfilter.org>
Tue, 15 Dec 2015 18:40:50 +0000 (19:40 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 28 Dec 2015 17:37:20 +0000 (18:37 +0100)
The following sequence inside a batch, although not very useful, is
valid:

 add table foo
 ...
 delete table foo

This may be generated by some robot while applying some incremental
upgrade, so remove the defensive checks against this.

This patch keeps the check on the get/dump path by now, we have to
replace the inactive flag by introducing object generations.

Reported-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/nf_tables_api.c

index 5729844..28cbc45 100644 (file)
@@ -832,8 +832,6 @@ static int nf_tables_deltable(struct net *net, struct sock *nlsk,
        table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME]);
        if (IS_ERR(table))
                return PTR_ERR(table);
-       if (table->flags & NFT_TABLE_INACTIVE)
-               return -ENOENT;
 
        ctx.afi = afi;
        ctx.table = table;
@@ -1493,14 +1491,10 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk,
        table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE]);
        if (IS_ERR(table))
                return PTR_ERR(table);
-       if (table->flags & NFT_TABLE_INACTIVE)
-               return -ENOENT;
 
        chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME]);
        if (IS_ERR(chain))
                return PTR_ERR(chain);
-       if (chain->flags & NFT_CHAIN_INACTIVE)
-               return -ENOENT;
        if (chain->use > 0)
                return -EBUSY;
 
@@ -2192,8 +2186,6 @@ static int nf_tables_delrule(struct net *net, struct sock *nlsk,
        table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE]);
        if (IS_ERR(table))
                return PTR_ERR(table);
-       if (table->flags & NFT_TABLE_INACTIVE)
-               return -ENOENT;
 
        if (nla[NFTA_RULE_CHAIN]) {
                chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]);
@@ -2362,8 +2354,6 @@ static int nft_ctx_init_from_setattr(struct nft_ctx *ctx, struct net *net,
                table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE]);
                if (IS_ERR(table))
                        return PTR_ERR(table);
-               if (table->flags & NFT_TABLE_INACTIVE)
-                       return -ENOENT;
        }
 
        nft_ctx_init(ctx, net, skb, nlh, afi, table, NULL, nla);
@@ -2898,8 +2888,6 @@ static int nf_tables_delset(struct net *net, struct sock *nlsk,
        set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]);
        if (IS_ERR(set))
                return PTR_ERR(set);
-       if (set->flags & NFT_SET_INACTIVE)
-               return -ENOENT;
        if (!list_empty(&set->bindings))
                return -EBUSY;
 
@@ -3022,8 +3010,7 @@ static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX +
 static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net,
                                      const struct sk_buff *skb,
                                      const struct nlmsghdr *nlh,
-                                     const struct nlattr * const nla[],
-                                     bool trans)
+                                     const struct nlattr * const nla[])
 {
        const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
        struct nft_af_info *afi;
@@ -3036,8 +3023,6 @@ static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net,
        table = nf_tables_table_lookup(afi, nla[NFTA_SET_ELEM_LIST_TABLE]);
        if (IS_ERR(table))
                return PTR_ERR(table);
-       if (!trans && (table->flags & NFT_TABLE_INACTIVE))
-               return -ENOENT;
 
        nft_ctx_init(ctx, net, skb, nlh, afi, table, NULL, nla);
        return 0;
@@ -3146,9 +3131,11 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
                return err;
 
        err = nft_ctx_init_from_elemattr(&ctx, net, cb->skb, cb->nlh,
-                                        (void *)nla, false);
+                                        (void *)nla);
        if (err < 0)
                return err;
+       if (ctx.table->flags & NFT_TABLE_INACTIVE)
+               return -ENOENT;
 
        set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
        if (IS_ERR(set))
@@ -3212,9 +3199,11 @@ static int nf_tables_getsetelem(struct sock *nlsk, struct sk_buff *skb,
        struct nft_ctx ctx;
        int err;
 
-       err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, false);
+       err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla);
        if (err < 0)
                return err;
+       if (ctx.table->flags & NFT_TABLE_INACTIVE)
+               return -ENOENT;
 
        set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
        if (IS_ERR(set))
@@ -3536,7 +3525,7 @@ static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
        if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
                return -EINVAL;
 
-       err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, true);
+       err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla);
        if (err < 0)
                return err;
 
@@ -3630,7 +3619,7 @@ static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
        if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
                return -EINVAL;
 
-       err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, false);
+       err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla);
        if (err < 0)
                return err;