]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
netfilter: nf_tables: report EEXIST on overlaps
authorPablo Neira Ayuso <pablo@netfilter.org>
Sun, 2 Aug 2020 01:05:25 +0000 (03:05 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sun, 2 Aug 2020 17:53:45 +0000 (19:53 +0200)
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>
net/netfilter/nf_tables_api.c

index fac552b0179fc8b3cb7e07379b0de1d9a110e3fc..6571789989bccae1dd4b26206c6ce2fde7550cce 100644 (file)
@@ -2097,7 +2097,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);
@@ -2107,21 +2107,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);
@@ -5262,10 +5262,8 @@ 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),
@@ -5273,7 +5271,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
                            (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) {
@@ -6423,7 +6421,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;
                                }
                        }