Skip to content

Commit

Permalink
netfilter: nf_tables: report EEXIST on overlaps
Browse files Browse the repository at this point in the history
[ Upstream commit 77a9218 ]

Replace EBUSY by EEXIST in the following cases:

- If the user adds a chain with a different configuration such as different
  type, hook and priority.

- If the user adds a non-base chain that clashes with an existing basechain.

- If the user adds a { key : value } mapping element and the key exists
  but the value differs.

- If the device already belongs to an existing flowtable.

User describe that this error reporting is confusing:

- https://bugzilla.netfilter.org/show_bug.cgi?id=1176
- https://bugzilla.netfilter.org/show_bug.cgi?id=1413

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
ummakynes authored and gregkh committed Sep 3, 2020
1 parent 71e8627 commit 8ceddd7
Showing 1 changed file with 7 additions and 9 deletions.
16 changes: 7 additions & 9 deletions net/netfilter/nf_tables_api.c
Expand Up @@ -2037,7 +2037,7 @@ static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy,

if (nla[NFTA_CHAIN_HOOK]) {
if (!nft_is_base_chain(chain))
return -EBUSY;
return -EEXIST;

err = nft_chain_parse_hook(ctx->net, nla, &hook, ctx->family,
false);
Expand All @@ -2047,21 +2047,21 @@ static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy,
basechain = nft_base_chain(chain);
if (basechain->type != hook.type) {
nft_chain_release_hook(&hook);
return -EBUSY;
return -EEXIST;
}

if (ctx->family == NFPROTO_NETDEV) {
if (!nft_hook_list_equal(&basechain->hook_list,
&hook.list)) {
nft_chain_release_hook(&hook);
return -EBUSY;
return -EEXIST;
}
} else {
ops = &basechain->ops;
if (ops->hooknum != hook.num ||
ops->priority != hook.priority) {
nft_chain_release_hook(&hook);
return -EBUSY;
return -EEXIST;
}
}
nft_chain_release_hook(&hook);
Expand Down Expand Up @@ -5160,18 +5160,16 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) ^
nft_set_ext_exists(ext2, NFT_SET_EXT_DATA) ||
nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) ^
nft_set_ext_exists(ext2, NFT_SET_EXT_OBJREF)) {
err = -EBUSY;
nft_set_ext_exists(ext2, NFT_SET_EXT_OBJREF))
goto err_element_clash;
}
if ((nft_set_ext_exists(ext, NFT_SET_EXT_DATA) &&
nft_set_ext_exists(ext2, NFT_SET_EXT_DATA) &&
memcmp(nft_set_ext_data(ext),
nft_set_ext_data(ext2), set->dlen) != 0) ||
(nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) &&
nft_set_ext_exists(ext2, NFT_SET_EXT_OBJREF) &&
*nft_set_ext_obj(ext) != *nft_set_ext_obj(ext2)))
err = -EBUSY;
goto err_element_clash;
else if (!(nlmsg_flags & NLM_F_EXCL))
err = 0;
} else if (err == -ENOTEMPTY) {
Expand Down Expand Up @@ -6308,7 +6306,7 @@ static int nft_register_flowtable_net_hooks(struct net *net,
list_for_each_entry(hook2, &ft->hook_list, list) {
if (hook->ops.dev == hook2->ops.dev &&
hook->ops.pf == hook2->ops.pf) {
err = -EBUSY;
err = -EEXIST;
goto err_unregister_net_hooks;
}
}
Expand Down

0 comments on commit 8ceddd7

Please sign in to comment.