Commit f4c756b4 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso

netfilter: nf_tables: remove check against removal of inactive objects

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: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 5ebe0b0e
...@@ -832,8 +832,6 @@ static int nf_tables_deltable(struct net *net, struct sock *nlsk, ...@@ -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]); table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME]);
if (IS_ERR(table)) if (IS_ERR(table))
return PTR_ERR(table); return PTR_ERR(table);
if (table->flags & NFT_TABLE_INACTIVE)
return -ENOENT;
ctx.afi = afi; ctx.afi = afi;
ctx.table = table; ctx.table = table;
...@@ -1493,14 +1491,10 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk, ...@@ -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]); table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE]);
if (IS_ERR(table)) if (IS_ERR(table))
return PTR_ERR(table); return PTR_ERR(table);
if (table->flags & NFT_TABLE_INACTIVE)
return -ENOENT;
chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME]); chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME]);
if (IS_ERR(chain)) if (IS_ERR(chain))
return PTR_ERR(chain); return PTR_ERR(chain);
if (chain->flags & NFT_CHAIN_INACTIVE)
return -ENOENT;
if (chain->use > 0) if (chain->use > 0)
return -EBUSY; return -EBUSY;
...@@ -2192,8 +2186,6 @@ static int nf_tables_delrule(struct net *net, struct sock *nlsk, ...@@ -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]); table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE]);
if (IS_ERR(table)) if (IS_ERR(table))
return PTR_ERR(table); return PTR_ERR(table);
if (table->flags & NFT_TABLE_INACTIVE)
return -ENOENT;
if (nla[NFTA_RULE_CHAIN]) { if (nla[NFTA_RULE_CHAIN]) {
chain = nf_tables_chain_lookup(table, 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, ...@@ -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]); table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE]);
if (IS_ERR(table)) if (IS_ERR(table))
return PTR_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); 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, ...@@ -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]); set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]);
if (IS_ERR(set)) if (IS_ERR(set))
return PTR_ERR(set); return PTR_ERR(set);
if (set->flags & NFT_SET_INACTIVE)
return -ENOENT;
if (!list_empty(&set->bindings)) if (!list_empty(&set->bindings))
return -EBUSY; return -EBUSY;
...@@ -3022,8 +3010,7 @@ static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX + ...@@ -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, static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net,
const struct sk_buff *skb, const struct sk_buff *skb,
const struct nlmsghdr *nlh, const struct nlmsghdr *nlh,
const struct nlattr * const nla[], const struct nlattr * const nla[])
bool trans)
{ {
const struct nfgenmsg *nfmsg = nlmsg_data(nlh); const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
struct nft_af_info *afi; struct nft_af_info *afi;
...@@ -3036,8 +3023,6 @@ static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net, ...@@ -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]); table = nf_tables_table_lookup(afi, nla[NFTA_SET_ELEM_LIST_TABLE]);
if (IS_ERR(table)) if (IS_ERR(table))
return PTR_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); nft_ctx_init(ctx, net, skb, nlh, afi, table, NULL, nla);
return 0; return 0;
...@@ -3146,9 +3131,11 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -3146,9 +3131,11 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
return err; return err;
err = nft_ctx_init_from_elemattr(&ctx, net, cb->skb, cb->nlh, err = nft_ctx_init_from_elemattr(&ctx, net, cb->skb, cb->nlh,
(void *)nla, false); (void *)nla);
if (err < 0) if (err < 0)
return err; return err;
if (ctx.table->flags & NFT_TABLE_INACTIVE)
return -ENOENT;
set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]); set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
if (IS_ERR(set)) if (IS_ERR(set))
...@@ -3212,9 +3199,11 @@ static int nf_tables_getsetelem(struct sock *nlsk, struct sk_buff *skb, ...@@ -3212,9 +3199,11 @@ static int nf_tables_getsetelem(struct sock *nlsk, struct sk_buff *skb,
struct nft_ctx ctx; struct nft_ctx ctx;
int err; 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) if (err < 0)
return err; return err;
if (ctx.table->flags & NFT_TABLE_INACTIVE)
return -ENOENT;
set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]); set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
if (IS_ERR(set)) if (IS_ERR(set))
...@@ -3536,7 +3525,7 @@ static int nf_tables_newsetelem(struct net *net, struct sock *nlsk, ...@@ -3536,7 +3525,7 @@ static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
return -EINVAL; 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) if (err < 0)
return err; return err;
...@@ -3630,7 +3619,7 @@ static int nf_tables_delsetelem(struct net *net, struct sock *nlsk, ...@@ -3630,7 +3619,7 @@ static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
return -EINVAL; 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) if (err < 0)
return err; return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment