Skip to content

Commit 89d6ab2

Browse files
committed
netfilter: nf_tables: disallow rule removal from chain binding
jira VULN-34732 cve CVE-2023-5197 commit-author Pablo Neira Ayuso <pablo@netfilter.org> commit f15f29f upstream-diff Used the cleanly applying 9.4 backport 29530d2 Chain binding only requires the rule addition/insertion command within the same transaction. Removal of rules from chain bindings within the same transaction makes no sense, userspace does not utilize this feature. Replace nft_chain_is_bound() check to nft_chain_binding() in rule deletion commands. Replace command implies a rule deletion, reject this command too. Rule flush command can also safely rely on this nft_chain_binding() check because unbound chains are not allowed since 62e1e94 ("netfilter: nf_tables: reject unbound chain set before commit phase"). Fixes: d0e2c7d ("netfilter: nf_tables: add NFT_CHAIN_BINDING") Reported-by: Kevin Rich <kevinrich1337@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> (cherry picked from commit f15f29f) Signed-off-by: Marcin Wcisło <marcin.wcislo@conclusive.pl>
1 parent ff501e7 commit 89d6ab2

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

net/netfilter/nf_tables_api.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,7 +1371,7 @@ static int nft_flush_table(struct nft_ctx *ctx)
13711371
if (!nft_is_active_next(ctx->net, chain))
13721372
continue;
13731373

1374-
if (nft_chain_is_bound(chain))
1374+
if (nft_chain_binding(chain))
13751375
continue;
13761376

13771377
ctx->chain = chain;
@@ -1416,7 +1416,7 @@ static int nft_flush_table(struct nft_ctx *ctx)
14161416
if (!nft_is_active_next(ctx->net, chain))
14171417
continue;
14181418

1419-
if (nft_chain_is_bound(chain))
1419+
if (nft_chain_binding(chain))
14201420
continue;
14211421

14221422
ctx->chain = chain;
@@ -2733,6 +2733,9 @@ static int nf_tables_delchain(struct sk_buff *skb, const struct nfnl_info *info,
27332733
return PTR_ERR(chain);
27342734
}
27352735

2736+
if (nft_chain_binding(chain))
2737+
return -EOPNOTSUPP;
2738+
27362739
if (info->nlh->nlmsg_flags & NLM_F_NONREC &&
27372740
chain->use > 0)
27382741
return -EBUSY;
@@ -3721,6 +3724,11 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info,
37213724
}
37223725

37233726
if (info->nlh->nlmsg_flags & NLM_F_REPLACE) {
3727+
if (nft_chain_binding(chain)) {
3728+
err = -EOPNOTSUPP;
3729+
goto err_destroy_flow_rule;
3730+
}
3731+
37243732
err = nft_delrule(&ctx, old_rule);
37253733
if (err < 0)
37263734
goto err_destroy_flow_rule;
@@ -3828,7 +3836,7 @@ static int nf_tables_delrule(struct sk_buff *skb, const struct nfnl_info *info,
38283836
NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_CHAIN]);
38293837
return PTR_ERR(chain);
38303838
}
3831-
if (nft_chain_is_bound(chain))
3839+
if (nft_chain_binding(chain))
38323840
return -EOPNOTSUPP;
38333841
}
38343842

@@ -3862,7 +3870,7 @@ static int nf_tables_delrule(struct sk_buff *skb, const struct nfnl_info *info,
38623870
list_for_each_entry(chain, &table->chains, list) {
38633871
if (!nft_is_active_next(net, chain))
38643872
continue;
3865-
if (nft_chain_is_bound(chain))
3873+
if (nft_chain_binding(chain))
38663874
continue;
38673875

38683876
ctx.chain = chain;
@@ -10661,7 +10669,7 @@ static void __nft_release_table(struct net *net, struct nft_table *table)
1066110669
ctx.family = table->family;
1066210670
ctx.table = table;
1066310671
list_for_each_entry(chain, &table->chains, list) {
10664-
if (nft_chain_is_bound(chain))
10672+
if (nft_chain_binding(chain))
1066510673
continue;
1066610674

1066710675
ctx.chain = chain;

0 commit comments

Comments
 (0)