From: Pablo Neira Ayuso <pablo@netfilter.org>
To: Phil Sutter <phil@nwl.cc>, Florian Westphal <fw@strlen.de>,
Matthieu Baerts <matttbe@kernel.org>,
netfilter-devel@vger.kernel.org,
Jozsef Kadlecsik <kadlec@netfilter.org>,
coreteam@netfilter.org
Subject: Re: Netfilter: suspicious RCU usage in __nft_rule_lookup
Date: Fri, 25 Oct 2024 15:16:26 +0200 [thread overview]
Message-ID: <ZxuaKpavQuIMIRC8@calendula> (raw)
In-Reply-To: <ZxuEXQe3j8rH_3c5@calendula>
[-- Attachment #1: Type: text/plain, Size: 375 bytes --]
On Fri, Oct 25, 2024 at 01:43:28PM +0200, Pablo Neira Ayuso wrote:
> On Fri, Oct 25, 2024 at 12:56:03PM +0200, Phil Sutter wrote:
[...]
> > We would not change behaviour in stable this way, also not the worst
> > thing to do. Your call!
>
> I am still exploring how ugly this fix looks, you will see get to know.
This is a quick preview, compile-tested only at this stage.
[-- Attachment #2: candidate-fix.patch --]
[-- Type: text/x-diff, Size: 2441 bytes --]
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 91ae20cb7648..8dd8e278843d 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -1120,6 +1120,7 @@ struct nft_chain {
char *name;
u16 udlen;
u8 *udata;
+ struct rcu_head rcu_head;
/* Only used during control plane commit phase: */
struct nft_rule_blob *blob_next;
@@ -1282,6 +1283,7 @@ struct nft_table {
struct list_head sets;
struct list_head objects;
struct list_head flowtables;
+ possible_net_t net;
u64 hgenerator;
u64 handle;
u32 use;
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index a24fe62650a7..762879187edb 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -1495,6 +1495,7 @@ static int nf_tables_newtable(struct sk_buff *skb, const struct nfnl_info *info,
INIT_LIST_HEAD(&table->sets);
INIT_LIST_HEAD(&table->objects);
INIT_LIST_HEAD(&table->flowtables);
+ write_pnet(&table->net, net);
table->family = family;
table->flags = flags;
table->handle = ++nft_net->table_handle;
@@ -11430,22 +11431,39 @@ int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
}
EXPORT_SYMBOL_GPL(nft_data_dump);
-int __nft_release_basechain(struct nft_ctx *ctx)
+static void __nft_release_basechain_rcu(struct rcu_head *head)
{
+ struct nft_chain *chain = container_of(head, struct nft_chain, rcu_head);
struct nft_rule *rule, *nr;
+ struct nft_ctx ctx = {
+ .family = chain->table->family,
+ .net = read_pnet(&chain->table->net),
+ };
+
+ list_for_each_entry_safe(rule, nr, &chain->rules, list) {
+ list_del(&rule->list);
+ nf_tables_rule_release(&ctx, rule);
+ }
+ nf_tables_chain_destroy(chain);
+ put_net(ctx.net);
+}
+
+int __nft_release_basechain(struct nft_ctx *ctx)
+{
+ struct nft_rule *rule;
if (WARN_ON(!nft_is_base_chain(ctx->chain)))
return 0;
nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain);
- list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
- list_del(&rule->list);
+ list_for_each_entry(rule, &ctx->chain->rules, list)
nft_use_dec(&ctx->chain->use);
- nf_tables_rule_release(ctx, rule);
- }
+
nft_chain_del(ctx->chain);
nft_use_dec(&ctx->table->use);
- nf_tables_chain_destroy(ctx->chain);
+ get_net(ctx->net);
+
+ call_rcu(&ctx->chain->rcu_head, __nft_release_basechain_rcu);
return 0;
}
next prev parent reply other threads:[~2024-10-25 13:16 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-24 16:56 Netfilter: suspicious RCU usage in __nft_rule_lookup Matthieu Baerts
2024-10-24 17:35 ` Florian Westphal
2024-10-24 18:00 ` Pablo Neira Ayuso
2024-10-24 17:57 ` Pablo Neira Ayuso
2024-10-24 18:20 ` Pablo Neira Ayuso
2024-10-24 23:22 ` Florian Westphal
2024-10-25 8:14 ` Matthieu Baerts
2024-10-25 9:23 ` Florian Westphal
2024-10-25 9:42 ` Pablo Neira Ayuso
2024-10-25 9:46 ` Phil Sutter
2024-10-25 10:26 ` Pablo Neira Ayuso
2024-10-25 10:56 ` Phil Sutter
2024-10-25 11:43 ` Pablo Neira Ayuso
2024-10-25 13:16 ` Pablo Neira Ayuso [this message]
2024-10-25 10:35 ` Pablo Neira Ayuso
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZxuaKpavQuIMIRC8@calendula \
--to=pablo@netfilter.org \
--cc=coreteam@netfilter.org \
--cc=fw@strlen.de \
--cc=kadlec@netfilter.org \
--cc=matttbe@kernel.org \
--cc=netfilter-devel@vger.kernel.org \
--cc=phil@nwl.cc \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox