Commit 4548ad72 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Pablo Neira Ayuso says:

====================
Netfilter fixes for net

1) Fix UAF when creating non-stateful expression in set.

2) Set limit cost when cloning expression accordingly, from Phil Sutter.

* git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf:
  netfilter: nft_limit: Clone packet limits' cost value
  netfilter: nf_tables: disallow non-stateful expression in sets earlier
====================

Link: https://lore.kernel.org/r/20220526205411.315136-1-pablo@netfilter.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 6c465408 558254b0
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -2873,27 +2873,31 @@ static struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,

	err = nf_tables_expr_parse(ctx, nla, &expr_info);
	if (err < 0)
		goto err1;
		goto err_expr_parse;

	err = -EOPNOTSUPP;
	if (!(expr_info.ops->type->flags & NFT_EXPR_STATEFUL))
		goto err_expr_stateful;

	err = -ENOMEM;
	expr = kzalloc(expr_info.ops->size, GFP_KERNEL_ACCOUNT);
	if (expr == NULL)
		goto err2;
		goto err_expr_stateful;

	err = nf_tables_newexpr(ctx, &expr_info, expr);
	if (err < 0)
		goto err3;
		goto err_expr_new;

	return expr;
err3:
err_expr_new:
	kfree(expr);
err2:
err_expr_stateful:
	owner = expr_info.ops->type->owner;
	if (expr_info.ops->type->release_ops)
		expr_info.ops->type->release_ops(expr_info.ops);

	module_put(owner);
err1:
err_expr_parse:
	return ERR_PTR(err);
}

@@ -5413,9 +5417,6 @@ struct nft_expr *nft_set_elem_expr_alloc(const struct nft_ctx *ctx,
		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;
+2 −0
Original line number Diff line number Diff line
@@ -213,6 +213,8 @@ static int nft_limit_pkts_clone(struct nft_expr *dst, const struct nft_expr *src
	struct nft_limit_priv_pkts *priv_dst = nft_expr_priv(dst);
	struct nft_limit_priv_pkts *priv_src = nft_expr_priv(src);

	priv_dst->cost = priv_src->cost;

	return nft_limit_clone(&priv_dst->limit, &priv_src->limit);
}