]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
netfilter: nf_tables: add nft_set_elem_expr_alloc()
authorPablo Neira Ayuso <pablo@netfilter.org>
Wed, 11 Mar 2020 14:30:12 +0000 (15:30 +0100)
committerThadeu Lima de Souza Cascardo <cascardo@canonical.com>
Wed, 1 Jun 2022 23:03:49 +0000 (20:03 -0300)
CVE-2022-1966

Add helper function to create stateful expression.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
(cherry picked from commit a7fc936804084145e2a6374e23744defdc948e09)
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
Acked-by: Andrea Righi <andrea.righi@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
include/net/netfilter/nf_tables.h
net/netfilter/nf_tables_api.c
net/netfilter/nft_dynset.c

index 886866bee8b2753c363892a7ed50157f49fa385b..c2867bf2f6f70cb2495a83023d12099ab2e63584 100644 (file)
@@ -655,6 +655,10 @@ static inline struct nft_object **nft_set_ext_obj(const struct nft_set_ext *ext)
        return nft_set_ext(ext, NFT_SET_EXT_OBJREF);
 }
 
+struct nft_expr *nft_set_elem_expr_alloc(const struct nft_ctx *ctx,
+                                        const struct nft_set *set,
+                                        const struct nlattr *attr);
+
 void *nft_set_elem_init(const struct nft_set *set,
                        const struct nft_set_ext_tmpl *tmpl,
                        const u32 *key, const u32 *data,
index 545da270e802061873845ee850a21f5ba4aba44d..02ed2de05ea2dc5c4a26e263e6ff6cb72a170845 100644 (file)
@@ -4415,6 +4415,36 @@ static struct nft_trans *nft_trans_elem_alloc(struct nft_ctx *ctx,
        return trans;
 }
 
+struct nft_expr *nft_set_elem_expr_alloc(const struct nft_ctx *ctx,
+                                        const struct nft_set *set,
+                                        const struct nlattr *attr)
+{
+       struct nft_expr *expr;
+       int err;
+
+       expr = nft_expr_init(ctx, attr);
+       if (IS_ERR(expr))
+               return expr;
+
+       err = -EOPNOTSUPP;
+       if (!(expr->ops->type->flags & NFT_EXPR_STATEFUL))
+               goto err_set_elem_expr;
+
+       if (expr->ops->type->flags & NFT_EXPR_GC) {
+               if (set->flags & NFT_SET_TIMEOUT)
+                       goto err_set_elem_expr;
+               if (!set->ops->gc_init)
+                       goto err_set_elem_expr;
+               set->ops->gc_init(set);
+       }
+
+       return expr;
+
+err_set_elem_expr:
+       nft_expr_destroy(ctx, expr);
+       return ERR_PTR(err);
+}
+
 void *nft_set_elem_init(const struct nft_set *set,
                        const struct nft_set_ext_tmpl *tmpl,
                        const u32 *key, const u32 *data,
index 6fdea0e57db8a61bd3cab14ebda0dd4dd0bb10c6..d50ff93bbf7ca2065db76c414f329a2a276cc3cf 100644 (file)
@@ -199,21 +199,10 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
                if (!(set->flags & NFT_SET_EVAL))
                        return -EINVAL;
 
-               priv->expr = nft_expr_init(ctx, tb[NFTA_DYNSET_EXPR]);
+               priv->expr = nft_set_elem_expr_alloc(ctx, set,
+                                                    tb[NFTA_DYNSET_EXPR]);
                if (IS_ERR(priv->expr))
                        return PTR_ERR(priv->expr);
-
-               err = -EOPNOTSUPP;
-               if (!(priv->expr->ops->type->flags & NFT_EXPR_STATEFUL))
-                       goto err1;
-
-               if (priv->expr->ops->type->flags & NFT_EXPR_GC) {
-                       if (set->flags & NFT_SET_TIMEOUT)
-                               goto err1;
-                       if (!set->ops->gc_init)
-                               goto err1;
-                       set->ops->gc_init(set);
-               }
        }
 
        nft_set_ext_prepare(&priv->tmpl);