Skip to content

Commit 0ef235c

Browse files
Florian Westphalummakynes
authored andcommitted
netfilter: nf_tables: warn when expr implements only one of activate/deactivate
->destroy is only allowed to free data, or do other cleanups that do not have side effects on other state, such as visibility to other netlink requests. Such things need to be done in ->deactivate. As a transaction can fail, we need to make sure we can undo such operations, therefore ->activate() has to be provided too. So print a warning and refuse registration if expr->ops provides only one of the two operations. v2: fix nft_expr_check_ops to not repeat same check twice (Jones Desougi) Signed-off-by: Florian Westphal <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent cd5125d commit 0ef235c

File tree

1 file changed

+19
-0
lines changed

1 file changed

+19
-0
lines changed

net/netfilter/nf_tables_api.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,18 @@ static int nft_delchain(struct nft_ctx *ctx)
207207
return err;
208208
}
209209

210+
/* either expr ops provide both activate/deactivate, or neither */
211+
static bool nft_expr_check_ops(const struct nft_expr_ops *ops)
212+
{
213+
if (!ops)
214+
return true;
215+
216+
if (WARN_ON_ONCE((!ops->activate ^ !ops->deactivate)))
217+
return false;
218+
219+
return true;
220+
}
221+
210222
static void nft_rule_expr_activate(const struct nft_ctx *ctx,
211223
struct nft_rule *rule)
212224
{
@@ -1907,6 +1919,9 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk,
19071919
*/
19081920
int nft_register_expr(struct nft_expr_type *type)
19091921
{
1922+
if (!nft_expr_check_ops(type->ops))
1923+
return -EINVAL;
1924+
19101925
nfnl_lock(NFNL_SUBSYS_NFTABLES);
19111926
if (type->family == NFPROTO_UNSPEC)
19121927
list_add_tail_rcu(&type->list, &nf_tables_expressions);
@@ -2054,6 +2069,10 @@ static int nf_tables_expr_parse(const struct nft_ctx *ctx,
20542069
err = PTR_ERR(ops);
20552070
goto err1;
20562071
}
2072+
if (!nft_expr_check_ops(ops)) {
2073+
err = -EINVAL;
2074+
goto err1;
2075+
}
20572076
} else
20582077
ops = type->ops;
20592078

0 commit comments

Comments
 (0)